Jump to content
IGNORED

need some help with collision detection


Nognir

Recommended Posts

Hey!

 

I'm fooling around with batari Basic lately, to do something useful.

 

I tried to do some demo where simply a ball is shooting around on the screen but I don't know how to access the collision detection best.

 

Already it detects the collision with the upper screen, but then its going wild

 

here's the code:

 

main
COLUBK = 124
COLUPF = 187
COLUP0 = 86

 playfield:
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 X..............................X
 X..............................X
 X..............................X
 X..............................X
 X..............................X
 X..............................X
 X..............................X
 X..............................X
 XXXXXX.......XXXXX........XXXXXX
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

 player0:
011000
111100
%01111110
111100
011000
end

 t = 1
 x = 60
 y = 60

 player0x = x
 player0y = y

 drawscreen
 goto moveup


moveup

 x = x + t
 y = y - t - t

 player0x = x
 player0y = y

 if collision(player0,playfield) then goto movedown

 drawscreen
 goto moveup

movedown

 x = x + t
 y = y + t + t

 player0x = x
 player0y = y

 if y > 70 then goto moveup

 drawscreen
 goto movedown

 

I know that this line is disposable:

 

 if y > 70 then goto moveup

 

but I took it in to let the ball "flip around" at least.

 

Hope that someone could push me a little in the right direction ;)

 

Thanks in advance!

 

Michael

Edited by Nognir
Link to comment
Share on other sites

the player0 sprite is:

 

00011000

00111100

01111110

00111100

00011000

 

don't know why the forum changes it :?

Yep, there's some kind of bug ever since the upgrade in the forum software. To get around the bug until it's fixed, you can insert some empty whatchamacallums after the %, like bold on and bold off:

 

%{b}{/b}00011000

%{b}{/b}00111100

%{b}{/b}01111110

%{b}{/b}00111100

%{b}{/b}00011000

 

(You would actually use the square brackets, [ and ], instead of the the curly set brackets, { and }-- I just used the curly set brackets so you could see the "codes." If you use the square brackets, it will look like this (the bold on and bold off don't show up):

 

%00011000

%00111100

%01111110

%00111100

%00011000

 

Michael

Link to comment
Share on other sites

Hope that someone could push me a little in the right direction ;)

You have a few problems.

 

First, you need to check for collisions *after* you draw the screen, and *before* you update any of the positions again, something like this:

 

moveup

  x = x + t
  y = y - t - t

  player0x = x
  player0y = y

  drawscreen

  if collision(player0,playfield) then goto movedown

  goto moveup

movedown

  x = x + t
  y = y + t + t

  player0x = x
  player0y = y

  drawscreen

  if collision(player0,playfield) then goto moveup

  goto movedown

That still isn't correct, but it's getting closer, and at least the ball doesn't get frozen inside a wall (but it does do some weird things).

 

Second, you aren't handling the cases when the ball hits a vertical surface-- or for that matter, when it hits a corner (two surfaces at once, one vertical and one horizontal). Your two routines (after adjusting them slightly to fix the placement of the collision detection) handle only the cases when the ball hits a horizontal surface, which is why the ball bounces around more or less okay as long as it doesn't hit a vertical surface. And the reason it gets inside a wall sometimes is because it doesn't get bounced off properly, and if it gets more than one pixel deep into a wall, then everywhere it moves it immediately collides with the playfield again, so it just keeps fluctuating between moveup and movedown (until it finally manages to slide out of the wall at the end).

 

Third, you're using x and y to calculate the position of the ball, and then setting player0x and player0y to x and y. This isn't the most efficient way to do it, because you might as well just use player0x and player0y directly in the calculations, such x and y are superfluous. Also, t is never anything besides 1, so you can replace t with 1, and replace double t with 2:

 

   player0x = 60
  player0y = 60

  drawscreen
  goto moveup


moveup

  player0x = player0x + 1
  player0y = player0y - 2

  drawscreen

  if collision(player0,playfield) then goto movedown

  goto moveup

movedown

  player0x = player0x + 1
  player0y = player0y + 2

  drawscreen

  if collision(player0,playfield) then goto moveup

  goto movedown

However, it would actually be better to use x and y for indicating the *direction* the ball is moving in, where x is the amount of change in player0x, and y is the amount of change in player0y. That way you can set x to 1 to move right, or to 255 (equivalent to -1) to move left. Likewise, you can set y to 2 to move down, or to 254 (equivalent to -2) to move up. Then you'd add x and y to player0x and player0y, sort of like this:

 

   player0x = 60
  player0y = 60

  x = 1
  y = 254

loop

  player0x = player0x + x
  player0y = player0y + y

  drawscreen

  if collision(player0,playfield) then y = 0 - y

  goto loop

This is just a consolidation of your moveup and movedown routines; it still doesn't handle the cases of hitting a vertical surface or corner. But if you replace that one if with multiple ifs, to handle the various possibilities, then you should have it.

 

What you'll probably need to do is convert the ball's position into equivalent playfield pixel positions, and then use the pfread statement, so you can check the playfield pixels immediately around the ball to see which ones are turned on. Then you'll know which direction the ball needs to bounce in. You really need to check only two playfield pixels, depending on which way the ball is moving when the collision occurs:

 

If x = 1 and y = 2, then the ball is moving SE, so check the playfield pixels to the right of the ball, and below the ball.

 

If x = 1 and y = 254 (or -2), then the ball is moving NE, so check the playfield pixels to the right of the ball, and above the ball.

 

If x = 255 (or -1) and y = 2, then the ball is moving SW, so check the playfield pixels to the left of the ball, and below the ball.

 

If x = 255 (or -1) and y = 254 (or -2), then the ball is moving NW, so check the playfield pixels to the left of the ball, and above the ball.

 

You can use something like the following:

 

loop

  player0x = player0x + x
  player0y = player0y + y

  drawscreen

  if collision(player0,playfield) then gosub checkwalls

  goto loop

checkwalls

  if x = 1 then gosub checkeast else gosub checkwest
  if y = 2 then gosub checksouth else gosub checknorth
  return

checkeast

  rem * if the pfpixel to the east is on, then x = 255
  return

checkwest

  rem * if the pfpixel to the west is on, then x = 1
  return

checksouth

  rem * if the pfpixel to the south is on, then y = 254
  return

checknorth

  rem * if the pfpixel to the north is on, then y = 2
  return

That still leaves you to figure out the code to convert the player coordinates into playfield coordinates, and peek at the playfield pixels using pfread. :)

 

