用cocos2d-x做一个简单的windows phone 7游戏(一)

 

本教程基于子龙山人翻译的cocos2d的IPHONE教程,用cocos2d-x for XNA引擎重写,加上我一些加工制作。教程中大多数文字图片都是原作者和翻译作者子龙山人,还有不少是我自己的理解和加工。感谢原作者的教程和子龙山人的翻译。本教程仅供学习交流之用,切勿进行商业传播。

子龙山人翻译的Iphone教程地址:http://www.cnblogs.com/andyque/archive/2011/03/22/1990716.html

Iphone教程原文地址:http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial

游戏截图:

 

 

cocos2d-x for XNA 是在今年2月17号发布的开源引擎,原来这个引擎就有好几个平台的。是一个跨平台的开源引擎。现在很多公司都基于这个引擎来开发游戏。详细可以到http://cn.cocos2d-x.org/了解。它可以为你开发window phone上面的游戏节省大量的时间。目前支持精灵(sprite)、动画、物理引擎、声音引擎以及许许多多非常酷的图像效果等等。

我也是刚开始学这个引擎,我觉得一个非常简单,但是可以跑起来的游戏。这个游戏包括怎么使用动画、碰撞检测和播放声音,这就够了,并不需要使用太多高级的特性。这样的游戏会对初学者有帮助。

有人会说为什么要用引擎了。原来XNA就能制作游戏,我也尝试过,但是对于精灵的管理,碰撞的实现,动作的实现,原来的XNA就没那么方便快捷的实现了。有了引擎,很多就不用自己去实现,做起来就快了。

 

这篇教程将会从头至尾、一步一步地教你如何使用cocos2d-x来制作一个简单的WP7游戏。你可以按照教程一步步来,或者干脆直接跳到文章的最后,下载样例程序。没错!游戏里面有忍者。

 

 

下载并安装cocos2d-x:

确认安装了WP7 SDK。

http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Download下载FOR WP7,XNA版本,然后,解压安装。这个不用多说。

Hello, Cocos2D-X!

让我们从最简单的HelloWorld项目开始吧!启动VS2010。新建项目

 

 

命名为cocos2dHelloWorld。确定。然后有这么一个弹窗:

 

 

这个是openlive提供的一个插件,使游戏可以获取到排名积分等东西。这里我们不需要。去掉那个勾。然后点击OK。这样,项目就算是建好了。游戏的结构不多说。里面包含了两个项目,熟悉XNA游戏的应该了解。不熟悉的这里也不多说,慢慢的会了解的。

点击运行,发现了很多错误,因为cocos2d的库文件没有找到。

在cocos2dHelloWorld工程上右键--添加---新建文件夹。命名为lib。然后到安装包下找到这四个文件夹下的bin目录下的对应文件名的DLL。

 

 

添加到项目的lib目录下:

然后到把引用里面的带叹号的移除,并且添加当前工程目录的DLL。

 

 

 

对下面的Content项目也做同样的操作。

然后点击运行。

 

运行成功!。

cocos2d-x是按照“场景”(scene)的概念组织的,对一个游戏来说,就好像某个关卡或者屏幕之类的。比如,你可能需要一个场景来为你的游戏建立初使化菜单界面,另外一个场景当作玩游戏的主要界面,还有一个游戏结束的时候的界面。在一个场景里面,你可以有许多“层”(layer)(这个和photoshop有点类似)。每一个层又可以包含一些结点,比如精灵、标签、菜单等。而且一个结点也可以包含其它的结点。(比如,一个精灵可以包含一个子精灵),如果你看一下样例工程,你会看到只有一个场景HelloWorldScene

现在,把解决方案和项目的名字分别改成cocos2dSimpleGame,cocos2dSimpleGame,cocos2dSimpleGameContent。

 

新建一个场景。并且添加一个层。

在cocos2dSimpleGame工程的classes目录上右键--添加---新建项。添加一个类。命名为GamePlayScreen.cs。

 

