一旦你定义了窗体,就需要一些数据成员,一个构造函数和一些事件句柄。我会依次向您阐释Windows Forms和C#。首先是基本的数据成员,一个tic-tac-toe板。Tic-tac-toe游戏的数据包含了一个表示游戏板的3*3的矩阵数组。这个游戏定义了一块板的格子。
- public struct BoardSpace {
- public BoardSpace(Mark mark,
- int left,
- int top,
- int right,
- int bottom) {
- // Initialize internal state?
- }
- public void SetMark(Player player) {
- // if the space is blank, mark it using
- // the player enumeration
- }
- public void Render(Graphics g) {
- Pen pen =
- new Pen(Color.FromARGB(170, Color.Black), 3);
- switch(m_mark) {
- case Mark.XMark:
- g.DrawLine(pen, m_left, m_top, m_right,
- m_bottom);
- g.DrawLine(pen, m_left, m_bottom, m_right,
- m_top);
- break;
- case Mark.OMark:
- int cx = m_right - m_left;
- int cy = m_bottom - m_top;
- g.DrawEllipse(pen, m_left, m_top, cx, cy);
- break;
- default:
- break;
- }
- }
- public Mark m_mark;
- public int m_top, m_left, m_right, m_bottom;
- };
每一个板的格子都表示在屏幕上的一个位置并确定玩家是否做了标记。此外,格子还使用了一个X和一个O,来决定哪个玩家做了标记。我还会细致的说明的。
Tic-tac-toe板管理了3*3的格子。
- public struct TicTacToeBoard {
- BoardSpace[,] m_BoardSpaces;
- public void Initialize() {
- m_BoardSpaces = new BoardSpace[3,3];
- // Initialize each space with a location on the screen and a
- // blank mark.
- // Here‘s the first space:
- m_BoardSpaces[0, 0] = new BoardSpace(Mark.Blank, 1,
- 1, 50, 50);
- // Do the rest like that?
- }
- public void ClearBoard() {
- // loop through the spaces clearing them
- }
- public Player EvaluateGame() {
- // Check adjacent marks and see who won.
- }
- public Positions HitTest(int x, int y, Player player) {
- // Test the incoming Coords and mark the right space
- // using the player enumeration
- }
- public void Render(Graphics g) {
- Pen pen = new Pen(Color.FromARGB(170,
- Color.Black), 5);
- g.DrawLine(pen, 1, 50, 150, 50);
- g.DrawLine(pen, 50, 1, 50, 150);
- g.DrawLine(pen, 1, 100, 150, 100);
- g.DrawLine(pen, 100, 1, 100, 150);
- for(int i = 0; i < 3; i++) {
- for(int j = 0; j < 3; j++) {
- m_BoardSpaces[i, j].Render(g);
- }
- }
- }
- };
它也管理着BoardSpace对象3*3的数组,并用线条来划分tic-tac-toe的格子并让每一个格子来绘制它们自己。大部分的游戏逻辑都是由板来负责的,所以制作这个游戏的最主要的部分就是建立一个窗体,把板作为数据成员,并且当鼠标按下时请求板的绘制。
- public class CSharpTicTacToe : Form {
- public Player m_Player = Player.XPlayer;
- TicTacToeBoard m_board = new TicTacToeBoard();
- public CSharpTicTacToe() {
- SetStyle(ControlStyles.Opaque, true);
- Size = new Size(500, 500);
- Text = "CSharp Tic Tac Toe";
- m_board.Initialize();
- //Finally add a button so that we can render to a bitmap
- Button buttonRestart = new Button();
- buttonRestart.Size=new Size(100,50);
- buttonRestart.Location=new Point(300,100);
- buttonRestart.Text="Restart";
- buttonRestart.AddOnClick(new EventHandler(Restart));
- this.Controls.Add(buttonRestart);
- }
- //Fired when the restart button is pressed
- private void Restart(object sender, EventArgs e) {
- m_Player = Player.XPlayer;
- m_board.ClearBoard();
- this.Invalidate();
- }
- protected override void OnMouseDown(MouseEventArgs e) {
- base.OnMouseDown(e);
- Positions position = m_board.HitTest(e.X, e.Y, m_Player);
- if(position == Positions.Unknown) {
- return;
- }
- if(m_Player == Player.XPlayer) {
- m_Player = Player.OPlayer;
- } else {
- m_Player = Player.XPlayer;
- }
- this.Invalidate();
- }
- protected override void OnPaint(PaintEventArgs e) {
- Graphics g = e.Graphics;
- e.Graphics.SmoothingMode =
- SmoothingMode.AntiAlias;
- g.FillRectangle(new
- SolidBrush(Color.FromARGB(250,
- Color.White)), ClientRectangle);
- m_board.Render(g);
- }
- public static void Main() {
- Application.Run(new CSharpTicTacToe());
- }
- }
- }
包含了Windows Forms应用程序的初始化代码。注意这个过程就是初始化游戏板,创建一个Reset按钮和其事件句柄,然后截获MouseDown和Paint事件。
大部分的时间,响应事件就是重载(override)正确的函数。例如,游戏要响应MouseDown事件(通过把鼠标的位置交给板来处理)和Paint 事件。当它生成了事件,系统就会自动的调用。你还可以为非系统的、用户定义的事件如按钮被按下而手工关联事件句柄。该游戏也可以创建一个Reset按钮来处理清除游戏板的事件。
Windows Forms编程最基本的就是基于用户界面,请求你来绘制屏幕的过程。Windows Forms定义了一个捕获WM_PAINT消息的良好方法。Form类包含了一个名为OnPaint()的函数来让你重载。通过重载这一方法,你可以捕获绘图事件并在屏幕上做你想做的。看一下例程的源代码,你会注意到Paint事件的参数包括一个Graphics对象,它类似于SDK编程时的一个设备上下文。Graphics对象包括了画线和图形、填充区域以及任何你想在屏幕上做的。
Tic-tac-toe游戏通过让游戏板自绘来响应Paint事件。如果你在例程中看一下TicTacToeBoard类和BoardSpace类,你就会发现每一个类都有一个Render()函数来使用Graphics对象的DrawLine()和DrawEllipse()方法在屏幕上绘图。Windows Forms和C#的强大地方就在于你不必考虑管理GDI类型的资源,因为。NET Framework为你做了。
Windows Forms也提供给你很多的可行性,包括在Windows 窗体上添加菜单和图标,显示对话框和捕获Paint和MouseDown事件以外的大量事件。以上介绍Windows Forms和C#的强大。
【编辑推荐】