Reaperman Posted March 16, 2016 Share Posted March 16, 2016 (edited) 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 March 16, 2016 by Reaperman Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 16, 2016 Share Posted March 16, 2016 Have you looked at any of the example programs on the bB page that use collision prevention? randomterrain.com/atari-2600-memories-batari-basic-commands.html#ex_sprite_collision_prevention randomterrain.com/atari-2600-memories-batari-basic-commands.html#sprite_missile_bankswitching_example randomterrain.com/atari-2600-memories-batari-basic-commands.html#ex_sound_with_bg_music 1 Quote Link to comment Share on other sites More sharing options...
Reaperman Posted March 16, 2016 Author Share Posted March 16, 2016 (edited) 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 March 16, 2016 by Reaperman Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted March 16, 2016 Share Posted March 16, 2016 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. 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 16, 2016 Share Posted March 16, 2016 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_coordinatesI 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. 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: 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. 1 Quote Link to comment Share on other sites More sharing options...
Reaperman Posted March 16, 2016 Author Share Posted March 16, 2016 (edited) 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 March 16, 2016 by Reaperman Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.