So my code is counting the collisions but its adding 4 to the score label everytime. Its suppose to only add 1, can anybody see my error? Thank you.
This is the collision detection
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair eggCollision:(CCNode *)egg dinoCollision:(CCNode *)dino
{
[egg removeFromParent];
lifes--;
[lifeslabel setString:[NSString stringWithFormat:#"Lifes: %d", lifes]];
return YES;
}
now this is the code for the egg and its physics body
- (void)addEgg:(CCTime)dt
{
egg = [CCSprite spriteWithImageNamed:#"egg.png"];
int minX = egg.contentSize.height/2 - egg.contentSize.height/2;
int maxX = self.contentSize.height;
int rangeX = maxX - minX;
int randomX = (arc4random() % rangeX) + minX;
egg.position = CGPointMake(randomX, self.contentSize.height + egg.contentSize.height/2);
egg.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero, egg.contentSize} cornerRadius:0];
egg.physicsBody.collisionGroup = #"eggGroup";
egg.physicsBody.collisionType = #"eggCollision";
[_physicsWorld addChild:egg];
}
Breakpoint -
Related
What I'm trying to achieve is a sprite moving to another sprite in a 2D environment. I started with the basic Mx = Ax - Bx deal. But I noticed that the closer to the target the sprite gets, the more it slows down. So I tried to create a percentage/ratio based on the velocity then each x and y gets their percent of a speed allowance, however, it's acting very strangely and only seems to work if Mx and My are positive
Here's the code extract:
ballX = ball->GetX();
ballY = ball->GetY();
targX = target->GetX();
targY = target->GetY();
ballVx = (targX - ballX);
ballVy = (targY - ballY);
percentComp = (100 / (ballVx + ballVy));
ballVx = (ballVx * percentComp)/10000;
ballVy = (ballVy * percentComp)/10000;
The /10000 is to slow the sprites movement
Assuming you want the sprite to move at a constant speed, you can do a linear fade on both the X and Y position, like this:
#include <stdio.h>
int main(int, char **)
{
float startX = 10.0f, startY = 20.0f;
float endX = 35.0f, endY = -2.5f;
int numSteps = 20;
for (int i=0; i<numSteps; i++)
{
float percentDone = ((float)i)/(numSteps-1);
float curX = (startX*(1.0f-percentDone)) + (endX*percentDone);
float curY = (startY*(1.0f-percentDone)) + (endY*percentDone);
printf("Step %i: percentDone=%f curX=%f curY=%f\n", i, percentDone, curX, curY);
}
return 0;
}
Thanks for the responses, I got it working now but normalising the vectors instead of the whole percent thing, here's what I have now:
ballX = ball->GetX();
ballY = ball->GetY();
targX = target->GetX();
targY = target->GetY();
ballVx = (targX - ballX);
ballVy = (targY - ballY);
vectLength = sqrt((ballVx*ballVx) + (ballVy*ballVy));
ballVx = (ballVx / vectLength)/10;
ballVy = (ballVy / vectLength)/10;
I am new on cocos2d-x, i followed Cocos2d-x Game Development Essentials Ebook and trying to make demo app in iOS. with the help of its guidance,but when i trying to Move Astroids in GameScreen.cpp file as written in book, they actually doesn't move and i can't understand what am i missing?
here is code that i used:
bool GameScene::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
//Add EVENT LISTENER TO HANDLE TOUCH EVENT,
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(GameScene::ontouchBegin,this);
listener->onTouchMoved = CC_CALLBACK_2(GameScene::ontouchMoved, this);
listener->onTouchCancelled = CC_CALLBACK_2(GameScene::ontouchCanceled, this);
listener->onTouchEnded = CC_CALLBACK_2(GameScene::ontouchEnded, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
istouching = false;
touchPosition = 0;
visibleSize = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
auto backgroundSprite = Sprite::create("Game_Screen_Background.png");
backgroundSprite->setPosition(Point((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y));
this->addChild(backgroundSprite, -1);
auto pauseItem =
MenuItemImage::create("Pause_Button.png","Pause_Button(Click).png",CC_CALLBACK_1(GameScene::PushToGamePauseScene, this));
pauseItem->setPosition(Point(pauseItem->getContentSize().width-(pauseItem->getContentSize().width/4)+origin.x,visibleSize.height - pauseItem->getContentSize().height +(pauseItem->getContentSize().width / 4) + origin.y));
auto menu = Menu::create(pauseItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu);
for (int i = 0; i < 2; i ++){
backgroundSpriteArray[i] = Sprite::create("Game_Screen_Background.png");
backgroundSpriteArray[i]->setPosition(Point((visibleSize.width/2)+origin.x,(-1*visibleSize.height*i)+(visibleSize.height/2)+origin.y));
this->addChild(backgroundSpriteArray[i],-2);
}
playerSprite = Sprite::create("Space_Pod.png");
playerSprite->setPosition(Point(visibleSize.width/2,pauseItem->getPosition().y-(pauseItem->getContentSize().height/2)-(playerSprite->getContentSize().height/2)));
this->addChild(playerSprite, 1);
this->schedule(schedule_selector(GameScene::spawnAsteroid), 1.0);
this->scheduleUpdate();
return true;
}
Following is update method
void GameScene::update(float dt){
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
for (int i = 0; i < 2; i ++){
if (backgroundSpriteArray[i]->getPosition().y >=visibleSize.height + (visibleSize.height / 2) -1){
backgroundSpriteArray[i]->setPosition(Point((visibleSize.width / 2) + origin.x, (-1 *visibleSize.height) + (visibleSize.height / 2)));
}
}
for (int i = 0; i < 2; i ++){
backgroundSpriteArray[i]->setPosition(Point(backgroundSpriteArray[i]->getPosition().x,backgroundSpriteArray[i]->getPosition().y + (0.75 *visibleSize.height * dt)));
}
for (int i = 0; i < asteroids.size(); i++){
asteroids[i]->setPosition(Point(asteroids[i]->getPosition().x,asteroids[i]->getPosition().y+(0.75 * visibleSize.height * dt)));
if (asteroids[i]->getPosition().y > visibleSize.height * 2){
this->removeChild(asteroids[i]);
asteroids.erase(asteroids.begin() + i);
}
}
//check for Touching
if(istouching == true){
//now check, which side of the screen is being touched
if(touchPosition < visibleSize.width /2){
//now, move the space pod to left
float positionX = playerSprite->getPosition().x;
playerSprite->setPositionX(positionX - (0.50* visibleSize.width * dt));
positionX = playerSprite->getPositionX();
//prevent space pod to getting off the screen (left side)
if(positionX <= 0+(playerSprite->getContentSize().width/2))
{
playerSprite->setPositionX(playerSprite->getContentSize().width / 2);
}
}
else{
//now, move the space pod to right
float positionX = playerSprite->getPositionX();
playerSprite->setPositionX(positionX + (0.50 * visibleSize.width *dt));
positionX = playerSprite->getPositionX();
// check to prevent the space pod from going off the screen (right side)
if(positionX >= visibleSize.width-(playerSprite->getContentSize().width/2))
{
playerSprite->setPositionX(visibleSize.width-(playerSprite->getContentSize().width/2));
}
}
}
}
For move astroid code:
void GameScene::spawnAsteroid(float dt){
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
int asteroidIndex = (arc4random() % 3) + 1;
__String* asteroidString = __String::createWithFormat("Asteroid_%i.png",asteroidIndex);
auto *tempAsteroid = Sprite::create(asteroidString->getCString());
int xRandomPosition = (arc4random() % (int)(visibleSize.width - (tempAsteroid->getContentSize().width / 2))) + (tempAsteroid->getContentSize().width / 2);
tempAsteroid->setPosition(Point(xRandomPosition + origin.x, -tempAsteroid->getContentSize().height +origin.y));
asteroids.push_back(tempAsteroid);
this->update(touchPosition);
this->addChild(asteroids[asteroids.size() - 1], -1);
}
That method has been called at run time but don't know that my astroid object does not moved can anybody please help me for figure it out issue and how to fix it.
Edit
OK,i put this->scheduleUpdate() in init(),and starts moving astroids on the screen but when i move my sprite(not astroids) with touchBegin event the astroid got disappear from screen. please guide me on this.
please put this line in your init method
this->scheduleUpdate();
Hope it helps
Sprite->runAction(Sequence::create(MoveTo::create(1.0f, Vec2(100,200)),NULL));
The sprite should be moving from north to south when the screens orientation is portrait.
Yet the sprite is going from east to west in portrait mode. When the screens orientation is landscape the sprite moves from east to west and i'm very confused about this. I'm trying to make the sprite move from up to down.
Code controlling the sprite
- (void)addMonster:(CCTime)dt
{
monster = [CCSprite spriteWithImageNamed:#"MarioTube_Body_Rev.png"];
int minY = monster.contentSize.height / 2;
int maxY = self.contentSize.height - monster.contentSize.height / 2;
int rangeY = maxY - minY;
int randomY = (arc4random() % rangeY) + minY;
monster.position = CGPointMake(self.contentSize.width + monster.contentSize.width/2, randomY);
[self addChild:monster];
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int randomDuration = (arc4random() % rangeDuration) + minDuration;
CCAction *actionMove = [CCActionMoveTo actionWithDuration:randomDuration position:CGPointMake(-monster.contentSize.width/2, randomY)];
CCAction *actionRemove = [CCActionRemove action];
[monster runAction:[CCActionSequence actionWithArray:#[actionMove,actionRemove]]];
}
So after player around with it i figured out it was simply changing some of the "heights" and widths around
- (void)addMonster:(CCTime)dt
{
monster = [CCSprite spriteWithImageNamed:#"MarioTube_Body_Rev.png"];
int minX = monster.contentSize.height/2 - monster.contentSize.height/2;
int maxX = self.contentSize.height;
int rangeX = maxX - minX;
int randomX = (arc4random() % rangeX) + minX;
monster.position = CGPointMake(randomX, self.contentSize.height + monster.contentSize.height/2);
[self addChild:monster];
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int randomDuration = (arc4random() % rangeDuration) + minDuration;
CCAction *actionMove = [CCActionMoveTo actionWithDuration:randomDuration position:CGPointMake(randomX, -monster.contentSize.height/100)];
CCAction *actionRemove = [CCActionRemove action];
[monster runAction:[CCActionSequence actionWithArray:#[actionMove,actionRemove]]];
}
I'm new to this cocos2d.I'm developing one game in iPhone using cocos2d in that i've to display sprites on left and right side on iPhone (portrait mode). I tried like this.
array_obstacle is a ccarray containing obstacles.
in first part I used array_obstacles as it is.In second part i scaled that sprite using same obstacles.
Here I used two sprites for displaying sprites on left and right side on iphone(portrait mode).
Now,I want to use only one sprite to display sprites on left and right side on iphone(portrait mode).
can any one suggest me regarding this?
int ran = arc4random() % [array_obstacles count];
randomSprite = [CCSprite spriteWithSpriteFrameName:[array_obstacles objectAtIndex:ran]];
int minX = 250;//(winSize.width/2)-120;
int maxX =300; //(winSize.width/2)+120;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
randomSprite.position = ccp( actualX,winSize.height+randomSprite.contentSize.width);
[spriteSheetBatch addChild:randomSprite];
id actionMove2 = [CCMoveTo actionWithDuration:1.5 position:ccp(actualX,-randomSprite.contentSize.width)];
[randomSprite runAction:actionMove2];
int r = arc4random() % [array_obstacles count];
myRandomSprite = [CCSprite spriteWithSpriteFrameName:[array_obstacles objectAtIndex:r]];int min_X = -50;//(winSize.width/2)-120;
int max_X =160; //(winSize.width/2)+120;
int range_X = max_X +min_X;
int actual_X = (arc4random() % range_X) + min_X;
myRandomSprite.position = ccp( actual_X,winSize.height+myRandomSprite.contentSize.width);
id actionMove1 = [CCMoveTo actionWithDuration:1.5 position:ccp(actual_X,-myRandomSprite.contentSize.width)];
myRandomSprite.scaleX = -1.0f;
[myRandomSprite runAction:actionMove1];
I drew a line with -(void)draw method:
-(void)draw // code for line draw
{
glEnable(GL_LINE_SMOOTH);
CGPoint start;
start.x = 50;
start.y = 50;
CGPoint end;
end.x = 50;
end.y = 200;
if (pointOne.x>300){
pointOne.x = 300;
}
if (pointOne.y>200){
pointOne.y = 200;
}
ccDrawLine(start, pointOne);//get a line
[self Bezier:location.x:location.y:pointOne.x:pointOne.y];
}
and now I want to curve this line through Bezier in cocos2d. When I move finger that time line should draw the curve.
Bezier Code is:
- (void) Bezier:(NSInteger) CP_x:(NSInteger) CP_y:(NSInteger) end_x:(NSInteger) end_y
{
CGPoint start;
start.x = 50;
start.y = 50;
ccBezierConfig bezier;
bezier.controlPoint_1 = ccp(CP_x, CP_y);
bezier.controlPoint_2 = ccp(CP_x,CP_y);
bezier.endPosition = ccp(end_x,end_y);
}
How can I implement this line in bezier?
try this.
CCDrawBezier in last of your -(void)Bezier methord
ccDrawCubicBezier(StartPoint, controlPoint_1, controlPoint_2, EndPoint,NSInteger);
This is a method is wrote to my game.
//Bezier calculation on multiple points
//Can be set to any number of points
//The t parameter is the time 0 = start point -> 1 = end point.
//Made by Sebastian Winbladh
-(CGPoint)getBezerAtTime:(float)t array:(NSArray*)a{
int count = [a count];
float xPoints[count],yPoints[count];
int c=0;
//Makeup an array for our points
for(int i=0;i<count;i++){
CGPoint p = CGPointMake([[[a objectAtIndex:i] objectAtIndex:0] floatValue], [[[a objectAtIndex:i] objectAtIndex:1] floatValue]);
xPoints[i] = p.x;
yPoints[i] = p.y;
c++;
}
//Calculate our bezier curve here
while(c != 0){
for(int i=0;i<c-1;i++){
CGPoint p0 = CGPointMake(xPoints[i], yPoints[i]);
CGPoint p1 = CGPointMake(xPoints[i+1], yPoints[i+1]);
float dx = p1.x - p0.x;
float dy = p1.y - p0.y;
dx = p0.x + (dx * t);
dy = p0.y + (dy * t);
xPoints[i] = dx;
yPoints[i] = dy;
}c--;
}
return CGPointMake(xPoints[0], yPoints[0]);
}