Cocos2d-x3.x tower defense game (defending radish) from scratch (1), cocos2d tower defense
I. Prerequisites:
Complete the creation and compilation of the Hello Game project.
For details, see Cocos2dx. 3x_Hello Game project creation.
Ii. Objectives of this article:
L talk about ideas and ideas about anti-tower games
L implement a simple anti-tower game prototype
Iii. content:
L talk about ideas and ideas about anti-tower games
First, a tower defense game PSD design
Game story settings:
This game is about defending radishes, but it cannot be about defending radishes, because the game for defending radishes already exists. I just want to use this famous tower anti-DDoS game for publicity and reference. Now mainstream online games will first tell the story to give gamers a sense of playing. Our story is like this: a long time ago, there are a group of beautiful girls living in the beautiful university dormitory area, but the evil uncle satyr always wants to do some bad things to them, then our hero's kind and brave female dormitory administrator uses weapons like kitchen knives, leather shoes, and toy planes to attack uncle's path and protect the girls from these uncles.
Game element composition:
1. MAP: maps of different levels are different, mainly because of different roads and different Fort positions.
2. turret: fruit knife, kitchen knife, mouse medicine, high heels, toy aircraft, etc. Different guns have different prices, attack speeds, attack attributes, and attack methods.
3. Bullets: these bullets are launched by the artillery station and have different attack values, diffusion values, slowness values, and attack range values.
4. Monsters: various types of uncles, called beasts and color wolves. Different color wolves have different speed values, damage values, and resistance values, along the road on the map, the heroine keeps approaching the end of the road.
5. Heroine: The girl at the end of the road, who does not have the attack power and needs the protection of the turret, has a certain purity value. When the purity value is corrupted by Uncle, the game will end.
6, Score & Resource: You can get a certain score by killing different color wolves. The score can be used to buy a new gun. Each level has a certain initial score to support the initial consumption of the game, the scores of each level can only be used in this level. When the next level is enabled, the accumulated scores are cleared.
7. Treasure Chest: You can purchase a treasure chest with score resources, which has a certain probability of returning several times the input score.
8. Doctors: buy medical care with scores to repair the pure value of the heroine.
Game Development Mode:
This is the way the entire game is developed. First, a very small game core prototype is implemented, and then the game prototype is constantly modified and expanded until the game is completed. I think this method is more suitable for readers to understand and follow the article to learn how to understand the development of this game.
L implement a simple game prototype
Create a game project named DefendTheGirl (defending girl) and package name: com. game. defendthegirl. If no project is created, see Cocos2dx. 3x getting started trilogy-Hello Game project creation (2 ).
This prototype requires implementation:
1. Load a map in the home scene.
2. Place a heroine at the end of the map and an uncle colorwolf at the start of the map.
3. Let Uncle colorwolf go along the route specified by the map to the heroine's position.
Prepare materials and images:
Level_bg_1.png 960px, 640px
Girl.png
Uncle color wolf picture dashu.png
Copy these images to the Resources folder.
1Load a map in the home scene
Step 1:
Use Microsoft Visual Studio 2012 to open the proj. win32 project, and then create MainScene. h and MainScene. cpp under src as the main scenario of the game? Reference: Cocos2dx. 3x getting started trilogy-Hello Game project analysis (3 ).
Step 2:Download the map level_bg_1.png in init(upload images. The Code is as follows:
Bool MainScene: init () {if (! Layer: init () {return false;} Size visibleSize = Director: getInstance ()-> getVisibleSize (); Vec2 origin = Director: getInstance () -> getVisibleOrigin (); // loads the map background auto sprite = Sprite: create ("level_bg_1.png"); sprite-> setPosition (Vec2 (visibleSize. width/2 + origin. x, visibleSize. height/2 + origin. y); this-> addChild (sprite, 0); return true ;}
Step 3:Open AppDelegate. cpp file to introduce MainScene. h header file, and in the applicationDidFinishLaunching method, change auto scene = HelloWorld: createScene (); to auto scene = MainScene: createScene (); and then run.
2Put a heroine at the end of the map, and an uncle Sato at the start of the map
Step 1:Add the following code in the init () method:
// Load the map background ...... Auto sprite = Sprite: create ("level_bg_1.png"); sprite-> setPosition (Vec2 (visibleSize. width/2 + origin. x, visibleSize. height/2 + origin. y); this-> addChild (sprite, 0); // place a color wolf auto dsSprite = Sprite: create ("dashu.png") at the starting point of the map "); dsSprite-> setPosition (Vec2 (40,390); this-> addChild (dsSprite, 0); // place a heroine auto nhSprite = Sprite at the map endpoint :: create ("girl.png"); nhSprite-> setPosition (Vec2 (920,480); this-> DdChild (nhSprite, 0 );......
Step 2:Then you can see Uncle satyr and the heroine on the screen.
1,Let Uncle satyr move closer to the heroine along the route specified by the map
This is a difficult task. First, we will perform a Coordinate Analysis On The Road paths of this map:
As shown in, taking the lower right vertex of the map as the coordinate system origin point, the whole road is divided into 12 coordinate points. The heroine points at the coordinate point at the first day, and the uncle color wolf points at the 12th day. Now uncle satyr will follow the yellow line in the figure from... Until, my implementation thought is like this. When the color wolf sets out from, it tells it that the target point is, when the color wolf reaches, it continues to tell it that the next target point is.
Several implementation technical points:
1. The setPosition Method for Sprite can change the position of Sprite on the graph to realize Sprite movement.
2. Calculate the vector value from the Sprite position to the target point, and then calculate the Sprite's distance offset in the x and y directions based on the vector value and the moving speed of the color wolf, adjust the Sprite position with this offset value
Judge whether Sprite reaches the target point (for example,). As shown in, when the distance between the Sprite coordinate point and the target point is smaller than a certain value, it is determined to reach the target point, you need to set a new target point.
With these Implementation ideas, you can write the code now:
Step 1:From the above Implementation ideas, we can see that our basic implementation is the path point. Here we will create a new path point class object named Waypoint. h, Waypoint. cpp, inherited from: cocos2d: CCNode.
Waypoint. h:
Class Waypoint: public cocos2d: CCNode {public: Waypoint (void );~ Waypoint (void); // initialization method static Waypoint * nodeWithTheLocation (cocos2d: Point location); bool initWithTheLocation (cocos2d: Point location ); // set the next path of the current vertex void setNextWaypoint (Waypoint * waypoint); // obtain the next path of the current vertex Waypoint * getNextWaypoint (); // The current path Point location CC_SYNTHESIZE (cocos2d: Point, _ myPosition, MyPosition); private: // The next path Point Waypoint * _ nextWaypoint;}; Waypoint. cpp: Waypoint (void) {_ nextWaypoint = NU LL;} Waypoint ::~ Waypoint (void) {} Waypoint * Waypoint: nodeWithTheLocation (cocos2d: Point location) {Waypoint * pRet = new Waypoint (); if (pRet & pRet-> initWithTheLocation (location) {pRet-> autorelease (); return pRet;} else {delete pRet; pRet = NULL; return NULL ;}} bool Waypoint: initWithTheLocation (cocos2d: Point location) {bool bRet = false; do {_ myPosition = location; this-> setPosition (Point: ZERO ); bRet = true;} while (0); return bRet;} void Waypoint: setNextWaypoint (Waypoint * waypoint) {_ nextWaypoint = waypoint;} Waypoint * Waypoint: getNextWaypoint () {return _ nextWaypoint ;}
Step 2:Declare the following code in MainScene. h:
Public :...... // Override the update method of Layer. // We mainly implement the color wolf mobile virtual void update (float delta); CREATE_FUNC (MainScene); private: // path start point Waypoint * beginningWaypoint; // path target point Waypoint * destinationWaypoint; // color Wolf's moving speed float walkingSpeed; // color Wolf's current position cocos2d: Vec2 myPosition; // uncle colorwolf cocos2d: Sprite * dsSprite; // path point set cocos2d: Vector <Waypoint *> wayPositions; // judge whether two points are close to bool collisionWithCircle (cocos2d :: vec2 circlePoint, float radius, cocos2d: Vec2 circlePointTwo, float radiusTwo );
Here, the code is modified and restructured. For example, the dsSprite (color Wolf) declared in the init () method is changed to a global variable, because it needs to be operated in the subsequent update method.
Step 2:Create a path point set in the init () method of MainScene. cpp and write the following code:
...... // Initialize the map path point set this-> wayPositions = Vector <Waypoint *> (); // Add the Map No. 1 path point to the set Waypoint * waypoint1 = Waypoint :: nodeWithTheLocation (Point (920,435 + dsh/2.0f); if (this-> wayPositions. size ()> 0) {// set the next node waypoint1-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint1); // Add the path no. 2 to the map. Point * waypoint2 = Waypoint: nodeWithTheLocation (Point (762,435 + dsh/2.0f); if (this-> wayPositio Ns. size ()> 0) {waypoint2-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint2); // Add the path no. 3 to the map. Point * waypoint3 = Waypoint: nodeWithTheLocation (Point (762,360 + dsh/2.0f )); if (this-> wayPositions. size ()> 0) {waypoint3-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint3); // Add the path no. 4 of the map to Waypoint * waypoint4 = Waypoint: nodeWithTheLocatio in the collection. N (Point (685,360 + dsh/2.0f); if (this-> wayPositions. size ()> 0) {waypoint4-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint4); // Add the path No. 5 to the map. Point * waypoint5 = Waypoint: nodeWithTheLocation (Point (685,116 + dsh/2.0f )); if (this-> wayPositions. size ()> 0) {waypoint5-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint5); // Add the map's path number 6 to the set Waypoint * waypoint6 = Waypoint: nodeWithTheLocation (Point (520,116 + dsh/2.0f); if (this-> wayPositions. size ()> 0) {waypoint6-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint6); // Add the path number of Map No. 7 to Waypoint * waypoint7 = Waypoint: nodeWithTheLocation (Point (520,180 + dsh/2.0f) in the collection )); if (this-> wayPositions. size ()> 0) {waypoint7-> setNextWaypoint (this-> wayPositions. back ();} this-> wa YPositions. pushBack (waypoint7); // Add the path no. 8 to the map. Point * waypoint8 = Waypoint: nodeWithTheLocation (Point (285,180 + dsh/2.0f )); if (this-> wayPositions. size ()> 0) {waypoint8-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint8); // Add the path number of map 9 to the Point * waypoint9 = Waypoint: nodeWithTheLocation (Point (285,268 + dsh/2.0f) in the collection )); if (this-> wayPositions. size ()> 0) {waypoint9-> setNex TWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint9); // Add the path number 10 of the map to the Point * waypoint10 = Waypoint: nodeWithTheLocation (Point (204,268 + dsh/2.0f) in the collection )); if (this-> wayPositions. size ()> 0) {waypoint10-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint10); // Add the path on Map No. 11 to the Point in the collection. Waypoint * waypoint11 = Waypoint: nodeWithTheLocation (Point (204,350 + dsh/2.0f) ); If (this-> wayPositions. size ()> 0) {waypoint11-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint11); // Add the path number 12 of the map to the Point * waypoint12 = Waypoint: nodeWithTheLocation (Point (50,350 + dsh/2.0f) in the collection )); if (this-> wayPositions. size ()> 0) {waypoint12-> setNextWaypoint (this-> wayPositions. back ();} this-> wayPositions. pushBack (waypoint12 );......
Step 3:Initialize several variables in the init () method of MainScene. cpp and compile the following code in the initial position of the genie:
...... // Obtain the last vertex in the Set, point 12 Waypoint * waypoint0 = wayPositions. back (); // set the start point of the motion beginningWaypoint = waypoint0; // set the target point of the motion to the next point of point 12, destinationWaypoint = waypoint0-> getNextWaypoint (); // you can specify the current position myPosition = waypoint0-> getMyPosition (); // set the initial position of the color wolf in the map dsSprite-> setPosition (myPosition); // set the initial position of the heroine in the map to nhSprite-> setPosition (wayPositions. front ()-> getMyPosition (); // set the moving speed this-> walkingSpeed = 0.2f; // set Timer this-> scheduleUpdate ();......
Step 4:Write the following code to implement the collisionWithCircle method in MainScene. cpp:
// Determine whether two dots are near. // circlePoint: coordinate of the first Dot. // radius: radius of the first circle. // circlePointTwo: coordinate of the second dot. // radiusTwo: bool MainScene: collisionWithCircle (cocos2d: Vec2 circlePoint, float radius, cocos2d: Vec2 circlePointTwo, float radiusTwo) {// calculate the float xdif = circlePoint based on the distance formula between two points. x-circlePointTwo. x; float ydif = circlePoint. y-circlePointTwo. y; float distance = sqrt (xdif * xdif + ydif * ydif); if (distance <= radius + radiusTwo) {return true;} return false ;}
Step 5:The update method is implemented in MainScene. cpp:
// Determine whether uncle satyr meets the target point if (this-> collisionWithCircle (myPosition, 1, destinationWaypoint-> getMyPosition (), 1 )) {// whether there is another target point if (destinationWaypoint-> getNextWaypoint () {// reset the start point and target point beginningWaypoint = destinationWaypoint; destinationWaypoint = destinationWaypoint-> getNextWaypoint ();}} // obtain the coordinates of the Target Point. Point targetPoint = destinationWaypoint-> getMyPosition (); // calculate the target Point vector. Point normalized = Point (targetPoint. x-myPosition.x, targetPoint. y-myPosition.y ). getNormalized (); // calculate the offset value float ox = normalized in the x and y modes based on the velocity and vector respectively. x * walkingSpeed; float oy = normalized. y * walkingSpeed; myPosition = Point (myPosition. x + ox, myPosition. y + oy); // reset the color wolf position to move dsSprite-> setPosition (myPosition );
Step 6:Run the test game effect to see if the color wolf will move along the path we set.
Windows Effect
Let's take a look at the effect of the android phone and add the two newly added cpp files to Android. then start compiling and packaging the so file in the mk file (For details, refer to Cocos2dx. 3 x portal trilogy-Hello Game project analysis (3 ). After packaging, connect to the mobile phone in eclipse to run the following results:
It is found that when running on a real machine, the heroine and the color wolf are on the road, and it seems that the background map does not show any part of the top and bottom of the full background, however, windows does run normally. Why? How can I adjust it? My mobile phone resolution is 960x540, and our map material image resolution is 960x640, which leads to this problem. This is about screen resolution adaptation for different mobile phones, in the next article, we will continue to improve and modify the game prototype to solve this problem.
The author communicated QQ: 2303452599
Email: mymoney1001@126.com