wp7使用Cocos2d-X for XNA制作一個(gè)塔防類游戲 (一)游戲基礎(chǔ)場(chǎng)景搭建
游戲基礎(chǔ)場(chǎng)景搭建
Loading,進(jìn)入主菜單然后再進(jìn)入選關(guān)界面最后進(jìn)入游戲,紅色箭頭的流程。
退出,Back鍵完成藍(lán)色箭頭的流程,最后完成退出。Demo源代碼下載

有LoadingScreen.cs,MainMenuScreen.cs,ChooseScreen.cs,GameScreen.cs四個(gè)場(chǎng)景類構(gòu)成,他們都繼承于CCScene。
游戲開(kāi)始進(jìn)入LoadingScreen在等待3秒后載入MainMenuScreen,點(diǎn)擊開(kāi)始游戲進(jìn)入選單場(chǎng)景ChooseScreen,關(guān)卡圖片可以滑動(dòng),點(diǎn)擊關(guān)卡圖標(biāo)進(jìn)入游戲主界面GameScreen.紅色箭頭流程。
響應(yīng)物理鍵back完成游戲的退出,當(dāng)在LoadingScreen和MainMenuScreen的時(shí)候Back鍵直接退出游戲,在GameScreen場(chǎng)景時(shí)back有退出提示,確定則退回上一場(chǎng)景。藍(lán)色箭頭
流程。
一、下載安裝我們的模板后,新建cocos2d-xna項(xiàng)目
1.打開(kāi)cocos2d-xna項(xiàng)目新建cocos2d-x工程。


2.清理沒(méi)有用的HelloCocos2D項(xiàng)目和Classes文件夾里的HelloWorldScene.cs,刪掉AATDDemoContent下所有的文件,讓整個(gè)項(xiàng)目干凈一點(diǎn)。
3.在Screen文件夾里添加LoadingScreen.cs,MainMenuScreen.cs,ChooseScreen.cs,GameScreen.cs,他們都繼承與CCScene。

二、實(shí)現(xiàn)LoadingScreen
LoadingScreen在顯示3秒Loading.jpg后跳轉(zhuǎn)到MainMenuScreen。
LoadingScreen只在每次游戲開(kāi)始時(shí)出現(xiàn)一次Back鍵無(wú)法回到改場(chǎng)景。
添加單例代碼如下:
View Code
private static LoadingScreen _current; public static LoadingScreen Current { get { GameMain.CurrentScreen = -1; if (_current == null) { _current = new LoadingScreen(); } return _current; } } CCDelayTime delayTime; private LoadingScreen() { }
在構(gòu)造函數(shù)LoadingScreen()中加入圖片Loading.jpg
View Code
CCSprite loadingImage = CCSprite.spriteWithFile("Images/Loading"); addChild(loadingImage); loadingImage.position = new CCPoint(400, 240);
現(xiàn)在要解決的一個(gè)問(wèn)題是讓這個(gè)場(chǎng)景停留3秒然后跳轉(zhuǎn)到下一個(gè)場(chǎng)景MainMenuScreen。
方法很多這里用到了CCDelayTime這個(gè)延時(shí)action,給他設(shè)置延時(shí)時(shí)間3秒,執(zhí)行這個(gè)action,在游戲更新循環(huán)中檢測(cè)它是否完成如果完成則跳轉(zhuǎn)場(chǎng)景。
delayTime = CCDelayTime.actionWithDuration(3); loadingImage.runAction(delayTime); sheduleUpdate();
sheduleUpdate();注冊(cè)了該CCScene的更新邏輯是update方法,重寫(xiě)update方法,處理跳轉(zhuǎn)邏輯
public override void update(float dt) { if (delayTime.isDone()) { CCDirector.sharedDirector().replaceScene(MainMenuScreen.Current); } }
MainMenuScreen也是一個(gè)單例實(shí)現(xiàn)方式和本類相同,恩恩ChooseScreen,GameScreen,也一樣都是單例。
三、MainMenuScreen
添加按鈕
private MainMenuScreen() { CCTexture2D menusImage = CCTextureCache.sharedTextureCache().addImage("Images/Menus"); CCSprite startSprite = CCSprite.spriteWithTexture(menusImage, new CCRect(0, 0, 250, 80)); CCSprite optionSprite = CCSprite.spriteWithTexture(menusImage, new CCRect(0, 80, 250, 80)); CCSprite aboutSprite = CCSprite.spriteWithTexture(menusImage, new CCRect(0, 160, 250, 80)); CCMenuItem startMenuItem = CCMenuItemImage.itemFromNormalSprite(startSprite, null, this, StartCallBack); CCMenuItem optionMenuItem = CCMenuItemImage.itemFromNormalSprite(optionSprite, null, this, OptionCallBack); CCMenuItem aboutMenuItem = CCMenuItemImage.itemFromNormalSprite(aboutSprite, null, this, AboutCallBack); CCMenu menus = CCMenu.menuWithItems(startMenuItem, optionMenuItem, aboutMenuItem); menus.alignItemsVerticallyWithPadding(20); menus.position = new CCPoint(400, 200); addChild(menus); }
menus.png是這樣的一張圖片

