8 Replies - 1354 Views - Last Post: 17 January 2012 - 09:20 AM Rate Topic: -----

#1 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Passing undefined variables?

Posted 16 January 2012 - 05:11 AM

Ok so i have been working on a game in python and i am trying to make a more modular, reusable interface for the game. I have character object with variables like health etc. and a list of characters (player and enemies) and on this chracter object, when an enemy is targeted it has a variable called target so i do something like this when the player has a target.
characters["Player"].target = characters["Enemy1"]

and when there is no target then .target is None.

Now when i use my interface i have made, when the game starts, you define all the elements on the interface (player name, player health, enemy name, enemy health etc.) and their positions and the interface module deals with drawing them and any updates and or button that may be on the interface.

My problem is that at the begging of the game when i have to define the interface elements for the enemy stats area i do this
stat = characters["Player"].target.health
Interface.add_stat_bar(x, y, stat)


Problem is the player does not always have a target. so the above code fails because character["Player"].target == None.

I am not sure how to fix this, i already have a system in place that only draws the elements effected if the player has a target but i still need to store the variable location at the begging. is there any way to store a location but not actually look inside it until it is needed?

Thanks in advance, if i can get this working the rest of my game should fall into place fine.
Nekroze

Is This A Good Question/Topic? 0
  • +

Replies To: Passing undefined variables?

#2 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Passing undefined variables?

Posted 16 January 2012 - 07:25 AM

One way to do it would be to store the key for the character, rather than the character itself:

characters["Player"].target = "Enemy1"
...
target = characters["Player"].target
stat = characters[target].health
Interface.add_stat_bar(x, y, stat)


Was This Post Helpful? 0
  • +
  • -

#3 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Re: Passing undefined variables?

Posted 16 January 2012 - 08:09 AM

to be clear the add_stat_bar function of the interface adds a set of variables to a list of widgets that the developer has defined for the interface, stores the inputed values, then later in the main loop draws the widgets as directed.

this is a very simplistic show of what the add_stat_bar function looks like:
class Interface:
 self.widgets = {}
 self.lastwidget = 0
 
 def add_stat_bar(self, x, y, stat):
  self.widgets[lastwidget] = {"Type":"StatBar", "X": x, "Y": y, "Stat": stat}
  self.lastwidget += 1


This way when i sort widgets dictionary then i can draw the widgets in the order they where added to the interface incase the developer wants that kind of thing.

But because of this i am not sure your solution would work because, correct me if i am wrong, but it would still look into character["Player"].target in order to reference the stat target.health so it would once again fail because the players target is nothing, right?

Thanks Motoma, for your always swift and useful responses.

This post has been edited by Nekroze: 16 January 2012 - 08:10 AM

Was This Post Helpful? 0
  • +
  • -

#4 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Passing undefined variables?

Posted 16 January 2012 - 08:26 AM

Perhaps I misunderstood your problem. I was assuming that you ran into an issue where you wanted Player1's target to be Enemy1, but because you hadn't created Enemy1 yet, target was set to None. The code I listed would allow Player1 to have Enemy1 as a target as soon as Enemy1 is created.

However, if your problem is that you want to add your status bar before the entity that backs it is created, then solutions are a bit different.

If you know that there will always be an Enemy1 character, you can pre-initialize your the character. When the character's stats get updated, your stat bar will pull the information automatically.

Another option is to pass the character reference to the stat bar; similar to my code above, but you would pass target directly to the add_stat_bar function, and let it look up the value from characters at render time.

A third way would be to add the widget only when the backing data is available! Rather than using a FIFO list to maintain order, you would use a heap queue (priority queue) to control the order in which they are rendered.
Was This Post Helpful? 0
  • +
  • -

#5 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Re: Passing undefined variables?

Posted 16 January 2012 - 08:41 AM

ah yes, sorry i was not clear, my issue is not when the player has a target it is when the player has no target, before the map is started.

View PostMotoma, on 16 January 2012 - 08:26 AM, said:

Another option is to pass the character reference to the stat bar; similar to my code above, but you would pass target directly to the add_stat_bar function, and let it look up the value from characters at render time.


This seems to be a good idea to solve it, i would have to implement some kind of final variable for which stat so it would have to be something like this?:
 def add_stat_bar(self, x, y, target, stat):
  self.widgets[lastwidget] = {"Type":"StatBar", "X": x, "Y": y, "Stat": stat, "Target": target}
  self.lastwidget += 1


then the actual draw function would have to look through all of the possible stat inputs which are string and hardcode their object counterparts ie:
if self.widgets[0]["Stat"] == "Health":
 draw(self.widgets[0]["Target"].health)
elif self.widgets[0]["Stat"] == "Magic":
 draw(self.widgets[0]["Target"].magic)


that should work i beleive. Will give it a go, thanks Motoma. Will report back once i give it a go!
Was This Post Helpful? 0
  • +
  • -

#6 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Re: Passing undefined variables?

Posted 16 January 2012 - 09:29 AM

Ok so far it seems to work as it has passed the functions that previously crashed it however i am not getting things drawn on the screen properly and the switch to draw the enemy data only if an enemy is targeted isnt showing up in any circumstance... i will work on testing this as this is the first time this new interface system has even gotten to draw, i may have made mistakes on those parts however one of the main problems i am having atm is that text is showing up to be pure white boxes not even white letters and when i aquire a target it should draw those white boxes around the place aswell...

EIDT: Ok i have fixed up the white text, just some silly mistakes on my part. now i have got it all working and diagnosed exactly why my enemy data is not showing up, it is the same reason that my normal stats will not change at all. it seems when i am storing stats in my widgets dictionary it is not using a reference but it is capturing the state of the in putted stat at the time i define the widget/interface thus when my player looses health, gains a level, targets an enemy although the game can calculate the damages and if the player has died and respond accordingly the interface will not display that because the health that it is displaying is not the health of the player each time it is draw (as i need it to be) but rather the health the player had when he started the game/map.

From what i understood, python would always use a reference rather then a copy when a variable is assigned to another variable unless explicitly told to copy... i have not done this so what is going on?

Quick Report, working better now give me time to see if all is fixed and i can close this thread.

Big thanks Motoma.
Nekroze

This post has been edited by Nekroze: 16 January 2012 - 09:50 AM

Was This Post Helpful? 0
  • +
  • -

#7 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Re: Passing undefined variables?

Posted 17 January 2012 - 06:42 AM

I have changed self.widgets to a list actualy so the add_stat_bar uses this now:
def add_stat_bar(self, x, y, target, stat):
 self.widgets.append({"Type":"StatBar", "X": x, "Y": y, "Stat": stat, "Target": target})

I now realize it is much more likely that the append function does not do references but only makes copies of the values it is given, is there anyway to force it to reference?
Was This Post Helpful? 0
  • +
  • -

#8 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Passing undefined variables?

Posted 17 January 2012 - 07:20 AM

If you pass the character object, rather than that stat you want to display, you should be fine. Consider:
>>> class Character:
...   target = None
...   stat = 50
... 
>>> player = Character()
>>> enemy = Character()
>>> player.target = enemy
>>> enemy.target = player
>>> player.stat = 100
>>> enemy.stat = 10
>>> player.target.stat
10


Was This Post Helpful? 0
  • +
  • -

#9 Nekroze  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 170
  • Joined: 08-May 11

Re: Passing undefined variables?

Posted 17 January 2012 - 09:20 AM

I have managed to get this working with the help of the good people at #python irc.

Thanks a lot for the help guys, it has gotten me very close to getting this all working.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1