記得在大學學java時,同學在下載了很多java的視頻,看到里面有些是介紹簡單游戲開發的,馬士兵老師講的,挺感興趣的。一起看了看視頻寫了寫程序。現在畢業了,因為工作中用的是C#,最近很想拿C#把以前寫的坦克大戰重寫下,來熟悉熟悉C#的基本語法。
程序很簡單,跟java代碼相比沒有多大改動
實現方法如下
1.在form中添加一個panel,在panel的 Paint方法中得到Graphics對象
2.通過Graphics對象再panel畫出坦克,子彈等相關內容
3.添加timer控件 來控制panel的重畫 實現坦克,子彈的運動
4.根據電腦按下的方向鍵,確定出坦克的方向,panel重畫時根據坦克的方向修改坦克的X,Y軸坐標,來實現坦克的移動
5.通過Rectangle的IntersectsWith函數來進行碰撞檢測,實現子彈打擊坦克
具體實現代碼
1.在項目里面添加枚舉類型
/// <summary>
/// 表示方向的的枚舉類型
/// </summary>
public enum Direction { L, U, D, R, STOP }
2.添加子彈類的相關常量,屬性
/// <summary>
/// 子彈X軸的速度,單位PX
/// </summary>
public static int XSPEED = 10;
/// <summary>
/// 子彈Y軸的速度,單位PX
/// </summary>
public static int YSPEED = 10;
/// <summary>
/// 子彈的寬度
/// </summary>
public static int WIDTH = 10;
/// <summary>
/// 子彈的高度
/// </summary>
public static int HEIGHT = 10;
/// <summary>
/// 子彈的坐標
/// </summary>
int x, y;
/// <summary>
/// 子彈的方向
/// </summary>
Direction dir;
/// <summary>
/// 子彈的存活狀態
/// </summary>
private bool live = true;
/// <summary>
/// TankClient窗體實例
/// </summary>
private TankClient tankClient;
/// <summary>
/// 敵我雙方的標記
/// </summary>
private bool good;
3.添加draw方法來畫出子彈
public void Draw(Graphics g)
{
if (!live)
{
tankClient.missiles.Remove(this);
return;
}
//通過畫橢圓函數在界面上顯示子彈
g.FillEllipse(Brushes.Black, x, y, Missile.WIDTH, Missile.HEIGHT);
Move();
}
4.添加子彈打擊坦克的方法
public bool HitTank(Tank t)
{
//用IntersectsWith來檢測兩個矩形相碰撞
if (GetRectangle().IntersectsWith((t.GetRectangle())) && t.Live && this.live && this.good != t.Good)
{
t.Live = false;
this.live = false;
return true;
}
return false;
}
5.添加坦克類相關屬性,常量
/// <summary>
/// 坦克x軸的速度
/// </summary>
public static int XSPEED = 5;
/// <summary>
/// 坦克y軸的速度
/// </summary>
public static int YSPEED = 5;
/// <summary>
/// 坦克的寬度
/// </summary>
public static int WIDTH = 30;
/// <summary>
/// 坦克的高度
/// </summary>
public static int HEIGHT = 30;
/// <summary>
/// 坦克的坐標
/// </summary>
private int x, y;
/// <summary>
/// 標記上下左右鍵是否按下
/// </summary>
private bool l = false, u = false, r = false, d = false;
/// <summary>
/// 坦克的方向
/// </summary>
private Direction dir = Direction.STOP;
/// <summary>
/// 坦克炮筒方向
/// </summary>
private Direction ptDir = Direction.D;
/// <summary>
/// TankClient窗體實例
/// </summary>
TankClient tankClient;
/// <summary>
/// 標記敵我雙方
/// </summary>
private bool good;
/// <summary>
/// 控制敵人坦克不規則運行時使用
/// </summary>
private int step = 0;
/// <summary>
/// 標記坦克的存活狀態
/// </summary>
private bool live = true;
6.在tank類中實現畫坦克方法
public void Draw(Graphics g)
{
if (!live)
{
if (!good)
{
tankClient.tanks.Remove(this);
}
return;
}
if (good)
{
//通過FillEllipse來畫坦克
g.FillEllipse(Brushes.Red, x, y, WIDTH, HEIGHT);
}
else
{
g.FillEllipse(Brushes.Blue, x, y, WIDTH, HEIGHT);
}
//根據炮筒坦克來畫出坦克的炮筒
switch (ptDir)
{
case Direction.D:
g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y + HEIGHT);
break;
case Direction.U:
g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y);
break;
case Direction.L:
g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x, y + HEIGHT / 2);
break;
case Direction.R:
g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH, y + HEIGHT / 2);
break;
}
Move();
}
7.鍵盤按鍵處理的相關代碼
public void KeyPressed(KeyEventArgs e)
{
Keys key = e.KeyCode;
switch (key)
{
case Keys.Right:
r = true;
break;
case Keys.Left:
l = true;
break;
case Keys.Up:
u = true;
break;
case Keys.Down:
d = true;
break;
}
LocateDirection();
}
8.tank發子彈的方法
public Missile Fire()
{
if (!live) return null;
int x = this.x + WIDTH / 2 - Missile.WIDTH / 2;
int y = this.y + HEIGHT / 2 - Missile.HEIGHT / 2;
Missile missile = new Missile(x, y, good, ptDir, tankClient);
tankClient.missiles.Add(missile);
return missile;
}
9.主窗體類加入坦克
myTank = new Tank(50, 20, true, this);//放到前面 this不能用 //y軸比java的減少了30
for (int i = 0; i < 15; i++)
{
//添加10個坦克x軸間距為40px
tanks.Add(new Tank(50+40*(i+1),20,false,this)); //y軸比java的減少了30
}
10.主窗體類中調用子彈打擊坦克的方法
for (int i = 0; i < missiles.Count; i++)
{
Missile m = missiles[i];
m.HitTank(myTank);
m.HitTanks(tanks);
m.Draw(g);
}
11.主窗體處理按鍵代碼
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
myTank.KeyPressed(e);
}
12.控制重畫代碼
private void timer1_Tick(object sender, EventArgs e)
{
//間隔50毫秒控制panel的重畫
panel1.Invalidate();
}
13.這是主要代碼基本完成,但是游戲會有閃爍問題
可以通過雙緩沖來解決,C#解決時很省事,一個函數就能解決
this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
順便改了個手機版本的但是手機版本的沒能解決雙緩沖問題,屏幕有些閃爍,朋友們可以自己改進
代碼下載 http://files.cnblogs.com/hehe108/tanker.rar
如果你發現有什么不合理的,需要改進的地方,郵件聯系328452421@qq.com(qq常年不在線,郵件聯系) 。相互交流 謝謝
作者:hehe108
出處:http://www.cnblogs.com/hehe108/
關於作者:菜鳥一枚。如有問題或建議,請多多賜教!
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接
如有問題,可以通過 328452421@qq.com 聯系我,非常感謝。