📄 gameengine.cs
字号:
}
if (gameFont != null)
{
// Clean up the game font
gameFont.Dispose();
gameFont = null;
}
// Clean up the textures used for the mesh level
if ((levelTextures != null) && (levelTextures.Length > 0))
{
for(int i = 0; i < levelTextures.Length; i++)
{
levelTextures[i].Dispose();
}
// Clean up the mesh level itself
levelMesh.Dispose();
}
// Make sure to cleanup the blocks
Block.Cleanup();
}
/// <summary>
/// This callback function will be called once at the beginning of every frame. This is the
/// best location for your application to handle updates to the scene, but is not
/// intended to contain actual rendering calls, which should instead be placed in the
/// OnFrameRender callback.
/// </summary>
public void OnFrameMove(Device device, double appTime, float elapsedTime)
{
if (FrameworkTimer.IsStopped)
return; // Nothing to do
if ((isQuitMenuShowing) || (isMainMenuShowing) || (isSelectScreenShowing))
{
return; // Nothing to do
}
// Update the player
player.Update(elapsedTime, (float)appTime);
// Make sure the level isn't started until the camera moves to position
UpdateCamera(elapsedTime);
// See if we need to keep showing the 'you win' screen
if ((currentLevel.IsGameWon) && (winningLevelTime > ShowWinningTime))
{
// Make sure the new level exists
if (Level.DoesLevelExist(levelNumber + 1))
{
// Reset the variables
levelNumber++;
LoadCurrentLevel();
}
}
// If the level is won, then increment our timing for showing the screen
if (currentLevel.IsGameWon)
{
winningLevelTime += elapsedTime;
}
// Update the current level
currentLevel.Update(elapsedTime);
}
/// <summary>
/// This callback function will be called at the end of every frame to perform all the
/// rendering calls for the scene, and it will also be called if the window needs to be
/// repainted. After this function has returned, the sample framework will call
/// Device.Present to display the contents of the next buffer in the swap chain
/// </summary>
public void OnFrameRender(Device device, double appTime, float elapsedTime)
{
bool beginSceneCalled = false;
// Clear the render target and the zbuffer
device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0, 1.0f, 0);
try
{
device.BeginScene();
beginSceneCalled = true;
// Decide what to render here
if (isMainMenuShowing)
{
mainScreen.Draw();
}
else if (isSelectScreenShowing)
{
selectScreen.Draw((float)appTime);
}
else
{
RenderGameScene(device, appTime);
}
#if (DEBUG)
// Show debug stats (in debug mode)
debugFont.DrawText(null, sampleFramework.FrameStats, new System.Drawing.Rectangle(2,0,0,0),
DrawTextFormat.NoClip, unchecked((int)0xffffff00));
debugFont.DrawText(null, sampleFramework.DeviceStats, new System.Drawing.Rectangle(2,15,0,0),
DrawTextFormat.NoClip, unchecked((int)0xffffff00));
#endif
}
finally
{
if (beginSceneCalled)
device.EndScene();
}
}
#region Creation methods
/// <summary>
/// Create the graphical objects
/// </summary>
private void CreateGraphicObjects(SelectLoopyScreen screen)
{
// No need to create the level mesh
if (levelMesh == null)
{
// Create the mesh for the level
ExtendedMaterial[] mtrls;
levelMesh = Mesh.FromFile(MediaPath + "level.x", MeshFlags.Managed, sampleFramework.Device, out mtrls);
// Store the materials for later use, and create the textures
if ((mtrls != null) && (mtrls.Length > 0))
{
levelTextures = new Texture[mtrls.Length];
for (int i = 0; i < mtrls.Length; i++)
{
// Create the texture
levelTextures[i] = TextureLoader.FromFile(sampleFramework.Device, MediaPath +
mtrls[i].TextureFilename);
}
}
}
// Create our player object
player = new Player(screen.LoopyMesh, screen.LoopyTexture,
screen.LoopyMaterial);
// Load the current level
LoadCurrentLevel();
}
/// <summary>
/// Load the current level
/// </summary>
private void LoadCurrentLevel()
{
// Load our level
currentLevel = new Level(levelNumber, sampleFramework.Device, player);
// Create a random camera location
CreateRandomCamera();
// Now we're loading the level
isLoadingLevel = true;
winningLevelTime = 0.0f;
}
#endregion
/// <summary>
/// This method will render the entire scene for a level
/// </summary>
private void RenderGameScene(Device device, double appTime)
{
// First render the level mesh, but before that is done, you will need
// to turn off the zbuffer. This isn't needed for this drawing
device.RenderState.ZBufferEnable = false;
device.RenderState.ZBufferWriteEnable = false;
device.Transform.World = Matrix.Scaling(15,15,15) * Matrix.Translation(0,22,0);
device.RenderState.Lighting = false;
for(int i = 0; i < levelTextures.Length; i++)
{
device.SetTexture(0, levelTextures[i]);
levelMesh.DrawSubset(i);
}
// Turn the zbuffer back on
device.RenderState.ZBufferEnable = true;
device.RenderState.ZBufferWriteEnable = true;
// Now, turn back on our light
device.RenderState.Lighting = true;
// Render the player
player.Draw(device, (float)appTime);
currentLevel.Draw(device);
int width = sampleFramework.DeviceSettings.presentParams.BackBufferWidth;
int height = sampleFramework.DeviceSettings.presentParams.BackBufferHeight;
if (isQuitMenuShowing)
{
quitScreen.Draw();
}
if (isLoadingLevel)
{
string loadingText = string.Format(
"Try Level {0}\r\nAre you ready?", levelNumber);
if (!isQuitMenuShowing)
{
gameFont.DrawText(null, loadingText, new System.Drawing.Rectangle(
System.Drawing.Point.Empty, new System.Drawing.Size(width,height)),
DrawTextFormat.Center | DrawTextFormat.VerticalCenter |
DrawTextFormat.NoClip, System.Drawing.Color.WhiteSmoke);
}
}
else
{
// if there is a level happening, update some stats
if (currentLevel != null)
{
// Draw current state
string blockInfo = string.Format("Blocks Remaining {0} - Correct {1}",
currentLevel.NumberBlocks - currentLevel.NumberCorrectBlocks,
currentLevel.NumberCorrectBlocks);
System.Drawing.Color statColor = System.Drawing.Color.White;
// Change the color once you've gotten more than halfway complete
if ((currentLevel.NumberBlocks - currentLevel.NumberCorrectBlocks)
> currentLevel.NumberCorrectBlocks)
{
statColor = System.Drawing.Color.Turquoise;
}
gameFont.DrawText(null, blockInfo, new System.Drawing.Rectangle(0,
height - 60, width, height),
DrawTextFormat.Center | DrawTextFormat.NoClip,
statColor);
if (!currentLevel.IsGameOver)
{
string gameState = string.Format("Moves: {0} (Max: {1})\r\nTime Remaining: {2}",
currentLevel.TotalMoves, currentLevel.MaximumMoves,
currentLevel.TimeRemaining);
gameFont.DrawText(null, gameState, new System.Drawing.Rectangle(0,
30, width, height), DrawTextFormat.Center | DrawTextFormat.NoClip,
System.Drawing.Color.Yellow);
}
else
{
string gameState;
System.Drawing.Color c;
if (currentLevel.IsGameWon)
{
gameState = string.Format("Congratulations! You win this level!");
c = System.Drawing.Color.White;
}
else
{
gameState = string.Format("Game Over!!");
c = System.Drawing.Color.Red;
}
gameFont.DrawText(null, gameState, new System.Drawing.Rectangle(0,
30, width, height), DrawTextFormat.Center | DrawTextFormat.NoClip, c);
}
}
}
}
#region Lighting
/// <summary>
/// Turn on the correct light for the scene
/// </summary>
private void EnableLights()
{
// Turn on the correct light, turn off the other light
if (isSelectScreenShowing)
{
sampleFramework.Device.Lights[1].Enabled = true;
sampleFramework.Device.Lights[0].Enabled = false;
}
else
{
sampleFramework.Device.Lights[0].Enabled = true;
sampleFramework.Device.Lights[1].Enabled = false;
}
}
#endregion
#region Camera Functions
/// <summary>
/// Create a random camera position to 'fly by' the level
/// </summary>
private void CreateRandomCamera()
{
Random r = new Random();
currentCameraPosition = new Vector3(
(float)r.NextDouble() * 5.0f + 15.0f,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -