游戲基礎場景搭建
Loading,進入主菜單然后再進入選關界面最后進入游戲,紅色箭頭的流程。
退出,Back鍵完成藍色箭頭的流程,最后完成退出。Demo源代碼下載

有LoadingScreen.cs,MainMenuScreen.cs,ChooseScreen.cs,GameScreen.cs四個場景類構成,他們都繼承於CCScene。
游戲開始進入LoadingScreen在等待3秒后載入MainMenuScreen,點擊開始游戲進入選單場景ChooseScreen,關卡圖片可以滑動,點擊關卡圖標進入游戲主界面GameScreen.紅色箭頭流程。
響應物理鍵back完成游戲的退出,當在LoadingScreen和MainMenuScreen的時候Back鍵直接退出游戲,在GameScreen場景時back有退出提示,確定則退回上一場景。藍色箭頭
流程。
一、下載安裝我們的模板后,新建cocos2d-xna項目
1.打開cocos2d-xna項目新建cocos2d-x工程。


2.清理沒有用的HelloCocos2D項目和Classes文件夾里的HelloWorldScene.cs,刪掉AATDDemoContent下所有的文件,讓整個項目干凈一點。
3.在Screen文件夾里添加LoadingScreen.cs,MainMenuScreen.cs,ChooseScreen.cs,GameScreen.cs,他們都繼承與CCScene。

二、實現LoadingScreen
LoadingScreen在顯示3秒Loading.jpg后跳轉到MainMenuScreen。
LoadingScreen只在每次游戲開始時出現一次Back鍵無法回到改場景。
添加單例代碼如下:
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() { }
在構造函數LoadingScreen()中加入圖片Loading.jpg
View Code
CCSprite loadingImage = CCSprite.spriteWithFile("Images/Loading"); addChild(loadingImage); loadingImage.position = new CCPoint(400, 240);
現在要解決的一個問題是讓這個場景停留3秒然后跳轉到下一個場景MainMenuScreen。
方法很多這里用到了CCDelayTime這個延時action,給他設置延時時間3秒,執行這個action,在游戲更新循環中檢測它是否完成如果完成則跳轉場景。
delayTime = CCDelayTime.actionWithDuration(3); loadingImage.runAction(delayTime); sheduleUpdate();
sheduleUpdate();注冊了該CCScene的更新邏輯是update方法,重寫update方法,處理跳轉邏輯
public override void update(float dt) { if (delayTime.isDone()) { CCDirector.sharedDirector().replaceScene(MainMenuScreen.Current); } }
MainMenuScreen也是一個單例實現方式和本類相同,恩恩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是這樣的一張圖片

先把它保存到了一個CCTexture2D中,截取它的一部分來創建CCSprite,CCSprite.spriteWithTexture(menusImage, new CCRect(0, 80, 250, 80));
用CCSprite創建CCMenuItem,把CCMenu中的CCMenuItem豎向排列間距為20px,並放在相應的位置。
在StartCallBack回調函數中跳轉場景到ChooseScreen
void StartCallBack(CCObject sender) { CCDirector.sharedDirector().replaceScene(ChooseScreen.Current); }
四、ChooseScreen
ChooseScreen是一個可滑動的選擇菜單,而CCScene只是一個容器他是不能響應touch事件的。
添加能響應touch事件的CCLayer
private ChooseScreen() { this.addChild(new ChooseLayer()); }
在Screen文件夾地下再添加一個Layer文件夾來盛放所有的CCLayer。
添加5個按鈕CCMenuItem(按鈕是五個很帥的魔獸角色大法師,死亡騎士,劍聖,惡魔獵手和火法帝、他真的不是一個普通的血法師)
這五個角色(menus)被addChild到背景里了所以只要改變背景CCSprite的位置,按鈕的坐標就相對的發生了改變。
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中做位置處理,重寫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回調函數使場景跳轉到主游戲場景GameScreen。
五、GameScreen
GameScreen暫時只是打印出GameScreen而已
private GameScreen() { CCLabelTTF lb = CCLabelTTF.labelWithString("GameScreen", "Default", 1); lb.position = new CCPoint(400, 240); addChild(lb); }
這里的labelWithString第三個參數字體大小沒有發揮作用,需要修改自己的大小在.spritefont文件中修改Size節點。
六、Back鍵的處理
在Game1的構造函數中可以清楚的看到Cocos2d-xna只是一個GameComponents。
CCApplication application = new AppDelegate(this, graphics); this.Components.Add(application);
Game1.cs還是那么重要有很多操作仍需在里面做的比如說處理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這個靜態字段是為了處理back,標記當前場景的。
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賦值位置一樣。
語文不好小學開始就不及格,有看不懂的地方加群:190784175
