I’m making a vertical-scroll platformer game, and I want to create sprites that move left-to-right (or right-to-left) and when they’re out of the screen, they appear on the other side.
I have an implementation that is mostly working, the only problem is that the sprites on a single floor keeps getting closer and closer in every loop.
I’m really not good in describing things, so please check this video.
I’m using the following code to calculate the new position of the nodes:
pos.x = fmodf(size.width + pos.x + this->currentDir * this->speed * delta, this->len + size.width) - size.width;
len is the width after which the sprite gets repositioned to 0 (actually -size.width, which is the width of the sprite), currentDir is either 1 or -1 and delta is the time from the update() method.
Every sprite is positioned in it’s own update(), but I already tried doing everything in the Scene’s update() method, but the result was the same.
Hi @bugmenot,
Moving sprite on update functions behaves different for different devices. We need to consider Frame rate and any performance issue.
All the parameter (size.width,this->speed, delta, this->len) are same for each sprite?
If these Values differ in any time of the game then sprite may get close.
For testing purpose in update function move sprite with offset.
sprite->setPositionX(sprite->getPositionX() + dt * 100);
Regards,
Gurudath
Never use delta in update method. It’s a variable time step.
It’s better:
sprite->setPositionX(sprite->getPositionX() + 10.0f);
Use actions if you can.
I’m sorry @amin13a, but you should absolutely use delta time in your updates if you want smooth, time dependent movement. Since we cannot guarantee a constant time step, by using a fixed distance without applying delta time the object will move at different speeds each frame. If you look at cocos’s Action implementations you’ll see they do make use of delta time in the Action::step(float dt) overrides.
@bugmenot I would take this approach to wrap the sprite to the screen
(offset sprites on construction)
visibleWidth = Director::getVisibleSize().width;
//perform movement
pos.x += currentDir * speed * deltaTime;
//wrap to screen
if(pos.x > visibleWidth) { pos.x = -size.width; }
else if(pos.x < -size.width) { pos.x = visibleWidth; )
Hope this helps
Hi @almax27.
Thank you for that tip.
But fixed time step is needed for deterministic game logic and physics.
Always use delta in update*
Deterministic movement is out of the scope of the OPs question but is definitely a legitimate reason for not using frame delta time. However it does change the approach considerably. For example if your physics step is 0.1s but your frame delta time is ~0.2s you will need to run physics step approximately twice for every rendered frame. Further more there will be a little time left over as 0.1 will never modulus without remainder against frame delta time. So the general solution is to separate physics from rendering by extrapolating, or interpolating your rendered position from the physics state based on frame delta time. This will ensure your visible movement accurately represents the time past between frames.
1 Like