Endless Runner game speed and linear impulse

In my endless runner game, my player object is not moving at all, I move all the other game objects.
The way I move them is by something like this, with speed being increased every 5 secs.

local speed = 1    
local function increaseSpeed()
        speed = speed * 1.1
    end

  -- moving background objects on every frame
local function update()
  for i = #backgrounds, 1, -1 do
    local b = backgrounds[i]
     b:translate(-(speed * 3), 0)
   end
end

Runtime:addEventListener("enterFrame", update)
speedIncreaseTimer = timer.performWithDelay(5000, increaseSpeed, 0)

And my hero is just jumping over the blocks with a linear impulse like this

function hero:jumpNow()
    self:jumpAnimation()
	self:applyLinearImpulse(0, -8*self.mass, self.x, self.y )
end

The problem I am facing is as the game speed increases to a considerable amount, the player jumps are getting longer and longer, as expected because the blocks are coming with a higher speed.

I have 2 questions on this whole setup if someone could shed some light on -

  1. How do I setup a correlation between my game speed and linear impulse so the jump feel more natural as the game progresses ?

  2. Is my increasing the same speed increase mechanism right way to achieve something like this, or there are other options which I should look into ?

Thank you,

@duskandawn I think we need to see more code. My suspicion is that you are mixing display objects and physics objects. Once you add an object to the physics engine you are “surrendering” movement control to the physics engine. If you move a display object without using physics, you will decouple the physics engine from your visual experience. Change the physics drawMode to check for this - use “hybrid” to see display and physics objects at the same time.

I imagine that your jump:animation( ) function is the hero instead of the linear impulse.

Thanks for your reply @sporkfin
Here is some more code, basically,
My Hero is setup like this

 local instance = display.newSprite(group, spritesPlayer, sequenceSprite)
    instance.x = display.contentCenterX - x
	instance.y = y
    instance.isHero = true
    instance.isDead = false
    physics.addBody( instance, "dynamic", {bounce=0.0, density=.75})
    instance.isFixedRotation = true
    instance.isSleepingAllowed = false 

And my platforms which are moving towards the hero are setup like this

local pl2 = display.newImageRect( plGroup, "images/platformmid.png", pl2Width, 300 )
	pl2.isPlatform = true
	pl2.x = 400
	pl2.y = display.actualContentHeight + pl2Height
	physics.addBody(pl2, "static", {bounce=0.0})
	platforms[#platforms+1] = pl2

On touch listener I call hero:jumpNow() to simulate obstacle avoidance. But as the speed of platforms are increasing the jumps become longer due to the speed.
I feel I am looking for some way to dampen the linear impulse as my game speed is increasing ?

bump :frowning: , if others have any ideas on this…

Dampen the linear impulse you say? Try body.linearDamping

Off the top of my head, as the speed increases, I would:

This will cause the jump to take less and less time to complete (while retaining the max height of the jump), thus making the horizontal distance covered in a jump the same or near the same as when speed is low. You’ll have to experiment.

2 Likes

Thank you @roaminggamer,
Any suggestions for my question #2 for increasing the game speed.

With my current setup after the game is speed is increased a bit, I am seeing a flicker with my backgrounds scrolling, and I just not sure how to fix it, I have tried changing dimensions of my assets but the flicker doesnt go away.

I dont see if happening if I am not adding any parallax scrolling :slightly_frowning_face:

I suggest you always translate using whole pixel values. You may simply be getting rounding errors where a gap temporarily opens up between two background images or you get a temporary overlap which may also look weird.

Note: The way you’re doing that isn’t really right. Your enterFrame listener is assuming that the time between frames is exactly the same and it simply isn’t. You need to measure time from frame to frame and use that value as part of your translation calculation.

I’d write that enterFrame listener something like this:

local lastT = system.getTimer() -- Snag initial time
local speed = 100 -- Speed is in pixels per second

local function update()
   local curT = system.getTimer()
   local dT = (curT - lastT)/1000
   lastT = curT
   --
   local dX = math.round( dT * speed ) 
   --
   for i = #backgrounds, 1, -1 do
      backgrounds[i]:translate( -dX, 0 )
   end
end

1 Like

If this fails to work you’ll probably want to limit your translation to full pixels on the current device. i.e. incorporate the scaling factor in the calculation as a limit to ensure every translation resolves to a full pixel on the current device.

Thank you so much @roaminggamer, using your suggestions I almost don’t see any flicker anymore.
Thanks for the explanation, for newbie these are super helpful… :pray: