Bullet - I am your father! - Objectcommunication

Hi, a bad reference - i know.
But this thread is about reference and values.
I have some ideas, but the thing thats always on my mind is, that my ways may need to much processing-time.
The questions i mention are about the general solution of object/value-communication, but for the fun/understanding.
imagine a spacegame with hundreds of lasers.
I guess its better to ask for help to do it better/not wrong from the beginning.
Both problems seem highly related, but i dont know how to solve them efficient,
any helping resource, ideas? how would you solve that?

Whats are the (2) problems:

  1. Imagine i spawn a bullet. It “kills” an enemy. Now i want to add a score-point to the player who set the final shot. How is the information stored and transmitted?[INDENT=2]
    Solving-Suggestions:

a) I may parent the laser/bullet to the shooter,
and the dying enemy is asking for the bullet-parent-object.
and after that tells via message the name of the parent-object?

b) Does the Player tells a message " i am your father" to the spawn,
which adds a value to a property - to save who is the “father”?

c) A bullet is spawned and is parented to the shooter.
If a laser/bullet collides and is ended bacause of that
it checkes with which object it has collided.
It tells that object who is the parent.

d) maybe you have other Ideas.

I am not certain how to code a/b/… but i guess i will get that, with some time (and the Blender API)
[/INDENT]

  1. In a game, different Robot-Enemys have different strength.But they all fire the object “Laser” right from their eyes.

The Laser should be stronger if the enemy is stronger.
Or imagine it has a “power”, which is reduced, when it hits and pass through walls, until its power is “0”.

The Player-object is hit by different Laser-objects.
Laser 1 has 30 Power left -> should add -30 Hitpoints to the player.
Laser 2 has 40 Power left -> should add -40 Hitpoints to the player.
How does the Laser tell the Player, “hey i got that amount of damage and you should lose HP according to it”.

Suggestions: none

Use object.rayCast() for the lasers and then you know who is shooting, who got hit and stuff like that.

Thank you for your answer!
I have not much time to test it, but from the first impressions i think it will not work the way i imagined it should work.
It seems to be not flexible.
A Look inside this
http://www.tutorialsforblender3d.com/GameModule/ClassKX_GameObject_22.html
tells me, that the ray ~is an instant laserbeam between an Object (Collision-Object) and a Position.
That is great if the Object which fires is stationary and the Bullets can only move linear.
The ray will instantly fire all the way back and hit the spawn.
If the Object can move while the projectile travels
or the Bullet needs time to fly
and is influenced by reflection from walls (riochet)
or wind (imagine an arrow instead a usual projectile) or whatever, this will not return the Spawn or the player behind the Spawn.
The Ray is -in the mentioned scenarios- only flexible if i have a big calculation script, which calculates where the projectile may have come from. I guess thats quite difficult to handle and not very efficient.

Another Problem with rays may be, the ray shoots back and get the weapon instead of the player.
Ok, i can use a property which tells the ray to look further or return a value, but if i have my weapon/spawn a bit outside my player-collisionbox the ray can’t hit the player which commands the spawn of my bullet/arrow/laser. And because the weapon has not the right property (playerid = 1234) nothing will happen.

I would use collision with a ghost invisible plane in front of the gun to assign a value damage, that way each enemy just needs a little bit of adjustment, (adding 1 object with a value)

:slight_smile:

How does this work? I guess i dont understand :frowning: …maybe. I will try to go through your information and my thought to it.
But if i am wrong, can you describe with more details, which part of what does what? I am not very experienced and what seems clear for you isnt for me.

What i understood:
My Player Object has a Spawn. Before that i add a ghost-plane. If the bullet hits the plane, on collision, its property damage gets the value assigned.
With each “upgrade” of players power, i can replace the value of the ghostplane with a higher value.
The Reference to the “father” is assigned the same way, i guess. Saved in a String?

Ok, looks quite interesting!
And if i hit the enemy on collision i can ask the object which collides what its value is, and what its “father” is.

Did i get it right?
This seems a cool solution! Thanks for that.
Now i need only find out what the code for this may look like :slight_smile:

You wrote the bullet kills the enemy. This is one task. Then you said you want to give the player who shot te bullet the score.

So for scoring (which is a separate task) you need a relation between the “killing event” and the player that is responsible for this bullet.

This in general is more a question of your game model rather than the geometric relations (parenting). You need to trace back the cause of the killing event. There are several options to do that. An easy option is to distribute the responsibility or ownership.
Example:
The player triggers a gun to fire. The gun belongs to the player.
The gun creates a bullet that flies into space. The bullet belongs to the gun which belongs to the player.
The bulet hits the enemy and kills him = “kill event”. The relatin to the player is: bullet belongs to gun which belongs to player.

How to model this relationsship?
store it in a property, use other relationships, calculate it somehow.

You coul mark your bulets e.g with a color, or property
Bullet[belongsTo] = Gun[belongsTo]
Gun[belongsTo] = Gun.parent
Gun.parent = Player