先把它保存到了一個(gè)CCTexture2D中,截取它的一部分來(lái)創(chuàng)建CCSprite,CCSprite.spriteWithTexture(menusImage, new CCRect(0, 80, 250, 80));
用CCSprite創(chuàng)建CCMenuItem,把CCMenu中的CCMenuItem豎向排列間距為20px,并放在相應(yīng)的位置。
在StartCallBack回調(diào)函數(shù)中跳轉(zhuǎn)場(chǎng)景到ChooseScreen
void StartCallBack(CCObject sender) { CCDirector.sharedDirector().replaceScene(ChooseScreen.Current); }
四、ChooseScreen
ChooseScreen是一個(gè)可滑動(dòng)的選擇菜單,而CCScene只是一個(gè)容器他是不能響應(yīng)touch事件的。
添加能響應(yīng)touch事件的CCLayer
private ChooseScreen() { this.addChild(new ChooseLayer()); }
在Screen文件夾地下再添加一個(gè)Layer文件夾來(lái)盛放所有的CCLayer。
添加5個(gè)按鈕CCMenuItem(按鈕是五個(gè)很帥的魔獸角色大法師,死亡騎士,劍圣,惡魔獵手和火法帝、他真的不是一個(gè)普通的血法師)
這五個(gè)角色(menus)被addChild到背景里了所以只要改變背景CCSprite的位置,按鈕的坐標(biāo)就相對(duì)的發(fā)生了改變。
View Code
CCSprite back; public ChooseLayer() { this.isTouchEnabled = true; CCSprite ico1 = CCSprite.spriteWithFile("images/warcraft1"); CCSprite ico2 = CCSprite.spriteWithFile("images/warcraft2"); CCSprite ico3 = CCSprite.spriteWithFile("images/warcraft3"); CCSprite ico4 = CCSprite.spriteWithFile("images/warcraft4"); CCSprite ico5 = CCSprite.spriteWithFile("images/warcraft5"); CCMenuItem menu1 = CCMenuItemSprite.itemFromNormalSprite(ico1, null, this, CallBack); CCMenuItem menu2 = CCMenuItemSprite.itemFromNormalSprite(ico2, null, this, CallBack); CCMenuItem menu3 = CCMenuItemSprite.itemFromNormalSprite(ico3, null, this, CallBack); CCMenuItem menu4 = CCMenuItemSprite.itemFromNormalSprite(ico4, null, this, CallBack); CCMenuItem menu5 = CCMenuItemSprite.itemFromNormalSprite(ico5, null, this, CallBack); CCMenu menus = CCMenu.menuWithItems(menu1, menu2, menu3, menu4, menu5); CCTexture2D texture = new CCTexture2D(); texture.PixelsWide = 2000; texture.PixelsHigh = 480; back = CCSprite.spriteWithTexture(texture); addChild(back); back.position = GameMath.ScreenCenter; back.addChild(menus); menus.position = new CCPoint(back.contentSize.width / 2, back.contentSize.height / 2); menus.alignItemsHorizontallyWithPadding(100); }
在Touch Moved中做位置處理,重寫(xiě)ccTouchesMoved方法
View Code
public override void ccTouchesMoved(List<CCTouch> touches, CCEvent event_) { if (touches.Count > 0) { var touch = touches.Single(); CCPoint touchLocation = touch.locationInView(touch.view()); CCPoint prevLocation = touch.previousLocationInView(touch.view()); touchLocation = CCDirector.sharedDirector().convertToGL(touchLocation); prevLocation = CCDirector.sharedDirector().convertToGL(prevLocation); CCPoint diff = new CCPoint(touchLocation.x - prevLocation.x, touchLocation.y - prevLocation.y); CCPoint currentPos = back.position; if (currentPos.x + diff.x < 800 && currentPos.x + diff.x > 0) { back.position = new CCPoint(currentPos.x + diff.x, 240); } } }
CallBack回調(diào)函數(shù)使場(chǎng)景跳轉(zhuǎn)到主游戲場(chǎng)景GameScreen。
五、GameScreen
GameScreen暫時(shí)只是打印出GameScreen而已
private GameScreen() { CCLabelTTF lb = CCLabelTTF.labelWithString("GameScreen", "Default", 1); lb.position = new CCPoint(400, 240); addChild(lb); }
這里的labelWithString第三個(gè)參數(shù)字體大小沒(méi)有發(fā)揮作用,需要修改自己的大小在.spritefont文件中修改Size節(jié)點(diǎn)。
六、Back鍵的處理
在Game1的構(gòu)造函數(shù)中可以清楚的看到Cocos2d-xna只是一個(gè)GameComponents。
CCApplication application = new AppDelegate(this, graphics); this.Components.Add(application);
Game1.cs還是那么重要有很多操作仍需在里面做的比如說(shuō)處理Back的邏輯,把背景填充為黑色。
View Code
protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) { switch (GameMain.CurrentScreen) { case -1: case 0: this.Exit(); break; case 1: CCDirector.sharedDirector().replaceScene(MainMenuScreen.Current); break; case 2: string msg = "Quit Game?"; List<string> MBButtons = new List<string>(); MBButtons.Add("Yes"); MBButtons.Add("No"); Guide.BeginShowMessageBox("Game Over", msg, MBButtons, 0, MessageBoxIcon.Alert, GetMBResult, null); break; default: this.Exit(); break; } } base.Update(gameTime); } void GetMBResult(IAsyncResult r) { int? b = Guide.EndShowMessageBox(r); if (b == 0) { CCDirector.sharedDirector().replaceScene(ChooseScreen.Current); } } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.Black); base.Draw(gameTime); }
GameMain.CurrentScreen這個(gè)靜態(tài)字段是為了處理back,標(biāo)記當(dāng)前場(chǎng)景的。
LoadingScreen:-1,MainMenuScreen:0,ChooseScreen:1,GameScreen:2
private static GameScreen _current; public static GameScreen Current { get { GameMain.CurrentScreen = 2; if (_current == null) { _current = new GameScreen(); } return _current; } }
其他類的GameMain.CurrentScreen賦值位置一樣。
語(yǔ)文不好小學(xué)開(kāi)始就不及格,有看不懂的地方加群:190784175


浙公網(wǎng)安備 33010602011771號(hào)