Jump to content
IGNORED

Multi-Direction movement


Recommended Posts

Just something I was thinking about as I am making a Food Fight port for Intellivision. People have been asking about making use of the INTV disc to go in all directions not just 8.

 

So for now I have 8 directions which is pretty standard I think. 

 

x = x + 1 'EAST
x = x - 1 'WEST
y = y - 1 'NORTH
y = y + 1 'SOUTH

y = y - 1: x=x+1 'NORTH EAST
y = y - 1: x=x-1 'NORTH WEST
y = y + 1: x=x+1 'SOUTH EAST
y = y + 1: x=x-1 'SOUTH WEST

 

I just am not sure about NORTH_NORTH_EAST, EAST_NORTH_EAST etc.

 

would NORTH_NORTH_EAST be something like  y=y - 2 : x=x +1?

Edited by Brian's Man Cave
  • Like 1
Link to comment
Share on other sites

You need sub-pixel resolution:

 

Example, use 16 bits instead of 8 bits to store the X value.

If moving east, add 256 to X. If moving north east, add 256 * .707 = 181. Scale all the numbers as you see fit. Make a table of x increments per angle.

Only use the upper 8 bits to determine where to place the character. The lower 8 bits are essentially decimal places. 8 bits to the left of the decimal place, and 8 bits to the right. 8.8 I'd call that. Doesn't need to be 8.8... you could do 7.1 (single byte), or 12.4, or whatever works. I'm assuming 8.8 works well for IntyBASIC, if you can easily grab the upper 8 bits for display purposes.

 

This will also make your 45 degree angles better. Right now your speed is faster at 45 vs. 0 or 90 degrees. Sub-pixels will make the speed more constant.

 

With this method, you can also easily add acceleration. Set the acceleration (and deceleration) to a specific value, and each frame add the acceleration to the speed, and add the speed to the position. You'll need to do math on the table already mentioned, of course.

Edited by 5-11under
  • Like 1
Link to comment
Share on other sites

1 hour ago, 5-11under said:

You need sub-pixel resolution:

 

Example, use 16 bits instead of 8 bits to store the X value.

If moving east, add 256 to X. If moving north east, add 256 * .707 = 181. Scale all the numbers as you see fit. Make a table of x increments per angle.

Only use the upper 8 bits to determine where to place the character. The lower 8 bits are essentially decimal places. 8 bits to the left of the decimal place, and 8 bits to the right. 8.8 I'd call that. Doesn't need to be 8.8... you could do 7.1 (single byte), or 12.4, or whatever works. I'm assuming 8.8 works well for IntyBASIC, if you can easily grab the upper 8 bits for display purposes.

 

This will also make your 45 degree angles better. Right now you're speed is faster at 45 vs. 0 or 90 degrees. Sub-pixels will make the speed more constant.

 

With this method, you can also easily add acceleration. Set the acceleration (and deceleration) to a specific value, and each frame add the acceleration to the speed, and add the speed to the position. You'll need to do math on the table already mentioned, of course.

Thanks! I will have to read this a few times and see if any of it sinks in... my math sucks 😁

Link to comment
Share on other sites

Remember that the circle has 360 degrees or 2*pi radians. When you move to the left or right, you use cos(rad) and when you move up or down you use sin(rad).

 

Starting at 0,0:

Move one step to the right, angle 0 degrees = 0 * pi. Horizontal movement cos(0) = 1, vertical movement sin(0) = 0.

Move one step up, angle 90 degrees = 0.5 * pi. Horizontal movement cos(0.5*pi) = 0, vertical movement sin(0.5*pi) = 1.

Move one step to the left, angle 180 degrees = 1 * pi. Horizontal movement cos(pi) = -1, vertical movement sin(pi) = 0.

Move one step down, angle 270 degrees = 1.5 * pi. Horizontal movement cos(1.5*pi) = 0, vertical movement sin(1.5*pi) = -1.

 

If you move northeast at 45 degrees = 0.25 * pi. Horizontal movement cos(0.25*pi) = 0.707, vertical movement sin(0.25*pi) = 0.707.

If you move east-northeast at 22.5 degrees = 0.125 * pi. Horizontal movement cos(0.125*pi) = 0.924, vertical movement sin(0.125*pi) = 0.382.

 

