Make a simple windows phone 7 game with cocos2d-x: Rotate turret (2) make a simple windows phone 7 game with cocos2d-x: more monsters and more levels (3)

Source: Internet
Author: User
Tags sin cos

This tutorial is based on the Child Dragon Mountain Man translation cocos2d IPHONE tutorial, rewrite with cocos2d-x for XNA engine, plus some of my processing and production. In the tutorial, most of the text images are from the original author and the author of the translation, Long Shan, and many others are my own understandings and processing. I would like to thank the original author for his tutorial and the translation of Zilong shangren. This tutorial is only for learning and communication purposes. Do not conduct commercial communications.

Iphone tutorial address: http://www.cnblogs.com/andyque/articles/1997820.html

Iphone tutorial original address: http://www.raywenderlich.com/692/rotating-turrets

 

Rotate the turret to change the shooting direction. Many games have this function,

 

In this tutorial, we will explain in detail how to implement this function, that is, how to add the turret rotation function to a game.

Preparations

If you have read and practiced the previous tutorial, you can continue to use the project. If not, download the code of this link.

Next, download the new player sprite and projectile sprite images and add them to the images directory of the Content project. And modify the original genie initialization code.

// In the init methodCCSprite player = CCSprite.spriteWithFile(@"images/player2");// In the ccTouchesEnded methodCCSprite projectile = CCSprite.spriteWithFile(@"images/Projectile2");

 

Compile and run your project. If everything goes well, you will see a turret launching bullets. Then, this is not very good, because the turret did not face that direction when shooting. Therefore, let's solve this problem.

 

 

 

Rotate and fire

 

Before rotating the turret, we first need to save the reference of the Player genie for use when rotating it later. Put the Player genie declaration in the class:

CCSprite player;


Modify the code in init:

player = CCSprite.spriteWithFile(@"images/player2");

 

Now, let's retrieve the reference of the player Object and rotate it! To rotate it, we need to calculate the Rotation Angle first. To solve this problem, think about the triangular algebra we learned in high school. Do you still remember sin cos tan? For ease of understanding, the following figure is used to explain: tan = opposite/adjacent edge.

 

 

As shown above, we want to rotate the angle of arctangent (angle), that is, evaluate the arctangent operation for offY/offX.

However, there are two more things to consider. First, when we calculate actangent (offY/offX), the result is a radian, but cocos2d uses an angle. Fortunately, cocosd2d provides a very convenient macro that facilitates conversion between angle and radians.

Second, we assume that the angle Deflection in the preceding figure is positive 20 degrees, but the clockwise direction in cocos2d is positive (rather than the clockwise direction shown in the figure ). Let's see the figure below:

 

 

 

Therefore, in order to get the correct direction, we can multiply the calculation result by A-1. For example, if we multiply the angle in the above image by-1, we have to get-20 degrees, which is actually 20 degrees in the clockwise direction. (I feel that foreigners are talking so well. I am afraid some smart readers have understood it for a long time! :)

Okay, I have talked enough about it! Let's write some code. Add the following code in ccTouchesEnded to add the position before your projectile runAction.

            //Determine angle to face            float angleRadians = (float)Math.Atan(offRealY / offRealX);            float angleDegrees = MathHelper.ToDegrees(angleRadians);            float cocosAngle = -1 * angleDegrees;            player.rotation = cocosAngle;

 

 

Compile and run the project. Now our turret can change its direction when shooting.

Rotate before shooting

It's not bad at the moment, but it's a bit strange. It seems that the turret suddenly jumps to a certain direction and is not smooth enough. We can solve this problem, but before that, we need to refactor the code.

First, open the GamePlayLayer class and add the following member variables to your class:

CCSprite nextProjectile = null;

Then, modify your ccTouchesEnded method and add a new method called finishShoot, as shown below:

        public override void ccTouchesEnded(List<CCTouch> touches, CCEvent event_)        {            if (nextProjectile != null)                return;            CCTouch touch = touches.FirstOrDefault();            CCPoint location = touch.locationInView(touch.view());            location = CCDirector.sharedDirector().convertToGL(location);            //set up initial location of projectile            CCSize winSize = CCDirector.sharedDirector().getWinSize();            //CCSprite projectile = CCSprite.spriteWithFile(@"images/Projectile");            nextProjectile = CCSprite.spriteWithFile(@"images/Projectile2");            nextProjectile.position = new CCPoint(20, winSize.height / 2);            //Determine offset of location to projectile            float offX = location.x - nextProjectile.position.x;            float offY = location.y - nextProjectile.position.y;            //Bail out if we are shooting or backwards            if (offX <= 0)            {                return;            }            //Determine where we wish to shoot the projectile to            float realX = winSize.width + nextProjectile.contentSize.width / 2;            float ratio = offY / offX;            float realY = realX * ratio + nextProjectile.position.y;            CCPoint realDest = new CCPoint(realX, realY);            //Determine the length of how far we're shooting            float offRealX = realX - nextProjectile.position.x;            float offRealY = realY - nextProjectile.position.y;            float length = (float)Math.Sqrt(offRealX * offRealX + offRealY * offRealY);            float velocity = 480 / 1;//480pixls/lsec            float realMoveDuration = length / velocity;            //Determine angle to face            float angleRadians = (float)Math.Atan(offRealY / offRealX);            float angleDegrees = MathHelper.ToDegrees(angleRadians);            float cocosAngle = -1 * angleDegrees;            float rotateSpeed = (float)(0.5 / Math.PI);//Would take 0.5 seconds to rotate 0.5 radians ,or half a circle            float rotateDuration = Math.Abs(angleRadians * rotateSpeed);            player.runAction(CCSequence.actions(CCRotateTo.actionWithDuration(rotateDuration,cocosAngle), CCCallFunc.actionWithTarget(this, finishShoot)));            //Move projectile to actual endpoint            nextProjectile.runAction(CCSequence.actions(CCMoveTo.actionWithDuration(realMoveDuration, realDest),                CCCallFuncN.actionWithTarget(this,spriteMoveFinished)));            nextProjectile.tag = 2;                        //SimpleAudioEngine.sharedEngine().playEffect(@"resource/pew-pew-lei");        }        void finishShoot()        {             // Ok to add now , we are finished rotation            this.addChild(nextProjectile);            _projectiles.Add(nextProjectile);            nextProjectile = null;        }

It seems that there are a lot of code, but in fact we have not changed much-most of them just do some small refactoring. The following is a list of modified content:

1. Check whether the value of nextProjectile is nil at the beginning of the function. This means that our current touch event is happening in the shooting process. That is to say, the turret has shot a bullet.

2. Previously, we used a projectile local variable and added it to the current scenario. In this version, we added a member variable of nextProjectile, but it was not immediately added to the current scenario. Because it will be used later.

3. Define the turret Rotation Angle and rotate half a circle in half a second. Remember, a circle has 2 PI radians.

4. How long does it take to calculate the Specific Rotation Angle? Here we multiply the radians by the speed.

5. Next, we will use a sequence action to rotate our turret. Finally, call a function to add projectile to the current scenario.

Okay, you're done! Compile and run the project. Now the turret can be rotated and shot smoothly!

 

Download this project: http://dl.dbank.com/c0cvo9f1gc

Learn more: make a simple windows phone 7 game with cocos2d-x: more monsters and more levels (3)

 

Related Article

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.