Jump to content
IGNORED

failing to understand playfield collision example


Reaperman

Recommended Posts

I don't know what it is, but I just cannot seem to wrap my head around playfield collision. I see some very complex examples, I see some simpler examples, and lots of talk about sticky collision, but I am having trouble understanding why this is at all hard.
I've tried what I suspect are the usual solutions:
  • adding/subtracting x/y when a collision is detected, which sometimes kind of worked
  • remembering the last x/y and reverting to them when a collision is detected, which somehow works even worse

my program code (also attached at bottom):

 

 

 

    rem Kernel options for this program eliminate the blank lines.
   set kernel_options no_blank_lines

        rem   x and why for plotting player, b and c for previous xy
     x=50
     y=75
 dim _oldx = b
 dim _oldy = c


 rem direction code 1=right, 2=left, 3=up, 4=down--starts player off going right
 dim _direction = a
 _direction = 1



    rem  Change the background color with COLUBK

 COLUBK=02

     rem  You need to set a color for the playfield

 COLUPF=222

  rem player shape

 player0:
 %1
end

     rem playfield shape Must use capital X, must be 32x11.
 playfield:
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 X...................XXXXXXXXXXXX
 X...................XXXXXXXXXXXX
 X....XXXXXXXXXXX....XXXXXXXXXXXX
 X....XXXXXXXXXXX...............X
 X....XXXXXXXXXXX...............X
 X....XXXXXXXXXXXXXXXXXXXXXX....X
 X....XXXXXXXXXXXXXXXXXXXXXX....X
 X..............................X
 X..............................X
 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

 
main
 
     rem  COLUP0=<xx> sets the color of the player 0 sprite. Valid range is 0-254

 COLUP0=158

 rem Make the guy move
 if joy0right then _direction =1
 if joy0left then _direction=2
 if joy0up then _direction=3
 if joy0down then _direction=4

 if _direction=1 then x=x+1
 if _direction=2 then x=x-1
 if _direction=3 then y=y-1
 if _direction=4 then y=y+1
 

 rem old crappy collision detection
 ; if collision(player0,playfield) && _direction=1 then x = x - 2
 ; if collision(player0,playfield) && _direction=2 then x = x + 2
 ; if collision(player0,playfield) && _direction=3 then y = y + 2
 ; if collision(player0,playfield) && _direction=4 then y = y - 2

 rem new crappier (somehow) collision detection
 if collision(player0,playfield) then x=_oldx : y=_oldy


     rem  put player down
 player0x=x
 player0y=y
 _oldx=x
 _oldy=y

     rem  this command instructs the program to write data to the TV screen.

 drawscreen

 
  goto main



 

 

 

Then, joy of joys, sample 15 in the code samples for beginners thread does exactly what I want to do in a much more elegant way than most other examples I've seen. However there are no comments in it, and I'm having a heck of a time figuring out exactly what is going in it and why that works. Could I get some help wrapping my head around the below sample code, or maybe a point in the right direction on mine?

 

code sample 15_MoveSpriteWithPlayfieldBoundaries:

 

 

 

   dim p0_x = b
   dim p0_y = c

   player0:
   %01101100
   %00101000
   %00111000
   %00010000
   %11111110
   %00010000
   %00111000
   %00111000
   %00111000
end

   COLUBK = 0
   COLUPF = 144

   player0x = 92
   player0y = 47

main

   playfield:
   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XX............................XX
   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
end

   COLUP0 = 28

   p0_x = 0
   if joy0left then p0_x = 255
   if joy0right then p0_x = 1
   player0x = player0x + p0_x

   p0_y = 0
   if joy0up then p0_y = 255
   if joy0down then p0_y = 1
   player0y = player0y + p0_y


   drawscreen

   if collision(player0,playfield) then gosub knock_player_back

   goto main

knock_player_back
   player0x = player0x - p0_x
   player0y = player0y - p0_y
   return

 

 

Collision failure.bas

Edited by Reaperman
Link to comment
Share on other sites

Have you looked at any of the example programs on the bB page that use collision prevention?

 

 

