📄 gamerenderer.cs
字号:
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.Samples.DirectX.UtilityToolkit;
using System.Collections;
using System.Drawing;
namespace TankGogogo.GameRenderer
{
/// <summary>
/// GameRenderer 的摘要说明。
/// </summary>
public class GameRenderer : IFrameworkCallback,IDeviceCreation
{
const int gameCellheight=55;
const int gameCellwidth=70;
#region Creation
public GameRenderer(Framework f)
{
gameFramework=f;
infoDlg=new Dialog(gameFramework);
}
#endregion
#region members
private float timeToAdvance = 0;
private Framework gameFramework = null;
private Sprite batchSprite;
private CharacterSprite characterSprite;
private Canvas canvas;
private Texture myTankTexture;
private const float fps = 20;
private SurfaceDescription bbufferDesc;
private Vector2 upperLeft;
#endregion
#region user interface
private Dialog infoDlg = null; //a dialog for game infomation controls
private const int liveNumText=1; //记录命的条数
private const int enemyNumText=2; //记录已销毁的敌方坦克数
private const int scoreText=3; //记录分数
private const int keyNumText=4;
private const int keyTotalText=5;
private const int ofText=6; //"of"
#endregion
#region gameinfo
private int keyNum=1;
private int keyTotal=3;
private int score=100;
private int enemyNum=40;
private int liveNum=4;
#endregion
#region IDeviceCreation 成员
/// <summary>
/// 设备初始化时调用,该代码检测设备的一些能力,若无法通过最小能力测试,则拒绝运行。
/// </summary>
public bool IsDeviceAcceptable(Caps caps,Format adapterFormat,Format backBufferFormat, bool isWindowed)
{
if(!Manager.CheckDeviceFormat(caps.AdapterOrdinal,caps.DeviceType,adapterFormat,
Usage.QueryPostPixelShaderBlending,ResourceType.Textures,backBufferFormat))
return false;
return true;
}
/// <summary>
/// 该反馈函数在当某设备被创建时调用,以允许应用修改该设备的设置。本游戏框架并不更正错误设置。
/// 当设置错误时,设备将无法被成功创建
/// </summary>
/// <param name="settings">包含了框架选定的新的设备的设置,应用可以直接修改该结构</param>
/// <param name="caps"></param>
public void ModifyDeviceSettings(DeviceSettings settings, Caps caps)
{
if ((!caps.DeviceCaps.SupportsHardwareTransformAndLight) ||
(caps.VertexShaderVersion < new Version(1, 1)))
{
settings.BehaviorFlags = CreateFlags.SoftwareVertexProcessing;
}
else
{
settings.BehaviorFlags = CreateFlags.HardwareVertexProcessing;
}
// This application is designed to work on a pure device by not using
// any get methods, so create a pure device if supported and using HWVP.
if ((caps.DeviceCaps.SupportsPureDevice) &&
((settings.BehaviorFlags & CreateFlags.HardwareVertexProcessing) != 0))
settings.BehaviorFlags |= CreateFlags.PureDevice;
// Debugging vertex shaders requires either REF or software vertex processing
// and debugging pixel shaders requires REF.
#if(DEBUG_VS)
if (settings.DeviceType != DeviceType.Reference )
{
settings.BehaviorFlags &= ~CreateFlags.HardwareVertexProcessing;
settings.BehaviorFlags |= CreateFlags.SoftwareVertexProcessing;
}
#endif
#if(DEBUG_PS)
settings.DeviceType = DeviceType.Reference;
#endif
// For the first device created if its a REF device, optionally display a warning dialog box
if (settings.DeviceType == DeviceType.Reference)
{
Utility.DisplaySwitchingToRefWarning(gameFramework, "SpriteSample");
}
}
#endregion
private void OnCreateDevice(object sender,DeviceEventArgs e)
{
upperLeft = new Vector2(0,0);
unchecked
{
myTankTexture = TextureLoader.FromFile(e.Device,Utility.FindMediaFile("8tanks.bmp"),210,167,
0,Usage.None,Format.A8R8G8B8,Pool.Managed,Filter.None,Filter.None,(int)0xFF000000);
characterSprite = new CharacterSprite(myTankTexture,gameCellwidth,gameCellheight,3,3,8,0,60,
0,new Vector2((float)gameCellwidth/2,(float)gameCellheight/2),new Rectangle(0,0,gameCellwidth,gameCellheight));
}
canvas = new Canvas(e.Device,640,480);
}
/// <summary>
/// 该事件在Direct3D 设备被重启,即当某设备场景丢失后被激活
/// </summary>
private void OnResetDevice(object sender,DeviceEventArgs e)
{
bbufferDesc = e.BackBufferDescription;
float aspectRetio=(float)bbufferDesc.Width / (float)bbufferDesc.Height;
infoDlg.SetLocation(bbufferDesc.Width-170,0);
infoDlg.SetSize(170,170);
infoDlg.SetBackgroundColors(new ColorValue(1.0f,0.0f,0.0f,1.0f));
batchSprite = new Sprite(e.Device);
}
/// <summary>
/// 该函数当d3d设备进入一个lost状态并且重启命令还未调用的时候被调用。在ResetDevice时被新建的资源在此处被释放。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnLostDevice(object sender,EventArgs e)
{
if(batchSprite !=null)
{
batchSprite.Dispose();
batchSprite = null;
}
}
/// <summary>
/// D3D设备被摧毁时该函数被调用。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDestroyDevice(object sender,EventArgs e)
{
if(myTankTexture!=null)
{
myTankTexture.Dispose();
myTankTexture = null;
}
if(canvas!=null)
{
canvas.Dispose();
canvas = null;
}
}
/// <summary>
/// 该反馈函数在每帧的开始被调用一次,此处可以放置场景更新代码,但最好不要在此调用渲染函数。
/// </summary>
public void OnFrameMove(Device device,double appTime,float elapsedTime)
{
timeToAdvance -= elapsedTime;
if (timeToAdvance < 0)
{
characterSprite.MovebyFrame();
timeToAdvance += 1 / fps;
}
}
public void OnFrameRender(Device device,double appTime,float elapsedTime)
{
bool beginScenceCall=false;
device.Clear(ClearFlags.ZBuffer|ClearFlags.Target,0x00,1.0f,0);
try
{
device.BeginScene();
beginScenceCall=true;
batchSprite.Begin(SpriteFlags.AlphaBlend);
characterSprite.Draw(batchSprite,System.Drawing.Color.White);
canvas.Draw(batchSprite,System.Drawing.Rectangle.Empty,
new Rectangle(0,0,bbufferDesc.Width,bbufferDesc.Height),
System.Drawing.Color.Pink);
batchSprite.End();
}
finally
{
if(beginScenceCall)
device.EndScene();
}
}
private void OnKeyEvent(object sender,System.Windows.Forms.KeyEventArgs e)
{
switch(e.KeyCode)
{
case System.Windows.Forms.Keys.Up:
characterSprite.moveto(CharacterSprite.UP);
break;
case System.Windows.Forms.Keys.Down:
characterSprite.moveto(CharacterSprite.DOWN);
break;
case System.Windows.Forms.Keys.Left:
characterSprite.moveto(CharacterSprite.LEFT);
break;
case System.Windows.Forms.Keys.Right:
characterSprite.moveto(CharacterSprite.RIGHT);
break;
}
}
/// <summary>
/// 初始化控件
/// </summary>
public void InitializeApplication()
{
int y=10;
StaticText keyNumT = infoDlg.AddStatic(keyNumText,keyNum.ToString(),35,y,10,10);
StaticText keyTotalT = infoDlg.AddStatic(keyTotalText,keyTotal.ToString(),35,y+=12,10,10);
StaticText ofT = infoDlg.AddStatic(ofText,"of",35,y+=12,10,10);
StaticText liveNumT = infoDlg.AddStatic(liveNumText,liveNum.ToString(),35,y+=12,10,10);
StaticText enemyNumT = infoDlg.AddStatic(enemyNumText,enemyNum.ToString(),35,y+=12,10,10);
StaticText scoreT=infoDlg.AddStatic(scoreText,score.ToString(),35,y+=12,10,10);
}
static int Main()
{
System.Windows.Forms.Application.EnableVisualStyles();
using (Framework sampleFramework = new Framework())
{
GameRenderer sample = new GameRenderer(sampleFramework);
// Set the callback functions. These functions allow the sample framework to notify
// the application about device changes, user input, and windows messages. The
// callbacks are optional so you need only set callbacks for events you're interested
// in. However, if you don't handle the device reset/lost callbacks then the sample
// framework won't be able to reset your device since the application must first
// release all device resources before resetting. Likewise, if you don't handle the
// device created/destroyed callbacks then the sample framework won't be able to
// recreate your device resources.
sampleFramework.Disposing += new EventHandler(sample.OnDestroyDevice);
sampleFramework.DeviceLost += new EventHandler(sample.OnLostDevice);
sampleFramework.DeviceCreated += new DeviceEventHandler(sample.OnCreateDevice);
sampleFramework.DeviceReset += new DeviceEventHandler(sample.OnResetDevice);
//sampleFramework.SetWndProcCallback(new WndProcCallback(sample.OnMsgProc));
sampleFramework.SetCallbackInterface(sample);
try
{
// Show the cursor and clip it when in full screen
sampleFramework.SetCursorSettings(true, true);
// Initialize
sample.InitializeApplication();
// Initialize the sample framework and create the desired window and Direct3D
// device for the application. Calling each of these functions is optional, but they
// allow you to set several options which control the behavior of the sampleFramework.
sampleFramework.Initialize(true, true, true); // Parse the command line, handle the default hotkeys, and show msgboxes
sampleFramework.CreateWindow("SpriteSample");
// Hook the keyboard event
sampleFramework.Window.KeyDown += new System.Windows.Forms.KeyEventHandler(sample.OnKeyEvent);
sampleFramework.CreateDevice(0, true, Framework.DefaultSizeWidth, Framework.DefaultSizeHeight,
sample);
// Pass control to the sample framework for handling the message pump and
// dispatching render calls. The sample framework will call your FrameMove
// and FrameRender callback when there is idle time between handling window messages.
sampleFramework.MainLoop();
}
#if(DEBUG)
catch (Exception e)
{
// In debug mode show this error (maybe - depending on settings)
sampleFramework.DisplayErrorMessage(e);
#else
catch
{
// In release mode fail silently
#endif
// Ignore any exceptions here, they would have been handled by other areas
return (sampleFramework.ExitCode == 0) ? 1 : sampleFramework.ExitCode; // Return an error code here
}
// Perform any application-level cleanup here. Direct3D device resources are released within the
// appropriate callback functions and therefore don't require any cleanup code here.
return sampleFramework.ExitCode;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -