In the previous article, the prototype of a mouse-hitting game was simply implemented. A good game requires many debugging and polishing for a long time to become an interesting product, rather than the code of the segment, in the previous article, we used the simplest way to generate a static interface. This time we will integrate animations to make interesting games by using various behavioral classes derived from CCActionInterval. Now let's start.
CCActionInterval is a common behavior class in Cocos2d. Its Derived classes are in charge of different objects and produce different results. Some of these models are called scripts and some are called controllers in some game engines, it may be a bit dizzy at the beginning, but it will become increasingly familiar with the increase in the number of use, today I will use the following behavior to achieve the animation effect of the game:
CCDelayTime: a delayed action. It is only a timer. The action ends after the specified time.
CCAnimate and CCAnimation: animation behavior class. They can be combined to control a CCSprite frame animation.
CCCallFunc: Call behavior class. It specifies a callback function, which is called during execution.
CCSequence: behavior queue class. It can combine several behaviors so that you do not need to judge the logic at regular intervals. For example, if a delayed behavior is added with a callback behavior, it will call back the specified function after the specified delay.
In addition to these, there are many useful behavior classes, but it is enough to use them only.
For example, the following code:
CCDelayTime delayTime = CCDelayTime.actionWithDuration(DelaySecond);delayAction = CCSequence.actionOneTwo(delayTime, CCCallFunc.actionWithTarget(this, showCompled));this.runAction(delayAction);
This code is replaced with an image, which means this is the case.
If you have read it carefully, you will find that CCSequence is also a CCActionInterval. Its function is to combine multiple behaviors to achieve coherence. This is an interesting method. You can use it to do many interesting behaviors, the preceding Code calls back the showCompled method after DelaySecond seconds. In the final code, you will find that this method is used three times to achieve different effects in different places.
In addition to latency, there can also be a combination of animations, so that we can accurately know the events after an animation ends, for example:
// Drill out the animation CCAnimation marmotShowanimation = CCAnimation. animationWithFrames (frames, 0.1f); CCAnimate action = CCAnimate. actionWithAnimation (marmotShowanimation, false); showAction = CCSequence. actionOneTwo (action, CCCallFunc. actionWithTarget (this, callback); body. runAction (showAction );
This Code creates an animation behavior through the frames frame sequence, and then uses the Animate nesting to play the video. The execution target is the CCSprite body. After the playback ends, the callback method is executed.
Behavior animation plays an important role in the game. In this example, it is the simplest way to play a single image sequence. In fact, it is easier to use cocos2d animation plist, however, design tools are cumbersome, so I plan to introduce the production and code of animations in the next chapter.
In the current cocos2dxna version, text cannot be directly displayed, which is similar to other platforms. You can use other methods to display English and numbers. In this regard, the engine provides multiple classes to solve this problem, the simplest one is CCLabelTTF. It does not need to independently load the text sequence or specify the source image, and displays a row of specified English and numbers directly at the position of the screen. For example:
label_Score = CCLabelTTF.labelWithString("0", "Arial", 24);label_Score.Color = new ccColor3B(255, 0, 0);label_Score.anchorPoint = new CCPoint(1, 0.5f);this.addChild(label_Score);label_Score.position = new CCPoint(CCDirector.sharedDirector().getWinSize().width - 24, CCDirector.sharedDirector().getWinSize().height - 24);
This line means that a 0 character is displayed in the upper right corner of the screen, and the change is also very simple, directly:
label_Score.setString(“999”);
We use this part to show the points when hit the hamster.
The sound system is an independent class in cocos2dxna. In the namespace CocosDenshion, SimpleAudioEngine can play music and sound effects. Its usage is also simple:
// Play the cracked sound SimpleAudioEngine. sharedEngine (). playEffect (CCFileUtils. fullPathFromRelativePath ("Sounds/sound43 "));
Before that, add the sound to Hit_MoleContent.
The source code of this project is downloaded here
The code is actually very simple. There are only two cs files, one Mole and one Scene1, which have been added with comments. We hope everyone will not look so hard.
Class 1: Mole
Using cocos2d; using System. collections. generic; using CocosDenshion; namespace Hit_Mole {public class Mole: CCMenuItemSprite {CCSprite body; CCSprite hideimage; CCActionInterval showAction; CCActionInterval delayAction; // static List frames of animation sequence frames; public Mole (Scene1 root, SEL_MenuHandler selector) {// read a "rat hole" image and add it to the menu item. It serves as the background CCSprite hole = CCSprite. spriteWithFile ("Hole"); hole. anchorPoint = new CCPoint (0, 0); this. addChild (hole); // read a mole body image and set it to the default image body = CCSprite. spriteWithFile ("marmot_3"); NormalImage = body; // read the image SelectedImage = CCSprite displayed when a mole is selected (clicked. spriteWithFile ("marmot_4"); // hidden image, which is useless in this article, so it is invisible hideimage = CCSprite. spriteWithFile ("marmot_5"); hideimage. anchorPoint = new CCPoint (0, 0); hideimage. visible = false; this. addChild (hideimage); // initialization selector, Hit will occur and the status of the clicked initWithTarget (root, selector); // set the content size, when inheriting the class, contentSize is not refreshed. You must specify contentSize = body. contentSize; body. visible = false; // create a static frame List to prevent useless CCSpriteFrame if (frames = null) {frames = new List (); for (int I = 1; I <4; I ++) {CCTexture2D texture = CCTextureCache. sharedTextureCache (). addImage ("marmot _" + I); // There is an engine bug. If this parameter is not set, the animation texture cannot be played. name = (uint) I; var frame = CCSpriteFrame. frameWithTexture (texture, new CCRect (0, 0, texture. contentSizeInPixels. width, texture. contentSizeInPixels. height); frames. add (frame) ;}}m_bisenabled = false;} // method. When this method is called, the mole is created to drill out the animation and execute public void Show () {IsShow = true; body. visible = true; // drill out the animation CCAnimation marmotShowanimation = CCAnimation. animationWithFrames (frames, 0.1f); CCAnimate action = CCAnimate. actionWithAnimation (marmotShowanimation, false); showAction = CCSequence. actionOneTwo (action, CCCallFunc. actionWithTarget (this, callback); // Let the body drill out the animation body. runAction (showAction); // delay action control the action CCDelayTime delayTime = CCDelayTime. actionWithDuration (DelaySecond); delayAction = CCSequence. actionOneTwo (delayTime, CCCallFunc. actionWithTarget (this, showCompled); this. runAction (delayAction);} // how long will the latency be drilled back to public float DelaySecond = 2; // public void Hide () {// stop various actions immediately: stopAction (showAction); stopAction (delayAction); // currently, you cannot click IsShow = false; // execute a delayed action, after the drill-back operation is completed, reset the animation CCDelayTime delayTime = CCDelayTime. actionWithDuration (0.3f); var timespan = CCSequence. actionOneTwo (delayTime, CCCallFunc. actionWithTarget (this, hideCompled); body. visible = false; hideimage. visible = true; runAction (timespan);} private void callback () {}// callback private void showCompled () {SimpleAudioEngine. sharedEngine (). playEffect (CCFileUtils. fullPathFromRelativePath ("Sounds/sound63"); Hide () ;}// callback private void hideCompled () {hideimage when the drill is complete. visible = false;} // use an attribute to identify whether to click public bool IsShow {set {base. m_bIsEnabled = value;} get {return base. m_bIsEnabled; }}// you can use this attribute to determine whether to click public override void selected () {if (IsShow) base. selected ();}}}
Class 2: Scene1
Using cocos2d; using System. collections. generic; using System; using CocosDenshion; namespace Hit_Mole {public class Scene1: CCScene {Random _ randome = new Random (int) DateTime. now. ticks); CCLabelTTF label_Score; List _ molelist = new List (); public Scene1 () {// initialize ();} public bool initialize () {// L1 // read scene.jpg images from hit_molecontentto become an genie in the game: CCSprite background = CCSprite. spriteWithFi Le ("scene"); // set the anchor point to (). The default anchor point for reading a single image is (0.5f, 0.5f. anchorPoint = new CCPoint (0, 0); // Add the background to the scene. this. addChild (background); // L2 // obtain the width of the current window var w = CCDirector. shareddire (). getWinSize (). width/4; // get the height and offset 80 pixels var h = (CCDirector. shareddire (). getWinSize (). height-80)/3; // declare a CCMenuItemSprite array Mole [] moles = new Mole [4*3]; for (int I = 0; I <4; I ++) {for (int j = 0; j <3; j ++) {// create a menu (button) for the hamster, and arrange Mole mole = new Mole (this, onClick) in 4*3; mole. position = new CCPoint (I * w + w/2, j * h + h/2); moles [j * 4 + I] = mole;} _ molelist. addRange (moles); // create CCMenu var menus = CCMenu. menuWithItems (moles); // the default position of the menu item is in the middle of the parent node container, so move them to menus at 0 and 0. position = new CCPoint (0, 0); this. addChild (menus); // L3 // display a text section label_Score = CCLabelTTF. labelWithString ("0", "Arial", 24); label_Score.Color = new ccColor3B (255, 0, 0); label_Score.anchorPoint = new CCPoint (1, 0.5f); this. addChild (label_Score); label_Score.position = new CCPoint (CCDirector. shareddire (). getWinSize (). width-24, CCDirector. shareddire (). getWinSize (). height-24); beginTimeSpan (2); return base. init ();} void beginTimeSpan (float second) {// The cyclic callback with the specified latency, which is used to solve the logic CCDelayTime d of the mole that will be drilled out during each period of time ElayTime = CCDelayTime. actionWithDuration (second); var action = CCSequence. actionOneTwo (delayTime, CCCallFunc. actionWithTarget (this, loopCallback); this. runAction (action);} // score int _ valuescore = 0; // The score attribute, and refresh the displayed text int valueScore {get {return _ valuescore ;} set {_ valuescore = value; label_Score.setString (value. toString () ;}}// the callback public void onClick (CCObject sender) {// score + 1 valueScore + = 1; if (sender as Mole ). isShow) {(sender as Mole ). hide (); // play the cracked sound SimpleAudioEngine. sharedEngine (). playEffect (CCFileUtils. fullPathFromRelativePath ("Sounds/sound43") ;}}// method of loop back call public void loopCallback () {// here, the moles are getting faster and faster through simple calculations. float sub = 1-(float) valueScore/20366f; if (sub <= 0) sub = 0; beginTimeSpan (0.5f + sub); SetAllMoleDelaySecond (1.0f + sub); var t = getRandomMole (); if (t! = Null) t. show () ;}// get a random mouse private Mole getRandomMole () {for (int I = 0; I <_ molelist. count; I ++) {Mole t = _ molelist [_ randome. next () % _ molelist. count]; _ molelist. remove (t); _ molelist. add (t);} foreach (var item in _ molelist) {if (item. isShow = false) return item;} return null;} // reset the delay time for all the hamster to drill back. private void SetAllMoleDelaySecond (float second) {foreach (var item in _ molelist) {item. delaySecond = second ;}}}}
A good game requires careful scrutiny. In this example, the logic is simply implemented. The specific rules can be changed according to your own needs. I wish you an unlimited experience on the road to game development.
We recommend WindowsPhone and Silverlight game development blog: dark blue right hand