Yes, I've seen a few of those. I'll have to look harder at them tomorrow since I'm pretty spent tonight, and they're really complex. You lose me when you fill a temp variable with (x-10)/4--but it's past midnight, which isn't helping. Why is detecting a collision and moving a some coordinates back so hard to do, anyway?

 

And more curiously, what is the sample15 code I posted doing adding 255 to x/y? That's really got me confused.

 

Even when I add another set of player0x/y above the collision check as below, the screen shows player0 'inside' the playfield when I test it. Something about the collision detection isn't working as I would expect, since I wouldn't think it would ever be drawing the screen while I'm 'collided.'

 

     rem  put player down
 player0x=x
 player0y=y

 if collision(player0,playfield) then x=_oldx : y=_oldy

     rem  put player down
 player0x=x
 player0y=y
 _oldx=x
 _oldy=y
Edited by Reaperman
Link to comment
Share on other sites

Why is detecting a collision and moving a some coordinates back so hard to do, anyway?

 

Incomplete information - the TIA lets us know that player collided with the playfield, but it doesn't let us know which part of the player collided. If we knew it was at the top we'd just adjust the Y value to move the player down. If we knew it was on the left we'd adjust the X value to move the player right. And so on for the bottom and right sides.

 

So we have to programmatically try to figure out which part collided so we know how to adjust the player's position in respond to the collision. I don't know which code you're looking at, but the (x-10)/4 is most likely an attempt to figure out which playfield pixel was hit as the playfield pixels are 4x the size of the player pixels. The -10 part of that equation seems odd to me though.

  • Like 1
Link to comment
Share on other sites

Some of the example programs in that thread were made by people who were newbies at the time, so they wasted entire variables and had other bad habits.

I'll have to look harder at them tomorrow since I'm pretty spent tonight, and they're really complex. You lose me when you fill a temp variable with (x-10)/4--but it's past midnight, which isn't helping. Why is detecting a collision and moving a some coordinates back so hard to do, anyway?


Run this example program in Stella:

randomterrain.com/atari-2600-memories-batari-basic-commands.html#find_border_coordinates

I changed the program last night to include a playfield pixel. When you select the playfield pixel and move it around, notice the coordinates in the score (0 through 31 across and 0 through 10 vertically). When you select the sprite and move it around, notice how different the coordinates are.

post-13-0-42601700-1458133603.gif


In the plain vanilla, straight out of the box standard kernel, if you wanted to draw a sprite that is the same size as a playfield pixel, you'd make it 4 pixels wide and 7 pixels high. We can't forget about those pesky blank lines, so now we know that we can divide using the numbers 4 and 8.

If we want to see if a playfield pixel is in the way of a moving sprite, we have to use pfread and that means we'd need to use something like this:


   temp4 = (player0x-17)/4
   temp6 = (player0y)/8

   if pfread(temp4,temp6) then do something




Why are we subtracting 17? Because the sprite is offset by 17 pixels:

post-13-0-70058100-1458135255.gif


But we can't start thinking that 17 is a magic number, because the number we subtract changes depending on the direction the sprite is traveling and how tall and wide it is. How do we find the numbers we need? If we're not math geniuses, the only solution is trial and error in a test program. We just keep trying numbers until the collision prevention code works.


And more curiously, what is the sample15 code I posted doing adding 255 to x/y? That's really got me confused.


I didn't see the number 255 in the program you posted. But 255 is the same as -1, so they could have been using it that way in whatever program you saw it in.

 

 

 

 

post-13-0-42601700-1458133603_thumb.gif

 

post-13-0-70058100-1458135255_thumb.gif

 

 

  • Like 1
Link to comment
Share on other sites

Okay, this is actually starting to make some good sense to me.

 

That, and while I was sleeping I was (for some reason) thinking about the order I was checking/moving/offsetting things in, and how they might not be ideal.

Luckily, in my simple dot-moving construction, I have a 100% sure way of knowing exactly which sprite pixel touched and which direction it was going, but that won't always be the case with more complex programs, so I should probably get used to it now.

 

Thanks so much for all this help.

I'm not sure why I was letting this collision bit bug me so much, I just killed the player for it the last time I made this game, which is far easier.

Edited by Reaperman
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...