修改代码为:
namespace cocos2dSimpleGame.Classes
{
    class GamePlayScene:CCScene
    {
        public override void onEnter()
        {
            base.onEnter();
            CCLayerColor colorLayer = CCLayerColor.layerWithColor(new ccColor4B(255, 255, 255, 255));//新建一个白色的颜色层,作为背景
            this.addChild(colorLayer);
            this.addChild(GamePlayLayer.node());
        }
    }
    class GamePlayLayer:CCLayer
    {
     public override bool init()
        {
   
            if (!base.init())
            {
                return false; 
            }
        return true;
    }
    public static new CCLayer node()
        {
            GamePlayLayer screen = new GamePlayLayer();
            if (screen.init())
            {
                return screen;
            }
            else
            {
                screen = null;
            }
            return screen;
        }
     }
}

上面的操作,新建了一个场景,在场景进入的时候,新建了一个白色层当中背景,并且把游戏层添加进去。游戏层中什么操作也没有做。

下面的操作,我们需要一些图片。http://dl.dbank.com/c0l9kbdian
把图片全部添加到Content项目的Images文件夹中。
我觉得还是先需要一个菜单。那么先新建一个菜单类吧。新建一个类命名为MainMenu.cs。并且使MainMenu这个类继承于CCLayer.
在MainMenu类中重载init方法。并且在里面实现背景,Title,菜单的添加。并且在下面实现菜单功能的实现。
具体代码如下:
public override bool init()
        {

            if (!base.init())
            {
                return false;
            }

            CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.CCDeviceOrientationLandscapeLeft;

            this.m_bIsTouchEnabled = true;//添加触摸
            var width = CCDirector.sharedDirector().getWinSize().width;
            var height = CCDirector.sharedDirector().getWinSize().height;

            CCSprite background = CCSprite.spriteWithFile(@"images/sprites");//加入一个背景
            background.position = new CCPoint(width / 2, height / 2);
            this.addChild(background);

            CCLabelTTF title = CCLabelTTF.labelWithString("Simple Game", "Arial", 24);
            title.Color = new ccColor3B(0, 255, 255);
            title.position = new CCPoint(width / 2, height - 50);
            this.addChild(title);
            //添加菜单。。。
            CCMenuItemImage playItem = CCMenuItemImage.itemFromNormalImage(@"images/playButton", @"images/playButton", this, playCallback);
            CCMenuItemImage aboutItem = CCMenuItemImage.itemFromNormalImage(@"images/aboutButton", @"images/aboutbutton", this, aboutCallback);

            CCMenu mainMenu = CCMenu.menuWithItems(playItem, aboutItem);
            mainMenu.alignItemsVerticallyWithPadding(15f);
            mainMenu.position = new CCPoint(width / 2, height-150);
            this.addChild(mainMenu);

            CCMenuItemImage exitItem = CCMenuItemImage.itemFromNormalImage(@"CloseSelected", @"CloseSelected", this, exitCallback);
            CCMenu exitMenu = CCMenu.menuWithItems(exitItem);
            exitMenu.position = new CCPoint(width - exitItem.contentSize.width / 2, exitItem.contentSize.height / 2);
            this.addChild(exitMenu);


            return true;
        }

        public static new CCLayer node()
        {
            MainMenu ret = new MainMenu();
            if (ret.init())
            {
                return ret;
            }
            else
            {
                ret = null;
            }

            return ret;
        }

        void playCallback(object sender)
        {
            GamePlayScene pScene = new GamePlayScene();
            CCDirector.sharedDirector().pushScene(pScene);
        }

        void aboutCallback(object sender)
        { 
            
        }

        void exitCallback(object sender)
        {
            CCDirector.sharedDirector().end();
            CCApplication.sharedApplication().Game.Exit();
        }

 


注意:在cocos2d,坐标是左下角为(0,0)。右上角为最大。并且精灵等元素的Position都是其中心点。并不是常规的左上角或者其他。

