Cocos2D Moving sprite sometimes jerky - cocos2d-iphone

Here I want to move some cocos2D sprite object from top to bottom. Sprites r generated at random position in screen. Some time all sprite's movement s jerky..I can't use CCMove as I want to maintain equal distance between sprite.
[self schedule: #selector(updateObjects:)];
-(void)updateObjects:(ccTime) dt
{
//when I print dt, it gives different value..
//jerk comes when this value s larger than ideal value..
for(Obstacles *Obs in ObsArray)
{
CGPoint pos = Obs.position;
pos.y -= gameSpeed;
Obs.position = pos;
}
}
How can I solve this problem.

Cocos2d uses variable time step: dt is time in seconds since last call of this scheduled selector. If your gameSpeed is distance the object has to move by per second (in points), then you must change your object position by gameSpeed * dt.

Resolved problem by
1. Removed all printf and cocos2D logs
2. Added separate thread for image loading.
3. Used multiple 1024x1024 sprite sheet in place of 2048x2048 in HD mode.

I had the same issue i tried lots of thing, at the end i found that it will jerk more on android devices then ios devices.. the frame-rate they rendered should be updated on constant interval .. if you use update method then set the constant delta time
For example i have used update method
void MyClass::update(float dt) {
int positioniteration=8;
int valocityiteration=8;
world->Step(1/60.0,valocityiteration,positioniteration);//60 FPS }
and also i have added these lines in appdelegate
director->setDepthTest(false);
director->setProjection(Director::Projection::_2D);// MY GAME IS 2D SO USED 2D PROJECTION .. IT HELPED ME
Hope this helps.:)

Related

Rotating image around a point

I'm trying to solve this one for hours and I can't figure out where I am going wrong..
On my page there is an image and a "selection frame". This frame can be moved and resized.
I am trying to make the image turn with the center point of the turn being the center of the frame.
I created a small handle at the top for rotation.
Here's the fiddle: http://jsfiddle.net/8PhqX/7/ (give it a minute to load)
The code in the fiddle is very long because I couldn't isolate the specific area relevant to my question. As you play around with it you'll see that the first rotation usually works fine, but then, things go crazy.
Here's the codeline for the rotation:
//selfRotator.handle.angle is the angle(clockwise) at which the rotation handle was rotated
//selfSelector.rotator.ox/oy is the position of the middle of the selection frame
//selfDefaults.imageArea.y is the y position of the section with the image (because of the red stripe in the top)
//selfImageArea.page.startX/Y is starting position of the image storing its position when the drag begins
//rotating by angle, at center point of selection
selfImageArea.page.transform(
['r', -selfRotator.handle.angle, selfSelector.rotator.ox - selfImageArea.page.startX, selfSelector.rotator.oy - (selfImageArea.page.startY - selfDefaults.imageArea.y)]
)
//tracking the image's start position and compensating
selfImageArea.page.attr({
transform: "...T" + (selfImageArea.page.startX) + "," + (selfImageArea.page.startY - selfDefaults.imageArea.y)
});
It looks like it gets messed up because of the getBBox values that don't follow the picture outlines.
I've added gridlines to illustrate the problem
also, iv'e came across this code(https://groups.google.com/forum/#!topic/raphaeljs/b8YG8DfI__g) for "getBBoxRotated()" function that should solve my issue but I can't seem to implement it.

Lerping issue with timers

I have been having an issue related to timers when I am lerping objects in my game engine. The lerping is almost correct and when I am applying the lerping to an object moving or rotating it is fine except every few seconds it appears as if the object quickly flashes to it's previous position before continuing to move smoothly.
Running the engine in windowed mode gives me 1500~fps but if I run in full screen with vsync clamping to 60fps the glitch happens a lot more often.
I have been trying to find either a good resource or explanation on lerping and how I can improve what I have.
For working out the tick gap I use:
float World::GetTickGap()
{
float gap = (float) (TimeMs() - m_lastTick) / m_tickDelay;
return gap > 1.f ? 1.f : gap;
}
My update function:
m_currentTick = TimeMs();
if(m_currentTick > m_lastTick+m_tickDelay)
{
m_lastTick = m_currentTick;
//Update actors
}
Then when rendering each actor I am giving the tick gap for them to lerp between their positions.
My lerping function:
float math::Lerp(float a, float b, float t)
{
return a + t*(b-a);
}
And an example of the lerping function being called:
renderPosition.x = (math::Lerp(m_LastPosition.x, m_Position.x, tickDelay));
I'm unsure where to start on trying to fix this problem. As far as I'm aware it is the timing issues with the functions. Though could anything else cause a small dip in performance at a constant rate?
Any help with this problem would be greatly appreciated. :)
I'm not really able to reconstruct your code from what you posted
But I remember that calling your time function more than once per frame is bad idea generally.
You seem to do that. Try thinking about what effect that has.
E.g. It might mean that the "update Actors" loops are out of sync with the "tickGap" intervals and actors are updated a second time with 0 gap.

