How to make a class Mario's horizontal version of the platform action Game continued

Source: Internet
Author: User
Tags addchild


Welcome back, the last article we talked about the physics engine in the gravity environment simulation and the protagonist koala and the ground wall collision, I believe we have a 2D world of physical simulation has a certain understanding, and now we continue to talk about how to let the test pull up!

Let the test pull up!
Here control koala move becomes very simple, it only forward and jump two ability (source I added the koala back function, suggest you add a few virtual keys to achieve more non-rich function) If you press the left half of the screen will go forward, press and hold the right half of the koala will jump up (the original setting koala will not back-_-).
We need to add two member variables in Player.h:
BOOL _forwardmarch; Whether to go forward
BOOL _mightaswelljump; Can you jump?
Set them to False in the Init method of the Player.cpp or in the constructor
Add touch to the Gamelevellayer class and add the following in the. h file:

virtual void registerwithtouchdispatcher (); void Cctouchesbegan (Cocos2d::ccset *ptouches, cocos2d::ccevent *pEvent); void Cctouchesmoved (Cocos2d::ccset *ptouches, cocos2d::ccevent *pevent); void cctouchesended (Cocos2d::ccset *pTouches , Cocos2d::ccevent *pevent);
Add (after loading the map code) in the GameLevelLayer.cpp init
Settouchenabled (TRUE); To set the touch
Then write the register touch method
void Gamelevellayer::registerwithtouchdispatcher () {ccdirector* pdirector = Ccdirector::shareddirector ();pD irector- >gettouchdispatcher ()->addstandarddelegate (this, 0); Register multi-Touch}
Now, let's take a look at those three touch events!
void Gamelevellayer::cctouchesbegan (Cocos2d::ccset *ptouches, cocos2d::ccevent *pevent) {CCSetIterator iter = Ptouches->begin (); for (; Iter!=ptouches->end (); iter++) {cctouch* Ptouch = (cctouch*) (*iter); Ccpoint touchlocation = This->converttouchtonodespace (Ptouch);  Convert touch point position to local coordinates if (touchlocation.x > +)   //At the far right of the screen, just jump {_player->bmightaswelljump = true;} else {_player->bforwardmarch = true;}}} void gamelevellayer::cctouchesended (Cocos2d::ccset *ptouches, cocos2d::ccevent *pevent) {_player->bForwardMarch = False When the key is released, it is set to not jump or forward state _player->bmightaswelljump = false;}
The code at a glance, when the Cctouchesbegan according to the position of the player determines whether the koala state is forward or jump, release the button to reset the two state variables to false.

The real character movement is done in the player's Update method, looking at the code:

void Player::  Update (float delta) {Ccpoint gravity = CCP (0.F, -450.F); Koalas drop 450 units per second ccpoint Gravitystep = Ccpmult (Gravity, delta); Calculates how much the delta time falls under the influence of gravity, that is, how much the drop speed after dt time is ccpoint forwardmove = CCP (800.F, 0.F);   Forward speed, forward 800.fCCPoint per second forwardstep = Ccpmult (Forwardmove, Delta); 1this->_velocity = Ccpadd (this->_velocity, gravitystep); Current speed = current speed + acceleration of gravity this->_velocity = CCP (this->_velocity.x *0.9f, THIS->_VELOCITY.Y); 2if (this->bforwardmarch) {this->_velocity = Ccpadd (this->_velocity, forwardstep);//current speed to add forward speed vector}// 3CCPoint minmovement = CCP ( -120.F, -350.F); Ccpoint maxmovement = CCP (120.0f, 250.f); this->_velocity = Ccpclamp (this->_velocity, minmovement, maxmovement); 4CCPoint stepvelocity = Ccpmult (this->_velocity, Delta); Calculates the number of this->_desiredposition that the protagonist has moved under this speed = Ccpadd (This->getposition (), stepvelocity); Position currently expected to go = Current position + current speed} 
Let's take a look at the new section in detail:

    1. When the player touches the forward and is similar to the gravity simulation, we add a forward push force of 800.F, which is treated in the same way as gravity.
    2. The 2nd step transverse velocity multiplied by 0.9 is the simulated friction effect, considering that the player will move forward when there is a forward thrust. Did you stop right now? That looks too stiff, so the x-axis speed is multiplied by 0.9 per frame, which is the effect of a uniform deceleration, just like friction.
    3. Check to see if the player has pressed forward, press the advance speed to add the forward impetus, it played a moving effect
    4. This step is called clamp is the limit speed before and after not too big, give it a maximum value. The previous sentence set the maximum drop speed can be removed.
well run, we can see our protagonist koala now can move forward!

Let the koala jump up and down!
Jumping is one of the most obvious features of an action game. We want the character to jump smooth and realistic, now let's implement it.
To the Update method of the Player class, add the following code before the IF (this->_forwardmarch) statement:

Ccpoint Jumpforce = CCP (0.F, 310.F); if (This->_mightaswelljump && this->_onground) {  this->_ Velocity = Ccpadd (this->_velocity, Jumpforce);}
As long as you add an upward force, the character can jump up.
If you stop here, you will get an old-fashioned Jadelli jump, that is, each jump is the same height, each time you give the player a similar force, and then wait for gravity to pull you back to the ground.
There seems to be nothing wrong, if you ask not high, but carefully look at a variety of popular platform games, such as Super Mario, Sonic, Locke, water, such as bucket, it seems that the player can control the height of the jump by pressing the button to achieve a more flexible effect. How did that happen?
In fact, to achieve this effect is also very simple, the so-called player Key Press Force is a long time, according to the length of time is to apply the jumping force of the time is long, jump of course high, halfway if the player does not give force, of course, will jump to half off the chain, but the player has an illusion is to jump to high- Don't want to jump, release the key is-_-
Ccpoint Jumpforce = CCP (0.F, 310.F);  Upward jumping Force player has been pressing the jump key when the jump force float jumpcutoff = 150.f;   The player does not hold the jump key when the jump force if (this->bmightaswelljump && this->onground)  ///If the current player has pressed the jump key and on the ground {this->_ Velocity = Ccpadd (this->_velocity, Jumpforce); Jumping is adding an upward speed}else if (!this->bmightaswelljump && this->_velocity.y > Jumpcutoff)//player does not hold down the jump key, And the upward speed has exceeded the set value, it limits the upward jump speed {this->_velocity = CCP (this->_velocity.x, Jumpcutoff);}
The explanation is very clear, and there is not much explanation.
Well, build a run of our game, see, our koala can be free and jubilant to fly up and down.

Jumping is very happy to jump, but the tragedy is that it jumps to the far right to jump out of the screen, invisible.
To fix this problem, this problem is actually the viewpoint follow, on the COCOS2DX has the standard algorithm which solves this problem, the post code:
void Gamelevellayer::setviewpointcenter (Cocos2d::ccpoint pos) {ccsize winsize = Ccdirector::shareddirector () Getwinsize ();//Limited role cannot exceed half screen int x = max (pos.x, WINSIZE.WIDTH/2); int y = max (pos.y, WINSIZE.HEIGHT/2);//Limited role cannot run out of screen x = MIN (x, (_map->getmapsize (). Width * _map->gettilesize (). width)-WINSIZE.WIDTH/2); y = MIN (Y, (_map->getmapsize (). Height * _map->gettilesize (). Height)-WINSIZE.HEIGHT/2); Ccpoint actualposition = CCP (x, y); Ccpoint Centerofview = CCP (WINSIZE.WIDTH/2, WINSIZE.HEIGHT/2); Ccpoint viewPoint = ccpsub (Centerofview, actualposition);//Set the location of the map _map->setposition (viewPoint);}
The method parameter is the current location of the player koala. This method can not only be able to follow and follow the protagonist up and down, very useful. The principle of this method in many blogs have been mentioned, the principle is actually the map with the player to do the direction of movement, we can look at other articles explaining its principle, but I do not want to say more here, not one or two can say, we just use this method on the line.
All we have to do is call it in the Update method of the Gamelevellayer class and put it before the end of the Update method, as follows:
This->setviewpointcenter (_player->getposition ());
Now build and run again, this time our little koala will never run out of the screen!


Taste the Hurt!
Now we can start to do the game clearance and Gameover function.
There is a hazards layer in the map, and this layer has some object that the koala will hang on. In fact, the nature of the collision detection, see the code:

void Gamelevellayer::handlehazardcollisions (player* Player) {Ccarray *tiles = this->getsurroundingtilesatposition (Player->getposition (), _hazards); ccdictionary* dic = NULL; ccobject* obj = Null;float x=0.f; Float y = 0.f;int gid = 0; Ccarray_foreach (tiles, obj) {dic = (ccdictionary*) obj;x = Dic->valueforkey ("x")->floatvalue (); y = dic-> Valueforkey ("Y")->floatvalue (); Ccrect Tilerect = Ccrectmake (x, Y, _map->gettilesize (). Width, _map->gettilesize (). height); Ccrect prect= Player->collisionboundingbox (); gid = Dic->valueforkey ("gid")->intvalue (); if (GID && Tilerect.intersectsrect (prect))  //If there is a spike and the player collides with it, gameover{this->gameover (false);}}
Code seems to be very familiar with Ah, you remember correctly, in fact, is from the Checkandresolvecollisions method of the copy, but not so many cases and the way of processing is simple just call the Gameover method, Gameover Boolean argument True indicates game wins, false is a failure
_hazards is also a member variable of the cctmxlayer* map layer type in the Gamelevellayer class, which is initialized in this class's Init method:
_hazards = _map->layernamed ("hazards");
This method is then called in the Update method, and now the Update method looks like this:
void Gamelevellayer::update (float delta) {_player->update (delta); this->handlehazardcollisions (_player); This->checkforandresolvecollisions (_player); This->setviewpointcenter (_player->getposition ());}
Now implement the Gameover method, when the player jumps to the thorn in the harads layer, we will call this method game end, or when the player comes to the end, I will also call this method, this method will show a restart button, and print some information on the screen, Tell the player you're dead or you win or something.-_-
void Gamelevellayer::gameover (bool Bwon) {Bgameover = true; ccstring* gametext;if (bwon) {gametext = Ccstring::create ("You won!");} Elsegametext = Ccstring::create ("You have died!"); cclabelttf* Diedlabel = Cclabelttf::create (gametext->getcstring (), "Marker Felt", max);d iedlabel->setposition ( CCP (240, 200)); Ccmoveby *slidein = ccmoveby::create (1.f, CCP (0, 250)); Ccmenuitemimage* replay = ccmenuitemimage::create ("Replay.png", "Replay.png", "replay.png", this, Menu_selector ( Gamelevellayer::restartgame)); Ccarray *menuitems = Ccarray::create (); Menuitems->addobject (replay); Ccmenu *menu = Ccmenu::create () menu->addchild (replay); Menu->setposition (CCP ( -100)); This->addchild ( menu); This->addchild (Diedlabel); menu->runaction (Slidein);} 
The variable bgameover at the beginning of the method is also a member variable of the new definition of the Gamelevellayer class, initialized to False in Init, which indicates whether the game is over. The function of this variable is that you begin to judge in the Update method, if Bgameover==true, then return directly to do nothing. As follows:
void Gamelevellayer::update (float delta) {if (bgameover) return;_player->update (Delta);this-> Handlehazardcollisions (_player); this->checkforandresolvecollisions (_player); This->setviewpointcenter (_ Player->getposition ());}
Now you compile and run, hit the nail board to try, there will be a cup of the outcome ...

Don't try too much, beware animal protection organizations will find your home Men Lai (-_-is this the so-called American humor?) )

Fix a fatal bug
Do you remember what happened in the front when the koala dropped out of the map? There are some pits in the game map we meant to pull it off and the game would end, but in fact the program was blown away. All with tiled map will appear this problem, as long as the role out of the map boundary game will be collapsed, this problem has troubled a lot of people, including me. In fact, to solve this bug is very simple, the key is the Tilegidat method.
This method you open the source implementation to know, it has a Ccassert macro, to determine the map will throw an exception. Is it supposed to be? This method is to take a map of a tile on the GID, you are out of the map and take what is of course to throw an exception. Here we will add a judgement in the Getsurroundingtilesatposition method, note that of course, before calling the Tilegidat method, do not let the test pull out the map:

if (Tilepos.y > (_map->getmapsize (). height-1)) {This->gameover (false); return NULL;}
There are calls in the Checkforandresolvecollisions method.Getsurroundingtilesatposition method, if it returns an empty array can be bad, so in Checkforandresolvecollisions also want to change, in ccarray* tiles = this- >getsurroundingtilesatposition (Player->getposition (), _walls); after one sentence, add
if (bgameover)//The player may fall out of the pit and will not process {return;}
compile and run, the koala fell into the pit to try to find that the program is no longer down!



winner!
in the end, we deal with the situation when the koala goes to the finish line and shows the victory.
here we simply, just judge how far to go to the right to win the test
void Gamelevellayer::checkforwin () {if (_player->getpositionx () >3130.0) {This->gameover (true);}}
In real game we usually put an object at the end, such as the gate of the castle flag or something, the protagonist met on the victory can enter the next level, interested in their own try!
This method should also be put into the Gamelevellayer Update method, as follows:
void Gamelevellayer::update (float delta) {if (bgameover) return;_player->update (Delta);this-> Handlehazardcollisions (_player); This->checkforwin (); this->checkforandresolvecollisions (_player); this- >setviewpointcenter (_player->getposition ());}
Run, go to the finish line try:



Add Sound
After winning, there is no music how to do, a silent world can be very desperate, let us add some sound!
In GameLevelLayer.cpp and player.cpp add the header file as follows:
#include "SimpleAudioEngine.h"
using namespace Cocosdenshion;
In the Init method of Gamelevellayer, add:
Simpleaudioengine::shareengine ()->playbackgroundmusic ("Level1.mp3");
In the Update method in Player.cpp, the player jumps to the point where the sound is added:
if (this->bmightaswelljump && this->onground)  //If the current player presses the jump key and is on the ground {this->_velocity = Ccpadd ( This->_velocity, Jumpforce); Jumping is to add an upward velocity simpleaudioengine::sharedengine ()->playeffect ("Jump.wav");}
The Gameover method in GameLevelLayer.cpp also adds sound effects:
void Gamelevellayer::gameover (bool Bwon) {if (bgameover)  //Do not repeatedly call {return;} Bgameover = true; Simpleaudioengine::sharedengine ()->playeffect ("Hurt.wav");
Compile and run, and try your hand-crafted game with a sense of music!
Source: Download

What else do we have left?
What else to do, character animation No, there are monsters, AI, level, character state machine and so on. These are all in iOS game three-piece setPlatformer Start Kit, as I said earlier, this tutorial is just the prelude of this start kit, what is the real platformer game like?

After completing this tutorial, you can learn









What do you think? Heart, involved in the issue of copyright inconvenience in this public, interested to see this: horizontal version of the platform game source
Also one of the famous three-piece set of the horizontal version fighting game Beat ' Em up Game Starter Kitis also very exciting oh! On-line open source code tutorial is not One-twentieth-_-inside












interested to see this: horizontal version of fighting game source










How to make a class Mario's horizontal version of the platform action Game continued

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.