Game Move Alogrithm

I’m toying with a game idea… for sake of argument think “PacMan”.
Internally the game board is an 11x11 integer array, with each element being blank, a power pill, etc (things for the main character to interact with)

Here is the problem… the main character (actor) can more one of 4 directions … but on the display the movement needs to be fluid (not jumping from cell to cell), but attempts to turn, pick up the cells object , have to occur when the actor is completely in the cell…
the actor class has two floating values (X,Y) and technically when those are both “integer” ( floor(x)=ceil(x) ) is when I need things to be checked, but because they are double values, rounding errors make this difficult to detect. Also, as well as checking if there is an object to pick up… at the same time it needs to check if there is a maze wall which would stop forward motion.

I fear I’m way overthinking this… so am hoping someone will slap me up side the head (virtually)

for x=1 to 1000
    actor.x=x
   if x/cellsize then ????   // cellsize would be how many points wide/tall each of the 11x11 values cover graphiclly
  // when condition, then need to check which cell for what conditon
next x

in reality actor.x and actor.y would be altered by events, and may non necessary be altered by +/- 1, it could be +/- 10, 15 or n points

virtually slaps upside the head
Use a game engine.

Creating a game in Xojo is like using a shotgun to kill a fly.
It’s going to be really difficult, and there’s a lot of holes in your wall when you finally get it to work.

What about

if x mod cellsize = 0 then
   cell = x/cellsize
   etc...

Not a viable option… 1) I have 80% of the rest of the app (including graphics animations etc) completed, as well as the control interface to control the direction of the actor… The main actor and the “enemy” (think pacman ghosts) are all members of the same class, the difference is in their sprite, and the enemy actors will invoke an AI to determine their move behaviour, but the way that movement translates to the screen will be identical for all actors.

[quote=298934:@Tim Hare]What about

if x mod cellsize = 0 then cell = x/cellsize etc... [/quote]
Hmmmmm… this would require some rethinking… as the actor.x/y is a value from 0 to 11 (where the actor class draw method translates that to screen coordinates… so if the actor was at (5.5,6.2) and the cellsize was 30 the pixel location would be 165,186, and the cellsize is NOT fixed… it will change depending on the screen size/resolution and how the window is set

I would go about animation events then. I would have the character “grid position” always be an integer, and to move an animation handles the specifics. When the move animation completes it raises an event that says so. In that move animation complete event I would have it check for objects to pick up, and change the allowed directions.

Actually leaning that direction… since the actor can’t officially “stop” between cells… the only other thing is if an enemy actors rectangle overlaps the actors rectangle during the move… (detecting the collision itself is easy, if just “when”)

So I’m thinking instead of a generic “Move Delta” method… I will have a Move(direction) as Bool method, which will return false if the move cannot be made (ran into a wall), and that method will animate the actor moving 1 cell in the indicated direction, with continous calls until it fails, or the user (or AI) decides to change directions

That makes the game play timing dependent on the animation which is probably not what you want.
A faster machine would play the game faster than a slower machine which is not a good experience.

A timing game is animation dependent. The user can’t react until the animation happens.

[quote=298942:@Norman Palardy]That makes the game play timing dependent on the animation which is probably not what you want.
A faster machine would play the game faster than a slower machine which is not a good experience.[/quote]
not if the frames of the animation are controlled by a consistent timer…
ie… it takes 0.x seconds to moved from cell A to cell B

(thats the beauty of event driven programming)

It should not play a lot faster on a faster machine and a lot slower on a slower machine

I should be able to get 60 FPS on a fast machine and 30 FPS on a slower machine and still have the overall game play at roughly the same speed

Game timing should not be dependent on your FPS

That’s all I’m saying

[quote=298954:@Norman Palardy]It should not play a lot faster on a faster machine and a lot slower on a slower machine

I should be able to get 60 FPS on a fast machine and 30 FPS on a slower machine and still have the overall game play at roughly the same speed

Game timing should not be dependent on your FPS

That’s all I’m saying[/quote]

and I’m saying the two are not connected… as a matter of fact to help with that … the display is multiple layers with each layer (picture) being changed only when required… a few layers never change at all… a few change alot, but those changes occur way less than even 20x a second… so FPS is not an issue, because the variance between the fastest and slowest machines (and I have one of each), is barely noticable.

Hi Dave,

Another possibility is to have a timer for logic and another timer for redrawing the screen. Here is some pseudocode to help explain:

//Timer#1 set to fire every 1/60 of a second for a 60 fps rate Canvas redraw

//Use movement based on speed, or if you want to get fancier, use acceleration //Timer#2 fires once every 1/30 of a second (or whatever you would like) XPosition = XPosition + XSpeed YPosition = YPosition + YSpeed //Check if character has reached the final position If XPosition = XEndPosition then XSpeed = 0 If YPosition = YEndPosition then YSpeed = 0 ...etc...

//Check the keyboard to move character into new position in KeyDown event If Key="w" then XSpeed = 1 If Key="s" then XSpeed = -1 If Key="a" then YSpeed = -1 If Key="d" then YSpeed = 1

Edit:Added info about arrays

I have an example of this in my OpenGL book, where the array is used to draw the scene, where 1’s are the wall and 0’s are open spaces.

(1,1,1,1,1,1,1)
(1,0,0,0,0,0,1)
(1,1,1,0,0,0,1)
(1,0,0,0,0,0,1)
(1,1,1,1,1,1,1)

After every movement recheck the 8 squares around you to see if the character is hitting a wall, or running over a pickup chest, etc.

I came up with a routine based on something Tim said.
Originally I was planning on have a Move(dx,dy) which would move the actor fractional cells,
now its more of a MoveTo(cx,cy) where that routine would animate the actor moving into Cell(cx,cy)

I attach actions to sprites when doing this. My MoveTo action works like this.

[code]Public Sub RunAction(sprite As SpriteNodePF, deltaTime As Double)
if not Initiated then

dim offset As Vector = goal - sprite.Position

sprite.Velocity = offset.normalized * (sprite.Position.DistanceTo(Goal) / Duration)

Initiated = true

end if

’ Move the sprite towards the goal

Dim movementAmount As Vector = sprite.velocity * deltaTime

Dim distanceToGoal as double = sprite.Position.DistanceTo(Goal)

Dim moveEnd As Vector = sprite.position + movementAmount

Dim distanceMomentum As double = sprite.position.distanceto(moveEnd)

if distanceMomentum < distanceToGoal then

sprite.Position = sprite.Position + movementAmount

else

sprite.Position = New Vector(Goal.x, Goal.y)

sprite.velocity = New Vector(0,0)

me.Remove = true

end if

End Sub
[/code]

and the constructor

[code]Public Sub Constructor(goal As Vector, duration As Double)
’ Calling the overridden superclass constructor.
Super.Constructor(duration)

me.Goal = goal
End Sub
[/code]