+Random Terrain Posted May 14, 2013 Share Posted May 14, 2013 Seems like most bB programs with Adventure-style movement use sticky or bouncy collision detection where you either stick to the walls or bounce along the walls when you rub the sprite diagonally against them. The program below uses collision prevention with a bit of collision detection to make the sprite move smoothly along the walls. The good news is there is no sticking or bouncing when you rub the sprite diagonally along the walls, but the bad news is that the code is gobbledygook to new users and it's also difficult to change when switching to objects that are larger or smaller than 8 x 8. First, can any of you better programmers simplify the code so it will be easier for new users to understand? Second, can you do anything using constants or def that will make it easier when using tall sprites or wide sprites or a missile or the ball? Here's the .bin file to use with an emulator or Harmony cart: collision_prevention_with_detection_2013y_05m_14d_0155t.bin Here's the bB code with REMs: collision_prevention_with_detection_2013y_05m_19d_1521t.bas Here's the bB code with fewer REMs: collision_p_with_d_fewer_rems_2013y_05m_19d_1524t.bas http://www.youtube.com/watch?v=IQfmOBNntj0 Thanks. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 16, 2013 Share Posted May 16, 2013 I appreciate you making this topic R.T. I'm also looking at my archive of old code and dusty examples for clearer non-sticky collision demonstrations. Quote Link to comment Share on other sites More sharing options...
Cybearg Posted May 18, 2013 Share Posted May 18, 2013 In my opinion, you use way too many comments. Breaking each line apart with a big chunk of comments means you can't see how the lines work together with a quick scan of the eyes. Comments to explain what something does are fine, but I think you over-isolate. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 18, 2013 Author Share Posted May 18, 2013 In my opinion, you use way too many comments. Breaking each line apart with a big chunk of comments means you can't see how the lines work together with a quick scan of the eyes. Comments to explain what something does are fine, but I think you over-isolate. That's easy to fix: collision_p_with_d_fewer_rems_2013y_05m_18d_1731t.bas Quote Link to comment Share on other sites More sharing options...
Cybearg Posted May 19, 2013 Share Posted May 19, 2013 (edited) Maybe it's just me, but your example doesn't seem to work at all. I can pass through the playfield and just wiggle around a bit. I can't say I have any ideas for a better way to do it than the "sticky" methods you mentioned, basically restricting movement based on of whether there is a collision and based on which joystick directions are being held down. Edited May 19, 2013 by Cybearg Quote Link to comment Share on other sites More sharing options...
Cybearg Posted May 19, 2013 Share Posted May 19, 2013 (edited) This collision detection should prevent the player from getting stuck on the walls and such, even on diagonals. dim colbits = a def heldup = colbits{0} def heldright = colbits{1} def helddown = colbits{2} def heldleft = colbits{3} ... if collision(playfield, player0) then goto block if joy0up then player0y = player0y - 1: heldup = 1 else heldup = 0 if joy0right then player0x = player0x + 1: heldright = 1 else heldright = 0 if joy0down then player0y = player0y + 1: helddown = 1 else helddown = 0 if joy0left then player0x = player0x - 1: heldleft = 1 else heldleft = 0 goto movedone block if heldup then player0y = player0y + 1 if heldright then player0x = player0x - 1 if helddown then player0y = player0y - 1 if heldleft then player0x = player0x + 1 movedone The problem is that, in order for hardware collision to work, there needs to be a drawscreen'd overlap of pixels, so if you try running against a wall, you'll see the sprite superimposed in two places as it is trying to move one way and then being pushed back the next frame, only to move back into the wall again. The only way I see of avoiding that is to use your soft collision calculations to use pfread to check whether there is a pfpixel in the way or not. pfread may be pretty cycle-intensive, though. I'm not sure how many it costs. Ideally, if it didn't take too many cycles, you'd keep a directional byte that had a 1 or 0 for each bit to show where pfpixels are in relation to the player, but I'm betting that would suck away all your cycles. EDIT: I checked the .bin you posted and it works fine, though it doesn't work for me from the .bas. Apparently my version of pfread is bugged, because it doesn't seem to detect a positive pfread almost any of the time. Sorry for all the blabbering above, then, since it's apparently irrelevant. That said, I'd think you could simplify the code to this: rem **************************************************************** rem * rem * Joy0 Up rem * rem ` if !joy0up then goto __Skip_Joy0_Up temp2 = 0 temp3 = ((player0x-15)/4) temp5 = temp3 + 1 temp6 = ((player0y-1)/8) - 1 if pfread(temp3,temp6) then temp2{0} = 1 else temp2{0} = 0 if pfread(temp5,temp6) then temp2{1} = 1 else temp2{1} = 0 if !temp2 then player0y = player0y - 1 __Skip_Joy0_Up Edited May 19, 2013 by Cybearg Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 19, 2013 Author Share Posted May 19, 2013 Maybe it's just me, but your example doesn't seem to work at all. I can pass through the playfield and just wiggle around a bit. I see you edited your post. Quote Link to comment Share on other sites More sharing options...
bogax Posted May 19, 2013 Share Posted May 19, 2013 (edited) EDIT: I checked the .bin you posted and it works fine, though it doesn't work for me from the .bas. Apparently my version of pfread is bugged, because it doesn't seem to detect a positive pfread almost any of the time. Sorry for all the blabbering above, then, since it's apparently irrelevant. That said, I'd think you could simplify the code to this: rem **************************************************************** rem * rem * Joy0 Up rem * rem ` if !joy0up then goto __Skip_Joy0_Up temp2 = 0 temp3 = ((player0x-15)/4) temp5 = temp3 + 1 temp6 = ((player0y-1)/8) - 1 if pfread(temp3,temp6) then temp2{0} = 1 else temp2{0} = 0 if pfread(temp5,temp6) then temp2{1} = 1 else temp2{1} = 0 if !temp2 then player0y = player0y - 1 __Skip_Joy0_Up I think pfread uses temp1 and temp2 perhaps this temp4 = ((player0x-15)/4) temp5 = temp4 + 1 temp6 = ((player0y-1)/8) - 1 if !pfread(temp4,temp6) then if !pfread(temp5,temp6) then player0y = player0y - 1 Edited May 19, 2013 by bogax Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 19, 2013 Author Share Posted May 19, 2013 Cybearg, I tried that last bit of code and it doesn't work correctly. I had to change temp2 to temp4 to make the code work, but since you got rid of the collision code, the sprite can go into a wall. That temp3 thing was a goofy mistake. Can't believe I didn't catch that. rem **************************************************************** rem * rem * Joy0 Up rem * rem ` if !joy0up then goto __Skip_Joy0_Up temp3 = ((player0x-15)/4) temp5 = temp3 + 1 temp6 = ((player0y-1)/8)-1 if !pfread(temp5,temp6) then if !pfread(temp3,temp6) then goto __Skip_to_Move_Up goto __Skip_Joy0_Up __Skip_to_Move_Up player0y = player0y - 1 if !collision(playfield,player0) then goto __Skip_Joy0_Up temp5 = (temp3*4)+16 if player0x > temp5 then player0x = player0x - 1 : goto __Skip_Joy0_Up player0x = player0x + 1 __Skip_Joy0_Up Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 19, 2013 Author Share Posted May 19, 2013 Here's the latest code with the fixed temp3 and a fix to the down movement code: collision_p_with_d_fewer_rems_2013y_05m_19d_1524t.bas Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 20, 2013 Share Posted May 20, 2013 One thing I just realised is that some of this code uses pfread commands. Nothing wrong with that EXCEPT when the bB newb tries to use different res playfields or multi-sprite (pfread add-on doesn't work for me). I could have sworn there was a non-sticky collision example that did not use pfread commands. I think it used that technique where you add 255 instead of substracting -1. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 20, 2013 Author Share Posted May 20, 2013 I could have sworn there was a non-sticky collision example that did not use pfread commands. I think it used that technique where you add 255 instead of substracting -1. If you can find a non-sticky example that doesn't use pfread, please post it. Fewer cycles wasted is a good thing. 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 20, 2013 Share Posted May 20, 2013 Well. I tried and failed to make a non-pfread bouncy/sliding collision demo. It has two major flaws: A. Smashing horizontally into a wall while pushing the joystick diagonally makes you move the wrong way vertically. B. When you meet a diagonal border the player rams himself through the playfield blocks. I post this only in the hopes it's a dumb mistake on my part and can be salvaged. bouncyfail.bas Quote Link to comment Share on other sites More sharing options...
RevEng Posted May 20, 2013 Share Posted May 20, 2013 The root of the problem with your slide-bounce attempt is you have no way of knowing if a diagonal collision was with a horizontal or vertical wall, even if you store the last direction for backout. I'm aware of two algorithms for slide-bounce collision that don't resort to pfread. Both string the detection across multiple frames. The first is the simplest. If you split horizontal and vertical motion across alternate frames and use sticky collision, the result is a simple slide-bounce. Pro: simple to understand. Con: diagonal motion looks blocky. bouncy-style1.bas bouncy-style1.bas.bin The second - used in Adventure - is a bit more complicated. It does motion in one frame, and tries to free any collisions with position backouts for the following 3 frames. (the last check+backout frame is actually shared with the first motion frame) Pro: diagonal motion looks fine Con: more complicated than the first type, and if you require fast motion it can get chunky because moving can only happen every 3 frames. bouncy-style2.bas bouncy-style2.bas.bin 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 21, 2013 Author Share Posted May 21, 2013 The test program below for the standard kernel uses one of theloon's sprites. It has collision prevention and partial collision detection correction. I don't know how to add collision detection correction for a larger sprite in two of the directions, so the sprite may overlap some playfield pixels once in a while. Here's the .bin file to use with an emulator or Harmony cart: collision_prevention_partial_cd_2013y_05m_21d_1748t.bin Here's the bB code with very few REMs: collision_prevention_partial_cd_2013y_05m_21d_1748t.bas 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 22, 2013 Share Posted May 22, 2013 Actually, the sprite was from the new game I'm working on. RevEng took mercy on me and vastly corrected my code. I think my Knight sprite is pretty cool Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted May 22, 2013 Author Share Posted May 22, 2013 Actually, the sprite was from the new game I'm working on. RevEng took mercy on me and vastly corrected my code. I think my Knight sprite is pretty cool If you're using the standard kernel, you could adapt the code above if you want smooth collision detection. You don't have to understand it to use it. I don't understand it, but it works. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted May 22, 2013 Share Posted May 22, 2013 Oh, yeah. It does seem much shorter. I think smaller examples seem less daunting. It still uses pfread so I can't use it. RevEngs massive correction to my code in his two examples don't seem to use pfread. I was just trying to make it clear that's my sprite and his awesome code (the bouncy examples he posted) 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.