Then you would use the fixed point math as mentioned in the manual, and multiply the fraction with 256 as 5-11under wrote

Link to comment
Share on other sites

The easiest way to do this is to define a data table with the velocities at each of the 16 directions.  The idea is to treat the 16 directions as vectors, and pre-compute the fixed-point velocity of the X and Y components of each vector in a table.  Then, you use the disc direction as an index in that table to add the necessary velocities to the X and Y positions.

 

That's how I do it.  You may want to take a look at @intvnut's excellent IntyBASIC example program called "accel," included in the "Contributions" folder of the IntyBASIC SDK.  (I believe it is also included in the regular compiler distribution.)

 

It does a lot more than 360˚ movement, but you can ignore all the acceleration and friction physics, and focus on the use of the data table.

 

     -dZ.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

I used 16-directional movement plus sub-pixel precision in X-Ray & DILLIGAS.  I think I have it documented in Appendix E of Advanced Game Programming For Intellivision.  If you want me to dig up some code, I can help you.

 

I remember setting straight up/down/left/right to move 200/256th of a pixel each video frame.  From there, I calculated the exact X/Y offset values for the diagonals and "half-wind" directions as if they were points on a circle.  If you want the exact values, I can send them your way.

Link to comment
Share on other sites

I have a little script that generates a data table of 16 vector component pairs based on a given velocity.  The velocity is given in "pixels per frame."

 

I can share the script if you are interested, or just the table of values you need for whatever velocity you want.

 

The key thing is that, for you to use it, you need to employ sub-pixel movement using fixed-point fractional values in 16-bit variables (what @5-11under mentioned above).  The reason for this is that some of the angles will not correspond to whole pixel displacement in either the X or Y coordinates (or both, depending on the velocity).

 

(Consider that moving [x+1, y+0] will move you horizontally, and [x+1, y+1] will move you in a perfect diagonal at a 450 angle.  So, how do you get to one of the slight diagonals like North-North-East with whole numbers?)

 

If you are interested in learning how that works and how to use it in your program, let us know, and we can assist.

 

Otherwise, I personally see little value in throwing solutions at you if you do not know how to apply them to your program. :)

 

   dZ.

Link to comment
Share on other sites

On 4/10/2023 at 5:16 AM, DZ-Jay said:

I have a little script that generates a data table of 16 vector component pairs based on a given velocity.  The velocity is given in "pixels per frame."

 

I can share the script if you are interested, or just the table of values you need for whatever velocity you want.

 

The key thing is that, for you to use it, you need to employ sub-pixel movement using fixed-point fractional values in 16-bit variables (what @5-11under mentioned above).  The reason for this is that some of the angles will not correspond to whole pixel displacement in either the X or Y coordinates (or both, depending on the velocity).

 

(Consider that moving [x+1, y+0] will move you horizontally, and [x+1, y+1] will move you in a perfect diagonal at a 450 angle.  So, how do you get to one of the slight diagonals like North-North-East with whole numbers?)

 

If you are interested in learning how that works and how to use it in your program, let us know, and we can assist.

 

Otherwise, I personally see little value in throwing solutions at you if you do not know how to apply them to your program. :)

 

   dZ.

Thanks for this... I am thinking this goes way over my head ..haha!

 

So far my game is using the 8 directions and seems to work ok.

Link to comment
Share on other sites

55 minutes ago, Brian's Man Cave said:

Thanks for this... I am thinking this goes way over my head ..haha!

 

So far my game is using the 8 directions and seems to work ok.


No worries, I understand.

 

It shouldn't be too hard to understand fixed-point arithmetic and sub-pixel movement, really.  I was able to learn it, and I suck at maths as well.  I also am very slow to learn, and getting older.

 

You can always search online for some tutorials.  I'm sure there are plenty.  The main topics to look for are:

  • Fixed-Point Arithmetic
  • Digital Differential Analyzer
  • Simple physics like acceleration, vectors, and displacement

 

Honestly, I know those sound scary (and they can be thick in math formulas and hairy equations); but for our purposes, we just need to apply some very simple principles from them.  All we need is a straightforward functional basic knowledge and we got our tools to implement some really cool stuff.

 

I'll see if I can provide a tutorial one of these days.  It seems to be a common question around here.

 

    dZ.

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