Cocos2d-x v3.6 Making Archery Game (iii)

Source: Internet
Author: User

We have created the role of archery in the previous chapter, and we will begin to implement the archery section in the next chapter.

The main contents of this chapter:

    1. Add the player's archery logic;
    2. Explain how the bows and arrows do the curve movement.
Archery

First, let's look at some of the logical behavior of the Player in archery (before the bow and arrow an arrow).

A simple analysis of the first:

When the user touches the end, the player will have a pull arrow ready to shoot arrows, and when the action is finished, the player will take the bow and arrow of the place to create an arrow, and the arrow will fly out according to the curve trajectory.
But just imagine, if we have not finished the arrow in the extraction of the screen, then we have not yet waited for a bow and arrow to launch the second, and constantly click on the screen, will continue to create the launch of the bow and arrow, obviously, such results are not what we want. So when we perform the pull, we need to add a variable to the Player that controls it and does not let it shoot arrows, which is the isrunaction declared in the previous chapter.

After the analysis, let's take a look at the concrete implementation. Its code we write in the Createandshootarrow function declared in the previous chapter, in which the function will complete all archery behavior. The implementation is as follows:

12345678910111213141516 void Player::createAndShootArrow( Point touchPoint){    // 1        isRunAction = true;    // 2    auto animation = AnimationCache::getInstance()->getAnimation("player");    auto animate = Animate::create(animation);    // 3    auto funcall1= CallFunc::create(CC_CALLBACK_0(Player::shootArrow, this));    // 4    auto delayTime = DelayTime::create(0.5f);    // 5    auto funcall2= CallFunc::create(CC_CALLBACK_0(Player::finishRunAction, this));    // 6    playerbody->runAction(Sequence::create(animate, funcall1, delayTime, funcall2, NULL));}
    1. At the beginning of the call Createandshootarrow, we first set the isrunaction to true, that is, tell the program: Now uncle began to pull arrows.
    2. Animation is a cached animation data called "Player" from the Animationcache (animated cache), which is a animation (noun) object, which represents the player's pull-arrow animation. Animate, which is a animate (verb) object, is an animated action generated from this data.
      Now if you want to ask me how the cache has "player" this animated data, I can only tell you, of course, I added the Ah, this later we will talk about.
    3. FUNCALL1 is a function callback action of the Callfunc type.
      Sometimes when certain actions are completed, some data processing needs to be performed, such as adding and reducing blood after attacking an enemy. You will need to use the function callback action Callfunc.
      The FUNCALL1 function here is to call the Shootarrow method to create and shoot arrows.
    4. Delay action, delay 0.5 seconds.
      Delay action is a "do nothing" action, its most common usage is in a Sequence sequence action, into a number of delay time, so that the execution speed of the action slow down, not dazzling, so that people do not respond.
    5. Callback action, execute the Finishrunaction function, the Finishrunaction function will set the Isrunaction to False, that is, tell the program: Grandpa this time the archery process is complete, you slag can start shooting the second time.
    6. Let the Playerbody object in turn perform the above actions, that is, the first execution of the arrow action, and then start archery, and then delay a small meeting, and then end the archery. Here Sequence is an action that enables node to perform a sequence of actions.

The above code comment mentions the cached animation data, as well as the Shootarrow,finishrunaction function. Where the Finishrunaction function is very simple, it is defined as follows:

1234 voidPlayer::finishRunAction(){    isRunAction = false;}

Next we'll look at how the other two are implemented.

The origin of cached data

About the animation data in the cache, here we are loaded in the Gamescene class. As below, we declare a createanimation function in GameScene.h.

1 Animation* createAnimation(std::string prefixName, intframesNum, floatdelay);

and define it in GameScene.cpp:

12345678910111213141516 Animation* GameScene::createAnimation(std::string prefixName, int framesNum, float delay){    // 1    Vector<SpriteFrame*> animFrames;    // 2    for (int i = 1; i <= framesNum; i++)    {        char buffer[20] = { 0 };        sprintf(buffer, "%i.png",  i);        std::string str =  prefixName + buffer;        auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);        animFrames.pushBack(frame);    }    // 3    return Animation::createWithSpriteFrames(animFrames, delay);}

The function of the Createanimation method is to add the sprite frame to the Animation to generate the animation data, which has the following parameters.

Parameter 1: The sprite frame prefix name, such as the prefix we set as "player", then we will add its middle part of the numbers and suffixes in the program. That is, "player" + "frame" + ". png" = Player1.png, Player2.png, and so on. Parameter 2: The total number of frames, that is, how many frames the sprite frame animation has. Parameter 3: Intra-frame delay, which is the time required to play between frames, controlling the animation playback rate.

It should be noted here that the prefix name and total frame number is not random, it must be spriteframecache in the data, that is, the texture.plist must have the frame, as follows:

    1. Defines an array of spriteframe sprite frames for storing all sprite frame data for an animation.
    2. Iterate through all the frames, remove the corresponding sprite frames, and press them into the animframes array in turn.
      Here Spriteframecache is the sprite frame cache class, and the required sprite frames are loaded into the spriteframecache when we add the package resources plist and PVR.CCZ files in our second chapter. For more details, please refer to this section.
    3. Creates a Animation object from the sprite frame array and returns it.

After the Createanimation method is implemented, we can use this function to create the desired animation object. Back in the Init method of Gamescene, we add the following code:

12 auto animation = createAnimation("player", 8, 0.06f);AnimationCache::getInstance()->addAnimation(animation, "player");

Here we create a Animation animation data object with the Createanimation method, and add such an object to the animation cache class with the name set to "Player". As a result, in a later process, we can get an animated object named "Player" anywhere by Animationcache this singleton class.

The future of the enemy jumping animation, attack animation, death animation, as well as other games required animation, we have been implemented by the above methods. namely

1234567891011 auto animation = createAnimation("player", 8, 0.06f);AnimationCache::getInstance()->addAnimation(animation, "player");animation = createAnimation("arrowfire", 5, 0.05f);AnimationCache::getInstance()->addAnimation(animation, "arrowfire");animation = createAnimation("arrowdrug", 5, 0.1f);AnimationCache::getInstance()->addAnimation(animation, "arrowdrug");animation = createAnimation("enemy1_XXX", X, X);AnimationCache::getInstance()->addAnimation(animation, "enemy1_XXX");animation = createAnimation("enemy2_XXX", X, X);AnimationCache::getInstance()->addAnimation(animation, "enemy2_XXX");// .....................等等诸如此类的,很多。
The realization of Archery

The Shootarrow method creates and launches a bow and arrow, where the part that creates the bow and arrows is very well implemented, and the main problem we need to overcome here is how to get the arrows out. Let's look at the code for creating a bow and arrow in the Shootarrow method, as follows:

12345678910 void Player::shootArrow(){    // 创建箭    Sprite* arrow = Sprite::createWithSpriteFrameName("arrow1.png");    arrow->setPosition(Vec2(playerarrow->getPosition().x/2, playerarrow->getPosition().y));    this->addChild(arrow);    // 以下将写射出箭的代码    // .................}

In the second half of the Shootarrow method we will add the logic of the bow curve, which is referenced below.

Idiomatic Bessel

Usually, combined with the characteristics of the Cocos2d-x engine, it is common to think of the process of using Bessel action (Bezierto/bezierby) to achieve the bow-and-arrow curve flight. Next, let's try the Bessel action to implement this function.

In the Shootarrow () method, we try to add a snippet of code like this:

1234567 ccBezierConfig bezier;bezier.controlPoint_1 = Vec2(100, 200);bezier.controlPoint_2 = Vec2(200, 200);bezier.endPosition = Vec2(300, 0);auto action = BezierTo::create(2, bezier);arrow->runAction(action);

The code creates a Bezier action and lets the arrow object arrow perform the action. Here the control point, the end point is to test casually set, the effect will be like the following.

You will find that although the bow and arrow do curve movement, but it does not follow the curve path transformation angle, so we urgently need to rewrite a new action to replace the above method.

Here we briefly introduce the above Bezier curve, the beginner can see.

the Bezier curve is a mathematical curve applied to a two-dimensional graphic application, which is a smooth curve drawn from any point coordinates of four locations. The four points defined by the curve are: The starting point, the terminating point, and the two mutually separated intermediate points. Sliding two intermediate points, the shape of the Bezier curve changes. "

The configuration information for Bezier curves defined in the Cocos2d-x engine is as follows:

12345678 typedef struct _ccbezierconfig {      //! end position of the Bézier &NBSP;&NBSP;&NBSP;&NBSP; vec2 endposition; &NBSP;&NBSP;&NBSP;&NBSP; //! Bézier control point 1 &NBSP;&NBSP;&NBSP;&NBSP; vec2 controlpoint_1; &NBSP;&NBSP;&NBSP;&NBSP; //! Bézier Control point 2 &NBSP;&NBSP;&NBSP;&NBSP; vec2 controlpoint_2; Ccbezierconfig;

The three points in the structure are: the end point of the curve, the control point 1, and the control point 2. The beginning of the curve is not configured here, because the starting point of the Bézier in the engine is what we think is its current coordinate origin.

The Bezierto/bezierby class in the engine is a two-action package based on the Bezier principle, the difference being that Bezierto is setting the end point to the specified coordinate position, and Bezierby is setting the end point to the relative coordinate position. It's not clear. Children's shoes can be found in this article to find relevant instructions, this article can also be used as an extension of learning resources.
When using this type of action, we need to identify all the variable data in the Ccbezierconfig, that is, the end point of the Bezier curve and the two control points, as shown in the example above.

Back to our game, think about it, in fact, we only need to make a slight improvement on the basis of the existing Bessel action, the previous method is still feasible. There is only one small problem: the Bezier curve (Bezierto/bezierby Class) provided in the Cocos2d-x engine is controlled by two control points and an end point, and these points are constantly changing and not well-defined in the game.

So if we continue to follow the Bezierto/bezierby curve algorithm, then we will be more troublesome and ineffective in determining the control points and endpoints. The obtained Bezier curve is generally "crooked" is not control.

Even if we set the control point to the same position, its trajectory still looks very twisted, 4.

In fact, for this game, the trajectory of the Player's arrows is more like a parabola in some way, it is more like a curve determined by a control point, as shown below:

So to make it easier to define the trajectory of the curve, we will change the curve to be controlled by a control point. We will explain the specific implementation in the next chapter, "New Into the Bessel", please pay attention.

Cocos2d-x v3.6 Making Archery Game (iii)

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.