Moving object fast appears to be shaking/vibrating in cocos2d-x - cocos2d-x

I am using cocos2d-x 3.4, When I try to move object fast on screen in cocos2d-x,it appears like shaking, I am using MoveTo, function,and my object moves very fast. How can I make this move action smooth.
Please help me!
Here is my code:-
Vector<FiniteTimeAction*> actionVector;
CCLOG("inside movePlayerOnGrid %zd",playerPosArray.size());
for (int i=0; i < playerPosArray.size(); i++) {
auto moveAction = MoveTo::create(MOVING_TIME,playerPosArray[i]);
actionVector.pushBack(moveAction);
if(isDarkMode){
auto moveActionForDarkMode2 = MoveTo::create(MOVING_TIME,playerPosArray[i]);
actionVectorForDarkMode2.pushBack(moveActionForDarkMode2);
}
}
if(actionVector.size() > 0){
Sequence *seq = Sequence::create(actionVector);
player->runAction(seq);
here player is my object(Sprite)

Try increasing the value of MOVING_TIME. In the cases that I have encountered, increasing this reduces the shaking.

Related

libgdx - fixed timestep with interpolation - without box2d

I am having some problems implementing fixed timestep with graphic interpolation in my game.
Here is part of the render method:
#Override
public void render(float delta)
{
double newTime = TimeUtils.millis() / 1000.0;
double frameTime = Math.min(newTime - currentTime, 0.25);
accumulator += frameTime;
currentTime = newTime;
while (accumulator >= step)
{
updateObjects(step);
accumulator -= step;
}
double alpha = accumulator / step;
interpolateObjects((float)alpha);
}
Here is updateObjects:
for (int i = 0; i < world.level.gameObjects.size(); i++)
{
GameObject go = world.level.gameObjects.get(i);
go.prevPosition.set(go.position);//save previous position
go.update(delta);
}
interpolateObjects:
for (int i = 0; i < world.level.gameObjects.size(); i++)
{
GameObject go = world.level.gameObjects.get(i);
go.position.lerp(go.prevPosition, alpha);
}
And then objects are rendered using position
As far as i can tell this should work, but it doesn't.
On high fps (200-400) everything is too slow, movement isn't even visible, i can just see that position is changing by 0.0001 or something like that
On low fps (10-20), movement is visible but again objects are very slow...
If i disable interpolation, than everything works as it should (on any fps), but then everything is jittery.
So the problem is somewhere in interpolation.
Your interpolation go.position.lerp(go.prevPosition, alpha) is set up to assume that prevPosition was last updated at an exact multiple of step, but then when you update prevPosition like this go.prevPosition.set(go.position) you are destroying that contract on the first update of the frame. It also looks like you are lerping backwards (from position to the previous position).
I think you need a third vector so the last interpolated value is guaranteed not to influence your fixed time updates. Here I'll call it interpPosition, and it will be used for drawing instead of position.
You actually seem to technically be extrapolating (not interpolating) the value, since you are not updating ahead of time and your alpha is calculated from time left in the accumulator. If you want to linearly extrapolate from the last two positions calculated, you can do it like this (note the 1+alpha to extrapolate):
for (int i = 0; i < world.level.gameObjects.size(); i++)
{
GameObject go = world.level.gameObjects.get(i);
interpPosition.set(go.prevPosition).lerp(go.position, 1 + alpha);
}
Depending on the speed of your simulation (and how fast objects can accelerate), this might still look jerky. I think a smoother, but computationally slower way to do this would be to do a fully calculated update using alpha instead of step time, and storing that in the interpPosition vector. But only do that if necessary.

Forcing update rendering of MX ProgressBar?

Would anyone know a method (or trick) to force a rendering update to an MX ProgressBar in manual mode when using setProgress?
I have a situation with a block of code containing a couple of for loops which take a bit of time to complete. It would be tedious to unwrap this code to generate events, etc.
Update
Let me expand on this with a bit of pseudo code. I want to update the progress bar during operations on the contents of an array. THe for loops blocks so the screen isn't updating. I've tried validateNow() but that had no effect.
Is there some non-convoluted way I can either unwrap the for loop or use AS3's event model to update a progress bar? (I'm more accustomed to multi-threaded environments where this sort of task is trivial).
private function doSomeWork():void {
progressBar.visible = true;
for(var n = 0; n < myArray.length; n++){
progressBar.setProgress(n, myArray.length);
progressBar.label = "Hello World " + n;
progressBar.validateNow(); // this has no apparent effect
var ba:ByteArray = someDummyFunction(myArray[i]);
someOtherFunction(ba);
}
progressBar.visible = false;
}
In Flex, the screen is never updating while Actionscript code is running. It basically works like this:
Execute all runnable Actionscript code.
Update the screen.
Repeat continuously.
To learn more details, google for [flex elastic racetrack]. But the above is the nut of what you need to understand.
If you don't want a long-running piece of code to freeze the screen, you'll have to break it up into chunks and execute them across multiple frames, perhaps within a FRAME_ENTER event handler.
I am not sure what exactly is the problem. I tried the following code and it works without any need to validateNow.
protected function button2_clickHandler(event:MouseEvent):void
{
for(var n:int = 0; n < 100; n = n+20){
progressBar.setProgress(n, 100);
progressBar.label = "Hello World " + n;
// progressBar.validateNow();
}
}
<mx:VBox width="100%" height="100%">
<mx:ProgressBar id="progressBar"/>
<mx:Button label="Update Progress" click="button2_clickHandler(event)"/>
</mx:VBox>

Few basics in cocos2d-x v3 Windows

