Hi kind sirs. I’m currently working on the Space Shooter tutorial on http://www.raywenderlich.com/11338/cocos2d-x-for-ios-and-android-space-game
It seems that some of the code on the tutorial is not supported in the latest releases. I tried to search for alternatives and new methods to make it work. But I’m currently in a dilema and it keeps my game crashing.
I’m on the part of the tutorial where I have to add in some asteroids into the game. I pasted my HelloWorldScene.h and .cpp code. It seems that the game crashes when I use this line 184:
CCSprite asteroid = );
I’m not sure why. I appreciate any help. Thanks in advance and thank you for the developers working on cocos2d-x. I’m enjoying the learning so far.
HelloWorldScene.h
<pre>
*batchNode;
#ifndef HELLOWORLD_SCENE_H
#define HELLOWORLD_SCENE_H
#include “cocos2d.h”
#include “CCParallaxNodeExtras.h”
USING_NS_CC;
class HelloWorld : public cocos2d::CCLayer
{
private:
CCSpriteBatchNode
CCSprite**ship;
// Parallax
CCParallaxNodeExtras* *backgroundNode;
CCSprite**spacedust1;
CCSprite* *spacedust2;
CCSprite**planetsunrise;
CCSprite* *galaxy;
CCSprite**spacialanomaly;
CCSprite* spacialanomaly2;
// Accelerometer
floatshipPointsPerSecY;
public:
// Asteroids
CCArray* asteroids;
CCSprite* asteroid;
intnextAsteroid;
float *nextAsteroidSpawn;
void update;
// Asteroids
float randomValueBetween;
void setInvisible;
float getTimeTick;
// Accelerometer
virtual void didAccelerate;
// Here’s a difference. Method ‘init’ in cocos2d-x returns bool, instead of returning ‘id’ in cocos2d-iphone
virtual bool init;
// there’s no ‘id’ in cpp, so we recommand to return the exactly class pointer
static cocos2d::CCScene* scene;
// a selector callback
void menuCloseCallback;
// implement the “static node()” method manually
CREATE_FUNC;
};
#endif //*HELLOWORLD_SCENE_H_
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
using namespace cocos2d;
using namespace CocosDenshion;
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
// CLOSE
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback) );
pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition( CCPointZero );
this->addChild(pMenu, 1);
// End Close
// Load the spritesheet pvr.ccz in just 1 batch call
_batchNode = CCSpriteBatchNode::create("Sprites.pvr.ccz");
this->addChild(_batchNode);
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Sprites.plist");
// Ship Sprite
_ship = CCSprite::createWithSpriteFrameName("SpaceFlier_sm_1.png");
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
_ship->setPosition( ccp(winSize.width * 0.1, winSize.height * 0.5) );
_batchNode->addChild(_ship, 1);
// 1. Create the CCParallaxNode
_backgroundNode = CCParallaxNodeExtras::node();
this->addChild(_backgroundNode, -1);
// 2. Create the Sprite we'll add to the CCParallaxNode
_spacedust1 = CCSprite::create("bg_front_spacedust.png");
_spacedust2 = CCSprite::create("bg_front_spacedust.png");
_planetsunrise = CCSprite::create("bg_planetsunrise.png");
_galaxy = CCSprite::create("bg_galaxy.png");
_spacialanomaly = CCSprite::create("bg_spacialanomaly.png");
_spacialanomaly2 = CCSprite::create("bg_spacialanomaly2.png");
// 3. Determine the relative movement speeds for space dust and background
CCPoint dustSpeed = ccp(0.1, 0.1);
CCPoint bgSpeed = ccp(0.05, 0.05);
// 4. Add Children to CCParallaxNode
_backgroundNode->addChild( _spacedust1, 0, dustSpeed, ccp(0, winSize.height / 2) );
_backgroundNode->addChild( _spacedust2, 0, dustSpeed, ccp(_spacedust1->getContentSize().width, winSize.height/2) );
_backgroundNode->addChild(_galaxy, -1, bgSpeed, ccp(0, winSize.height * 0.7));
_backgroundNode->addChild(_planetsunrise, -1, bgSpeed, ccp(600, winSize.height * 0));
_backgroundNode->addChild(_spacialanomaly, -1, bgSpeed, ccp(900, winSize.height * 0.3));
_backgroundNode->addChild(_spacialanomaly2, -1, bgSpeed, ccp(1500, winSize.height * 0.9));
// Star Particles
// Initialize Particles
CCParticleSystemQuad* star1 = CCParticleSystemQuad::create("Stars1.plist");
CCParticleSystemQuad* star2 = CCParticleSystemQuad::create("Stars2.plist");
CCParticleSystemQuad* star3 = CCParticleSystemQuad::create("Stars3.plist");
// Set the position of start particles
star1->setPosition(ccp(winSize.width, winSize.height/2));
star2->setPosition(ccp(winSize.width, winSize.height/2));
star3->setPosition(ccp(winSize.width, winSize.height/2));
// Let there be light!
this->addChild(star1);
this->addChild(star2);
this->addChild(star3);
//HelloWorld::addChild(CCParticleSystemQuad::create("Stars1.plist")) ;
//HelloWorld::addChild(CCParticleSystemQuad::create("Stars2.plist")) ;
//HelloWorld::addChild(CCParticleSystemQuad::create("Stars3.plist")) ;
// Accelerometer
// Asteroids
#define KNUMASTEROIDS 15
CCArray *_asteroids = CCArray::createWithCapacity(15);
for(int i = 0; i < KNUMASTEROIDS; i++)
{
asteroid = CCSprite::createWithSpriteFrameName("asteroid.png");
asteroid->setVisible(false);
_batchNode->addChild(asteroid);
_asteroids->addObject(asteroid);
}
_nextAsteroid = 0;
this->scheduleUpdate();
this->setAccelerometerEnabled(true);
return true;
}
void HelloWorld::update(float dt)
{
CCPoint backgroundScrollVert = ccp(-1000, 0);
_backgroundNode->setPosition(ccpAdd(_backgroundNode->getPosition(),ccpMult(backgroundScrollVert,dt)));
// Space Dust Parallax
CCArray *spaceDusts = CCArray::createWithCapacity(2) ;
spaceDusts->addObject(_spacedust1) ;
spaceDusts->addObject(_spacedust2) ;
for ( int ii = 0 ; ii < spaceDusts->count() ; ii++ ) {
CCSprite * spaceDust = (CCSprite *)(spaceDusts->objectAtIndex(ii)) ;
float xPosition = _backgroundNode->convertToWorldSpace(spaceDust->getPosition()).x ;
float size = spaceDust->getContentSize().width ;
if ( xPosition < -size + 300 ) {
_backgroundNode->incrementOffset(ccp(spaceDust->getContentSize().width*2,0), spaceDust) ;
}
}
// Background Parallax
CCArray *backGrounds = CCArray::createWithCapacity(4) ;
backGrounds->addObject(_galaxy) ;
backGrounds->addObject(_planetsunrise) ;
backGrounds->addObject(_spacialanomaly) ;
backGrounds->addObject(_spacialanomaly2) ;
for ( int jj = 0 ; jj < backGrounds->count() ; jj++ ) {
CCSprite * background = (CCSprite *)(backGrounds->objectAtIndex(jj)) ;
float xPosition = _backgroundNode->convertToWorldSpace(background->getPosition()).x ;
float size = background->getContentSize().width ;
if ( xPosition < -size ) {
_backgroundNode->incrementOffset(ccp(2000,0),background) ;
}
}
// Accelerometer
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
float maxY = winSize.height - _ship->getContentSize().height/2;
float minY = _ship->getContentSize().height/2;
float diff = (_shipPointsPerSecY * dt) ;
float newY = _ship->getPosition().y + diff;
newY = MIN(MAX(newY, minY), maxY);
_ship->setPosition(ccp(_ship->getPosition().x, newY));
// Asteroids
float curTimeMillis = getTimeTick();
if(curTimeMillis > _nextAsteroidSpawn)
{
float randMillisecs = randomValueBetween(0.20,1.0) * 1000;
_nextAsteroidSpawn = randMillisecs + curTimeMillis;
float randY = randomValueBetween(0.0, winSize.height);
float randDuration = randomValueBetween(2.0,10.0);
CCSprite *asteroid = (CCSprite *)(_asteroids->objectAtIndex(_nextAsteroid)); // <--- this makes it crash
_nextAsteroid++;
if(_nextAsteroid >= _asteroids->count())
{
_nextAsteroid = 0;
}
asteroid->stopAllActions();
asteroid->setPosition( ccp(winSize.width+asteroid->getContentSize().width/2, randY));
asteroid->setVisible(true);
asteroid->runAction(CCSequence::create (
CCMoveBy::create(randDuration,ccp(-winSize.width-asteroid->getContentSize().width,0)) ,
CCCallFuncN::create(this,callfuncN_selector(HelloWorld::setInvisible)) ,
NULL // DO NOT FORGET TO TERMINATE WITH NULL (unexpected in C++)
));
}
}
void HelloWorld::didAccelerate(CCAcceleration* pAccelerationValue)
{
#define KFILTERINGFACTOR 0.1
#define KRESTACCELX -0.6
#define KSHIPMAXPOINTSPERSEC (winSize.height * 0.5)
#define KMAXDIFFX 0.2
float rollingX;
// Cocos2DX inverts X and Y accelerometer depending on device orientation
// in landscape mode right x=-y and y=x !!! (Strange and confusing choice)
pAccelerationValue->x = pAccelerationValue->y;
rollingX = (pAccelerationValue->x * KFILTERINGFACTOR) + (rollingX * (1.0 - KFILTERINGFACTOR));
// float accelX = pAccelerationValue->x - rollingX;
float accelX = pAccelerationValue->x;
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
float accelDiff = accelX - KRESTACCELX;
float accelFraction = accelDiff / KMAXDIFFX;
_shipPointsPerSecY = KSHIPMAXPOINTSPERSEC * accelFraction;
}
// Asteroids
float HelloWorld::randomValueBetween(float low, float high)
{
return (((float) arc4random() / 0xFFFFFFFFu) * (high - low)) + low;
}
void HelloWorld::setInvisible(CCNode * node)
{
node->setVisible(false);
}
float HelloWorld::getTimeTick()
{
timeval time;
gettimeofday(&time, NULL);
unsigned long millisecs = (time.tv_sec * 1000) + (time.tv_usec / 1000);
return (float) millisecs;
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}