Collision Detection

BlitzMax Forums/BlitzMax Programming/Collision Detection

tomhillmeyer(Posted 2014) [#1]
I'm sort of new here, but I can't get my images to collide. Any help?!



'shoot'

AutoMidHandle True

Graphics 640, 480
SetMaskColor 255, 255, 255
SetClsColor 158, 158, 158
Type Bullet
Field x, y
Field image
End Type

Type Ship
Field x, y
Field image
End Type

Type Asteroid
Field x, y
Field image
End Type

'Const BULLETSTRING:String = "|"
'Const SHIPSTRING:String = "<{A}>"
'Const ASTEROIDSTRING:String = "#"

'Global BULLETHEIGHT = TextHeight(BULLETSTRING)
'Global BULLETWIDTH = TextWidth(SHIPSTRING)
'Global ASTEROIDHEIGHT = TextHeight(ASTEROIDSTRING)
'Global ASTEROIDWIDTH = TextWidth(ASTEROIDSTRING)


SeedRnd MilliSecs()

Global Bullet1:Bullet = New Bullet
Global Ship1:Ship = New Ship
Global Asteroid1:Asteroid = New Asteroid

Ship1.y = 450
Ship1.x = 320

Bullet1.y = 470

Asteroid1.x = Rand(0,640)
Asteroid1.y = Rand(0,470)


Global xChange = 1
Global yChange = 1

Global bulletPic = LoadImage("bullet.bmp")

Global shipPic = LoadImage("ship.bmp")

Global invaderPic = LoadImage("invader.bmp")



Global lives = 10
Global score = 0



While Not KeyDown(KEY_ESCAPE)
Cls
Draw()
HUD()
TestInput()
AsteroidGo()
If KeyHit(KEY_SPACE)
Shoot()
EndIf




If ImagesCollide(bulletPic, Bullet1.x, Bullet1.y, 0, invaderPic, Asteroid1.x, Asteroid1.y, 0)
Cls
lives = lives - 1
HUD()
DrawImage(ShipPic, Ship1.x, Ship1.y)
Asteroid1.x = Rand(0,640)
Asteroid1.y = Rand(0,470)
Flip
EndIf

If ImagesCollide(invaderPic, Asteroid1.x, Asteroid1.y, 0, shipPic, Ship1.x, Ship1.y, 0)
Cls
score = score + 1
HUD()
DrawImage(ShipPic, Ship1.x, Ship1.y)
Asteroid1.x = Rand(0,640)
Asteroid1.y = Rand(0,470)
Flip
EndIf






Flip
Wend




Function Draw()

DrawImage shipPic, Ship1.x, Ship1.y

EndFunction


Function TestInput()

If KeyDown(KEY_RIGHT) And Ship1.x < 639
Ship1.x = Ship1.x + 5
EndIf

If KeyDown(KEY_LEFT) And Ship1.x > 0
Ship1.x = Ship1.x - 5
EndIf

EndFunction



Function Shoot()


While Bullet1.y > 1
Bullet1.y = Bullet1.y - 10
Bullet1.x = Ship1.x
DrawImage(bulletPic, Bullet1.x, Bullet1.y)
DrawImage(shipPic, Ship1.x, Ship1.y)
Wend

Bullet1.y = 470





EndFunction




Function AsteroidGo()


Asteroid1.x = Asteroid1.x + xChange

Asteroid1.y = Asteroid1.y + yChange

If (Asteroid1.x < 0 Or Asteroid1.x > 640)
xChange = xChange * -1
EndIf

If (Asteroid1.y < 0 Or Asteroid1.y > 460)
yChange = yChange * -1
EndIf


DrawImage(invaderPic, Asteroid1.x, Asteroid1.y)


End Function

Function HUD()
DrawText "Lives: " + lives, 0, 440
DrawText "Score: " + score, 0, 450
End Function

Function CollideDetect()
If ImagesCollide(bulletPic, Bullet1.x, Bullet1.y, 0, invaderPic, Asteroid1.x, Asteroid1.y, 0)
Cls
lives = lives - 1
HUD()
DrawImage(ShipPic, Ship1.x, Ship1.y)
Asteroid1.x = Rand(0,640)
Asteroid1.y = Rand(0,470)
Flip
EndIf

If ImagesCollide(invaderPic, Asteroid1.x, Asteroid1.y, 0, shipPic, Ship1.x, Ship1.y, 0)
Cls
score = score + 1
HUD()
DrawImage(ShipPic, Ship1.x, Ship1.y)
Asteroid1.x = Rand(0,640)
Asteroid1.y = Rand(0,470)
Flip
EndIf

EndFunction


Midimaster(Posted 2014) [#2]
Your Shoot()-function is the problem....

Function Shoot()
     While Bullet1.y > 1
          Bullet1.y = Bullet1.y - 10
          Bullet1.x = Ship1.x
          DrawImage(bulletPic, Bullet1.x, Bullet1.y)
          DrawImage(shipPic, Ship1.x, Ship1.y)
     Wend
     Bullet1.y = 470
EndFunction


You need to divide it into two parts "Shoot()", "Move()".

The "Shoot()" only starts the bullet and is called once by SPACE key.
The "Move()" cares about moving it some pixels until it reaches the screen top border and is called every While/Wend once.

Function Shoot()
     If Bullet1.y < 1
          Bullet1.y = 470
          Bullet1.x = Ship1.x
     Endif
EndFunction

Function Move()
     If Bullet1.y > 1
          Bullet1.y = Bullet1.y - 10
           DrawImage(bulletPic, Bullet1.x, Bullet1.y)
     Endif
EndFunction


Never do a second WHILE/WEND loop during the main WHILE/WEND loop! In your case the bullet will be finished within the first moment after fired: SPACE key starts the function Shoot(), inside the function the WHILE/WEND loop works until Bullet1.y reaches the screen top border. At the end of the function the bullet is already gone. No chance for testing any collision in the main loop anymore...