I have some basic questions about some Problems in cocos2d-x v3.
1.) when I create sprites like that:
cocos2d::Sprite *sprite1 = cocos2d::Sprite::create("test.png");
auto sprite2 = cocos2d::Sprite::create("test.png");
How I have to to erease them proplery? Should I use autorelease (it crashes when I use it after create it)? Can I for both variants just use:
sprite1->removeFromParentAndCleanup(true);
sprite2->removeFromParentAndCleanup(true);
2.) When I want an Animation have active in my HelloWorldScene, so that i can use it when i want, how can I do it? I tried something like that:
void HelloWorld::runAnimationWalk() {
auto spritebatch = cocos2d::SpriteBatchNode::create("robo.png");
auto cache = cocos2d::SpriteFrameCache::getInstance();
cache->addSpriteFramesWithFile("robo.plist");
//spritebatch->addChild(worker);
Vector<SpriteFrame *> animFrames(5);
char str[100] = {0};
for(int i = 1; i <= 5; i++)
{
sprintf(str, "robot%i.png", i);
cocos2d::SpriteFrame* frame = cache->getSpriteFrameByName( str );
animFrames.pushBack(frame);
}
auto animWalk = cocos2d::Animation::createWithSpriteFrames(animFrames, 0.1f);
vector<Worker>::iterator it = workerVector.begin();
for(int k = 0; k<workerVector.size();k++) {
if(it->getType() == 1)
it->getWorker()->runAction(RepeatForever::create(Animate::create(animWalk)));
it++;
}
}
That works, but i have to call the function always after I want to change the animation. I tried to save the spritebatch, cache etc... global, but the animation dissaperars after a few time.
Answer 1) Yes. This is a full scenario:
//Create
Sprite *sprite1 = cocos2d::Sprite::create("test.png");
this->addChild(sprite1);
// Deleter Later
sprite1->removeFromParent();
Answer 2) You can create an animation ( Animation* ) and run it on any sprite.
some note:
If you want the animation play again and again, you can make a infinite version of your animation with RepeatForever::create(YourAnimation).
If you want to create the animation but use(display) it later. you can create your Animation* and retain() it until you run it on some target(sprite). (don't forget ro release it when running on target)

Using byteArray with getPixel (no 's') then setPixelS

Here is what I am trying to do:
one byteArray (colorsByteArray) holds color values, that I created with the "getPixels" method;
for every pixel on screen, I make calculations and depending on that I get a rank that I use to retrieve the proper color value inside colorsByteArray;
finally, I write inside a second byteArray (pixelsByteArray) the color I just retrieved. Then I 'draw' this byteArray using the "setPixels" method.
Problem is I do not find the same image as if I simply wrote a "setPixel" for every pixel in my loop. The image I get is missing one line out of two, and is kind of repeated three times horizontally. Of course I guess I must be writing (or reading) something wrong from my second byteArray, but can someone explain me what I am doing wrong? Or even if my efforts are worth anything actually :-) cause I didn't find anything quite like this so far...
Thanks!
Here is a bit of my code to make things clearer:
colorsByteArray = bitmDext.getPixels(new Rectangle(0, 0, myShadeBMD.width, 1));
canvas.lock();
for(var i:int = 0; i < STAGE_WIDTH; i++)
{
for(var j:int = 0; j < STAGE_HEIGHT; j++)
{
//make some calculation on each pixel to get the 'colorRank' uint value
colorsByteArray.position = colorRank * 4;//unsigned int is 32 bytes, representing 4 slots of a byteArray
var colorValue:uint = colorsByteArray.readUnsignedInt();
//canvas.setPixel(i, j, colorValue);//works just fine
pixelsByteArray.writeUnsignedInt(colorValue);
}
}
pixelsByteArray.position = 0;
var myRect:Rectangle = new Rectangle(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
canvas.setPixels(myRect, pixelsByteArray);
canvas.unlock();
added a picture that may help:
http://www.oghel.com/pictures/stackOverflow/example3
the expected part is on the right, the wrong one on the left.

How to make smooth moving using as3?

I have loaded some images through XML and attached into dynamically created MovieClips named mc0,mc1,mc2...etc.
_loader.removeEventListener(ProgressEvent.PROGRESS, onLoadingAction);
count++;
var img:Bitmap = Bitmap(e.target.content);
img.cacheAsBitmap = true;
img.smoothing = true;
img.alpha = 0;
TweenLite.to(MovieClip(my_mc.getChildByName("mc"+count)).addChild(img),1, {alpha:1,ease:Quint.easeIn});
and within ENTER_FRAME handler
for (i=0; i < mc.numChildren; i++)
{
my_mc.getChildAt(i).x -= Math.round((mouseX-stage.stageWidth/2)*.006);
}
Everthing works fine. But it is shaking so that it was not looking good.
How do I achieve smooth movement?
One solution I've used is to round the (x,y) position to the closest integer. No matter that you've added smoothing to your bitmap and cached it, rounding could make it feel less choppy and way smoother.
Another thing you need to be careful is the dimensions of the images. Images that have an odd dimension won't be smoothed the same way as images with even dimensions. Check how to workaround this in my blog post Flash Smoothing Issue.
Since Flash has a variable frame rate (in the sense that it will drop frames), one shouldn't depend on the entering of a frame as a unit of action. Rather, it would be wiser to calculate the elapsed time explicitly.
For instance, in the enter frame handler:
var currentTime:Number = (new Date()).time;
for (i=0; i < mc.numChildren; i++)
{
my_mc.getChildAt(i).x -= speed * (currentTime - lastTime); // speed is in px/ms
}
lastTime = currentTime;
where you have the variable lastTime declared somewhere in a persistent scope:
var lastTime:Number = (new Date()).time;
I don't know if this addresses what you are calling "shaking", but it's at least something to consider.