接着修改AppDelegate.cs。看到这类的Launching。在return之前的修改为:
//CCScene pScene = cocos2dSimpleGameScene.scene();
            CCScene pScene = CCScene.node();
            pScene.addChild(cocos2dSimpleGame.Classes.MainMenu.node());

            //run
            pDirector.runWithScene(pScene);

现在,运行后点击Play,就能看到一片白色背景,毕竟我们也没有添加任何东西进去。接下来,添加一个忍者到GameplayLayer。

在GamePlayLayer的init函数return前添加:
            CCDirector.sharedDirector().deviceOrientation = ccDeviceOrientation.CCDeviceOrientationLandscapeLeft;
            this.m_bIsTouchEnabled = true;
            var screenWidth = CCDirector.sharedDirector().getWinSize().width;
            var screenHeight = CCDirector.sharedDirector().getWinSize().height;

            
            CCSprite player = CCSprite.spriteWithFile(@"images/player");
            player.position = new CCPoint(player.contentSize.width/2, screenHeight/2);
            this.addChild(player);

编译运行,点击Play,这样忍者就能在白色背景上了。


移动目标

  接下来,我们想增加一些目标怪物来与我们的忍者战斗。为了使事情变得更加有趣,我想让这些目标可以移动--实际上这也并不是很难!因此,让我们先在屏幕的右边靠外一点点创建一些目标,然后设置一个action,并使之从右边移动到左边。

接下来,添加一个函数,:
private void addTarget()
        {
            Random random = new Random();
            var screenWidth = CCDirector.sharedDirector().getWinSize().width;
            var screenHeight = CCDirector.sharedDirector().getWinSize().height;
            CCSprite target = CCSprite.spriteWithFile(@"images/Target");
            var minY = target.contentSize.height / 2;
            var maxY = screenHeight - target.contentSize.height / 2;
            float rangeY = maxY - minY;
            float actualY = (random.Next() % rangeY) + minY;

            //create the target slightly off-screen along the right edge;
            //and along a random position along the Y axis as calculated above
            target.position = new CCPoint(screenWidth + screenWidth / 2, actualY);
            this.addChild(target);

            //Determine speed of the target
            float minDuration = 2.0f;
            float maxDuration = 4.0f;
            float rangeDuration = maxDuration - minDuration;
            float actualDuration = random.Next() % rangeDuration + minDuration;

            //Create the actions
            var actionMove = CCMoveTo.actionWithDuration(actualDuration, new CCPoint(-target.contentSize.width / 2, actualY));
            var actionMoveDone = CCCallFuncN.actionWithTarget(this, spriteMoveFinished);
            target.runAction(CCSequence.actions(actionMove, actionMoveDone));

        }

  在这里我将以一种非常啰嗦的形式来介绍,目的是方便大家理解。第一部分需要解释的是我们之前已经讨论过了的:我们做一些简单的计算来决定把对象放在什么位置,然后设置对象的position,然后并把它加在场景上面,就和加载player精灵一样。

  这里增加的新的元素就是actions。cocos2d里面提供了许多非常方便的内置的action,你可以使用这样action来让你的精灵动起来。比如move action,jump action,fade action,animation action(就是播放图片序列)等等。这里,我们对目标对象使用了3种类型的action:

  • CCMoveTo:我们使用CCMoveTo action让目标从屏幕右边一直往左移动,直到移出屏幕。注意,这里我们可以指定这个过程要花费多长时间。这里使用了变化的时间间隔2-4秒。
  • CCCallFuncN:它可以让你为某个执行此action的对象指定一个回调函数。我们指定的回调函数是:spriteMoveFinished---目前并没有,到后面会具体给了来。
  • CCSequence: 它允许我们把一系列的action组成一个action序列,并且这些acton可以按顺序执行。一次执行完所有的action。在上面的例子中,我们让对象首先执行CcMoveTo,等CCMoveTo完成后,马上就会执行CCCallFuncN action。

