Post Path Projection ( trail ) in cocos2d iOS - ios

i want to create path projection like angry birds.
When i throw my ball i want to show projection on ball that on this path my ball has thrown.
I have seen a post on stackoverflow and i have implemented it .
if(trailtimer % 2 == 0 && isFired)
{
CCSprite * dot_Sprite = [[CCSprite alloc] initWithFile:#"whitedot.png"];
dot_Sprite.position = ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y * PTM_RATIO);
dot_Sprite.scale = 0.1;
[self addChild:dot_Sprite z:2 tag:111];
}
}
In this code its working fine . but adding multiple sprites will slow my game.
Is there anyother option/way to implement path projection in my game.

You could try to create the dot like this:
CCSprite * dot_Sprite = [[CCSprite spriteWithFile:#"whitedot.png"];
and see if it helps.
This will add the dot to the auto release pool and make sure memory is free after usage

Related

SUVAT Maths don't add up in SpriteKit's physics engine (iOS - Objective C)

I am using SpriteKit's built in Physics Engine to build a game for iOS. Basically it involves a bouncing ball which moves via me manually setting it's initial velocity and bounces via resetting the velocity within the contact event with the floor.
The issue is, the actual maths for this environment do not add up. Using 'SUVAT' equations it's easy to determine how far the ball's x-displacement should be when it reaches the floor after being thrown with a certain velocity, however (with gravity set to -9.81), it barely moves a couple of pixels.
I simplified the problem to just trying to shoot a ball a certain distance upwards (in the y-direction) and the same thing happened, it moves a couple of points up and then just falls to the floor, at least a 20th of how far it should move.
This is how I have set the physics environment up:
self.physicsWorld.contactDelegate = self;
self.physicsWorld.gravity = CGVectorMake(0.0, -9.81);
And then this is my function for generating this ball (shooting upwards) example. Mathematically it should reach the height of the tower:
-(void)generateTestBall {
self.ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
SKSpriteNode * tower = [SKSpriteNode spriteNodeWithImageNamed:#"player"];
self.ball.position = CGPointMake(self.scene.size.width/2,self.scene.size.height/2);
self.ball.size = CGSizeMake(20,20);
self.ball.color = [SKColor redColor];
self.ball.colorBlendFactor = 1;
tower.position = CGPointMake(self.scene.size.width/2 + 20,self.scene.size.height/2+100);
tower.size = CGSizeMake(20,200);
tower.color = [SKColor blueColor];
tower.colorBlendFactor = 1;
[self addChild:tower];
[self addChild:self.ball];
self.ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
self.ball.physicsBody.affectedByGravity = YES;
self.ball.physicsBody.linearDamping = NO;
self.ball.physicsBody.dynamic = YES;
CGFloat ballVel = sqrt(2*9.81*tower.size.height);
NSLog(#"%f",ballVel);
self.ball.physicsBody.velocity = CGVectorMake(0.0f, ballVel);
}
Please can someone explain what I am doing wrong? I've double checked my maths (I'm a maths student so fingers crossed that's not the issue)!
Thanks!
Steve
So I FINALLY managed to figure it out. Just incase anyone else is experiencing the same issue I'll post the answer here:
The issue was that, although gravity is (apparently) in ms^-2 and velocity m2^-1 (to replicate earth), any distances in Objective C are measured in POINTS rather than the required form of METRES. Therefore any calculation done with x,y position / size values taken from SKSpriteNodes etc will be a certain factor out.
After running a few tests I found the factor to roughly be 157. This means that you must multiply any sizes / distances in POINTS by 157 to get the relative 'METRE' value which will work with SUVAT.
The actual numbers themselves seem a bit ridiculous as they're all very big (velocity, distance etc) but that doesn't actually pose a problem anyway as they all now work relative to each other!
Hope this helps anyone!
Steve

car moving body in box2d with cocos2d-x

i have car body and 2 tiers as seprate images .
how to fix as car body(box2d with cocos2d-x) and moving animation.(i need to rotate tier) and jumping etc.,?
in normal cocos2d-x i can make something like this..
car = CCSprite::spriteWithFile("car.png");
car->setPosition(ccp(car->getContentSize().width/2+30, car->getContentSize().height-19));
this->addChild(car, 10);
tire = CCSprite::spriteWithFile("tire.png");
tire->setPosition(ccp(tire->getContentSize().width/2+43, tire->getContentSize().height+8));
this->addChild(tire, 10);
tire1 = CCSprite::spriteWithFile("tire.png");
tire1->setPosition(ccp(tire->getContentSize().width/2+136, tire->getContentSize().height+8));
this->addChild(tire1, 10);
CCRotateBy *Rot = CCRotateBy::actionWithDuration (1.0f, 360);
CCRepeatForever *rep = CCRepeatForever::actionWithAction(Rot);
CCRotateBy *Rot1 = CCRotateBy::actionWithDuration(1.0f, 360);
CCRepeatForever *rep1 = CCRepeatForever::actionWithAction(Rot1);
tire->runAction(rep);
tire1->runAction(rep1);
but in box2d how to make? any example..
for collison detction for all thing planing to use box2d.
cocos2D-x Doc contains an article about Box2D..
http://www.cocos2d-x.org/docs/manual/framework/native/physics/physics-integration/en
not that detailed, but good enough to start with.
Also cocos2D-x framework test contains example of both Box2D and Chipmumk physics example.
http://www.cocos2d-x.org/docs/manual/framework/native/getting-started/v3.0/how-to-run-cpp-tests-on-win32/en

Moving layer causes physics object to stay in place

I'm fiddling around with cocos2d v3 in combination with sprite builder.
The game is a simple catch and avoid game, objects coming down an the hero is standing in the bottom of the screen and you can move him around with the accelerometer.
I have a level file (cclayer) with some objects (ccnode) in it, the have physics enabled.
In my update function I move the layer slowly down.
If the objects have physics enabled, they just drop down. If I switch it to statics physics, they stay in place.
The only way I can find to move the object along with the layer is to turn off the physics completely. But then the collisions won't work anymore...
This kept me buys for the past 4 hours or so.
What is the best approach for this situation?
Thanks in advance guys!
this is my update function:
- (void)update:(CCTime)delta {
float maxX = winSize.width - _hero.contentSize.width/2;
float minX = _hero.contentSize.width/2;
CMAccelerometerData *accelerometerData = _motionManager.accelerometerData;
CMAcceleration acceleration = accelerometerData.acceleration;
CGFloat newXPosition = _hero.position.x + acceleration.x * 1000 * delta;
newXPosition = clampf(newXPosition, minX, maxX);
_hero.position = CGPointMake(newXPosition, _hero.position.y);
//level position
CGPoint oldLayerPosition = _levelNode.position;
float xNew = oldLayerPosition.x;
float yNew = oldLayerPosition.y -1.4f;
_levelNode.position = ccp(xNew, yNew);
}
This is a design decision made within the physics engine. Physics bodies do not move with their parents. See: https://github.com/cocos2d/cocos2d-iphone/issues/570
You need to change the design of your game so that your hero moves, and the obstacles stay in the same position. Then you implement a camera like mechanism to follow your moving hero.
We have used the same approach in our flappy bird tutorial.

Cannot figure out correct vertexZ in Isometric Tiled maps when creating sprites

I have a 50 X 50 isometric Tiled Map with base tile : 64 X 32.
I am using this function to create a sprite and add to a particular tile dynamically.
-(void)addTile:(NSString *)tileName AtPos:(CGPoint)tilePos onTileMap:(CCTMXTiledMap *)tileMap
{
CCTMXLayer *floorLayer=[tileMap layerNamed:#"FloorLayer"];
NSAssert(floorLayer !=nil, #"Ground layer not found!");
CGPoint tilePositionOnMap = [floorLayer positionAt:tilePos];
CCSprite *addedTile = [[CCSprite alloc] initWithFile:tileName];
addedTile.anchorPoint = CGPointMake(0, 0);
addedTile.position = tilePositionOnMap;
addedTile.vertexZ = [self calculateVertexZ:tilePos tileMap:tileMap];
[tileMap addChild:addedTile];
}
Floor layer is the only layer in my Tiled map and I have added the property cc_vertexz = -1000 to this layer.
I took the calculateVertexZ method from the KnightFight project. Based on the tile coordinates on isometric map it'll calculate the vertexZ and once you see the map it seems to make sense too.
-(float) calculateVertexZ:(CGPoint)tilePos tileMap:(CCTMXTiledMap*)tileMap
{
float lowestZ = -(tileMap.mapSize.width + tileMap.mapSize.height);
float currentZ = tilePos.x + tilePos.y;
return (lowestZ + currentZ + 1);
}
Now this is the code which i'm writing in the -init of my HelloWorldLayer of template cocos2d-2 project. -
self.myTileMap = [CCTMXTiledMap tiledMapWithTMXFile:#"IsometricMap.tmx"];
[self addChild:self.myTileMap z:-100 tag:TileMapNode];
[self addTile:#"walls-02.png" AtPos:CGPointMake(0, 0) onTileMap:self.myTileMap];
[self addTile:#"walls-02.png" AtPos:CGPointMake(0, 1) onTileMap:self.myTileMap];
[self addTile:#"walls-02.png" AtPos:CGPointMake(4, 1) onTileMap:self.myTileMap];
[self addTile:#"walls-02.png" AtPos:CGPointMake(4, 0) onTileMap:self.myTileMap];
Here's the wall image -
And here's the issue -
Case 1
(0,0) should be behind (0,1) according to calculateVertexZ method. And hence the sprite on ( (0,1) is rendered OVER sprite on (0,0).
Case 2
(4,0) should be behind (4,1) according to calculateVertexZ method. But somehow, because I'm adding block on (4,0) AFTER (4,1) its not giving me the desired results.
I had read that when two sprites have same vertexZ ONLY then whichever sprite was added later will be on top. But here the sprites have different vertexZ values, still order of creation is overriding that.
Also, I can't figure out what to do with zorder in this equation. SOMEBODY PLS HELP
I solved this by using the vertexZ property and zOrder property of the base tile.
-(void)addTile:(NSString *)tileName AtPos:(CGPoint)tilePos onTileMap:(CCTMXTiledMap *)tileMap
{
CCTMXLayer *floorLayer=[tileMap layerNamed:#"FloorLayer"];
NSAssert(floorLayer !=nil, #"Ground layer not found!");
CCSprite *baseTile = [floorLayer tileAt:tilePos];
CCSprite *addedTile = [[CCSprite alloc] initWithFile:tileName];
addedTile.anchorPoint = CGPointMake(0, 0);
addedTile.position = baseTile.position;
addedTile.vertexZ = baseTile.vertexZ;
[tileMap addChild:addedTile z:baseTile.zOrder tag:tile.tag];
}

GB2ShapeCache Shape Scale? (Physics Editor) [Box2D]

There is a class associated with the program Physics Editor called GB2ShapeCache that loads shapes that I make in the program. I noticed that it is not currently possible to change the scale of the shapes on the fly so I would like to be able to scale the fixtures for the shapes that I made in Physics Editor. Now the scale of my CCSprite in my app can be random so currently in the addShapesWithFile method, I do this for polygons:
vertices[vindex].x = (offset.x * sprite.scaleX) / ptmRatio_;
vertices[vindex].y = (offset.y * sprite.scaleY) / ptmRatio_;
and this for circles:
circleShape->m_radius = ([[circleData objectForKey:#"radius"] floatValue] / ptmRatio_) *sprite.scale;
I also changed the method so that I can pass in my sprite so I can get the scale to:
-(void) addShapesWithFile:(NSString*)plist forSprite:(CCSprite*)sprite
so that I can pass in my sprite so I can get the scale.
HOWEVER, I find this to be inefficient because I should not have to reload ALL my shapes in my plist since they are already added.
So is there any way to do what I am doing now but in the addFixturesToBody method? This way I do not re-create the already added plist shapes and I only scale the fixtures when it is ready to be added to my body.
If anyone needs to see more code or needs more info, feel free to ask. I know this issue must be simple!!!
Thanks!
I would recommend implementing it in the addFixturesToBody method.
(see https://github.com/AndreasLoew/GBox2D/blob/master/GBox2D/GB2ShapeCache.mm)
Try this method below, this should scale the shapes accordingly to the sprite's they are for. Just pass in your CCSprite and this method will handle the rest.
- (void)addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape forSprite:(CCSprite*)sprite {
BodyDef *so = [shapeObjects_ objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
if ((sprite.scaleX == 1.0f) && (sprite.scaleY == 1.0f)) {
// simple case - so do not waste any energy on this
while(fix) {
body->CreateFixture(&fix->fixture);
fix = fix->next;
}
} else {
b2Vec2 vertices[b2_maxPolygonVertices];
while(fix) {
// make local copy of the fixture def
b2FixtureDef fix2 = fix->fixture;
// get the shape
const b2Shape *s = fix2.shape;
// clone & scale polygon
const b2PolygonShape *p = dynamic_cast<const b2PolygonShape*>(s);
if(p)
{
b2PolygonShape p2;
for(int i=0; i<p->m_vertexCount; i++)
{
vertices[i].x = p->m_vertices[i].x * sprite.scaleX;
vertices[i].y = p->m_vertices[i].y * sprite.scaleY;
}
p2.Set(vertices, p->m_vertexCount);
fix2.shape = &p2;
}
// clone & scale circle
const b2CircleShape *c = dynamic_cast<const b2CircleShape *>(s);
if(c) {
b2CircleShape c2;
c2.m_radius = c->m_radius * sprite.scale;
c2.m_p.x = c->m_p.x * sprite.scaleX;
c2.m_p.y = c->m_p.y * sprite.scaleY;
fix2.shape = &c2;
}
// add to body
body->CreateFixture(&fix2);
fix = fix->next;
}
}
}

Resources