Michael

Link to comment
Share on other sites

That still leaves you to figure out the code to convert the player coordinates into playfield coordinates, and peek at the playfield pixels using pfread. :)

By the way, if you check the "similar topics" below this thread, you might be able to find some code or discussions that will help with that.

 

Michael

Link to comment
Share on other sites

Check out what I did in Insane Painter.

 

It defintely is not the optimal way to determine playfield collision with a ball/missile, but it seemed to work.

 

Note there is some really funky stuff going on in it (not that is it complicated, just a little convoluted). Specifically some funkiness is that once the missile1 comes on the screen the ball reacts to the missile collisions which was not originally intentional, but it added some chaos to it that I think made it a little more fun. If you forgive it not having any dim statements of note :) you might be able to reuse the pfread parts of it. Note also that the offset/division to determine pfread and pfpixel locations is not perfect, but was close enough for me.

 

Here is some sample code from it for collision (I think batari or michael or somebody came up with the original divide by 4 / divide by 8 thing to find the playfield x,y location, but they had an offset that it didn't seem like was needed for a small ball- it was probably for a player sprite):

 

doball

if d < r then d = r : f{0}=1

if d > 145 then d = 145 : f{0}=0

if e < r then e = r : f{1}=1

if e > 91 then e = 91 : f{1}=0

 

if f{0} then d = d + r else d = d - r

if f{1} then e = e + r else e = e - r

 

if collision(ball,playfield) then m = d : n = e : gosub ballcl

 

...

 

ballcl

if m > 16 then m = m - 17

m = m / 4

n = n / 8

 

if m < 31 then m = m + 1

if f{0} && pfread(m,n) then f{0}=!f{0} : pfpixel m n off

if m > 1 then m = m - 2

if !f{0} && pfread(m,n) then f{0}=!f{0} : pfpixel m n off

m = m + 1

if n < 10 then n = n + 1

if f{1} && pfread(m,n) then f{1}=!f{1} : pfpixel m n off

if n > 1 then n = n - 2

if !f{1} && pfread(m,n) then f{1}=!f{1} : pfpixel m n off

n = n + 1

 

rem for t = 1 to 3 : pfpixel m n flip : drawscreen : next

pfpixel m n off

 

rem this sets the a var I was looking at to do a sound

s = 17

 

...

 

return

 

...

 

in the gameloop...

 

rem sound for the collision

if s > 0 then s = s - 1 : AUDV0 = s : AUDC0 = s : AUDF0 = s : AUDV1 = s : AUDC1 = s : AUDF1 = s

Edited by Fort Apocalypse
Link to comment
Share on other sites

Check out what I did in Insane Painter.

Thanks for posting this. I started tinkering with it tonight, but my code doesn't work right. The shape of the ball makes it a little more challenging to check the appropriate playfield pixels. I'll post something when I've got it working right and can explain it.

 

Michael

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...