接下来, 为CCCallFuncN action增加一个回调函数。你可以在addTarget前面增加下面的代码:

void spriteMoveFinished(object sender)
        {
            CCSprite sprite = (CCSprite)sender;
            this.removeChild(sprite, true);
        }

这个函数的目的是当精灵飞出屏幕之后,需要移除出当前的scene。这个非常重要,这样的话我们就不会因为屏幕外面积累太多没有用到的精灵而造成内存泄漏。注意,其实还有其它更好的方式来解决这个问题,比如使用一组可以重用的精灵等。不过,对于初学者来说,我在这篇教程里,尽量简单化。

  在我们继续之前,还有最后一件事没做。我们需要调用这个方法来创建我们的目标怪物。而且,为了使事情变得更加有趣,我们会随着时间连续不断地发射一些怪物出来。我们可以使用cocos2d的定时scheduler,并指定一个回调函数来完成此功能。一秒钟调用一次回调函数就可以了。因此,在init函数返回之前,我们再加入下面的代码:

this.schedule(gameLogic, 1.0f);

然后简单的实现一下这个回调函数,如下:


        void gameLogic(float dt)
        {
            this.addTarget();
        }

 


编译运行,并且play,你可以看到怪物在屏幕上面happy地移动了!

发射飞盘

  在这里,我们的忍者需要有一些行动了--因此让我们增加一些射击吧!这里有许许多多实现射击的方式,但是在这个游戏里面,我们想让用户触摸一下屏幕,然后飞盘就会从player开始,沿着你触摸的位置发射出来。

  我们使用CCMoveTo action来实现这个功能。但是,为了使用这个功能,我们必须首先来做一些数学题。这是因为,CCMoveTo需要我们为飞盘指定目的地。但是我们又不能使用触摸点,因为触摸点仅仅代表飞盘飞的方向。我们实际上想让子弹超过触摸点,然后飞出屏幕之外去。

  下面这张图解释了这个问题:

因此,就像你看到的,在触摸点和player之间有一个小的三角形,由origin点,offx和offy组成。我们只需要画一个更大的三角形,同时使用一样的比率就行了。然后我们就可以根据比例算出飞盘飞出屏幕的位置。
这里,我们实现ccTouchesEnded方法,这是在用户完成一次touch之后调用的,代码如下:
public override void ccTouchesEnded(List<CCTouch> touches, CCEvent event_)
        {
            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");
            projectile.position = new CCPoint(20, winSize.height / 2);

            //Determine offset of location to projectile

            float offX = location.x - projectile.position.x;
            float offY = location.y - projectile.position.y;

            //Bail out if we are shooting or backwards
            if (offX <= 0)
            {
                return;
            }

            //Ok to add now - we're double checked position
            this.addChild(projectile);

            //Determine where we wish to shoot the projectile to
            float realX = winSize.width + projectile.contentSize.width / 2;
            float ratio = offY / offX;
            float realY = realX * ratio + projectile.position.y;
            CCPoint realDest = new CCPoint(realX, realY);

            //Determine the length of how far we're shooting
            float offRealX = realX - projectile.position.x;
            float offRealY = realY - projectile.position.y;
            float length = (float)Math.Sqrt(offRealX * offRealX + offRealY * offRealY);
            float velocity = 480 / 1;//480pixls/lsec
            float realMoveDuration = length / velocity;

            //Move projectile to actual endpoint
            projectile.runAction(CCSequence.actions(CCMoveTo.actionWithDuration(realMoveDuration,realDest),
                CCCallFuncN.actionWithTarget(this,spriteMoveFinished)));

            
        }

 

