Collision options

Monkey Forums/Monkey Beginners/Collision options

En929(Posted 2014) [#1]
I just want to make sure I got this collision function correct. The collision below works a bit, but hasn't seemed to worked as readily and as instantly accurate as some of the premade Java rectangle collision functions I worked with (I wish Monkey had a built in rectangle collision function like Java has). But anyway below is a collision code that I use. I just want to make sure that I'm using this correctly. Feel free to add to, take away from, or give me another one that I might not know about yet. Thanks!


The formula is:


Function RectsOverlap:Int(x1:Float, y1:Float, w1:Float, h1:Float, x2:Float, y2:Float, w2:Float, h2:Float)
	If x1 > (x2 + w2) Or (x1 + w1) < x2 Then Return False
	If y1 > (y2 + h2) Or (y1 + h1) < y2 Then Return False
	Return True
End	



So thus:


If RectsOverlap(PlayerX, PlayerY, PlayerW, PlayerH, EnemyX, EnemyY, EnemyW, EnemyH) Then

                                   EnemyX = rnd(640,800)  ' I recycle the enemy

End




therevills(Posted 2014) [#2]
Looks fine to me, whats the exact issue?

Are you compensating for midhandles?


En929(Posted 2014) [#3]
therevillis, I'm not sure. I guess the issue that I was having was sometimes the above code worked and sometimes not. And thus, that's one reason I was posting this here to see if maybe there was a reason for it not working sometimes and if I even wrote it correctly. Also, I'm not sure about the midhandle compensation.


therevills(Posted 2014) [#4]
Quick example for you:

Strict

Import mojo

Function Main:Int()
	New Game
	Return True
End

Class Game Extends App
	Field player:Player
	Field enemy:Enemy
	
	Method OnCreate:Int()
		SetUpdateRate(60)
		
		player = New Player(100, 100, 50, 50)
		enemy = New Enemy(Rnd(0, 640 - 50), Rnd(0, 480 - 50), 50, 50)
				
		Return True
	End
	
	Method OnUpdate:Int()
		player.Update()
		enemy.Update()
		
		' check collisions
		If RectsOverlap(player.x, player.y, player.w, player.h, enemy.x, enemy.y, enemy.w, enemy.h)
			enemy.x = Rnd(0, 640 - enemy.w)
			enemy.y = Rnd(0, 480 - enemy.h)
		End
		
		Return True
	End Method

	Method OnRender:Int()
		Cls
		player.Draw()
		enemy.Draw()
		
		Return True
	End
End

Class Sprite
	Field x:Float, y:Float
	Field w:Float, h:Float
	
	Method Update:Void() Abstract
	Method Draw:Void() Abstract
End

Class Player Extends Sprite

	Method New(x#, y#, w#, h#)
		Self.x = x
		Self.y = y
		Self.w = w
		Self.h = h
	End

	Method Update:Void()
		Controls()
	End

	Method Controls:Void()
		x = MouseX()
		y = MouseY()
	End
	
	Method Draw:Void()
		SetColor(0, 255, 0)
		DrawRect(x, y, w, h)
		SetColor(255, 255, 255)
	End
End

Class Enemy Extends Sprite

	Method New(x#, y#, w#, h#)
		Self.x = x
		Self.y = y
		Self.w = w
		Self.h = h
	End

	Method Update:Void()
	End
	
	Method Draw:Void()
		SetColor(255, 0, 0)
		DrawRect(x, y, w, h)
		SetColor(255, 255, 255)
	End
End


Function RectsOverlap:Int(x1:Float, y1:Float, w1:Float, h1:Float, x2:Float, y2:Float, w2:Float, h2:Float)
	If x1 > (x2 + w2) Or (x1 + w1) < x2 Then Return False
	If y1 > (y2 + h2) Or (y1 + h1) < y2 Then Return False
	Return True
End



Jesse(Posted 2014) [#5]
I suspect the player and enemy move too fast and skip over collision all together.


En929(Posted 2014) [#6]
That worked perfectly Jesse. There were absolutely no problems in the collision example you posted. Thus, I guess I will go recheck the methods that I used to write my game. Thanks!