Python debugging problem with dynamic text

I am a python noob, but have written a short Python script attached to the property actuator of a HUD:

# Setting things up

# get the bpy and GameLogic modules
import bpy
import GameLogic 

# get controller script is attached to
controller = GameLogic.getCurrentController()

# get a list of actuators attached to the controller
actList = controller.actuators

# get the property actuator named prop-position
position = actList["prop-position"]


# assign the bpy.data.objects 
Ship = bpy.data.objects["Ship"]

# get location data
x = str(int(Ship.location[0]))
y = str(int(Ship.location[1]))
z = str(int(Ship.location[2]))

position_out = "Position = [ " +x+" , "+y+" , "+z+" ]"

# position.value = position_out   {replaced with simple test string, (below,) for debugging}

position.value =  "help" 

controller.activate("prop-position")

Basically it is supposed to read the ships position and output that position as a string to the HUD.

For debugging, it is supposed to use the test string “help”, however what it does output is the string “[help not found]”.

The console reports no errors and I am using Blender 2.54. Could someone please point me in the right direction.

Okay, I have figured this out and in case someone arrives here looking for answers, here is the corrected code:

# Setting things up
# get the bpy and GameLogic modules
import bpy
import GameLogic 

# assign the objects 
Ship = bpy.data.objects["Ship"]                               ## debug from the overlay scene
Position = GameLogic.getCurrentScene().objects['Position']   ## ("Position" is the HUD overlay object)

# get location data
x = str(int(Ship.location[0]))
y = str(int(Ship.location[1]))
z = str(int(Ship.location[2]))

# make the output string
position_out = "Position = [ "  + x + " , " + y + " , " +  z + " ]"

# Do the business
Position['Text'] = position_out      ## "Text" is the string property of "Position"

# End script

For me this is a very satisfying result: It means I don’t need piles of different scripts and logic bricks to pad out the HUD Telemetry, but can have just one telemetry script attached to an “always” timer that updates all the telemetry once or twice a second :smiley:
.

Merde, spoke too soon. The above is a big improvement, but…

  1. It partially works as in it gives the expected output with the start/ rest position of the ship, but once the ship is moving it does not update the position.

  2. Also, I want to change the linePosition = GameLogic.getCurrentScene().objects[‘Position’]
    ToPosition = bpy.data.objects[‘Position’]
    So that I can run it from any scene, the problem is that if I do that, it does not even partially work

Does anybody have any ideas?

This time I have finally got it sussed, I have given the ship a couple of drives around the Solar System and there was no problems. The big secret is to use the “GameLogic.GlobalDict” to pass data between the main scene and the HUD overlay scenes.

Essentially, the Ship has an “always” sensor, (set to click once or twice a second,) with an attached python script that captures and calculates, the data and sends it to the Global Dictionary. Each element of the HUD also has a similar “always” sensor attached to a python script that retrieves the updated data from the global dictionary and sends it to the text property of the HUD element.

The data collection code is:

# Setting things up
# get the GameLogic module
import GameLogic

# get controller script is attached to
controller = GameLogic.getCurrentController()

# get new position
[x,y,z] = controller.owner.worldPosition

# recover old position
ox = controller.owner["prev_x"]
oy = controller.owner["prev_y"]
oz = controller.owner["prev_z"]

# make direction vector as a string
vx = str(int(10*(x-ox))/10)
vy = str(int(10*(y-oy))/10)
vz = str(int(10*(z-oz)/10))

# make the position vector a strings
sx = str(int(x))
sy = str(int(y))
sz = str(int(z))

# combine for the output strings
position_out = "Position = [ "  + sx + " , " + sy + " , " +  sz + " ]"
direction_out = "Direction = [ "  + vx + " , " + vy + " , " +  vz + " ]"


# save this position in pilot property "prev_x,y,z"
controller.owner["prev_x"] = x
controller.owner["prev_y"] = y
controller.owner["prev_z"] = z

# send vector strings to HUD
GameLogic.globalDict["position_vec"] = position_out
GameLogic.globalDict["direction_vec"] = direction_out

# End script

By way of explanation, the previous positions are stored in pilots properties and used to calculate a displacement or direction vector. There are a couple related standard functions but they are not really usable. Currently, the displacement vector is displayed as raw numbers and requires some work, but the principle works and I get constantly updated data onto the HUD display.

The HUD display code is:

# Setting things up
# get the  GameLogic module
import GameLogic


# get controller script is attached to
controller = GameLogic.getCurrentController()

# get new position vector string
position_out = GameLogic.globalDict["position_vec"]

# send it to the HUD-Position property "Text"
controller.owner["Text"] = position_out

# End script

Finally, the only reference that I have is this one and I wish anyone trying to understand it the best of luck and advise patience and dedication :smiley:

You don’t have to use GameLogic.globalDict. Any variable set to GameLogic (or bge.logic, now) is global. So, if you said:

Ship code

from bge import logic
cont = logic.getCurrentController()
obj = cont.owner
logic.shippos = obj.position