This is indeed a small example you can have a much longer responsibility chain. But i hope you get the idea.
Concrete example: give the bullet you spawn the property “player” with value “me”. So you know if a bullet with property player==me kills the enemy it is your score ;). Just make sure nobody else uses the same bullets/property value.

When you score do not mix with other things. To calculate score you only need to know
A) how much to score and
B) to whom to assign the score to.

A might involve the killed enemy
B is explainef above

I hope it helps

Bullet
(logic)
properties
Damage
WhoSentYou


“Collision” property “setDamage”------------python -(see below)


#python below
import bge
cont = bge.logic.getCurrentController()
own = cont.owner

target = bge.logic.getCurrentController().sensors[“Sensor”].hitObject
main()

Damage=target[‘Damage’]
own[‘WhoSentYou’]=target
own[‘Damage’]=Damage

So in plane
Property
Bullet
setDamage
Damage

In enemy(logic)
Health
RecentDamage
Damage


if Collide property Bullet--------Python
if property “Health” is 0 or less----------------------and--------------------------end object
_______________________________________---------------message to score keeper add value

#python
import bge
cont = bge.logic.getCurrentController()
own = cont.owner

target = bge.logic.getCurrentController().sensors[“Sensor”].hitObject
main()

Damage=target[‘Damage’]

own[‘RecentDamage’]=Damage
Health = own[‘Health’]
Health=Health-Damage
own[‘Health’]=Health

Bump edited alot

No problem :slight_smile:

Happy blending!

nice work :slight_smile:

you can setup the bullet is a way more easy and robust

in your script


if pressSpace:


  spawned_object= scene.addObject("nameBullet", own, 50) #name of the obj to add, position ,life(as in the brick)


  # spawned_object is the ID of the obj you have add, yes it already exist :)
  # so , change/add the property to the bullet 
  
  spawned_object['belongs_to'] = own



PS: i’m not sure if act.instantAddObject() is exactly the equivalent of scene.addObject().
but not see any reason to use it since in the best case your code become more long

I checked the methods with dir() , i guess you have less Options like ‘objectLastCreated’ but as long as you dont want to acess the different Options, both Functions seem to be equal and spawn the Object in the same Logic Tick.

Thanks for all helpers!

Well, that was the theory, the practical result is different.

Example 1:

 cont = bge.logic.getCurrentController()
    own = cont.owner
    keyboard = bge.logic.keyboard
    scene = bge.logic.getCurrentScene()
    scenelist =  bge.logic.getSceneList()
    act = cont.actuators['add_object']
    
    if act.objectLastCreated:   #Check for Created Objects
        spawned_object = act.objectLastCreated
        if spawned_object['belongs_to'] == 'NoOne' :
            spawned_object['belongs_to'] = own
            spawned_object['End_damage'] =  own['Base_Weapon_Energy'] * spawned_object['Base_damage']
            print(spawned_object['End_damage'])

     
    if bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.SPACEKEY]: #Create Objects with SPACE
        act.instantAddObject()

What this code does:

  1. It spawns multiple objects, if i keep pressing the Spacebutton.
  2. Tells the Objects about his origin (Player)
  3. has collision with the target! ->ends the target

Example 2:



   if keyboard.events[bge.events.SPACEKEY] == 1 :         
       spawned_object = scene.addObject("Bullet_GreenLaser", own, 50)         
       spawned_object['belongs_to'] = own         
       spawned_object['End_damage'] =  own['Base_Weapon_Energy'] * spawned_object['Base_damage']
  

What this code does:

  1. It spawns a single object, to continue pressing the SPACEKEY doesn’t spawn more than 1 Object.
  2. Tells the Object about his origin (Player)
  3. has collision with the target! -> ends the target

Conclusion, this is not a function with equal functionality!

1)cont.activate(act) ->spawns multiple objects, while pressing
2)act.instantAddObject() ->spawns multiple objects, while pressing
3)scene.addObject(“”,) ->spawns a single object

Conclusion, this is not a function with equal functionality!

1)cont.activate(act) ->spawns multiple objects, while pressing
2)act.instantAddObject() ->spawns multiple objects, while pressing
3)scene.addObject(“”,) ->spawns a single object

The functions themselves don’t know anything about keyboard state. I imagine the difference you are observing has something to do with how you are polling keyboard events, and the set up of the sensor triggering the script controller.

This is probably also why you get duplicate console output, double point addition, etc. For a keyboard sensor set up the default way, you want to check cont.sensors[‘keyboard’].positive before doing anything: the keyboard will send a pulse for true when the key is pressed, and false when it is released. You only want to react to it when the pulse is ‘positive’ (true).

This is different then when just using an AND controller because the AND controller filters out the False pulses.

Here is a revised version. I changed the target logic a bit and cleaned up the according code (target.py).

The score counting was changed as well. So it is now based on the number of received messages.

Attachments

JMH_AddobjectwithOwnerProperty_and_AddScore_Testgame_revised.blend (604 KB)

Another version. This time with a display that tells what attacker fired the deadly projectile.

Attachments

JMH_AddobjectwithOwnerProperty_and_AddScore_Testgame_revised.blend (611 KB)