This article practice from Ray Wenderlich article "How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial", the use of Cocos2D, I here To use Cocos2D-x3.0alpha0 for learning and porting, the former is written in Object-C, so porting to the Cocos2D-x will be somewhat different, such as some functions, some functions can not be directly implemented as the original, you need to implement another conversion method. The installation and simple use of Cocos2D-x has been introduced before, here is not introduced, directly enter the topic.
The procedure is as follows: Use a script to create a project
/Create-multi-platform-projects.py-p Ninja-k com. HuLuo. Ninja-l cpp
2. Compile and run, as shown in:
3. Download the resources required for this game and place the resources"Resources"Directory;
4. The game needs a white background. The simplest way is to use CCLayerColor and change the HelloWorldScene. h file "HelloWorld" class to the following:
class HelloWorld : public cocos2d::LayerColor
Then add the following code:
Sprite* _player; Sprite* _monster; void addMonster(); void spriteMoveFinished(Node* sender); void gameLogic(float dt);
First, add a player to the left center of the screen.
HelloWorldScene. cppFile
InitFunction, as follows:
bool HelloWorld::init(){ bool bRet = false; do { CC_BREAK_IF(!LayerColor::initWithColor(Color4B(255, 255, 255, 255))); Size winSize = Director::getInstance()->getWinSize(); _player = Sprite::create("Player.png"); _player->setPosition(Point(_player->getContentSize().width / 2, winSize.height / 2)); _player->setScale(2); this->addChild(_player); this->schedule(schedule_selector(HelloWorld::gameLogic), 1.0); bRet = true; } while (0); return bRet; }void HelloWorld::gameLogic(float dt){ }
5. Compile and run the game. You can see that the player genie is on a white background, as shown in:
6. Add monsters and let them move. create monsters on the right side of the screen, create actions to move them to the left, and addAddMonsterThe Code is as follows:
void HelloWorld::addMonster(){ _monster = Sprite::create("monster.png"); _monster->setScale(2); Size winSize = Director::getInstance()->getWinSize(); int minY = _monster->getContentSize().height / 2; int maxY = winSize.height - _monster->getContentSize().height / 2; int rangeY = maxY - minY; int actualY = (rand() % rangeY) + minY; _monster->setPosition(Point(winSize.width + _monster->getContentSize().width / 2, actualY)); this->addChild(_monster); int minDuration = 2; int maxDuration = 4; int rangeDuration = maxDuration - minDuration; int actualDuration = (rand() % rangeDuration) + minDuration; MoveTo* actionMove = MoveTo::create(actualDuration, Point(-_monster->getContentSize().width / 2, actualY)); CallFuncN* actionMoveDone = CallFuncN::create(std::bind(&HelloWorld::spriteMoveFinished, this,_monster)); _monster->runAction(Sequence::create(actionMove,actionMoveDone, NULL)); }
On the right side of the screen, add the monster genie at random positions. Note that the coordinates of the genie are calculated. The default point is in the center. Do not cut off the monsters. Then 2 ~ The four-second random total time allows the monster to move from the right to the left. After the boundary is moved out, the callback function spriteMoveFinished is used to delete the spriteMoveFinished object. The added spriteMoveFinished method is as follows:
void HelloWorld::spriteMoveFinished(cocos2d::Node *sender){ Sprite* sprite = (Sprite*)sender; this->removeChild(sprite);}
The next step is to create monsters on a regular basis. Install the timer and execute the timer every second before the init function returns. The Code is as follows:
this->schedule(schedule_selector(HelloWorld::gameLogic), 1.0);
Add the gameLogic method. The Code is as follows:
void HelloWorld::gameLogic(float dt){ this->addMonster();}
7. Compile and run the program. You can see that the monster on the right regularly increases and moves to the left at different speeds, as shown in:
8. then, the player can take a shot. When the user clicks on the screen, the player is asked to send a bullet in the direction of the click. the user's screen click point is not the final place where the bullet moves, use an image of the original text to describe:
To make the Layer Support touch, add the following code in the init method:
this->setTouchEnabled(true);
Reload the onTouchesEnded method. The Code is as follows:
void HelloWorld::onTouchesEnded(const std::vector
&touches, cocos2d::Event *event){ Touch* touch = touches.front(); Point location = this->convertTouchToNodeSpace(touch); Size winSize = Director::getInstance()->getWinSize(); Sprite* projectile = Sprite::create("Projectile.png"); projectile->setScale(2); projectile->setPosition(Point(20, winSize.height / 2)); Point offset = ccpSub(location, projectile->getPosition()); if (offset.x <= 0) { return; } this->addChild(projectile); int realX = winSize.width + projectile->getContentSize().width / 2; float ratio = (float)offset.y / (float)offset.x; int realY = realX * ratio + projectile->getPosition().y; Point realDest = Point(realX, realY); int offRealX = realX - projectile->getPosition().x; int offRealY = realY - projectile->getPosition().y; float length = sqrtf(offRealX * offRealX + offRealY * offRealY); float velocity = 480 / 1; float realMoveDuration = length / velocity; projectile->runAction(Sequence::create(MoveTo::create(realMoveDuration, realDest),CallFuncN::create(std::bind(&HelloWorld::spriteMoveFinished, this,projectile)), NULL));}
First, get the touch point, then create the bullet genie, and calculate the difference between the touch point and the initial position of the bullet. If the touch point is in front of the initial position (that is, the player in front ), add a bullet to the layer. The final coordinates of the bullet flying to the right of the screen are calculated using the same proportion method. Then, the length of the flight is calculated using the hook theorem. Assuming that the speed is 480 pixels per second, the total flight time is calculated. The next step is to let the bullet execute the given flight action and then delete its own call.
9. Compile and run the program. Click on the screen to view the bullet, as shown in:
10. When a bullet hits a monster, the monster is eliminated, and the bullet disappears, that is, collision detection. Target and bullet need to be tracked in the sceneHelloWorldScene. hThe statement is as follows:
Array* _monsters; Array* _projectiles;
In the constructor and destructor, add the following:
HelloWorld::HelloWorld(){ _monsters = NULL; _projectiles = NULL;}HelloWorld::~HelloWorld(){ if (_monsters) { CC_SAFE_RELEASE_NULL(_monsters); } if (_projectiles) { CC_SAFE_RELEASE_NULL(_projectiles); }}
Then initialize the two arrays in the init function:
this->_monsters = Array::create(); this->_monsters->retain(); this->_projectiles = Array::create(); this->_projectiles->retain();
Modify the addMonster function, add tags to the monster genie, and add the tags to the array. The Code is as follows:
_monster->setTag(1); _monsters->addObject(_monster);
Modify the onTouchesEnded function, add tags to the bullet genie, and add them to the array. The Code is as follows:
projectile->setTag(2); _projectiles->addObject(projectile);
Then modify the spriteMoveFinished function and add the following code:
if (sprite->getTag() == 1) { _monsters->removeObject(sprite); } else if (sprite->getTag() == 2) { _projectiles->removeObject(sprite); }
Add the following method:
void HelloWorld::update(float delta){ Array* projectilesToDelete = Array::create(); Object* pObject = NULL; Object* pObject2 = NULL; CCARRAY_FOREACH(_projectiles, pObject) { Sprite* projectile = (Sprite*)pObject; Array* monstersToDelete = Array::create(); CCARRAY_FOREACH(_monsters, pObject2) { Sprite* monster = (Sprite*)pObject2; if (projectile->getBoundingBox().intersectsRect(monster->getBoundingBox())) { monstersToDelete->addObject(monster); } } CCARRAY_FOREACH(monstersToDelete, pObject2) { Sprite* monster = (Sprite*)pObject2; _monsters->removeObject(monster); this->removeChild(monster); } if (monstersToDelete->count() > 0) { projectilesToDelete->addObject(projectile); } monstersToDelete->release(); } CCARRAY_FOREACH(projectilesToDelete, pObject) { Sprite* projectile = (Sprite*)pObject; _projectiles->removeObject(projectile); this->removeChild(projectile); } projectilesToDelete->release();}
Traverse the bullet array, calculate the monsters that each bullet may encounter, and use their respective boundary boxes for cross detection. If a cross is detected, the monster object is placed in the ToDelete array, you cannot delete an object during traversal. If a bullet encounters a monster, you also need to put the ToDelete (to be deleted) array. Then move it from the scenario and array. Similarly, install the timer in the init function. The Code is as follows:
this->scheduleUpdate();
11. Compile and run. When the bullets and monsters collide, they will disappear;
12. Next, create a new scenario to indicate "You Win" or "You Lose ". Create a new class
The GameOverLayer. h file code is:
#include "cocos2d.h"USING_NS_CC;class GameOverLayer:public LayerColor{ public: GameOverLayer(); ~GameOverLayer(); bool initWithWon(bool won); static Scene* sceneWithWon(bool won); void gameOverDone();};
The code of the GameOverLayer. cpp file is:
//// GameOverLayer. cpp // HelloCpp // Created by du jia on 13-12-1. //// # include "GameOverLayer. h "# include" HelloWorldScene. h "GameOverLayer: GameOverLayer () {} GameOverLayer ::~ GameOverLayer () {} GameOverLayer * GameOverLayer: createWithWon (bool won) {GameOverLayer * pRet = new GameOverLayer (); if (pRet & pRet-> initWithWon (won )) {} else {CC_SAFE_RELEASE_NULL (pRet);} return pRet;} bool GameOverLayer: initWithWon (bool won) {bool bRet = false; do {CC_BREAK_IF (! LayerColor: initWithColor (Color4B (255,255,255,255); char * message; if (won) {message = "You Won" ;}else {message = "You Lose ";} size winSize = Director: getInstance ()-> getWinSize (); LabelTTF * label = LabelTTF: create (message, "Arial", 32 ); label-> setColor (Color3B (0, 0, 0); label-> setPosition (Point (winSize. width/2, winSize. height/2); this-> addChild (label); this-> runAction (Sequence: cr Eate (DelayTime: create (3), CallFunc: create (std: bind (& GameOverLayer: gameOverDone, this); bRet = true ;} while (0); return bRet;} Scene * GameOverLayer: sceneWithWon (bool won) {Scene * scene = NULL; do {scene = Scene: create (); CC_BREAK_IF (! Scene); GameOverLayer * layer = GameOverLayer: createWithWon (won); CC_BREAK_IF (! Layer); scene-> addChild (layer);} while (0); return scene;} void GameOverLayer: gameOverDone () {Director: getInstance () -> replaceScene (HelloWorld: createScene ());}
When the game ends, it switches to the scenario created above. The scene layer displays a text and returns it to the HelloWorld scenario three seconds later.
13. Finally, add some game logic to the game. Records the number of monsters eliminated by the player, and determines whether the player wins or loses. In the HelloWorldScene. h file, add the following:
int _monstersDestroyed;
Add header file reference:
#include "GameOverLayer.h"
In the update timing function, the monstersToDelete loop removeChild (monster, true) is followed by the count of the destroyed monster, and the victory condition is judged. The Code is as follows:
_monstersDestroyed++; if (_monstersDestroyed > 2) { Scene* gameOverScene = GameOverLayer::sceneWithWon(true); Director::getInstance()->replaceScene(gameOverScene); }
Finally, add a failure condition for the player. It indicates that the player fails as long as a Monster runs to the screen on the left. In the spriteMoveFinished function, sprite-> getTag () = 1, add as follows:
Scene* gameOverScene = GameOverLayer::sceneWithWon(false); Director::getInstance()->replaceScene(gameOverScene);
14. Compile and run. Now a simple game has been completed, including sound effects, with the end of victory and failure. The game effect is as follows:
: Http://pan.baidu.com/s/17rpC3
If there is an error in the article, please point it out for correction.