selecting one from a group of members of a Type

Blitz3D Forums/Blitz3D Programming/selecting one from a group of members of a Type

Ian Martin(Posted 2010) [#1]
This may be a totally obvious question but I am having no luck working it out or finding a solution to it by searching the forums so here goes...

I'm working on a prototype of a game where I have a laser shooting as a single instant beam. I have enemies in a Type something like this:
Type badguy
Field X
Field Y
Field etc.
End Type
The problem is this: when the laser goes through more than one enemy, I need to figure out which one was hit first and stop the laser at that point. In order to do this, I am going through the members of the Type with Each, seeing which enemies are hit, then going through again trying to figure which one is closest to the laser. What I am wondering is how do I select a particular member of a Type? I would like to figure which enemies are hit, mark them somehow, and then check just the members hit to see which is hit first. Are the Type members identified somehow? I see the commands to move back and forth, first, last, etc. Can I somehow remember the name/number/whatever of a member and just test the ones that fit? It seems like all you can do is look through them all each time or just one at a time.

OK, to summarize, what I am asking is: how can you go through members of a type, set the ones that fit a certain criteria aside, and then select only certain members to test again or process or whatever.

Thanks for reading, any help appreciated! :)

Ian


Matty(Posted 2010) [#2]
The undocumented commands "object" and "handle" are useful for selecting a type instance directly.

for example:

type mytype

;fields etc

end type

for aliens.mytype = each mytype
;     i... processing here....

;okay we want to store this type instance so we can access it directly
     if aliens\ishit=1 then ;your code may differ of course..just an example
          mytypehandle = handle(aliens)
     endif

next

;sometime later you want to refer to the specific 'alien'
aliens.mytype = object.mytype(mytypehandle)




Now, that is a fairly basic example but if you wanted to store more than one handle to a type you could do so through either an array, a bank, or another type just containing the handles to the selected 'aliens'.

Hope that helps.

However, the problem you've mentioned above could also be solved another way...you could have a flag in the type which gets set when an alien is hit, then loop through them all.


Ian Martin(Posted 2010) [#3]
Thanks Matty!

...you could have a flag in the type which gets set when an alien is hit, then loop through them all

This is the way I have it figured to do right now, go through them all twice, see which one is closest. I knew there had to be a way to grab just one individually though. For time's sake, I don't want to go through twice as this is going to be collision code and I'm thinking up to 1000 possible aliens(!) at once or at least in the 100s anyway. At least until I try the code on my wife's netbook!

I will try out the 'handle' command, never heard of it before but I think it is just what I need in this instance :)
So then in the example,
;sometime later you want to refer to the specific 'alien'
aliens.mytype = object.mytype(mytypehandle)

I could use an array where "mytypehandle" is to store each hit alien and check how ever many of them there are to see which was hit first?

Anyway, thanks for the fast response! I never heard of those commands and they aren't in the help docs. You've saved me some hair pulling!

Ian


Matty(Posted 2010) [#4]
Yes, that is correct. (you could use an array).

Although you could use an array, I would think a second type list to store the handles would be the most userfriendly.

I don't know why those commands aren't documented...now...as they are so useful. They are listed as 'unsupported' but they've worked from the beginning and still work now....


Ian Martin(Posted 2010) [#5]
Cool, thanks! I'm new to using types and sometimes they confuse me, so arrays just seem simpler to me. It's funny how whatever you used first as a kid is what you want to go to, heheh A type would probably be better because you can delete extra ones and have whatever size needed - an array would have to be dimensioned first. I need a few hours straight at the computer to sort this all out. Thank you for your help :D
Ian


Stevie G(Posted 2010) [#6]
Can I ask why you need a second loop to check which alien has been hit first? Surely, you can do this in a single loop which means storing handles etc.. is overkill?

It's not clear how you are identifying which alien was hit first so I'm assuming a simple distance check as an example:

Hitfirst.alienT = null
NearDist# = 500000

for a.alienT = each alienT

   Dx# = a\x - Bullet\x
   Dy# = a\y - Bullet\y
   TmpDist# = sqr( Dx * Dx + Dy * Dy )

   if TmpDist < NearDist
     Hitfirst = a
     NearDist =TmpDist 
   endif

next

if HitFirst <> null
  {Destory HitFirst Alien}
  {Delete Bullet}
endif


If there is more to your check then please explain in more detail as there's likely a better and faster way of doing this.

Stevie

Last edited 2010


Charrua(Posted 2010) [#7]
probably i'm late in this thread, but a good technique is to name the blitz entity with the handle of the type instance that holds the info related to it ( NameEntity Entity,Handle(MyObjectInstance) ), so if you picked the entity (in some way) or get it via collisions, then you can get the type variable doing:
var.varType = object.varType(EntityName(PickedEntity()))
and isn't necesary to loop to all the instances.

hope that help

Juan


Ian Martin(Posted 2010) [#8]
Can I ask why you need a second loop to check which alien has been hit first?

Maybe I don't need the second loop, just can't figure out how to do it in one loop. In the game you are shooting a laser that instantly shoots to the edge of the screen. The problem comes in because what happens if you have more than one alien hit by the laser? The laser should stop after hitting the first alien or other object. So if I just do a check for whether the alien has been hit and go through all of the things hit, I will most likely be past the first hit alien/element of the Type and will have to somehow go back to an earlier alien/element.
What I mean is this, say I shoot the laser as a line, collision check this line. Say four aliens are hit. I check the first alien hit, find that it was is 400 pixels away, check the second alien hit and find it is 100 pixels away, check the third alien and find it is 300 pixels away, the fourth, 200 pixels away. I am already past the second alien in the For...Each loop. I need to somehow perform the hit on the second alien.
Basically, if the last alien hit is the closest one, one loop would work, but I won't know which one is closest until all have been checked. Something like that, if that makes sense(?)


Ian Martin(Posted 2010) [#9]
probably i'm late in this thread, but a good technique is to name the blitz entity with the handle of the type instance that holds the info related to it ( NameEntity Entity,Handle(MyObjectInstance) ), so if you picked the entity (in some way) or get it via collisions, then you can get the type variable doing:
var.varType = object.varType(EntityName(PickedEntity()))
and isn't necesary to loop to all the instances.

hope that help

Juan


Thank you Juan, I am looking at using Handle and Object now :)


Matty(Posted 2010) [#10]
Hi Ian,

After reading the other posts, I understand a bit better what your trying to do.

It is actually very easy to do what you want with a single check, without even using the object and handle commands (although it's always good to learn new things...)


MinDist#=999999.99 ;set mindist to a much higher number than is reasonable

StruckAlien. MyType = Null

For Alien.MyType = each MyType
     ;Do Distance Check / Collision Check
     If distancetotarget < MinDist and LaserHitAlien=true then ;store the distance between laser and target in a variable and compare with mindist and also store the collision result 
          MinDist=distancetotarget 
          StruckAlien.MyType = Alien.MyType
     endif   
Next

If StruckAlien.MyType<>null then 
     ;this is your closest alien without going through loop twice or using object handle commands
endif 



Last edited 2010


Ian Martin(Posted 2010) [#11]
Ah, yes! This is exactly what I had in mind, just couldn't figure out how to access just the one member of the Type collection. I'm new to Types in general, mostly just used them to multiply enemies so far. I think this will work well, and in one pass. I know blitz is very fast in straight code outside of functions but I still want it as simple as possible because I hope to have a cloud of enemies onscreen with no slowdown at 60 frames/second.

I'm sure the object and handle stuff will come in handy sometime too, thanks for explaining that as well :)

I'm using Sprite Candy on this prototype, so I am learning that at the same time and the collision is different. I'm used to dealing with absolute screen coordinates and SC seems to be waggling things a bit the way I have the code right now because I'm using automatic facing and movement commands. But that's the fun of doing something new. If I had everything figured out ahead of time, what challenge would there be, heheh

Thanks everybody for helping with this question. These forums are great! :D