在第一部分,我们选择一个touch来处理,获得它在当前view中的位置,然后调用convertToGL把坐标转换成我们当前层的坐标系中去。这个非常重要,因为我们使用的是landscape模式。

  接下来,我们加载飞盘精灵并且设置它的初始位置。然后,我们计算出它需要飞往何处,使用player和touch之间的向量并且根据前面描述的算法计算出来。

  注意,这个算法并不完美。我们强迫子弹飞出屏幕x轴的外边--即使在它已经飞出屏幕y轴的外边界了。这里有许多方向来解决这个问题,比如检查飞出屏幕的最短距离,或者使用一个游戏回调函数来检查一个飞盘是否飞出,飞出就移出场景。但是,在这里,我们尽量保持简单。

  最后一件事情就是,决定飞盘移动的时间。我们想让子弹以常量速度飞行,不管飞行方向如何。因此,我们不得不再做一点点数学。我们能够使用 Pythagorean Theorem来计算我们移动了多久。记得几何学中,三角形的斜边=两个直角边的平方和再开根号。

  一旦我们得到了距离,我们就可以通过除了速度来得到时间。因为速度=距离/时间。换句话说 时间=距离/速度。

  余下的部分就和设置我们target一样了。编译并运行,现在忍者可以射击侵犯的敌人了!

碰撞检测

  现在,我们可以看到飞镖到处乱飞了!但是,我们的忍者真正想做的,是能够放倒一些怪物。好吧,让我们增加一些代码来检测什么时候我们的飞镖与怪物相撞了。

  在cocos2d里面,有许多方法可以解决这个问题,包括使用cocos2d内置的开源物理引擎box2d和chipmunk。然而,为了使事情变得简单一点,在这里我们自己实现了一个简单的碰撞检测。

  为了实现这个,我们首先需要当前场景中存在的飞镖和怪物。在GamePlayLayer类里面增加下面的声明:

        List<CCSprite> _targets;
        List<CCSprite> _projectiles;

 


并且在init函数上初始化两个List.

            _projectiles = new List<CCSprite>();
            _targets = new List<CCSprite>();

 


现在,我们修改addTarget方法,可以在把target添加到层之前,把一个新的target加到targets数组里面,并且为这个target设置一个tag,以便将来使用:

            target.tag = 1;
            _targets.Add(target);

 


然后,修改ccTouchesEnded方法,同样的,把新增加的projectile加到projectiles数组里面,并为之设置一个tag供后面使用:

            projectile.tag = 2;
            _projectiles.Add(projectile);

 

最后,修改你的spriteMoveFinished方法,基于tag标签来从正确的数组中移除相应的sprite。

            if (sprite.tag == 1)//target
            {
                _targets.Remove(sprite);
            }
            else if (sprite.tag == 2)//projectile
            {
                _projectiles.Remove(sprite);
            }

  编译并运行程序,确保一切都ok。目前来说,应该没有什么可见的差别。但是,接下来我们就会去实现真正的碰撞检测了。

  现在,在GamePlayLayer里面增加如下方法:

public void updates(float dt)
        {
            List<CCSprite> projectilesToDelete = new List<CCSprite>();
            List<CCSprite> targetToDelete = new List<CCSprite>();
            //foreach (CCSprite projectile in _projectiles)
            for (int i = 0; i < _projectiles.Count; i++)
            {
                CCSprite projectile = _projectiles[i];
                CCRect projectileRect = new CCRect(projectile.position.x - projectile.contentSize.width / 2,
                    projectile.position.y - projectile.contentSize.height / 2,
                    projectile.contentSize.width, projectile.contentSize.height);
                
                foreach (CCSprite target in _targets)
                {
                    CCRect targetRect = new CCRect(target.position.x - target.contentSize.width / 2,
                        target.position.y - target.contentSize.height / 2,
                        target.contentSize.width,
                        target.contentSize.height);
                    if (CCRect.CCRectIntersetsRect(projectileRect,targetRect))
                    {
                        targetToDelete.Add(target);
                    }
                }
                foreach (CCSprite target in targetToDelete)
                {
                    _targets.Remove(target);
                    this.removeChild(target, true);
                }
                if (targetToDelete.Count > 0)
                {
                    projectilesToDelete.Add(projectile);
                }
                targetToDelete.Clear();
            }
            foreach (CCSprite projectile in projectilesToDelete)
            {
                _projectiles.Remove(projectile);
                this.removeChild(projectile, true);
            }
            projectilesToDelete.Clear();
        }

