日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

调整和改编赛车游戏——游戏屏幕

發(fā)布時(shí)間:2023/12/1 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调整和改编赛车游戏——游戏屏幕 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

游戲屏幕

賽車游戲中有很多不同的游戲屏幕,這些都是由RacingGame類中的gameScreens堆棧管理的。本節(jié)介紹游戲中使用的大部分屏幕和對(duì)應(yīng)的功能。大多數(shù)游戲屏幕相當(dāng)簡(jiǎn)單,但其他的有點(diǎn)復(fù)雜并實(shí)現(xiàn)了一個(gè)單元測(cè)試,通過(guò)單元測(cè)試能更好地了解這個(gè)類。例如,Credits屏幕是相當(dāng)簡(jiǎn)單的,它只顯示一個(gè)背景紋理,但主菜單很復(fù)雜并具有所有能進(jìn)入另一個(gè)屏幕的按鈕。Options屏幕介紹了許多新的控制選項(xiàng),這些都要進(jìn)行測(cè)試,這個(gè)類里有一個(gè)單元測(cè)試能幫你完成這個(gè)過(guò)程。

所有的游戲屏幕類都繼承于IgameScreen接口(見(jiàn)圖14-6),您也許還記得在第8章的Rocket Commander中也使用過(guò)。幾乎沒(méi)有改變,但更簡(jiǎn)單了。您現(xiàn)在只有一個(gè)叫做Render的方法,它沒(méi)有參數(shù)并返回一個(gè)布爾值。該代碼和你在XNA Shooter中使用的幾乎一樣。如果Render方法返回true意味著您可以返回到以前的游戲屏幕,一旦推出最后一個(gè)游戲屏幕則游戲推出。通常游戲屏幕返回false,因?yàn)橥婕以俅芜M(jìn)入游戲屏幕后不會(huì)立即退出。


圖 14-6

由于這個(gè)簡(jiǎn)單的接口,所以所有的游戲屏幕的類視圖幾乎是一樣的,它們都只有一個(gè)Render方法。有些類還會(huì)有一些私有的輔助方法,但它們大多是非常簡(jiǎn)單的。一些更復(fù)雜的游戲屏幕還有單元測(cè)試用以測(cè)試是否所有內(nèi)容和功能都能正確實(shí)行。處理整個(gè)游戲的GameScreen類是復(fù)雜的。不像XNA Shooeter或Rocket Commander,所有游戲代碼的的處理和渲染是在Landscape和model類中的。游戲邏輯在Player類中被處理,這個(gè)有點(diǎn)復(fù)雜,但你已經(jīng)在上一章學(xué)習(xí)了所有的CarPhysics類的基本物理知識(shí)和ChaseCamera類。

看看圖14-7了解一下游戲屏幕的基本概況。最復(fù)雜的類顯然是Mission類,它處理游戲過(guò)程和游戲邏輯。它不包含所有的游戲代碼,有些是在Player類和RacingGame類中被處理的。


圖 14-7

啟動(dòng)屏幕

啟動(dòng)屏幕(見(jiàn)圖14-8)是較容易的一個(gè)類,它只是等著玩家按下手柄上的Start。如果沒(méi)有手柄,Space或Esc鍵或鼠標(biāo)左鍵也可讓玩家繼續(xù)。這個(gè)類唯一令人感興趣的地方就是讓“Press Start to continue”文字閃爍的代碼。


圖 14-8

/// <summary> /// Render splash screen /// </summary> public bool Render() {// This starts both menu and in game post screen shader!BaseGame.UI.PostScreenMenuShader.Start();// Render background and black barBaseGame.UI.RenderMenuBackground();BaseGame.UI.RenderBlackBar(352, 61);// Show Press Start to continue.if ((int)(BaseGame.TotalTime / 0.375f) % 3 != 0)BaseGame.UI.Logos.RenderOnScreen(BaseGame.CalcRectangleCenteredWithGivenHeight(512, 352 + 61 / 2, 26, UIRenderer.PressStartGfxRect),UIRenderer.PressStartGfxRect);// Show logosBaseGame.UI.RenderLogos();// Clicking or pressing start will go to the menureturn Input.MouseLeftButtonJustPressed ||Input.KeyboardSpaceJustPressed ||Input.KeyboardEscapeJustPressed ||Input.GamePadStartPressed; } // Render()

