Jump to content

# some movement code

## Recommended Posts

Here's some Bresenham type movement code

This moves player0 towards player1 while joy0fire is pressed
When a collision occurs the players are repositioned randomly
and paused for 1 second

The setup_move code computes the absolute value of delta x and delta y
from x0,y0 and x1,y1 and sets a bit in f for each to indicate if they
were positive or negative it then sets a bit according to which is
larger. This determines the octant we're moving in and is used to
lookup the direction of movement (+1, -1) in the xinc and yinc tables

The playfield pixels are the octant were moving in (the f variable)
and some reference pixels to show which bits are which (var40 = %01010101)

(I did this for my own purposes but when I Googled for similar
stuff in bB I found nothing so I thought I'd share it in case some
else wants something like)

move.bas

move.bin

#### Share this post

##### Share on other sites

Is that basically the same as this?
_

```   if player1y < player0y then player1y = player1y + 1
if player1y > player0y then player1y = player1y - 1
if player1x < player0x then player1x = player1x + 1
if player1x > player0x then player1x = player1x - 1
```

#### Share this post

##### Share on other sites

Is that basically the same as this?

_

```   if player1y < player0y then player1y = player1y + 1
if player1y > player0y then player1y = player1y - 1
if player1x < player0x then player1x = player1x + 1
if player1x > player0x then player1x = player1x - 1
```

here you can compare the two

movement_comparison.bas

movement_comparison.bin

#### Share this post

##### Share on other sites

This is really cool. I think I still need to wrap my head around it and find an application for it. But I like it a lot.

Double post.

#### Share this post

##### Share on other sites

here you can compare the two

Thanks. That's a big difference. I've been trying to simulate it without using data and I can get close, but there is always something off and I end up using too much code anyway, so I might as well just adapt the code you posted.

#### Share this post

##### Share on other sites

What does the variable alias "ea" stand for in the code?

Also, is there a way to make this work if the target moves using the joystick? Or does it always have to be a stationary target?

#### Share this post

##### Share on other sites

ea is error accumulator

if eg dx is greater than dy then when you've
accumulated dx worth of dy's you've accumulated
a pixel's worth of error and it's time to take a
step in y (you're a pixel away from where you
want to be in the y direction)

I hadn't quite decided how to deal with a moving
target.
you'd need to re-do the setup but I think you
would want to retain the accumulated error so
you sort of bend the line of your path without
restarting.
I haven't decided the best way to do that.
the first thing I'll try is just re computing
the setup without changing ea and see what it
looks like
basically when you change octant dx and dy
swap places but the actual values you're
working with don't change much and presumably
if you don't change octant the difference
between changes wouldn't be much
(at least that's what I'm thinking)

this just (re) sets up the move without resetting ea
if player1 moves

moving_target.bas

moving_target.bin

#### Share this post

##### Share on other sites

Thanks. That looks nice and smooth. I'll start adapting this latest code. When I get done, I'll put an example program on the bB page and link back to this thread for people who want more info.

#### Share this post

##### Share on other sites

if you just leave player1 sitting you'll see player0

sometimes misses

#### Share this post

##### Share on other sites

There's two problems with the moving target code

One is the movement code just isn't very accurate
if you make both the players 1 pixel it will
generally miss

If you make at least one of the players 2 pixels
it won't miss if you're not moving but it's not
hard to cause a miss by holding still when player0
comes at you from far away so that dx and/or dy have
(relatively) large values, then dodging towards
but missing player0 when it gets very close (so that the
residual ea is large compared to the new dx and/or dy)

(I'm guessing, I didn't really look to see if that's
what's happening)

I expected to see it with the wrap around movement by
jumping back and forth between diagonally opposed
corners but it turns out it's not too hard to cause
a miss even when player1 is 4 x 4 pixels

This is not unexpected, I deliberately made the code
simple but I didn't expect it to be so easy to cause
a miss when player1 is as large as 4 x 4

The only change I'd make is to set ea to half of
dx or dy (when it comes time to set ea)

I think that would make it slightly more accurate
and not cost much

So for example I'd make the setting of ea a subroutine
that could be called only when it's really necessary
(in this case when a new player0 is spawned)

And just be aware that the code as is has limitations

moving_target_2.bas

moving_target_2.bin

#### Share this post

##### Share on other sites

Does "gosub set_ea" have to come after "gosub setup_move" in the line below?
_

`if collision(player0, player1) then gosub P0_rand : gosub setup_move : gosub set_ea : goto s2`

_
Would it still work OK if they are switched like in the example below?
_

`if collision(player0, player1) then gosub P0_rand : gosub set_ea : gosub setup_move : goto s2`

_

#### Share this post

##### Share on other sites

setup_move has to come first because it computes dx and dy

and sets f{0} to indicate which is larger and set_ea sets ea to the

larger (divided by two) of the two and uses f{0} to determine

which

Edited by bogax

#### Share this post

##### Share on other sites

setup_move has to come first . . .

Thanks. Here is the first draft:

If you think it looks OK, I'll put it on the bB page.

#### Share this post

##### Share on other sites

I suppose you think that's easier to understand than my code

The only real criticism I have is

1) the the player0 move code can move player0 on both
axis but you only test for one (x on one branch and
y on the other)

2) you should test for the limits and then skip the move
rather than make the move and try to undo it

also, in this bit of code

```  _x0 = player0x + 1 : _y0 = player0y + 1
_x1 = player1x + 1 : _y1 = player1y```

