Preface
In retrospect, last year, I also developed my first game in March 3 and April. It was this game that made me decide to embark on the path of independent developers. One year later, the first game reached its expected profitability. However, this game did not get another satisfactory work in the time it was developed. Until March April of this year, I used cocos2d-x to develop my first word game.
The portal of the first game
Portal for the first text game
Since using cocos2d-x, I found myself in love with this engine. It may not be powerful enough and perfect, but you can use it to experience the fun of coding, I can also regain the C ++ Technology (how persistent I am with C ++ in the end) for me, and improve NDK and JNI learning. It just satisfies my various pursuits.
This is the first text game named anw.puzzle. In fact, this game was rewritten by referring to this tutorial on RayWenderlich. This tutorial is written using iOS's UIKit, although the principles are the same, there are still a lot of difficulties in the rewrite process. Due to the First Preparation of cocos2d-x game, so the error is inevitable, hope readers are high up your hand, point to end ...... Don't talk nonsense, start coco2d-x now ~ How to create the first text game!
Ansible Introduction
Ansible is a game that breaks down the alphabetic order of words or phrases and is rearranged into a new word or phrase. For example, cinema can be rearranged into iceman. In the game, players are required to rearrange the words or phrases you provide. After the game is completed, the screen will be:
During the development of this game, you will be exposed to the following knowledge:
- MVC game Structure
- How to load levels from file configuration
- Load third-party Fonts
- Simple use of music Sound Effects
- Separating the HUD layer from the game layer
- Drag and animation with gestures
- Particle effect
There are some other basic knowledge of cocos2d-x, will be exposed in the development process.
Initialize the project
First of all, the most important of course is to use the command line to create a cocos2d-x project, of course there are other ways to create a project, but I think it is necessary to master the command line to create a basic skill. The creation method can be found here. After creation, the project folders of each platform are available. Our main project folders are proj. android and proj. ios. During the entire development process, I used Mac OS for development, so the code is carried out on XCode, while the Android project compilation uses the command line. For more information, see here.
After the project is created, copy the required Resource files to the Resource folder. Open the Xcode project. The current Resource folder is still the original Resource file. Right-click the Resource folder and choose Add Files to... to Add all the Resource Files to the project. After editing, the project will
1) load the configuration file
Open level1.plist and you can see the content in it.
There are three top keys:
PointsPerTile: The score obtained after each word is correct.
TimeToSolve: the time (in seconds) for solving this problem ).
Anagrams: a list of questions, including two items: the original phrase and the phrase to be spelled out.
This is the end of the level file. Next, write the Level class, and add the following content to Level. h:
class Level:public CCObject{public:static Level * levelWithNum(int levelNum);public:int mPointPerTile;int mTimeToSovle;CCArray * pAnagrams;};
The three variables correspond to the top three items in the level file. Another initialization function is to initialize the level file for external calls.
Now, enable Level. cpp to implement the levelWithNum function.
Level * Level::levelWithNum(int levelNum){char fileName[50];char fullPath[150];sprintf(fileName,"level%d.plist",levelNum);CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile(fileName,fullPath);CCDictionary * pListDict = CCDictionary::createWithContentsOfFile(fileName);if(pListDict == NULL){CCLog("level config not found");}Level * l = new Level();CCString * tempStr;tempStr = dynamic_cast<CCString*>(pListDict->objectForKey("pointsPerTile"));l->mPointPerTile = tempStr->intValue();tempStr = dynamic_cast<CCString*>(pListDict->objectForKey("timeToSolve"));l->mTimeToSovle = tempStr->intValue();l->pAnagrams = dynamic_cast<CCArray*>(pListDict->objectForKey("anagrams"));l->pAnagrams->retain();return l;}
Here, we first use CCDictionary to read the values in the level file, and then read and store the values in the corresponding key.
Now, open the main interface file. The default is the HelloWorldScene class, but I changed it to MainScene, where MainScene. h is like this.
class MainScene : public cocos2d::CCLayer{public: ~MainScene(); // 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 recommend returning the class instance pointer static cocos2d::CCScene* scene(); // implement the "static node()" method manually CREATE_FUNC(MainScene);private:Level * pLevel;};
It can be seen that the Level variable is added. Compile the init function in MainScene. cpp.
pLevel = Level::levelWithNum(1);
Of course, here we can print the content in pLevel through CCLog.
Add a new function in MainScene.
void dealRandomAnagram();
The specific implementation should be like this
void MainScene::dealRandomAnagram(){Common::random(0, pLevel->pAnagrams->count() - 1);int randomIndex = Common::random(0, pLevel->pAnagrams->count() - 1);CCAssert((randomIndex >= 0 && randomIndex < pLevel->pAnagrams->count()),"error random index!");CCArray * anagram = (CCArray*)pLevel->pAnagrams->objectAtIndex(randomIndex);CCString * ana1 = (CCString*)anagram->objectAtIndex(0);CCString * ana2 = (CCString*)anagram->objectAtIndex(1);int ana1len = ana1->length();int ana2len = ana2->length();}
Common: random is written by myself. It generates a random number between two values.
int Common::random(int s,int e){float i = CCRANDOM_0_1()*(e-s+1)+s;return (int)i;}
In this way, the phrase in the initial state and the phrase in the final state are obtained, and the dealRandomAnagram function is added to the init function of MainScene,
pLevel = Level::levelWithNum(1);dealRandomAnagram();
2) create a word View
Add a new class inherited from CCNode in the project named TileView. Add the following code in TileView. h:
public:static TileView * initWithLetter(const char * l,float sideLen);private:CCSprite * pSprite;char mLetter;bool mIsMatch;
InitWithLetter is the initialization function, pSprite is the display genie, mLetter is the corresponding letter, and mIsMatch indicates whether the result has been paired (that is, find the location where the letter should be located ).
In TileView. cpp, add the following code:
#include "TileView.h"TileView * TileView::initWithLetter(const char * l, float sideLen){TileView * tile = new TileView();CCSprite * bg = CCSprite::create("tile.png");tile->addChild(bg);tile->pSprite = bg;float scale = sideLen / bg->getContentSize().width;bg->setScale(scale);char chLetter[2];sprintf(chLetter,"%c",l[0] - 32);CCLabelTTF * letter = CCLabelTTF::create(chLetter,"Arial",75 * scale);letter->setColor(ccWHITE);tile->addChild(letter);tile->mIsMatch = false;tile->mLetter = chLetter[0];return tile;}
First, create a Genie With tile.png as the pattern, and then create letters on the pattern.
Next, we will display it in the interface, and add it in MainScene.
private:Level * pLevel;CCArray * pTiles;CCArray * pTargets;
PTiles is an array of TileView, and pTargets is an array of TargetView. TileView is the word of the phrase given at the bottom, and TargetView is the word of the target phrase. Add the code in the dealRandomAnagram function of MainScene. cpp.
int ana1len = ana1->length();int ana2len = ana2->length();float tileSide = ceilf( Common::getCameraWith()*0.9 / (float)std::max(ana1len, ana2len) ) - kTileMargin;float xOffset = (Common::getCameraWith() - std::max(ana1len,ana2len) * (tileSide + kTileMargin)) / 2;xOffset += tileSide/2;
In this case, the location of each TileView is calculated. First, compare the longest length between the original phrase and the target phrase, and then calculate the tileSide width required by each View and the xOffset interval between views.
By the way, do not forget to define global gaps
#define kTileMargin 20
Next, we will create our TileView.
pTiles = CCArray::createWithCapacity(ana1len);const char * ana1Letter = ana1->getCString();for(int i = 0;i < ana1len; i++){char letter[3];sprintf(letter,"%c",ana1Letter[i]);if(letter[0] != ' '){TileView * tile = TileView::initWithLetter(letter,tileSide);tile->setPosition(ccp(xOffset + i * (tileSide + kTileMargin),Common::getCameraHeight() / 4));this->addChild(tile);pTiles->addObject(tile);}}pTiles->retain();
The creation method is relatively simple, but it should be noted that the original phrase can contain free characters, and leave the blank characters in the blank space.
3) word View Optimization
Zheng's TileView looks a little cautious. The following optimizations are made to make them more vivid. Add the randomize function to TileView.
void TileView::randomize(){float rotation = Common::random(0,50) /(float)100 - 0.2;this->setRotation(rotation * 10);int yOffset = Common::random(0,10);this->setPositionY(this->getPositionY() + yOffset);}
Make TileView slightly rotate and offset, and then add the following statement in this-> addChild (tile) in the dealRandomAnagram function of MainScene.
tile->randomize();
4) add TargetView
With the original phrase, the View of the target phrase is created below. Compared with TileView, TargetView is relatively simple. Because it is a fixed position and does not need to display letters. Add the following code to TargetView. h:
class TargetView : public CCNode{public:TargetView(void);~TargetView(void);static TargetView * initWithLetter(const char * l,float sideLen);private:CCSprite * pSprite;char mLetter;bool mIsMatch;};
Similar to TileView, an initialization function has three private variables. It corresponds to TileView one by one.
TargetView * TargetView::initWithLetter(const char * l, float sideLen){TargetView * tile = new TargetView();CCSprite * bg = CCSprite::create("slot.png");tile->addChild(bg);tile->pSprite = bg;float scale = sideLen / bg->getContentSize().width;bg->setScale(scale);char chLetter[2];sprintf(chLetter,"%c",l[0] - 32);/*CCLabelTTF * letter = CCLabelTTF::create(chLetter,"Arial",78 * scale);letter->setColor(ccWHITE);tile->addChild(letter);*/tile->mIsMatch = false;tile->mLetter = chLetter[0];return tile;}
In the initWithLetter function of TargetView, the Comment statement is to display the result, but in the actual game, the letter on TargetView is not displayed.
Next, we need to display TargetView to the scene. Find the dealRandomAnagram method of MainScene and add the following code at the end.
pTargets = CCArray::createWithCapacity(ana2len);const char * ana2Letter = ana2->getCString();for(int i = 0;i < ana2len; i++){char letter[3];sprintf(letter,"%c",ana2Letter[i]);if(letter[0] != ' '){TargetView * target = TargetView::initWithLetter(letter,tileSide);target->setPosition(ccp(xOffset + i * (tileSide + kTileMargin),Common::getCameraHeight() / 4 * 3));this->addChild(target);pTargets->addObject(target);}}pTargets->retain();
Can you see TargetView? Here, we have completed the first part of AnagramPuzzle development, and finally the last
It feels good. You can easily display the game interface you need. This exposure to cocos2d-x knowledge is still relatively small, mainly how to add content to the home scene, how to create the genie. Next time, we need to write something challenging, such as how to drag the genie, how to determine whether it is in the correct position, and how to perform the countdown. The real Code fun is coming soon! Listen to the next decomposition.