上面的代码应该非常清楚。我们仅仅通过遍历projectiles和targets数组,为每个projectile和target创建边界矩形,然后使用CGRectIntersectsRect来检测碰撞。如果发现有碰撞了,我们就从场景中移除精灵,同时也把它移除出数组。注意,我们不得不添加一个toDelete数组,因为我们不能在遍历一个数组的时候去删除数组中的对象。当然,还有许多方式可以实现类似的逻辑,我只不过挑选了简单的方法。

  在你真正完成之前,还差最后一件事情。在你的init方法里面调用下面的函数:

this.schedule(updates);

编译并运行,现在,当你的飞镖和怪物相碰的时候,他们都会消失啦!

我们离制作一个可以玩的游戏(但是非常简单)的目标已经越来越近了。我们仅仅需要增加一些音效和背景音乐(试想哪个游戏没有声音呢!),再增加一点点简单的逻辑就更好了。cocos2d-x for xna 支持的音效文件为MP3和WMV。并且音效只支持WMV。背景音支持MP3(或许支持WMV,我没测试过).

现在,先在Content工程新建一个文件夹命名为resource,添加一些音效文件到resource文件夹吧。背景音MP3自己找,命名为backgroundmusic.mp3.音效文件自己找或者到这里下载http://dl.dbank.com/c0yuasxubb

现在先在cocos2dSimpleGame工程上添加lib目录里面的CocosDenshion.dll引用。
然后在GameplayScreen.cs里面添加using CocosDenshion;
在你的init方法里加载背景音乐: 
SimpleAudioEngine.sharedEngine().playBackgroundMusic(@"resource/backgroundmusic");

然后,在你的ccTouchesEnded方法里面添加音效代码:

SimpleAudioEngine.sharedEngine().playEffect(@"resource/pew-pew-lei");

在,让我们创建一个新的场景,来作为“You Win”或者“You Lose”的标志。右击Classes文件夹,添加一个新的类,命名为GameOverScene.cs,这次,我们直接在场景上添加相关信息。代码如下;

namespace cocos2dSimpleGame.Classes
{
    class GameOverScene:CCScene
    {
        public CCLabelTTF label;
        public GameOverScene()
        {
 
        }
        public GameOverScene(string msg)
        {
            CCLayerColor colorLayer = CCLayerColor.layerWithColor(new ccColor4B(255, 255, 255, 255));
            this.addChild(colorLayer);
            CCSize winSize = CCDirector.sharedDirector().getWinSize();
            label = CCLabelTTF.labelWithString(msg, "Arial", 32);
            label.Color = new ccColor3B(0, 0, 0);
            label.position = new CCPoint(winSize.width / 2, winSize.height / 2);
            this.addChild(label);
            this.runAction(CCSequence.actions(CCDelayTime.actionWithDuration(3), CCCallFunc.actionWithTarget(this, gameOverDone)));
        }
        void gameOverDone()
        {
            CCScene pScene = CCScene.node();
            pScene.addChild(cocos2dSimpleGame.Classes.MainMenu.node());
            CCDirector.sharedDirector().replaceScene(pScene);
        }

    }
}

注意,这里只是在屏幕的中间放置了一个label,然后运行了一个action。这个action的作用就是,等待3秒钟,然后调用一个回调函数切换回HelloWorld场景。最后,让我们增加一些基本的游戏逻辑。首先,让我们来追踪player销毁的飞镖projectiles。接下来,在GamePlayLayer类里面增加两个成员变量,如下所示:

  int projectilesDestroyed = 0;
        int quitProjectiles = 0;

