|
Post by Nicky Peter Hollyoake on Aug 10, 2014 19:22:37 GMT -5
Ok, I've done box collision hundreds of times and I may be over looking something. All the tiles around the border collision works fine, but the 2 blocks in the center it's having a problem with.
'map collision test glMatrixMode(GL_PROJECTION) glLoadidentity() glOrtho(0, 6, 6, 0, 0, 1) glMatrixMode(GL_MODELVIEW) textmode(TEXT_OVERLAID)
data 1, 1, 1, 1, 1, 1 data 1, 0, 0, 0, 0, 1 data 1, 0, 1, 0, 0, 1 data 1, 0, 0, 1, 0, 1 data 1, 0, 0, 0, 0, 1 data 1, 1, 1, 1, 1, 1
dim map(5)(5) dim p#(1)=vec2(1, 1), lp#(1) dim x, y
for y = 0 to 5 for x = 0 to 5 read map(x)(y) next next
while TRUE glClear(GL_COLOR_BUFFER_BIT) cls
lp# = p# 'last position before we move if scankeydown (VK_DOWN) then p#(1) = p#(1) + 0.1 elseif scankeydown (VK_UP) then p#(1) = p#(1) - 0.1 elseif scankeydown (VK_LEFT) then p#(0) = p#(0) - 0.1 elseif scankeydown (VK_RIGHT) then p#(0) = p#(0) + 0.1 endif
for y = 0 to 5 for x = 0 to 5 if Map(x, y) = 1 then 'collsion if (p#(0) + 1) > x and p#(0) < (x + 1) and (p#(1) + 1) > y and p#(1) < (y + 1) then 'p#=lp# 'go back on our last position locate 8, 20: print"collision!" drawtext() glColor3f(1, 0, 0) else glColor3f(0, 1, 1) endif
glPushMatrix() glTranslatef(x, y, 0) glBegin(GL_QUADS) glVertex2i(0, 0) glVertex2i(0, 1) glVertex2i(1, 1) glVertex2i(1, 0) glEnd() glPopMatrix() endif next next glPushMatrix() glTranslatef(p#(0), p#(1), 0) glBegin(GL_QUADS) glColor3f(0, 0, 1) glVertex2i(0, 0) glVertex2i(0, 1) glVertex2i(1, 1) glVertex2i(1, 0) glEnd() glPopMatrix() sleep(75) swapbuffers() wend
if I changed this line
dim p#(1)=vec2(1, 1)
to
dim p#(1)=vec2(2, 3)
no collision, it's fine. I think I may of found a bug? Let me know if it's happening to you.
If someone can help me find the problem I'd appreciate it & also I'm creating a 2D mini game with my friend who is a graphics designer.
- Nicky
|
|
|
Post by shadow008 on Aug 11, 2014 17:25:06 GMT -5
I think I speak for everyone when I say we were all holding our breath waiting for someone to comment. Thank you.
Anyhow...
Something has to be up with the precision of the variables in the background.
Added in a line right after the line locate 8, 20: printr"collision!" (note "print" got changed to "printr"):
printr p#(1) + " < " + (y + 1.0) + " = " (p#(1) < (y + 1.0))
And it's coming up with stuff like "4 < 4 = -1(true)"
Also, you need to put "drawtext()" right before "swapbuffers()" for the text to show up properly over the boxes.
The best I can come up with is to go straight floating point variables and see if the problem persists. Controlled, simple tests such as "if 4.0 > 4 then..." work out fine though.
|
|
|
Post by Nicky Peter Hollyoake on Aug 11, 2014 22:29:19 GMT -5
dim a# = 0 dim x = 2
do a# = a# + 0.1 loop until a#>2.9
print (a# < 3) drawtext()
On my computer that returns true.
But:
dim a# = 3
print (a# < 3) drawtext()
returns false.
I also have to put drawtext at the end of my text for it to show...But that one isn't bugging me as much as this. It seem it only fails when you increment the float variable, weird.
Hopefully someone has the answer to this.
- Nicky
|
|
|
Post by Nicky Peter Hollyoake on Aug 12, 2014 12:50:50 GMT -5
I was hoping to avoid using this way, but until I can figure out what's going on this is a work around.
'map collision test glMatrixMode(GL_PROJECTION) glLoadidentity() glOrtho(0, 6, 6, 0, 0, 1) glMatrixMode(GL_MODELVIEW) textmode(TEXT_OVERLAID)
data 1, 1, 1, 1, 1, 1 data 1, 0, 0, 0, 0, 1 data 1, 0, 1, 0, 0, 1 data 1, 0, 0, 1, 0, 1 data 1, 0, 0, 0, 0, 1 data 1, 1, 1, 1, 1, 1
dim map(5)(5) dim p(1), lp(1) dim x, y
p(0) = 10 p(1) = 10
for y = 0 to 5 for x = 0 to 5 read map(x)(y) next next
while TRUE glClear(GL_COLOR_BUFFER_BIT) cls lp = p 'last position before we move if scankeydown (VK_DOWN) then p(1) = p(1) + 1 elseif scankeydown (VK_UP) then p(1) = p(1) - 1 elseif scankeydown (VK_LEFT) then p(0) = p(0) - 1 elseif scankeydown (VK_RIGHT) then p(0) = p(0) + 1 endif for y = 0 to 5 for x = 0 to 5 if Map(x, y) = 1 then 'collsion if ((P(0)/10.0) + 1) > x and (P(0)/10.0) < (x + 1) and ((P(1)/10.0) + 1) > y and (P(1)/10.0) < (y + 1) then P=lP 'go back on our last position endif glPushMatrix() glTranslatef(x, y, 0) glBegin(GL_QUADS) glColor3f(0, 1, 1) glVertex2i(0, 0) glVertex2i(0, 1) glVertex2i(1, 1) glVertex2i(1, 0) glEnd() glPopMatrix() endif next next glPushMatrix() glTranslatef((P(0)/10.0), (P(1)/10.0), 0) glBegin(GL_QUADS) glColor3f(0, 0, 1) glVertex2i(0, 0) glVertex2i(0, 1) glVertex2i(1, 1) glVertex2i(1, 0) glEnd() glPopMatrix() sleep(75) swapbuffers() wend
I times everything by ten in a integer and I divide it by 10 when I need to. If anyone has got any better solutions, please share.
- Nicky
|
|
|
Post by shadow008 on Aug 12, 2014 16:20:57 GMT -5
This actually looks like a real bug. Quick screenshot of the debugger after running: As you can see, map(3)/map(p#(0)) should print out: {1,0,0,1,0,1} but instead, it prints the value of map(2): {1,0,1,0,0,1} This is definitely irrational behavior. Nothing really I can help. However, I was going to suggest you do your collision detection in an easier way, while taking advantage of the uniform grid pattern: Something like: if map(p#(0))(p#(1)) = 1 then Which, technically, would be faster because it's a lookup and not a comparison. But the above bug throws that one out the window so... I dunno what to say. Good luck!
|
|
|
Post by matthew on Aug 13, 2014 9:40:37 GMT -5
Hi Nicky, is there anything you've done differently in this program that you haven't done in the past?
As your other collision detection routines seemed to work fine.
|
|
|
Post by Nicky Peter Hollyoake on Aug 13, 2014 11:01:08 GMT -5
Hi Nicky, is there anything you've done differently in this program that you haven't done in the past? As your other collision detection routines seemed to work fine. I've not done anything differently as you can see from my previous post it works fine when I work with integers but doesn't work with floating variables. I've checked other demos around and everything I play is off by 0.1 and then I made this check: dim a# = 0 dim x = 2
do a# = a# + 0.1 loop until a#>2.9
printr a#
a# = int(a#)
printr a#
a# = 3.0
printr int(a#) drawtext() The results for me is... 3 2 3 That's weird. Maybe it's my computer? I mean I ain't having no issues/viruses, etc. Could it be a compatibility issue? I'm running Windows 7 Ultimate 64bit. Thank you Shadow I am aware of that routine (map(p(0), p(1))) and I'm using something similar in my main project. - Nicky edit: don't ask why I put val, it's gone now, but it doesn't change anything.
|
|
|
Post by matthew on Aug 13, 2014 11:21:57 GMT -5
I don't think that the problem you're encountering is due to your computer or the limitations of Basic4GL. It's probably got more to do with the inaccuracies that arise when you use floating-point numbers. There's a good article about the problem on this Wikipedia page.
|
|
|
Post by Nicky Peter Hollyoake on Aug 13, 2014 17:43:28 GMT -5
Oh, I kinda get it, and using "str$" gives me a better understanding:
dim a# = 0
do a# = a# + 0.1 loop until a#>2.9
printr str$(a#) drawtext()
How would I get a more accurate collision if I can't determine what my real digits are? For now my project is still under going using my other routine but I'd like a better solution if you got anything you suggest.
- Nicky
|
|
|
Post by matthew on Aug 14, 2014 4:28:37 GMT -5
Well I found a large thread on the forum here from back in 2009. It deals with a program that SMC wrote for detecting collisions, you'll notice that it appears to use the trick that you used of multiplying everything by Ten then dividing it when you need to calculate the position. Based on articles I've seen on collision-detection; creating a Constant and then multiplying/dividing by it looks like the accepted way of doing things, sometimes programmers will use 100 instead of 10 for even more accuracy.
|
|
|
Post by DJLinux on Aug 18, 2014 4:23:17 GMT -5
Hello Nicky your player has a center position so 0.5,0.5 is 0,0 in the map you know ?
Another point are your map x,y coords are integers% and the player position are single#. In scope of rounding errors it's a good practice to subtract a short value of the player size for collision detection. This is why i user mx=px#-.49 : my=py#-.49 and not .5
DJ
'map collision test
data 1, 1, 1, 1, 1, 1 data 1, 0, 0, 0, 0, 1 data 1, 0, 1, 0, 0, 1 data 1, 0, 0, 1, 0, 1 data 1, 0, 0, 0, 0, 1 data 1, 1, 1, 1, 1, 1
dim map(5,5)
function CollisionTest(px#,py#) as integer dim mx,my ' map x,y mx=px#-.49 : my=py#-.49 ' left top corner if map(mx,my) then return true : end if my=py#+.49 ' left bottom corner if map(mx,my) then return true : end if mx=px#+.49 ' right bootom corner if map(mx,my) then return true : end if my=py#-.49 ' right top corner if map(mx,my) then return true : end if ' no collision return false end function
glMatrixMode(GL_PROJECTION) glLoadidentity() glOrtho(0,6,6,0,-1,1) glMatrixMode(GL_MODELVIEW) textmode(TEXT_OVERLAID)
dim px#=2.5 dim py#=3.5 dim lpx# dim lpy# dim x,y
for y = 0 to 5 for x = 0 to 5 read map(x,y) next next
while TRUE glClear(GL_COLOR_BUFFER_BIT) : cls lpx# = px# ' last x position before we move lpy# = py# ' last y position before we move if scankeydown (VK_UP) then py# = py# - .1 : if py#<=0.5 then py#=0.5 : end if elseif scankeydown (VK_DOWN) then py# = py# + .1 : if py#>=5.5 then py#=5.5 : end if elseif scankeydown (VK_LEFT) then px# = px# - .1 : if px#<=0.5 then px#=0.5 : end if elseif scankeydown (VK_RIGHT) then px# = px# + .1 : if px#>=5.5 then px#=5.5 : end if endif for y = 0 to 5 for x = 0 to 5 if Map(x,y) = 1 then glPushMatrix() glColor3f(0,1,1) glTranslatef(x, y, 0) glBegin(GL_QUADS) glVertex2f(0,0) glVertex2f(0,1) glVertex2f(1,1) glVertex2f(1,0) glEnd() glPopMatrix() endif next next ' collsion ? if CollisionTest(px#,py#)=true then locate 0, 10: print"collision!" glColor3f(1, 0, 0) px#=lpx# py#=lpy# else glColor3f(0, 0, 1) endif glPushMatrix() glTranslatef(px#, py#, 0) glBegin(GL_QUADS) glVertex2f(-.5,-.5) glVertex2f(-.5, .5) glVertex2f( .5, .5) glVertex2f( .5,-.5) glEnd() glPopMatrix() locate 0,8 : print "player " + px# +":"+ py# DrawText() SwapBuffers() Sleep(50) wend
|
|
|
Post by Nicky Peter Hollyoake on Aug 19, 2014 18:26:00 GMT -5
Ahh, I see, thank you! That actually helped a lot, appreciate it.
- Nicky
|
|