RenderMenuBackground方法有點(diǎn)復(fù)雜。它用來(lái)顯示菜單背景,即顯示出汽車通過(guò)一條賽道。汽車是由計(jì)算機(jī)控制的而相機(jī)只是跟隨它。代碼不是很復(fù)雜:

// [From RenderMenuTrackBackground(), which is called by // RenderMenuBackground(), both located in the UIRenderer class]// [Some code to calculate carPos, carMatrix, etc.]// Put camera behind car RacingGame.Player.SetCameraPosition(carPos + carMatrix.Forward * 9 - carMatrix.Up * 2.3f);// For rendering rotate car to stay correctly on the road carMatrix =Matrix.CreateRotationX(MathHelper.Pi / 2.0f) *Matrix.CreateRotationZ(MathHelper.Pi) *carMatrix;RacingGame.Landscape.Render(); RacingGame.CarModel.RenderCar(randomCarNumber, randomCarColor, carMatrix);

借助于Landscape類的Render方法和Model類的RenderCar方法您不必?fù)?dān)心渲染場(chǎng)景、賽道或其他東西。相機(jī)矩陣可以確保你在正確的位置上觀看,而賽車通過(guò)汽車矩陣在賽道上行駛。.

所有其他游戲屏幕菜單也使用RenderMenuBackground方法顯示屏幕背景,但在一些游戲屏幕上不太明顯,因?yàn)槟惆岩粋€(gè)較暗的紋理放在前面(例如,在Credits屏幕上很難看到背景)。這只是一個(gè)背景效果,當(dāng)你正式開(kāi)始玩游戲時(shí)你可以看到更多的屏幕。

主菜單

主菜單(見(jiàn)圖14-9)比其他菜單屏幕復(fù)雜點(diǎn),但即使這樣這個(gè)類也只有約250行代碼。除了啟動(dòng)屏幕,其他屏幕都是從這里開(kāi)始的。最重要的選項(xiàng)是開(kāi)始游戲和觀看highscores (頭兩個(gè)按鈕)。


圖 14-9

這個(gè)類最酷的功能是菜單按鈕的動(dòng)畫。每個(gè)按鈕獲得一個(gè)介于0和1之間的浮點(diǎn)值,其中0代表按鈕尺寸的最小可能值而1代表最大。當(dāng)鼠標(biāo)懸浮或用手柄、鍵盤選擇按鈕時(shí),它將慢慢變大直到達(dá)到1.0。當(dāng)你離開(kāi)按鈕,它又緩慢變小。

第一個(gè)按鈕初始設(shè)為1,其他按鈕設(shè)為最小尺寸(0)。

/// <summary> /// Current button sizes for scaling up/down smooth effect. /// </summary> float[] currentButtonSizes =new float[NumberOfButtons] { 1, 0, 0, 0, 0, 0 };

然后在Rnnder方法中處理按鈕選擇和縮放。為了確保你會(huì)在同時(shí)懸浮在一個(gè)以上的按鈕,這里為鼠標(biāo)使用了一個(gè)輔助變量。如果不使用鼠標(biāo)選取菜單按鈕,這個(gè)變量將不會(huì)被使用。

// Little helper to keep track if mouse is actually over a button. // Required because buttons are selected even when not hovering over // them for GamePad support, but we still want the mouse only to // be applied when we are actually over the button. int mouseIsOverButton = -1;// [a little later in the code ...] for (int num = 0; num < NumberOfButtons; num++) {// Is this button currently selected?bool selected = num == selectedButton;// Increase size if selected, decrease otherwisecurrentButtonSizes[num] +=(selected ? 1 : -1) * BaseGame.MoveFactorPerSecond * 2;if (currentButtonSizes[num] < 0)currentButtonSizes[num] = 0;if (currentButtonSizes[num] > 1)currentButtonSizes[num] = 1;// Use this size to build rectRectangle thisRect =InterpolateRect(activeRect, inactiveRect, currentButtonSizes[num]);Rectangle renderRect = new Rectangle(xPos, yPos - (thisRect.Height - inactiveRect.Height) / 2,thisRect.Width, thisRect.Height);BaseGame.UI.Buttons.RenderOnScreen(renderRect, ButtonRects[num],// Make button gray if not selectedselected ? Color.White : new Color(192, 192, 192, 192));// Add border effect if selectedif (selected)BaseGame.UI.Buttons.RenderOnScreen(renderRect,UIRenderer.MenuButtonSelectionGfxRect);// Also check if the user hovers with the mouse over this buttonif (Input.MouseInBox(renderRect))mouseIsOverButton = num;// [etc.] } // for (num)if (mouseIsOverButton >= 0)selectedButton = mouseIsOverButton;