Chipmunk Physics Positioning

I've looked around quite a bit and haven't been able to find a concise answer to this question. For my Cocos2D game I have integrated the Chipmunk physics engine. On initialization, I setup the boundaries of the 'playing field' by establishing a series of bodies and static shapes as follows:
- (void)initPlayingField {
// Physics parameters
CGSize fieldSize = _model.fieldSize;
CGFloat radius = 2.0;
CGFloat elasticity = 0.3;
CGFloat friction = 1.0;
// Bottom
CGPoint lowerLeft = ccp(0, 0);
CGPoint lowerRight = ccp(fieldSize.width, 0);
[self addStaticBodyToSpace:lowerLeft finish:lowerRight radius:radius elasticity:elasticity friction:friction];
// Left
CGPoint topLeft = ccp(0, fieldSize.height);
[self addStaticBodyToSpace:lowerLeft finish:topLeft radius:radius elasticity:elasticity friction:friction];
// Right
CGPoint topRight = ccp(fieldSize.width, fieldSize.height);
[self addStaticBodyToSpace:lowerRight finish:topRight radius:radius elasticity:elasticity friction:friction];
// Top
[self addStaticBodyToSpace:topLeft finish:topRight radius:radius elasticity:elasticity friction:friction];
}
This setup works, except for one thing-- the positions of the boundaries appear to be off by a significant amount of pixels to the right. After initializing a player, and sending him towards the boundary walls, it does not bounce off the edges of the screen (as I would expect by setting up the bounding box at 0,0), but rather some number of pixels (maybe 30-50) inwards from the edges of the screen. What gives?
I initially thought the issue came from where I was rendering the player sprite, but after running it through the debugger, everything looks good. Are there special protocols to follow when using chipmunk's positions to render sprites? Do I need to multiply everything by some sort of PIXELS_PER_METER? Would it matter if they are in a sprite sheet? A sprite batch node? Here is how I set the sprite position in my view:
Player *player = [[RootModel sharedModel] player];
self.playerSprite.position = player.position;
self.playerSprite.rotation = player.rotation;
And here is how I set the position in my Model:
- (void)update:(CGFloat)dt {
self.position = self.body->p;
self.rotation = self.body->a;
}
(Yes, I know it's redundant to store the position because chipmunk does that inherently.)
Also, bonus question for for those who finished reading the post. How might you move a body at a constant velocity in whatever direction it is facing, only allowing it to turn left or right at any given time, but never slow down?
What's the shape of the physics body? Perhaps you simply forgot to consider making the shape the same size of the sprite. If you only consider the position, then the sprite will be able to move halfway outside the screen at any border because its position is at the center of the sprite.
To move a body at constant velocity, set its velocity while disabling friction (set to 0?) and allowing it to rebound off of collisions with its impact speed (in Box2D that would be restitution = 1, don't know about Chipmunk).
Have you tried debug drawing the collision shapes? Cocos2D 2.1 has my CCPhysicsDebugNode class in it that makes it pretty easy to add. That will let you know if your geometry is lined up with your graphics. How thick are your boundary shapes? Are you possibly adding the sprites to a parent node that might be offsetting them?
Chipmunk doesn't require you to tune it for any real units. You can just use pixels or whatever.
Lastly, #LearnCocos2D has the right idea about the constant velocity. Set friction to 0 and elasticity to 1.0. You will also probably want to check it's velocity every frame and accelerate it back towards it's normal velocity each frame. Colliding with non-static geometry will cause it to lose speed.

Animate CCSprite on Each Update

I have a CCSprite object of which I need to update the on screen (x,y) position as quickly as possible. It is an augmented reality app so the on screen position needs to appear fixed to a real world location.
Currently, during each update I check the heading and attitude of the device then move the sprite accordingly by determining the new x and y positions
[spriteObject setPosition:ccp(newX, newY)];
Each degree change in heading corresponds to 10 pixels in on screen position, so by setting the position this way the sprite jumps around in intervals of 10 pixels which looks stupid. I'd like to animate it smoothly, maybe by using
[spriteObject runAction:[CCMoveTo actionWithDuration:0.2f position:ccp(newX, newY)]];
but the problem here is that a new position update comes in while the sprite is animating and it sort of screws the whole thing up. Anyone know of a nice solution to this problem? Any help is much appreciated as I've tried numerous failed solutions to this point.
You can try to just animate your sprite movement to the point. I mean, you can several times during one second run animated position correction with duration of 1/numberOfUpdates in one second. Something like
- (void) onEnter
{
[super onEnter];
[self schedule:#selector(updatePositionAnimated) interval:0.2f];
}
- (void) updatePositionAnimated
{
[spriteObject runAction:[CCMoveTo actionWithDuration:0.2f position:ccp(newX, newY)]];
}
I suppose, you will have smooth enough animation in this case

CCSprite children coordinates transform fails when using CCLayerPanZoom and CCRenderTexture?

Thanks for reading.
I'm working on a setup in Cocos2D 1.x where I have a huge CCLayerPanZoom in a scene with free panning and zooming.
Every frame, I have to additionally draw a CCRenderTexture on top to create "darkness" (I'm cutting out the light). That works well.
Now I've added single sprites to the surface, and they are managed by Box2D. That works as well. I can translate to the RenderTexture where the light sources ought to be, and they render fine.
And then I wanted to add a HUD layer on top, by adding a CCLayer to the scene. That layer needs to contain several sprites stacked on top of each other, as user interface elements.
Only, all of these elements fail to draw where I need them to be: Exactly in the center of screen. The Sprites added onto the HUD layer are all off, and I have iterated through pretty much every variation "convertToWorldSpace", "convertToNodeSpace", etc.
It is as if the constant scaling by the CCPanZoomLayer in the background throws off anchor points in the layer above each frame, and resetting them doesn't help. They all seem to default into one of the corners of the node bounding box they are attached to, as if their transform is blocked or set to zero when it comes to the drawing.
Has anyone run into this problem? Is this a known issue when using CCLayerPanZoom and drawing a custom CCRenderTexture on top each frame?
Ha! I found the culprit! There's a bug in Cocos2D' way of using Zwoptex data. (I'm using Cocos2D v 1.0.1).
It seems that when loading in Zwoptex v3 data, sprite frames' trim offset data is ignored when the actual sprite frame anchor point is computed. The effect is that no anchor point on a sprite with trim offset in its definition (eg in the plist) has its anchor point correctly set. Really strange... I wonder whether this has occurred to anybody else? It's a glaring issue.
Here's how to reproduce:
Create any data for a sprite frame in zwoptex v3 format (the one that uses the trim data). Make sure you actually have a trimmed sprite, i.e. offset must be larger than zero, and image size must be larger than source.
Load in sprite, and try to position it at center of screen. You'll see it's off. Here's how to compute your anchor point correctly:
CCSprite *floor = [CCSprite spriteWithSpriteFrameName:#"Menu_OmeFloor.png"]; //create a sprite
CCSpriteFrame *frame=[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"Menu_OmeFloor.png"]; //get its frame to access frame data
[floor setTextureRectInPixels:frame.rect rotated:frame.rotated untrimmedSize:frame.originalSizeInPixels]; //re-set its texture rect
//Ensure that the coordinates are right: Texture frame offset is not counted in when determining normal anchor point:
xa = 0.5 + (frame.offsetInPixels.x / frame.originalSizeInPixels.width);
ya = 0.5 + (frame.offsetInPixels.y / frame.originalSizeInPixels.height);
[floor setAnchorPoint:ccp(xa,ya)];
floor.position=(where you need it);
Replace the 0.5 in the xa/ya formula with your required anchor point values.