Jump to content
IGNORED

Attention good programmers. Can you simplify this code?


Random Terrain

Recommended Posts

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by Cybearg
Link to comment
Share on other sites

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 by Cybearg
Link to comment
Share on other sites

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 by bogax
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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.

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...