Game Screen

GameScreen類(見(jiàn)圖14-10)是最重要的游戲屏幕,因?yàn)樗幚碚麄€(gè)游戲邏輯。游戲變量不儲(chǔ)存在這個(gè)類,但所有的重要組成部分(場(chǎng)景,賽道,汽車,對(duì)象,HUD等)從這里被渲染和調(diào)用。


圖 14-10

大多數(shù)玩家變量都存儲(chǔ)在Player類,所有的輸入和物理在Player的基類中(CarPhysics和ChaseCamera)處理。Player類還使用了所有的游戲變量比賽。大多數(shù)變量顯示在用戶界面中,比如在HUD上的目前的游戲時(shí)間,它們?cè)赑layer類的HandleGameLogic方法中被更新。

所有Render方法,包括HUD,都在UIRenderer輔助類中處理,其余的在Landscape類和model類中處理和渲染,陰影映射也在那里進(jìn)行。所有的渲染和游戲處理是從這里調(diào)用,所以這個(gè)類為您提供了游戲中發(fā)生了什么的一個(gè)很好的概括。如果你編寫一個(gè)改編版本,那么從這開(kāi)始修改代碼。在這或調(diào)用方法中注釋掉代碼,能很快地看到游戲的哪一部分受到了影響。

Render方法的第一部分處理所有的陰影映射,這不是很復(fù)雜,因?yàn)榇蠖鄶?shù)已在Landscape類中被處理了。你只需將數(shù)據(jù)提供給陰影映射類,這個(gè)類渲染所有陰影映射,這些陰影映射能直接被使用。

/// <summary> /// Render game screen. Called each frame. /// </summary> public bool Render() { if (BaseGame.AllowShadowMapping) {// Generate shadowsShaderEffect.shadowMapping.GenerateShadows(delegate{RacingGame.Landscape.GenerateShadow();RacingGame.CarModel.GenerateShadow(RacingGame.Player.CarRenderMatrix);});// Render shadowsShaderEffect.shadowMapping.RenderShadows(delegate{RacingGame.Landscape.UseShadow();RacingGame.CarModel.UseShadow(RacingGame.Player.CarRenderMatrix);}); } // if (BaseGame.AllowShadowMapping)

然后開(kāi)始post-screen glow shader并渲染所有的3D內(nèi)容。這包括天空盒,帶有賽道的場(chǎng)景和所有三維模型,最后是汽車。

// This starts both menu and in game post screen shader! BaseGame.UI.PostScreenGlowShader.Start();// Render background sky and lensflare. BaseGame.UI.RenderGameBackground();// Render landscape with track and all objects RacingGame.Landscape.Render();// Render car with matrix we got from CarPhysics RacingGame.CarModel.RenderCar(RacingGame.currentCarNumber, RacingGame.CarColor,RacingGame.Player.CarRenderMatrix);// And flush all models to be rendered BaseGame.MeshRenderManager.Render();

在MeshRenderManager渲染所有的三維模型后您可以添加陰影映射效果。這里的調(diào)用順序是重要的,因?yàn)槿绻陲@示陰影前還沒(méi)有渲染三維模型,陰影將不正確或不工作。

// Show shadows we calculated above if (BaseGame.AllowShadowMapping) {ShaderEffect.shadowMapping.ShowShadows(); } // if (BaseGame.AllowShadowMapping)// Apply post screen shader here before doing the UI BaseGame.UI.PostScreenGlowShader.Show();

代碼的最后是游戲的用戶界面,如果你想去除或改變HUD,在這里做這件事。