在update方法里,增加(销毁的projectile)计数,同时检测游戏胜利的条件。并在targetsToDelete循环里,紧接着_targets.Remove(target);的地方添加如下代码:


                    projectilesDestroyed++;
                    label.setString("Count:" + projectilesDestroyed.ToString());
                    if (projectilesDestroyed > 30)
                    {
                        GameOverScene pScene = new GameOverScene("YOU WIN");
                        //pScene.label.setString();
                        CCDirector.sharedDirector().replaceScene(pScene);
                    }

最后,让我们这样设计,只要有10个怪物(原来教程的1个真心容易挂)穿过了屏幕左边,你就输了。修改spriteMoveFinished方法,通过在tag==1里面_targets.Remove(sprite);后面添加下面的代码:

quitProjectiles++;
                if (quitProjectiles > 10)
                {
                    GameOverScene pScene = new GameOverScene("YOU LOSE");
                    //pScene.label.setString();
                    CCDirector.sharedDirector().replaceScene(pScene);
                }

继续,编译并运行程序。现在,你的游戏可以实现胜利或者失败的场景了!接下来,我们来添加一个about场景。添加一个新的类,命名为AboutScene.cs,并且使之继承于CCScene。

具体代码如下。也就添加了一个label。
    class AboutScene:CCScene
    {
        public AboutScene()
        {
            CCLayerColor colorLayer = CCLayerColor.layerWithColor(new ccColor4B(255, 255, 255, 255));
            this.addChild(colorLayer);
            string msg = "此程序由fengyun1989基于子龙山人翻译\r\n的IPHONE教程制作,仅供学习交流之用,\r\n切勿进行商业传播。如有什么意见或者建议,\r\n请发邮件到1024919409@qq.com!";
            CCLabelTTF label = CCLabelTTF.labelWithString(msg, "yaheiFont", 24);
            CCSize winSize = CCDirector.sharedDirector().getWinSize();
            label.position = new CCPoint(winSize.width / 2, winSize.height/2 - 40);       
            this.addChild(label);
        }

    }

 


这里有一个问题,就是中文支持的问题。具体操作可以看我转载的文章。里面有详细的操作。按照里面的操作就能完成中文的支持了。《转载》让cocos2d-x for WP7添加中文支持

另外,修改MainMenu的AboutCallBack。
        void aboutCallback(object sender)
        {
            AboutScene pScene = new AboutScene();
            CCDirector.sharedDirector().replaceScene(pScene);
        }

这样,拥有一个菜单,简单的游戏,关于提示窗口就完成了。

但是,如果玩下酒知道有问题,就是无论在哪个场景,只要按返回键,游戏就退出了。。。这样的设定很不友好,我玩游戏的时候想重新玩,还得重新进游戏,而不是按返回键退回到菜单。我这里就写了篇解决方法:http://blog.csdn.net/fengyun1989/article/details/7468699
那么来操作下吧。
打开Game1.cs,找到Update函数。在里面就能看到处理返回键的操作
因为我们这里有3个场景,分别是GamePlayScene,GameOverScene。AboutScene。
所以修改代码如下:
// Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                CCScene pScene = CCDirector.sharedDirector().runningScene;
                //Debug.WriteLine(pScene.GetType().ToString());
                string currentScene = pScene.GetType().ToString();
                if (currentScene == "cocos2dSimpleGame.Classes.GamePlayScene" || currentScene == "cocos2dSimpleGame.Classes.GameOverScene"
                    || currentScene == "cocos2dSimpleGame.Classes.AboutScene")
                {
                    CCScene mainMenu = CCScene.node();
                    mainMenu.addChild(cocos2dSimpleGame.Classes.MainMenu.node());
                    CCDirector.sharedDirector().replaceScene(mainMenu);
                }
                else
                    this.Exit();
            }

 


这样,一个不错的游戏就做好了。





工程代码下载:http://dl.dbank.com/c0kvl53qm8
继续学习:用cocos2d-x做一个简单的windows phone 7游戏:旋转炮塔(二)

posted on 2012-04-23 19:52  fengyun1989  阅读(1985)  评论(4编辑  收藏  举报