Collision...
BlitzMax Forums/BlitzMax Beginners Area/Collision...
| ||
Say I have two squares. One square is moved around with the cursor keys (the player), the other is stationary (a wall). Would it be possible to stop the player from entering the wall, if you don't know the wall's position or scale? Also: the player's movement may not move one pixel at a time. |
| ||
Presumable you're drawing it, so you ought to know the position.... |
| ||
If you don't know the walls position or scal, then you might want to readpixel the corners of the players square. And do the check before you actually move the player, so that you don't get the collision after the player is "inside" the wall. |
| ||
lets see if this helps... and please note this is not supposed to be runable code :D playerx:int playery:int objectx:int objecty:int size1:int size2:int while cls gosub move gosub checkcollision gosub draw flip wend function move: if keydown(key_left) then playerx=playerx-1 etc... etc... etc... endfunction function checkcollision: if playerx+size1 > objectx then playerx+size1 = objectx if playerx < objectx+size2 then playerx = objectx+size2 if playery+size1 > objecty then playery+size1 = objecty if playery < objecty+size2 then playery = objecty+size2 endfunction function draw: setcolor 255,0,0 drawrect playerx,playery,size1,size1 setcolor 0,0,255 drawrect objectx,objecty,size2,size2 endfunction turn that code into usable code and run it. You should be able to run into the object and be repelled. |
| ||
I apologize I ran my code after fixing it to see if it works and it doesn't seem to work after all... here's an updated code that actually runs though it has a problem. Global playerx:Int = 50 Global playery:Int = 50 Global objectx:Int = 100 Global objecty:Int = 100 Global size1:Int Global size2:Int Global extra:Int Graphics 640,480 While Not KeyHit(key_Q) Cls move() checkcollision() draw() Flip Wend Function move() If KeyDown(key_left) Then playerx=playerx-1 If KeyDown(key_right) Then playerx=playerx+1 If KeyDown(key_up) Then playery=playery-1 If KeyDown(key_down) Then playery=playery+1 EndFunction Function checkcollision() extra=playerx+20 If playerx+20 > objectx And playery+20 > objecty And playery < objecty+20 Then extra = objectx extra=objectx+20 If playerx < objectx+20 And playery+20 > objecty And playery < objecty+20 Then playerx = extra extra=playery+20 If playery+20 > objecty And playerx+20 > objectx And playerx < objectx+20 Then extra = objecty extra=objecty+20 If playery < objecty+20 And playerx+20 > objectx And playerx < objectx+20 Then playery = extra EndFunction Function draw() SetColor 255,0,0 DrawRect playerx,playery,20,20 SetColor 0,0,255 DrawRect objectx,objecty,20,20 EndFunction |
| ||
Oops forgot about this thread. Thanks all. I must not be thinking straight, but how would I stop the rects from overlapping in a scenario similar to the code above (knowing the position and scale of everything), only not bugged? Here's some code: SuperStrict Graphics(400,300,0) Local x1%=10,y1%=10,x2%=200,y2%=200 Local w1%=15,h1%=10,w2%=20,h2%=30 While Not KeyHit(KEY_ESCAPE) SetColor(255,255,255) DrawRect(x1,y1,w1,h1) SetColor(255,255,0) DrawRect(x2,y2,w2,h2) If KeyDown(KEY_UP) Then y1=y1-2 If KeyDown(KEY_DOWN) Then y1=y1+2 If KeyDown(KEY_LEFT) Then x1=x1-2 If KeyDown(KEY_RIGHT) Then x1=x1+2 If RectsOverlap(x1,y1,w1,h1,x2,y2,w2,h2) Then x1=x2-w1 EndIf Flip;Cls;ResetCollisions Wend End Function RectsOverlap%(x1%,y1%,w1%,h1%,x2%,y2%,w2%,h2%) If x1+w1>x2 And y1+h1>y2 And x1<x2+w2 And y1<y2+h2 Then Return True Else Return False EndIf End Function |
| ||
SuperStrict Graphics(400,300,0) Local x1%=10,y1%=10,x2%=200,y2%=200 Local w1%=15,h1%=10,w2%=20,h2%=30 Local TmpX:Int,TmpY:Int While Not KeyHit(KEY_ESCAPE) SetColor(255,255,255) DrawRect(x1,y1,w1,h1) SetColor(255,255,0) DrawRect(x2,y2,w2,h2) TmpX = x1 TmpY = y1 If KeyDown(KEY_UP) Then TmpY=TmpY-2 If KeyDown(KEY_DOWN) Then TmpY=TmpY+2 If KeyDown(KEY_LEFT) Then TmpX=TmpX-2 If KeyDown(KEY_RIGHT) Then TmpX=TmpX+2 If Not RectsOverlap(TmpX,TmpY,w1,h1,x2,y2,w2,h2) Then x1=tmpX y1=tmpY EndIf Flip;Cls;ResetCollisions Wend End Function RectsOverlap%(x1%,y1%,w1%,h1%,x2%,y2%,w2%,h2%) If x1+w1>x2 And y1+h1>y2 And x1<x2+w2 And y1<y2+h2 Then Return True Else Return False EndIf End Function Try that out. It checks if it collides BEFORE changing the position, rather than after. If it doesn't collide, then the move is made. |
| ||
Thanks, that works, but change the moving speed to something like 7 or 13 and you get large gaps in the collision. Is there a way to remove these gaps? Move the temp rect back a pixel until it no longer collides then place the real rect there? |
| ||
Probobly not the best method but it does accurate collision detection. It does partial collision checks depending on the direction of the box. |
| ||
I see, thanks. |
| ||
Any idea why the collision fails when moving up? It works perfectly in the other three directions. |
| ||
Fixed, sorry. |
| ||
Now I'm just wondering how I could do that except with mouse control. :/ |
| ||
Something like that? |
| ||
Ah, yes. Precisely. Thanks. |