Moving data between types
BlitzPlus Forums/BlitzPlus Programming/Moving data between types| 
 | ||
| each type has its own fields. These variables are specific to that type itself, and can't be used anywhere else except between the for blah.blah = each blah loop and when you are initializing the variables. I have my tricky ways to move data between types, but I feel like there is a better way to do it. My current issue is... What is the best way to check if one object has collided with another? I can't really do the whole if imagescollide thing, because they are there own types and their x, y and images are of their own type. What is the best way to go about this? | 
| 
 | ||
| If you design a variable GLOBAL you can use its field also outside the FOR/EACH loop: Type Enemy
    Field No%, X%, Y%
End Type
Global Hulk.Enemy=New Enemy
BlaBla
WaitKey()
Function BlaBla()
    Print Hulk\X
End FunctionYou can also swap this extern type member: 
Type Enemy
    Field No%, X%, Y%
End Type
Global Hulk.Enemy
For i%=0 To 9
     loc.Enemy =New Enemy
     loc\X=i*100
     loc\Y=Rnd(99)
     loc\No=i
Next
BlaBla
Print Hulk\X
WaitKey()
Function BlaBla()
    For  loc.Enemy =Each Enemy
          If loc\No=5
               Hulk=loc
         EndIf
    Next
End Function | 
| 
 | ||
| There's no particular requirement that the variable be global, only that it be any valid variable other than the one controlling the For loop. A loop only automatically increments its controlling variable; anything you put anywhere else will stay where it is. (You should avoid using globals unless you actually need global access to a variable name: in Midimaster's example the value should just be returned by the function, since that's all that the global is actually being used for) You can also put objects straight into variable slots - either local, bank, array, or fields of other objects - as soon as they're created, and not need to loop over them with For at all unless you actually want to loop over the whole list. Once you have a valid variable containing an object, the fields can be used for any purpose and modified at any time. So: Local a.Thing = GetThing() Local b.Thing = GetThing() Local dist# = Sqr((a\x - b\x)^2 + (a\y - b\y)^2) If dist < a\radius Or dist < b\radius Then HandleThingCollision a, b ...is valid, if not especially illuminating. | 
| 
 | ||
| ALright so we're getting somewhere here.  My next question is, say I wanted to spawn a new instance of that type somewhere outside the main program, like for example if you press space it'll spawn an enemy or something.  Then I wanted to check image collision with another type, the player.  What's the best way to do that?  I tried declaring the type as global and then creating a new instance in my while wend loop.  However, this doesn't work because I get an error or my program crashes. | 
| 
 | ||
| By itself that sounds more or less like a normal way to do things. Perhaps you could post some of your particular code? I don't know if this is on the right track, but remember that the type of a variable or value only affects what you can do with the whole variable or value; it doesn't place restrictions on what you use its component fields (if any) for - their own type does. So a player, that is an instace of PlayerType, and a bot, that is an instance of EnemyType, can't both be indiscriminately passed to the same comparison function (checking player/player, bot/bot, or player/bot without specifying) - but they can both contain e.g. an image field, and you can check collisions on the image without worrying about what the type of its owner is. e.g. Local p.Player = ..., e.Enemy = ... If ImagesCollide(p\img, p\x, p\y, 0, e\image, e\xpos, e\ypos, 0) Then ... Using different field names just to visually reinforce that the result of the expression carries no information about how it was obtained: an image is an image regardless of whether it was extracted from a field named img in an object of one type or a field named image in an object of another type. You could also factor out the common elements into a component type (e.g. "Movable"), that both bots and players might "own" instances of - that way you can just compare two Movables without needing to think about what they actually control. (This is a bit more complicated to implement.) Useful if you want to also have bots colliding with other bots, players hunting both players and bots, etc. | 
| 
 | ||
| normally you have one player, but a lot of enemies. Type TPlayer
     Field X%, Y%, Img%
End Type
Type TEnemy
     Field X%, Y%, Img%
End Type
Global Player.TPlayer= New TPlayer
For i%=0 to 9
     Enemy.TEnemy= New TEnemy
Next    
Function CheckAllCollisions()
     For loc.TEnemy =Each TEnemy
          If ImagesCollide(Player\Img, Player\x, Player\y, 0, loc\Img, loc\x , loc\y, 0)
                 Delete loc
          Endif
     Next
End
It is not necessary, that the player is GLOBAL, but it is more easy to understand for beginners.... | 
| 
 | ||
| Well basically how i did things was 
Type player
field x,y,image
end type
type enemy
field x,y,image
end type
player.player= new player
player\x=100
player\y=100
player\image=loadimage("blfsdjklfaskd.png")
enemy.enemy=new enemy
enemy\x=200
enemy\y=200
enemy\image=loadimage("jkldsfjlkjadf.png")
while not keyhit(1)
cls
for player.player = each player
drawimage player\image,player\x,player\y
player\x=player\x+rnd(-2,2)
next
for enemy.enemy = each enemy
drawimage enemy\image,enemy\x,enemy\y
enemy\y=enemy\y+rnd(-2,2)
next
flip
wend
NOW That is an extremely and simplified (and pointless) version of what I have so far (if i pasted what I really have it'd be a jumbled mess lol) SO for my example, what would be the best way to go about checking if the player\image collides with the enemy\image? I understand that the image handle kinda doesn't even matter, for some reason lol. It's just the x and y for each that I need to check against each other, which raises problems because they are in separate objects and in separate for loops. How I'd normally go about this is to simply declare a variable and name it like enemyx, and then one for enemyy, then for each iteration of the for next loop I'd make the enemy\x = enemyx, so that I can just check against that variable, not against the field of the enemy. Thanks a lot for helping though guys | 
| 
 | ||
|  raises problems because they are in ... separate for loops  Simplest solution: try nesting your loops: for player.player = each player
    for enemy.enemy = each enemy
        CheckCollision player\x, player\y, enemy\x, enemy\y     ;(however you do this)
    next
nextSo it loops over each player, and on each iteration checks every enemy against it. This method doesn't scale well (imagine: if you had a thousand of each, that's only two thousand things to draw on screen - not so bad - but a million collision checks), but it should be fine for say fewer than ten players and a couple of hundred enemies. For very large numbers of things you'd use a more complex approach, but no sense in getting complicated until you need it. Note also that you don't need to combine drawing and collision checking in the same section of code (in fact, it's a good idea to keep them separate). You should use non-nested loops for the drawing, or you'll end up with a lot of redundant overdraw. |