the + 1's are there to compensate for the
size of the sprites to make the aiming point
somewhere near the middle, they're left over
junk that I should have removed (or adjusted)

you don't really need _x0, _y0, _x1, _y1
they're more in the nature of parameters
so that the setup move code isn't dedicated
to one set of conditions (player0 moving
towards player1 in this case)

#### Share this post

##### Share on other sites

I suppose you think that's easier to understand than my code

I've been going back to update the example programs on the bB page (I think I'm about halfway done) and I'm trying to make all of the code semi-consistent. Same for any new programs I'll be adding. Some people hate the comments with a passion, but at least it helps me remember what does what and why. People who hate the comments can use a program like Notepad++ and do a quick find and replace to get rid of them.

1) the the player0 move code can move player0 on both

axis but you only test for one (x on one branch and

y on the other)

Wow! I'm glad you caught that.

2) you should test for the limits and then skip the move

rather than make the move and try to undo it

I knew how to do that for the player, but my brain stopped working and I couldn't figure out how to handle it when x can go left or right and y and go up or down. I just updated the code. This seems to work:

_

```   temp1 = _error_accumulator

if _octant{0} then goto __Skip_Chase1
if player0y >= _Edge_Top && player0y <= _Edge_Bottom then player0y = player0y + _Data_yinc[_octant]
_error_accumulator = _error_accumulator - _delta_x
if temp1 >= _error_accumulator then goto __Skip_Chase2
_error_accumulator = _error_accumulator + _delta_y
if player0x >= _Edge_Left && player0x <= _Edge_Right then player0x = player0x + _Data_xinc[_octant]

goto __Skip_Chase2

__Skip_Chase1

if player0x >= _Edge_Left && player0x <= _Edge_Right then player0x = player0x + _Data_xinc[_octant]
_error_accumulator = _error_accumulator - _delta_y
if temp1 >= _error_accumulator then goto __Skip_Chase2
_error_accumulator = _error_accumulator + _delta_x
if player0y >= _Edge_Top && player0y <= _Edge_Bottom then player0y = player0y + _Data_yinc[_octant]

__Skip_Chase2

```

also, in this bit of code

```  _x0 = player0x + 1 : _y0 = player0y + 1
_x1 = player1x + 1 : _y1 = player1y```
the + 1's are there to compensate for the

size of the sprites to make the aiming point

somewhere near the middle, they're left over

junk that I should have removed (or adjusted)

you don't really need _x0, _y0, _x1, _y1

they're more in the nature of parameters

so that the setup move code isn't dedicated

to one set of conditions (player0 moving

towards player1 in this case)

Thanks. I just got rid of it.

Here is the updated code and .bin:

ex_bresenham_movement_2015y_03m_08d_2110t.bas

ex_bresenham_movement_2015y_03m_08d_2110t.bin

If you get a chance and feel like it, maybe you can expand on what each line of your code in the file above does so I can add it to the program. If you don't feel like it, no problem.

#### Share this post

##### Share on other sites

I think you should either skip the move code
altogether at the limits or redo the setup
if you apply the limit because doing only part
of the move will cause you to deviate from the
line you want to follow
The movement of the sprite and the operation
of the error accumulator are really independent
the sprite needs to follow what the error
accumulator is doing. If you limit what the
sprite does and not the error accumulator
they will diverge

You really shouldn't need the limits on the
player0 sprite it can only follow player1
and player1 is limited

Having said that it's still possible to make
player0 miss (and go off screen) (with the
previous code) but player1 has to hold still,
move slightly at just the right time, then
hold still again.
Even if player0 misses (and goes off screen),
any movement of player1 should bring it back

#### Share this post

##### Share on other sites

Here I've made two changes to the setup_move code to
improve the accuracy

First we can assume that dy wont be more than 128
so if dx is less than 128, dx and dy are multiplied
by 2 that should give you something like 1/2 pixel
accuracy in the calculations most of the time,
instead of 1 pixel

Second it sets ea iff ea looks like it's too far
out of whack for the current dx and/or dy

It's still possible to make player0 miss but it's
a lot harder

improved_movement.bas

improved_movement.bin

#### Share this post

##### Share on other sites

Thanks. I updated the code on the bB page.

#### Share this post

##### Share on other sites

Hey there, I'm curious. Is there a way to make the Bresenham movement only reversed? Instead of being chased by the dot, the dot trying to get away from you?

If so, I could certainly use some help figuring out how to do that.

#### Share this post

##### Share on other sites
Not sure exactly what you want

But assuming you want to steer your player

with the joystick and not be just left-right, up-down

Two possibilities come to mind.

Have a target you can steer (not necessarily visible)

that you can steer in the usual way and have your object

move towards that (something like missle command)

Or have your movement follow a vector you can rotate

and convert to dx and dy with a look up table

(something like asteroids)

#### Share this post

##### Share on other sites

Does this and other line algorithms require the data tables? I would really like to shoot in a straight line like i can do with this, but with smoother 8.8 type X & Y variables, is it possible?

#### Share this post

##### Share on other sites

Does this and other line algorithms require the data tables? I would really like to shoot in a straight line like i can do with this, but with smoother 8.8 type X & Y variables, is it possible?

how will you aim?

no, you don't need tables

I doubt 8.8 variable will get you anything

8 bits should be enough for the maximum

screen resolution

it will depend on how you aim (I think)

Edited by bogax

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

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.

×
• Forums
• Clubs

• All Activity

• #### Subscriptions

×
• Create New...