// Play motor sound Sound.UpdateGearSound(RacingGame.Player.Speed,RacingGame.Player.Acceleration);// Show on screen UI for the game. BaseGame.UI.RenderGameUI((int)RacingGame.Player.GameTimeMiliseconds,// Best time and current lap(int)RacingGame.Player.BestTimeMs,RacingGame.Player.CurrentLap+1,RacingGame.Player.Speed * CarPhysics.MeterPerSecToMph,// Gear logic with sound (could be improved ^^)1+(int)(5*RacingGame.Player.Speed/CarPhysics.MaxSpeed),// Motormeter0.5f*RacingGame.Player.Speed/CarPhysics.MaxSpeed +// This could be improved0.5f*RacingGame.Player.Acceleration,RacingGame.Landscape.CurrentTrackName,Highscore.GetTop5Highscores());if (Input.KeyboardEscapeJustPressed ||Input.GamePadBackJustPressed) {// Stop motor soundSound.StopGearSound();// Play menu music againSound.Play(Sound.Sounds.MenuMusic);// Return to menureturn true; } // if (Input.KeyboardEscapeJustPressed)return false; } // Render()
Highscores

Highscores屏幕(見(jiàn)圖14-11)非常相似與Rocket Commander的,但所有在線highscores被移除,因?yàn)闆](méi)有實(shí)現(xiàn)網(wǎng)絡(luò)代碼或Web服務(wù)。原因仍是XNA缺乏網(wǎng)絡(luò)支持,但在PC版本中仍有可能實(shí)現(xiàn)。


圖 14-11

在Highscores類中有幾個(gè)輔助方法,例如,幫助您確定當(dāng)前在游戲中的排名,但大多數(shù)方法已經(jīng)這本書的前面幾個(gè)游戲中用到過(guò)了。

下面的代碼是用來(lái)顯示排行榜前10名的玩家。你會(huì)發(fā)現(xiàn),借助于UIRenderer類中的輔助方法代碼是很簡(jiǎn)單的。如果您只想測(cè)試Highscores游戲屏幕,請(qǐng)使用類內(nèi)部的單元測(cè)試,這是用來(lái)定位所有的用戶界面元素的,此游戲的其他屏幕也以同樣的方式做這件事。我也在Visual Studio 2005使用了TestDriven.NET,它能通過(guò)熱鍵重新運(yùn)行測(cè)試。這樣我可以測(cè)試代碼,按下熱鍵,說(shuō):“哦,不,”,按下Escape,并修復(fù)代碼,直到類工作正常。大多數(shù)的UI代碼都是通過(guò)這種方式進(jìn)行測(cè)試的。

// Go through all highscores for (int num = 0; num < NumOfHighscores; num++) {// Show player in white if mouse is over line or else use gray colorRectangle lineRect = new Rectangle(0, yPos, BaseGame.Width, lineHeight);Color col = Input.MouseInBox(lineRect) ?Color.White : new Color(200, 200, 200);// Fill in text for this lineBaseGame.UI.WriteText(xPos1, yPos, (1 + num) + ".", col);BaseGame.UI.WriteText(xPos2, yPos,highscores[selectedLevel, num].name, col);BaseGame.UI.WriteGameTime(xPos3, yPos,highscores[selectedLevel, num].timeMs, Color.Yellow);yPos += lineHeight; } // for (num)

剩下的其他游戲屏幕類是Option,Help和Credit。它們和highscores類非常相似,并不令人興奮。Option有一些不錯(cuò)的UI功能,可以讓你在Input類的幫助下輸入文字,選取其中一個(gè)或多個(gè)滑塊并拖動(dòng)它們。使用Option類的單元測(cè)試更多地了解這些功能。Help和Credit類只是在屏幕上顯示一個(gè)紋理,非常類似于你先前看到的SplashScreen類。

最后,點(diǎn)擊退出按鈕可以退出游戲,因?yàn)橹鞑藛侮P(guān)閉后將不會(huì)有其他游戲屏幕了。而所有其他游戲屏幕總是返回到主菜單(包括SplashScreen類)。

轉(zhuǎn)載于:https://www.cnblogs.com/AlexCheng/archive/2010/10/17/2120185.html

總結(jié)

以上是生活随笔為你收集整理的调整和改编赛车游戏——游戏屏幕的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。