HUD code

from bge import logic
cont = logic.getCurrentController()
obj = cont.owner
obj[‘Text’] = string(logic.shippos)

That probably would’ve worked. Of course, I haven’t tested it, so it probably wouldn’t have displayed like yours. However, that’s great coding (I never use vectors like that).

I am not going to check out your code though I will reference it the next time I try this.

I will say that I struggled for two days trying to pass data between multiple scenes and a quick though, not thorough, check of my notes and saved scripts shows that I tried things very similar to what you suggest and none of them were 100% successful, the second, (partially successful,) script I published here for example has similar qualities to what you suggest and I tried god knows how many variations on that one.

But anyway, I am happy, (now,) and hope that my struggles will help some other noob in the future.

Finally, my last words, Gurus please note this could be the subject of a valued and often referenced tutorial. There is very little on this out there, I was reduced to plowing through the API documentation looking for clues, till i discovered that the documentation was duplicated on “Tutorials for Blender 3D” in a slightly more accessible form and started to plow through that instead.

Of course you will have problems later if you use instances, for example if you spawn enemy ships from a spawner and you want to get the pos of the nearest enemy.

In that case you can get the objects from a scene and (for obs in scene) run through the list getting the one you want by using a has_key and getdistance to.

So I usually use that method, because then I don’t have to change methods (one script can be used whetehr I’m using instances or not).

Smoking_mirror:

Being a noob, it took me a while to figure out what you were talking about. I did actually try something along those lines, (several things in fact,) I had a couple of problems:

  1. it only returned the default or start positions and refused to update

  2. The technique broke down completely with the HUD, I assume because it was an overlay, though I am not sure.

I have been thinking, in a general sense, about player hazards: asteroids and missiles,(enemy ships seem too complicated for my current level of skill,) what I was thinking of using was the “radar sensor” for warnings and “track to” to allow the missiles to lock on to my ship? Although I have not, as yet, went into the subject with any depth.

AI for a space game is actually very easy.
If I have time during the week I will put together a quick AI that you could use which would:

> get the nearest target (the player wouldbe the target, give him the property “player”)
> track to the player and fly towards him.

The problem with instances, when you spawn an instance of an object is that there can be many copies all with the same “name” and at the same time. So you have to get the name of the object “raw” not as a string or named in a script.

It’s one of the hard things about BGE and some thing you need to start looking at early on. It can be worked around, once you know that the problem exists.

I see what you are getting at about AI, I suspect that you are basically proposing something very similar to what I had in mind for the enemy missiles.

With some ingenuity and skill, one could probably come up with an enemy controller script that was moderately “intelligent”, though it would be a lot easier to do in language like Pascal that supports user defined “complex” data types. (I have only just started to learn Python and I detest C)

I was reading a post about a Blender chess GUI, the posters seemed to think they would have to make their own engine! Anyway, it started me thinking: Since there are quite a few open source chess engines available, I was wondering what the problems were in using Blender to create GUI wrappers. I would not have thought it would have been that difficult, though for the moment I am still struggling with the basics.
.

Here’s a “blender space game” ai.
The enemy ships will track to the player’s ship until they get too close, then they will switch to circling the player.
Have a look at the code and see if there is anything you can’t understand there.
You can find information about all the functions which blender game engine uses here:
http://www.tutorialsforblender3d.com/GameFunctions/ClassIndex_1.html

The fuctions I use are:

get (to check for properties)
get distance to (to compare distances and get the closest)

get vect to (to find the right vector to the target)
align Axis to vector (to “track to” the target)

with these four simple functions you can make a simple AI.
It took me about an hour (mostly testing and bug fixing to get everything working together properly)

Attachments

space_ai.blend (153 KB)

Thanks, I am overwhelmed. There is a slight problem in that, no matter which view, camera or layer I use the enemy ships just seem to fall through the floor. But the idea and the code is good and I will use it as a reference at some point.

Thankyou.

Ps, I did try changing gravity to 0, but it was still the same?

I’m using blender 2.49 so that could be it. ^^ You may have to change a few things to get it to work properly…

That is probably it, using 2.5xx as a learning tool is causing me no end of problems though I feel it is worth persevering with. Having said that, I find that the user interface in 2.5 is much more intuitive for a noob.

I am becoming quite an expert at converting 2.4x blends and scripts to 2.5x but I don’t really have time at the moment for your script, I am much more interested in getting this blend to work for 2.5x

It is a good quality animation sequence for a generic fireball type explosion. The basic blend works on its own in 2.54, but getting it into my game and working is proving to be a challenge. (see here,)

Neither importing the blend directly nor re-blending it from scratch was working, but just as your reply arrived, I suddenly got it working inside my blend. I now have to set it up so that it tracks my weapon reticule and bursts, (or replaces,) the target.

As is usually the case recently I have no idea exactly what it was I did to make it start working inside my game blend, but in this case who cares.

Again, I must say thank you for your efforts