Unlike in the previous backgrounds, the Game scene's background will be moving, providing a scrolling effect. Before you dive into the background code, an update
function needs to be scheduled to be called in every frame using the following steps:
update
function in the init()
method using the following code:this->scheduleUpdate();
update
function in the GameScene.h
file using the following code:void update(float dt);
update
function in the GameScene.cpp
file using the following code:void GameScreen::update(float dt) { }
The update
function is used to handle the game's logic and takes a float
parameter called delta time, which is the time between frames. As all devices are not capable of running at 60 fps, this is factored in during gameplay to provide a smooth experience across a wide variety of devices.
The following are the steps to implement a scrolling background:
cocos2d::Sprite *backgroundSpriteArray[2];
init()
method:for (int i = 0; i < 2; i ++) { backgroundSpriteArray[i] = Sprite::create("GameScreen/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); }
update()
method by factoring in the delta time (0.75 is just the speed that can be changed, possibly by the user in a settings scene, which could be implemented as a side task, and it is multiplied by the screen height to keep a constant speed on different devices). You will also need to add a visibleSize
variable, similar to what we did in the constructor:for (int i = 0; i < 2; i ++) { backgroundSpriteArray[i]->setPosition(Point(backgroundSpriteArray[i]->getPosition().x, backgroundSpriteArray[i]->getPosition().y + (0.75 * visibleSize.height * 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))); } }
The background is now scrolling and resets once it has gone off the screen.
Now, the scrolling asteroids will be implemented. The asteroids will spawn every 2.5 seconds randomly in the x axis just below the screen. Once an asteroid goes off the screen, it will be destroyed. Add the following code to implement scrolling asteroids:
GameScene.h
(the scheduler requires a float
parameter for delta time, but doesn't need it to be used):void spawnAsteroid(float dt);
std::vector<cocos2d::Sprite *> asteroids;
init()
method inside the GameScene.cpp
file (as the game will spawn asteroids every 1.0 second. 1.0 is specified as the interval time, but if it isn't specified, the method will be run for every frame):this->schedule(schedule_selector(GameScreen::spawnAsteroid), 1.0);
spawnAsteroid(float dt)
method:void GameScreen::spawnAsteroid(float dt) { Size visibleSize = Director::getInstance()->getVisibleSize(); Point origin = Director::getInstance()->getVisibleOrigin(); int asteroidIndex = (arc4random() % 3) + 1; __String* asteroidString = __String::createWithFormat("GameScreen/Asteroid_%i.png", asteroidIndex); Sprite *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->addChild(asteroids[asteroids.size() - 1], -1); }
spawnAsteroid(float dt)
method does:asteroidIndex
stores a random number that determines which asteroid will be spawned (as there are three different asteroids)__String
object, and using this
, a temporary asteroid sprite is declared and initializedupdate(float dt)
method, which will move the asteroids at the same speed as the speed at which the background is moving. Then, it will check whether the asteroid has moved off the screen; if so, it will remove the asteroid from the scene and from the asteroid's vector: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); } }
The final sprite to be added is the player's spaceship; use the following steps:
GameScene.h
file:cocos2d::Sprite *playerSprite;
init()
method in the GameScene.cpp
file:playerSprite = Sprite::create("GameScreen/Space_Pod.png");
playerSprite->setPosition(Point(visibleSize.width / 2, pauseItem->getPosition().y - (pauseItem->getContentSize().height / 2) - (playerSprite->getContentSize().height / 2)));
this->addChild(playerSprite, -1);
Now that the sprites have been implemented, here are the images of how the GameScene.h
and GameScene.cpp
files should look.
The following screenshot shows how the GameScene.h
file should look after all the code has been added by following the previous steps:
The following screenshot shows how the init()
method inside GameScene.cpp
should look after all the code has been added by following the previous steps to initialize the game's sprites:
The following screenshot shows how the update()
and spawnAsteroid()
methods inside GameScene.cpp
should look after all the code has been added by following the previous steps in order to add the asteroids randomly to provide a gameplay element to the game:
Finally, this is how our GUI will look: