Cocos2d scrolling scale sprite - cocos2d-iphone

I apologize for my English. Sprite size of 1 x 12 px, after I had to scaleX and try to scroll, I have nothing. Any of your ideas. Thank you!
Here's the code:
-(void) proba
{
CGPoint pos = ccp(50,100);
int dlin = 200;
wall = [CCSprite spriteWithFile:#"wall.png"]; //wall.png 1x12px
wall.scaleX = dlin;
wall.anchorPoint = ccp(0, 0.5);
wall.position = pos;
[self addChild:wall];
[self schedule:#selector(wall_scroll)];
}
-(void) wall_scroll
{
static float offset = 0.1f;
wall.textureRect = CGRectMake(wall.textureRect.origin.x - offset ,
wall.textureRect.origin.y ,
wall.scaleX,
wall.textureRect.size.height);
}

Instead of trying to scroll the textureRect, could you scroll the whole wall layer using wall.position?

Related

cocos2d flappy bird demo

I am working with the flappy bird demo trying different things just to get to "know each other".
Going through the demo, I've managed to change the direction of the game to vertical scroll moving upwards.
Having reversed the CGFloat to negative values makes my obstacles move upward but once they are out of bounds they do not re-spawn.
If I change the values for a downward scroll they re-spawn as per the update method.
Can someone explain to me what I'm doing wrong with the x to y conversion? Why is the bottom recognized and the top of my screen not?
Thanks in advance
#import "MainScene.h"
static const CGFloat scrollSpeed = -280.f; //upwards
static const CGFloat firstObstaclePosition = -568.f;
static const CGFloat distanceBetweenObstacles = 80;
#implementation MainScene {
CCSprite *_hero;
CCPhysicsNode *_physicsNode;
NSMutableArray *_obstacles;
}
- (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleYPosition = previousObstacle.position.y;
if (!previousObstacle) {
// this is the first obstacle
previousObstacleYPosition = firstObstaclePosition;
}
CCNode *obstacle = [CCBReader load:#"Obstacle"];
obstacle.position = ccp(0, previousObstacleYPosition + distanceBetweenObstacles);
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
- (void)update:(CCTime)delta {
_hero.position = ccp(_hero.position.x, _hero.position.y + delta * scrollSpeed);//move on Y axis
_physicsNode.position = ccp(_physicsNode.position.x, _physicsNode.position.y - (scrollSpeed *delta));//scroll in Y axis
//spawn more
NSMutableArray *offScreenObstacles = nil;
for (CCNode *obstacle in _obstacles) {
CGPoint obstacleWorldPosition = [_physicsNode convertToWorldSpace:obstacle.position];
CGPoint obstacleScreenPosition = [self convertToNodeSpace:obstacleWorldPosition];
if (obstacleScreenPosition.y < -obstacle.contentSize.height) {
if (!offScreenObstacles) {
offScreenObstacles = [NSMutableArray array];
}
[offScreenObstacles addObject:obstacle];
}
}
for (CCNode *obstacleToRemove in offScreenObstacles) {
[obstacleToRemove removeFromParent];
[_obstacles removeObject:obstacleToRemove];
// for each removed obstacle, add a new one
[self spawnNewObstacle];
}
}
- (void)didLoadFromCCB {
self.userInteractionEnabled = TRUE;
_obstacles = [NSMutableArray array];
[self spawnNewObstacle];
[self spawnNewObstacle];
[self spawnNewObstacle];
}
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
}
#end
I've attached the _physicsNode screenshot from SB.
It looks like your obstacles will be spawning fine if they are a short, constant height, and the distance between them value is large enough. It may be better to incorporate the height of the obstacles to get a more meaningful value of the distance variable. Just a thought.
The line -
obstacle.position = ccp(0, previousObstacleYPosition + distanceBetweenObstacles);
Could be -
obstacle.position = ccp(0, previousObstacleYPosition + distanceBetweenObstacles + previousObstacle.contentSize.height);
As for the problem of the vertical scrolling working downwards and not upwards I believe it is due to this line:
if (obstacleScreenPosition.y < -obstacle.contentSize.height) {
Since this line is responsible for determining when an obstacle is off the screen it has an effect on the spawning of the next obstacle. It makes sense why this line works for downwards scrolling but needs to be changed for upwards scrolling.
Try:
if (obstacleScreenPosition.y > (_physicsNode.contentSize.height + obstacle.contentSize.height)) {
You may or may not need the size of the obstacle depending on where it is anchored.
I hope this works, Good luck.

How to get perfect collision between 2 sprite in cocos 2D

I have 2 sprite. for collide i use bounding box. But its not perfect collision. its collide with transparent image also. i need perfect collision.
Suppose i have :
CCSprite *sprite1 = [CCSprite spriteWithFile:#"image.png"];
CCSprite *sprite2 = [CCSprite spriteWithFile:#"image.png"];
if (CGRectIntersectsRect([sprite1 boundingBox], [sprite2 boundingBox]))
{
// Collision Detected ....
}
But its create a prob . its collide but not perfectly collide.
anybody can help me? Thanks in advance
CCSprite *player = [CCSprite spriteWithFile:#"image.png"];
[self addChild:player];
CCSprite *enemy = [CCSprite spriteWithFile:#"image.png"];
[self addChild:enemy];
float pos_x = player.position.x - enemy.position.x;
float pos_y = player.position.y - enemy.position.y;
float pos_xy = (pos_x * pos_x) + (pos_y * pos_y);
float Collision = (10+5) * (10+5); // Let 10 be the radious of player & 5 be the radious of enemy
if (pos_xy <= Collision)
{
// Collision Detected
}
// But its is only for round shaped image . like: Ball.
And its create perfect collision using pythagorean Theorm

physicsBody applyForce does nothing

I'm doing this video tutorial:
http://www.spritebuilder.com/getting-started/
Everything works fine but the birds im shooting have no speed. They just fall down.
Hope you guys have a solution! Thanks in advance!
Here is my lauchBird function:
-(void)launchBird:(id)sender
{
//calc rotation
float rotationRadians = CC_DEGREES_TO_RADIANS(_launcher.rotation);
//vector for rotation
CGPoint directionVector = ccp(sinf(rotationRadians), cosf(rotationRadians));
CGPoint ballOffset = ccpMult(directionVector, 50);
//ball (bird)
CCNode* ball = [CCBReader load:#"Bird"];
ball.position = ccpAdd(_launcher.position, ballOffset);
//add ball to physicsNode
[_physicsNode addChild:ball];
//make impulse and apply force
CGPoint force = ccpMult(directionVector, 50000);
[ball.physicsBody applyForce:force];
}
As suggested by Allen S, you need to add a physicsBody to the ball. You can do this by
int padding = 5;
CGFloat radius = 0.5*(ball.contentSize.width - padding);
//create a physics body
CCPhysicsBody* body = [CCPhysicsBody bodyWithCircleOfRadius:radius andCenter:ball.anchorPointInPoints];
body.density = 1.0;
body.friction = 0.5f;
ball.physicsBody = body; //assign the created body to the node's physicsBody property.
Play around with the physicsBody's properties(density,friction,mass,elasticity...) to get the desired effect.

Camera following the touched body

I need to have the Cocos2d camera follow a sprite (attached to a Box2D body) that the user is touching on the screen. As the user is dragging the player around, I need it to be able to go to other parts of the world. This has to be through touch, and not automatic scrolling.
I tried several approaches based on tutorials but nothing seem to address this issue. For example the solution offered here Move CCCamera with the ccTouchesMoved method? (cocos2d,iphone) by #Michael Fredrickson has the entire layer move, but when it moves, the sprites / bodies on the screen have unmatched coordinations and when I test to see if they're touched, the if(fixture->TestPoint(locationWorld)) fails.
I also looked at the tutorials here http://www.learn-cocos2d.com/2012/12/ways-scrolling-cocos2d-explained/ but this also isn't what I'm looking for.
Any help would be greatly appreciated.
EDIT:
I'm accepting Liolik's answer below because it put me on the right track. The last piece of the puzzle, though, is to make the value received from the getPoint method an instance variable, and deduce it from locationWorld which I'm doing the TestPoint against. Like this:
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
b2Vec2 diff = b2Vec2(difference.x, difference.y);
for (b2Body* b = _world->GetBodyList(); b; b = b->GetNext()) {
b2Fixture* f = b->GetFixtureList();
while(f != NULL) {
if(f->TestPoint(locationWorld-diff)) {
b2MouseJointDef def;
def.bodyA = _groundBody;
def.bodyB = b;
def.target = locationWorld-diff;
def.maxForce = 9999999.0f * b->GetMass();
_mouseJoint = (b2MouseJoint*)_world->CreateJoint(&def);
b->SetAwake(true);
}
f = f->GetNext();
}
}
in update function :
CGPoint direction = [self getPoint:myBody->GetPosition()];
[self setPosition:direction];
- (CGPoint)getPoint:(b2Vec2)vec
{
CGSize screen = [[CCDirector sharedDirector] winSize];
float x = vec.x * PTM_RATIO;
float y = vec.y * PTM_RATIO;
x = MAX(x, screen.width/2);
y = MAX(y, screen.height/2);
float _x = area.width - (screen.width/2);
float _y = area.height - (screen.height/2);
x = MIN(x, _x);
y = MIN(y, _y);
CGPoint goodPoint = ccp(x,y);
CGPoint centerOfScreen = ccp(screen.width/2, screen.height/2);
CGPoint difference = ccpSub(centerOfScreen, goodPoint);
return difference;
}
So if i understand correctly, when the sprite is inside of the middle of the screen, the background is stationary and the sprite follows your finger, but when you scroll toward the edge, the camera starts to pan?
I had something roughly similar in my game Star Digger where there's a ship in the middle of the screen on its own layer that has to fly around the world, and had the same problem when the ship fired bullets into the main world layer.
heres what I did:
float thresholdMinX = winSize*1/3;
float thresholdMaxX = winSize*2/3;
if(touch.x > thresholdMaxX) //scrolling right
{
self.x += touch.x - thresholdMaxX;
}
else if(touchX < thresholdMinX)
{
self.x += thresholdMinX - touchX;
}
else
{
sprite.position = touch;
}
CGPoint spritePointInWorld = ccp(sprite.x - self.x, sprite.y - self.y);
then every time you calculate collisions, you need to recompute the sprites "actual" position in the world, which is its screen position minus the worlds offset, instead of the sprites screen position.

side scrollling boundaries in cocos2d with levelhelper

I am making a side scrolling game with levelhelper and sneakyinput.
i have couple questions.
i have sneakyinput on a different layer and i am facing a problem on scrolling with the parallax at levelhelper.
i cant manage to apply boundaries and move the layer properly.
how i will fix the scrolling? to be inside the boundaries and the character centered?
i have those 2 methods inside the update method
-(void) update:(ccTime)deltaTime{
[self applyJoystick:_leftJoystick forTimeDelta:deltaTime];
[self setViewpointCenter:hero.position];}
-(void)applyJoystick:(SneakyJoystick *)aJoystick forTimeDelta:(float)delta{
CGRect worldRect = [loader gameWorldSize];
CGPoint scaledVelocity=ccpMult(aJoystick.velocity, 90.0f);
CGPoint newPosition =ccp(hero.position.x+scaledVelocity.x*delta, hero.position.y +scaledVelocity.y *delta);
float posX = MIN(worldRect.origin.x + worldRect.size.width - hero.centerToSides, MAX(hero.centerToSides, newPosition.x));
float posY = MIN(worldRect.origin.y + worldRect.size.height - hero.centerToBottom, MAX(hero.centerToBottom, newPosition.y));
[hero setPosition:cpp(posX,posY)];}
-(void)setViewpointCenter:(CGPoint) position {
CGSize winSize = [[CCDirector sharedDirector] winSize];
CGRect worldRect = [loader gameWorldSize];
CGPoint centerOfView = ccp(winSize.width/2, winSize.height/2);
int x = MAX(position.x, worldRect.origin.x + winSize.width / 2);
int y = MAX(position.y, worldRect.origin.y + winSize.height / 2);
x = MIN(x, (worldRect.origin.x + worldRect.size.width) - winSize.width / 2);
y = MIN(y, (worldRect.origin.y + worldRect.size.height) - winSize.height/2);
CGPoint actualPosition = ccp(x, y);
CGPoint viewPoint = ccpSub(centerOfView, actualPosition);
self.position = viewPoint;}
also i try to flip the character (LHSprite) i use
if (newPosition.x< hero.position.x)
hero.flipX=YES;
else
hero.flipX = YES;
but isnt working but i tried to use also
hero.scaleX=-1
to flip it instead of flipX,flips but goes to the other side of the screen fliped.
solved partially.
it seemed that
myParallax = [loader parallaxNodeWithUniqueName:#"Parallax_1"];
was messing it up so i disable it,
i change the first method to
-(void)applyJoystick:(SneakyJoystick *)aJoystick forTimeDelta:(float)delta{
CGRect worldRect = [loader gameWorldSize];
CGSize winSize = [[CCDirector sharedDirector] winSize];
CGPoint scaledVelocity=ccpMult(aJoystick.velocity, 200.0f);
CGPoint newPosition =ccp(hero.position.x+scaledVelocity.x*delta, hero.position.y +scaledVelocity.y *delta);
float posX = MIN(worldRect.size.width - hero.centerToSides, MAX(hero.centerToSides, newPosition.x));
float posY = MIN(winSize.height -winSize.height/2+ hero.centerToBottom, MAX(hero.centerToBottom, newPosition.y));
if (scaledVelocity.x >= 0)
hero.scaleX = 1.0;
else
hero.scaleX = -1.0;
[hero setPosition:ccp(posX, posY)];
}
it seems when the scrolling isnt correct and goes to white area out of the world and everything is correct you need to find an equation about parallax ratio and levelsize and velocity.