C#__分析使用Winform开发坦克大战

// 窗口
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 坦克大战
{public partial class Form1 : Form{private Thread t; // 可以被FormClosed引用// private Graphics g;private static Graphics windowG; // 定义图private static Bitmap tempBmp; // 临时画布public Form1(){InitializeComponent(); // 调用方法,初始化组件this.StartPosition = FormStartPosition.CenterScreen; // 定义窗口开始位置windowG = this.CreateGraphics(); // 声明图// GameFramework.g = g;// 解决画布闪烁问题tempBmp = new Bitmap(450,450); // 定义临时画布大小Graphics bmpG = Graphics.FromImage(tempBmp); // 将临时画布的图像绘制到图bmpGGameFramework.g = bmpG; // 将图bmpG传递给GameFramework的静态图g// 阻塞现象的解决方法:线程//Thread t = new Thread(new ThreadStart(GameMainThread));t = new Thread(new ThreadStart(GameMainThread)); // 声明调用一个线程tt.Start(); // 线程开始运行}private static void GameMainThread(){// GameFrameworkGameFramework.Start(); // 调用GameFramework中的Start()方法int sleepTime = 1000 / 60; // 1000ms/60 = 1s/60 定义帧数while (true){GameFramework.g.Clear(Color.Black); // 将图的背景色涂黑GameFramework.Update(); // 60帧windowG.DrawImage(tempBmp, 0, 0); //从(0,0)坐标开始用临时图绘制画布Thread.Sleep(sleepTime); // 将当前线程挂起,并指定的毫秒数。}}private void Form1_FormClosed(object sender, FormClosedEventArgs e){t.Abort(); // 线程t终止}// 事件 消息 事件消息private void Form1_KeyDown(object sender, KeyEventArgs e){// if(e.KeyCode == Keys.W) // Keys.W,枚举类型,确定W键被按下GameObjectManager.KeyDown(e);}private void Form1_KeyUp(object sender, KeyEventArgs e){GameObjectManager.KeyUp(e);}}
}

// 框架
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 坦克大战
{enum GameState // 游戏状态{Running,GameOver}class GameFramework{public static Graphics g; // 定义静态图gprivate static GameState gameState = GameState.Running; // 定义游戏状态为运行中public static void Start() // 游戏开始{SoundManager.InitSound(); // 创建声音GameObjectManager.Start(); // 创建敌人GameObjectManager.CreateMap(); // 创建地图GameObjectManager.CreateMyTank(); // 创建我的坦克SoundManager.PlayStart(); // 播放声音}public static void Update() // 刷新地图{//GameObjectManager.DrawMap();//GameObjectManager.DrawMyTank();if (gameState == GameState.Running) // 游戏进行时{GameObjectManager.Update();}else if(gameState == GameState.GameOver) // 游戏结束{GameOverUpdate();}}private static void GameOverUpdate() // 游戏结束刷新方式{Bitmap bmp = Properties.Resources.GameOver; // 调用源文件图片GameOver给图bmpbmp.MakeTransparent(Color.Black); // 使透明化为黑色int x = 450 / 2 - Properties.Resources.GameOver.Width / 2; // 图片中心位于画布x轴中点位置int y = 450 / 2 - Properties.Resources.GameOver.Height / 2; // 图片中心位于画布y轴中点位置//g.DrawImage(Properties.Resources.GameOver, x, y);g.DrawImage(bmp, x, y); // 将图bmp放置(x,y)位置}public static void ChangeToGameOver() // 变为游戏结束状态{gameState = GameState.GameOver;}}
}
// 游戏对象的相关管理





// 管理者类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using 坦克大战.Properties;namespace 坦克大战
{class GameObjectManager{private static List wallList = new List(); // 定义一个红墙列表private static List steelList = new List(); // 定义一个铁墙列表private static NotMovething boss; // 定义一个bossprivate static MyTank myTank; // 定义我的坦克private static List tankList = new List(); // 定义一个敌人坦克列表private static List bulletList = new List(); // 定义一个子弹列表// private static Object _bulletLock = new Object();private static List expList = new List(); // 定义一个爆炸列表private static int enemyBornSpeed = 60; // 敌人产生的速度60帧(1s1个)private static int enemyBornCount = 60; // 计数器,敌人生成个数1个private static Point[] points = new Point[3]; // 定义一个二维数组(x,y),用于存放敌人生成位置public static void Start() // 敌人出现位置{points[0].X = 0; points[0].Y = 0; // (0,0)points[1].X = 7 * 30; points[1].Y = 0; // (210,0)points[2].X = 14 * 30; points[2].Y = 0; // (420,0)}public static void Update() // 刷新图片{foreach (NotMovething nm in wallList) // 刷新红墙{nm.Update();}foreach (NotMovething nm in steelList) // 刷新铁墙{nm.Update();}foreach(EnemyTank tank in tankList) // 刷新敌人坦克{tank.Update();}CheckAndDestroyBullet(); // 检查和销毁子弹//lock (bulletList) // 子弹撞击边界报错 内部用for循环,foreach遍历不允许修改//{foreach (Bullet bullet in bulletList) // 刷新子弹{bullet.Update();}//}foreach (Explosion exp in expList) // 爆炸效果刷新{exp.Update();}CheckAndDestroyExplosion(); // 检查并销毁爆炸效果boss.Update(); // boss刷新myTank.Update(); // 我的坦克刷新EnemyBorn(); // 生成敌人}public static void CreateBullet(int x, int y, Tag tag, Direction dir) // 创建子弹{Bullet bullet = new Bullet(x, y, 5, dir, tag); // 子弹射出位置(x,y),速度为5,方向为dir,标志为tagbulletList.Add(bullet); // 在子弹列表中添加子弹}public static void DestroyWall(NotMovething wall) // 销毁红墙{wallList.Remove(wall); // 从红墙列表中移除红墙}public static void DestroyTank(EnemyTank tank) //销毁敌人{tankList.Remove(tank);}private static void CheckAndDestroyBullet() // 检查并销毁子弹的方法{List needToDestroy = new List(); // 需要销毁的子弹集合foreach (Bullet bullet in bulletList) // 遍历子弹列表{if (bullet.IsDestroy == true) // 找到需要销毁的子弹{needToDestroy.Add(bullet); // 将其加入需要销毁的子弹集合}}foreach (Bullet bullet in needToDestroy) // 遍历需要销毁的子弹列表{bulletList.Remove(bullet); // 移除子弹}}public static void CreateExplosion(int x, int y) // 创建爆炸效果{Explosion exp = new Explosion(x, y); // 创建一个爆炸效果,赋予位置expList.Add(exp); // 添加到列表}private static void CheckAndDestroyExplosion() // 检查并销毁爆炸效果,同子弹销毁{List needToDestroy = new List();foreach (Explosion exp in expList){if (exp.IsNeedDestroy == true){needToDestroy.Add(exp);}}foreach (Explosion exp in needToDestroy){expList.Remove(exp);}}//public static void DestroyBullet(Bullet bullet)//{// bulletList.Remove(bullet);//}private static void EnemyBorn() // 敌人生成方法{enemyBornCount++; // 计数器加1if (enemyBornCount < enemyBornSpeed) return; // 计数数小于生成速度,没有到达生成时间SoundManager.PlayAdd(); // 敌人生成时的音效// 0-2Random rd = new Random(); // 生成随机数int index = rd.Next(0, 3); // 返回在指定范围内的任意整数到索引Point position = points[index]; // 将敌人生成坐标传递给positionint enemyType = rd.Next(1, 5); //返回在指定范围内的任意整数到索引switch (enemyType) // 生成敌人类型{case 1:CreateEnemyTank1(position.X, position.Y); // 创建敌人坦克1在该坐标break;case 2:CreateEnemyTank2(position.X, position.Y); // 创建敌人坦克2在该坐标break;case 3:CreateEnemyTank3(position.X, position.Y); // 创建敌人坦克3在该坐标break;case 4:CreateEnemyTank4(position.X, position.Y); // 创建敌人坦克4在该坐标break;}enemyBornCount = 0; // 计数器归零}private static void CreateEnemyTank1(int x, int y) // 创建敌人坦克1{EnemyTank tank = new EnemyTank(x, y, 2, Resources.GrayDown, Resources.GrayUp, Resources.GrayRight, Resources.GrayLeft);// 在(x,y)轴生成,速度为2,四个方向状态的图片tankList.Add(tank); // 列表加1}private static void CreateEnemyTank2(int x, int y) // 创建敌人坦克2{EnemyTank tank = new EnemyTank(x, y, 4, Resources.QuickDown, Resources.QuickUp, Resources.QuickRight, Resources.QuickLeft);tankList.Add(tank);}private static void CreateEnemyTank3(int x, int y) // 创建敌人坦克3 {EnemyTank tank = new EnemyTank(x, y, 2, Resources.GreenDown, Resources.GreenUp, Resources.GreenRight, Resources.GreenLeft);tankList.Add(tank);}private static void CreateEnemyTank4(int x, int y) // 创建敌人坦克422{EnemyTank tank = new EnemyTank(x, y, 1, Resources.SlowDown, Resources.SlowUp, Resources.SlowRight, Resources.SlowLeft);tankList.Add(tank);}public static NotMovething IsCollidedWall(Rectangle rt) // 检查是否和红墙发生碰撞{foreach(NotMovething wall in wallList){if (wall.GetRectangle().IntersectsWith(rt)) // 判断是否相交{return wall;}}return null;} public static NotMovething IsCollidedSteel(Rectangle rt) // 检查是否和铁墙发生碰撞{foreach(NotMovething wall in steelList){if (wall.GetRectangle().IntersectsWith(rt)) // 判断是否相交{return wall;}}return null;}public static bool IsCollidedBoss(Rectangle rt) // 检查是否和Boss发生碰撞,Boss只有一个{return boss.GetRectangle().IntersectsWith(rt);}public static MyTank IsCollidedMyTank(Rectangle rt) // 检查是否和我的坦克发生碰撞{if (myTank.GetRectangle().IntersectsWith(rt)) return myTank;else return null;}public static EnemyTank IsCollidedEnemyTank(Rectangle rt) // 检查是否和敌人坦克发生碰撞{foreach(EnemyTank tank in tankList){if (tank.GetRectangle().IntersectsWith(rt)){return tank;}}return null;}//public static void DrawMap()//{// foreach (NotMovething nm in wallList)// {// nm.DrawSelf();// }// foreach (NotMovething nm in steelList)// {// nm.DrawSelf();// }// boss.DrawSelf();//}//public static void DrawMyTank()//{// myTank.DrawSelf();//}public static void CreateMyTank() // 创建我的坦克{int x = 5 * 30;int y = 14 * 30;// MyTank myTank = new MyTank(x, y, 2); myTank = new MyTank(x, y, 2); // 位置(x,y),速度为2}public static void CreateMap() // 创建地图{// 打印红墙CreatWall(1, 1, 5, Resources.wall, wallList); // 从坐标(x,y)开始,向下打印5个红墙,并计入红墙列表CreatWall(3, 1, 5, Resources.wall, wallList);CreatWall(5, 1, 4, Resources.wall, wallList);CreatWall(7, 1, 3, Resources.wall, wallList);CreatWall(9, 1, 4, Resources.wall, wallList);CreatWall(11, 1, 4, Resources.wall, wallList);CreatWall(13, 1, 4, Resources.wall, wallList);CreatWall(7, 5, 1, Resources.steel, steelList);CreatWall(0, 7, 1, Resources.steel, steelList);CreatWall(2, 7, 1, Resources.wall, wallList);CreatWall(3, 7, 1, Resources.wall, wallList);CreatWall(4, 7, 1, Resources.wall, wallList);CreatWall(6, 7, 1, Resources.wall, wallList);CreatWall(7, 6, 2, Resources.wall, wallList);CreatWall(8, 7, 1, Resources.wall, wallList);CreatWall(10, 7, 1, Resources.wall, wallList);CreatWall(11, 7, 1, Resources.wall, wallList);CreatWall(12, 7, 1, Resources.wall, wallList);CreatWall(14, 7, 1, Resources.steel, steelList);CreatWall(1, 9, 5, Resources.wall, wallList);CreatWall(3, 9, 5, Resources.wall, wallList);CreatWall(5, 9, 3, Resources.wall, wallList);CreatWall(6, 10, 1, Resources.wall, wallList);CreatWall(7, 10, 2, Resources.wall, wallList);CreatWall(8, 10, 1, Resources.wall, wallList);CreatWall(9, 9, 3, Resources.wall, wallList);CreatWall(11, 9, 5, Resources.wall, wallList);CreatWall(13, 9, 5, Resources.wall, wallList);CreatWall(6, 13, 2, Resources.wall, wallList);CreatWall(7, 13, 1, Resources.wall, wallList);CreatWall(8, 13, 2, Resources.wall, wallList);CreatWall(7, 14, 2, Resources.wall, wallList);CreatBoss(7, 14, Resources.Boss);}private static void CreatBoss(int x, int y, Image img) // 创建boss{int xPosition = x * 30; // x轴位置int yPosition = y * 30; // y轴位置boss = new NotMovething(xPosition, yPosition, img); // (x,y)坐标打印图像img}private static void CreatWall(int x,int y, int count,Image img, List wallList) // 创建墙{int xPosition = x * 30;int yPosition = y * 30;for(int i = yPosition; i< yPosition + count * 30; i += 15) // 将4块(15*15)小墙连接成一块(30*30)大墙{NotMovething wall1 = new NotMovething(xPosition, i, img); // (x,y)坐标建立NotMovething wall2 = new NotMovething(xPosition+15, i, img); // (x+15,y)坐标建立wallList.Add(wall1);wallList.Add(wall2);}}public static void KeyDown(KeyEventArgs args) // 按键控制我的坦克运动{myTank.KeyDown(args);}public static void KeyUp(KeyEventArgs args) // 松键,停止控制操作{myTank.KeyUp(args);}}
}
// 音效管理

// 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using 坦克大战.Properties;namespace 坦克大战
{class SoundManager // 音效管理{private static SoundPlayer startPlayer = new SoundPlayer(); // 定义开始音效private static SoundPlayer addPlayer = new SoundPlayer(); // 定义增加敌人音效private static SoundPlayer blastPlayer = new SoundPlayer(); // 定义爆炸音效private static SoundPlayer firePlayer = new SoundPlayer(); // 定义发射子弹音效private static SoundPlayer hitPlayer = new SoundPlayer(); // 定义击败坦克音效public static void InitSound() // 初始化声音{startPlayer.Stream = Resources.start; // 开始音效addPlayer.Stream = Resources.add; // 增加敌人音效blastPlayer.Stream = Resources.blast; // 爆炸音效firePlayer.Stream = Resources.fire; // 发射子弹音效hitPlayer.Stream = Resources.hit; // 击败坦克音效}public static void PlayStart() // 开始音效方法{startPlayer.Play(); // 播放音效}public static void PlayAdd() // 增加敌人音效方法{addPlayer.Play();}public static void PlayBlast() // 爆炸音效方法{blastPlayer.Play();}public static void PlayFire() // 发射子弹音效方法{firePlayer.Play();}public static void PlayHit() // 击败坦克音效方法{hitPlayer.Play();}}
}
// 游戏对象

// 类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 坦克大战
{abstract class GameObject{//private int x;//public int X { get { return x; } set { value = x; } }// 简写protected int X { get; set; } // 访问X轴位置protected int Y { get; set; } // 访问Y轴位置public int Width { get; set; } // 访问Widthpublic int Height { get; set; } // 访问Heightprotected abstract Image GetImage(); // 需要在子类重写public virtual void DrawSelf() // 绘制自身{Graphics g = GameFramework.g;g.DrawImage(GetImage(), X, Y);}public virtual void Update(){DrawSelf(); // 重新绘制自己}public Rectangle GetRectangle() // 取得矩形{Rectangle rectangle = new Rectangle(X, Y, Width, Height);return rectangle;}}
}
// 不可移动物体

// 类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 坦克大战
{class NotMovething: GameObject // 不可移动的物体{// public Image Img { get; set; }private Image img; // 定义图片imgpublic Image Img { get { return img; } // 构造img的属性set {img = value;// 确定高度和宽度Width = img.Width;Height = img.Height;}}protected override Image GetImage() // 重载得到图片{return Img;}public NotMovething(int x,int y, Image img) // 创建不可移动物体的图片位置的方法{this.X = x;this.Y = y;this.Img = img;}}
}
// 可移动物体


//类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 坦克大战
{enum Direction // 枚举方向{Up = 0,Down = 1,Left = 2,Right = 3}class Movething : GameObject // 可移动物体{private Object _lock = new object(); // 定义一把锁public Bitmap BitmapUp { get; set; } // 访问向上图片,并取得public Bitmap BitmapDown { get; set; } // 访问向下图片,并取得public Bitmap BitmapLeft { get; set; } // 访问向左图片,并取得public Bitmap BitmapRight { get; set; } // 访问向右图片,并取得public int Speed { get; set; } // 访问速度,并取得//public Direction Dir { get; set; }private Direction dir; // 定义方向public Direction Dir { get { return dir; } // 访问方向并取得set {dir = value;Bitmap bmp = null;switch (dir){case Direction.Up: // 向上取得图片BitmapUpbmp = BitmapUp;break;case Direction.Down: // 向下取得图片BitmapDownbmp = BitmapDown;break;case Direction.Left: // 向左取得图片BitmapLeftbmp = BitmapLeft;break;case Direction.Right: // 向右取得图片BitmapRightbmp = BitmapRight;break;}lock (_lock) // 获取锁,防止线程冲突{Width = bmp.Width;Height = bmp.Height;}} }protected override Image GetImage() // 重载得到图像{Bitmap bitmap = null; // 定义bitmap图像#region 方案一//switch (Dir)//{// case Direction.Up:// return BitmapUp;// case Direction.Down:// return BitmapDown;// case Direction.Left:// return BitmapLeft;// case Direction.Right:// return BitmapRight;//}#endregionswitch (Dir) // 判断方向{case Direction.Up:bitmap = BitmapUp;break;case Direction.Down:bitmap = BitmapDown;break;case Direction.Left:bitmap = BitmapLeft;break;case Direction.Right:bitmap = BitmapRight;break;}bitmap.MakeTransparent(Color.Black); // 设置黑色为透明度// return BitmapUp; //默认返回值,无法转向return bitmap;}public override void DrawSelf() // 重载绘制自身 {lock (_lock){base.DrawSelf();}}}
}
// 我的坦克




// 类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using 坦克大战.Properties;namespace 坦克大战
{class MyTank : Movething{public bool IsMoving { get; set; } // 得到IsMoving属性public int HP { get; set; } // 得到HP属性private int originalX; // 用于存放最初的X轴位置private int originalY; // 用于存放最初的Y轴位置public MyTank(int x, int y, int speed) // 定义我的坦克的基本属性{IsMoving = false; // 默认不移动this.X = x;this.Y = y;originalX = x;originalY = y;this.Speed = speed;BitmapDown = Resources.MyTankDown;BitmapUp = Resources.MyTankUp;BitmapRight = Resources.MyTankRight;BitmapLeft = Resources.MyTankLeft;this.Dir = Direction.Up; // 默认方向HP = 4;}public override void Update(){MoveCheck(); // 移动检查Move();base.Update();}private void MoveCheck(){#region 检查我的坦克有没有超出窗体边界if (Dir == Direction.Up){if (Y - Speed < 0) // Y-Speed 将要移动到的位置{IsMoving = false; return;}}else if (Dir == Direction.Down){if (Y + Speed + Height > 450){IsMoving = false; return;}}else if (Dir == Direction.Left){if (X - Speed < 0){IsMoving = false; return;}}else if (Dir == Direction.Right){if (X + Speed + Width > 450){IsMoving = false; return;}}#endregion// 检查有没有其他元素发生碰撞Rectangle rect = GetRectangle();// rect表示将要走的位置switch (Dir){case Direction.Up:rect.Y -= Speed;break;case Direction.Down:rect.Y += Speed;break;case Direction.Left:rect.X -= Speed;break;case Direction.Right:rect.X += Speed;break;}// if (GameObjectManager.IsCollidedWall(GetRectangle()) != null) 卡墙现象if (GameObjectManager.IsCollidedWall(rect) != null) // 是否撞Wall{IsMoving = false; return;}if (GameObjectManager.IsCollidedSteel(rect) != null) // Steel{IsMoving = false; return;}if (GameObjectManager.IsCollidedBoss(rect)) // Boss{IsMoving = false; return;}}private void Move() // 移动{if (IsMoving == false) return;switch (Dir){case Direction.Up:Y -= Speed;break;case Direction.Down:Y += Speed;break;case Direction.Left:X -= Speed;break;case Direction.Right:X += Speed;break;}}// GameMainThread 和 KeyDown 冲突// 线程一和线程二 上锁public void KeyDown(KeyEventArgs args){switch (args.KeyCode) //获取的键盘{case Keys.W: // 按下W键//if (Dir != Direction.Up) // 方案一,减少调用次数(权宜之计)//{// Dir = Direction.Up;//}Dir = Direction.Up;IsMoving = true; // Y -= Speed;break;case Keys.S:Dir = Direction.Down;IsMoving = true;break;case Keys.A:Dir = Direction.Left;IsMoving = true;break;case Keys.D:Dir = Direction.Right;IsMoving = true;break;case Keys.Space:Attack(); // 发射子弹break;}}public void Attack() // 攻击{SoundManager.PlayFire(); // 调用音效// 发射子弹int x = this.X;int y = this.Y;switch (Dir){case Direction.Up:x = x + Width / 2;break;case Direction.Down:x = x + Width / 2;y = y + Height;break;case Direction.Left:y = y + Height / 2;break;case Direction.Right:x = x + Width;y = y + Height / 2;break;}GameObjectManager.CreateBullet(x, y, Tag.MyTank, Dir); // 创建子弹}public void KeyUp(KeyEventArgs args) // 松开键盘{switch (args.KeyCode){case Keys.W:IsMoving = false;break;case Keys.S:IsMoving = false;break;case Keys.A:IsMoving = false;break;case Keys.D:IsMoving = false;break;}}public void TakeDamage() // 承受伤害{HP--;if (HP <= 0){X = originalX;Y = originalY;HP = 4;}}}
}
// 敌人坦克



// 类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 坦克大战
{class EnemyTank:Movething{public int ChangeDirSpeed { get; set; } // 改变移动方向public int changeDirCount = 0; // 改变移动方向计数器public int AttackSpeed { get; set; } // 攻击速度private int attackCount = 0; // 攻击速度计数器private Random r = new Random(); // 调用同一个种子,保证随机public EnemyTank(int x, int y, int speed, Bitmap bmpDown, Bitmap bmpUp, Bitmap bmpRight, Bitmap bmpLeft) // 敌方坦克基本属性{this.X = x;this.Y = y;this.Speed = speed;BitmapDown = bmpDown;BitmapUp = bmpUp;BitmapRight = bmpRight;BitmapLeft = bmpLeft;this.Dir = Direction.Up;AttackSpeed = 60; // 攻击频率ChangeDirSpeed = 80; // 改变方向频率}public override void Update() // 重载更新{MoveCheck(); // 移动检查Move(); // 移动AttackCheck(); // 攻击检查AutoChangeDirection(); // 自动转向base.Update(); // 调用DrawSelf(); // 重新绘制自己}private void ChangeDirection() // 自动转向方法{// 4个朝向// private Random r = new Random(); 种子,算法,伪随机数,不同种子可能生成同种算法while (true){Direction dir = (Direction)r.Next(0, 4); // 随机生成(0,4)if (dir == Dir){continue;}else{Dir = dir; break;}}MoveCheck();}private void MoveCheck() // 移动检查方法{#region 检查敌人坦克有没有超出窗体边界if (Dir == Direction.Up){if (Y - Speed < 0) // Y-Speed 将要移动到的位置{ChangeDirection(); return;}}else if (Dir == Direction.Down){if (Y + Speed + Height > 450){ChangeDirection(); return;}}else if (Dir == Direction.Left){if (X - Speed < 0){ChangeDirection(); return;}}else if (Dir == Direction.Right){if (X + Speed + Width > 450){ChangeDirection(); return;}}#endregion// 检查有没有其他元素发生碰撞Rectangle rect = GetRectangle();// rect表示将要走的位置switch (Dir){case Direction.Up:rect.Y -= Speed;break;case Direction.Down:rect.Y += Speed;break;case Direction.Left:rect.X -= Speed;break;case Direction.Right:rect.X += Speed;break;}// if (GameObjectManager.IsCollidedWall(GetRectangle()) != null) 卡墙现象if (GameObjectManager.IsCollidedWall(rect) != null) // 是否撞Wall{ChangeDirection(); return;}if (GameObjectManager.IsCollidedSteel(rect) != null) // Steel{ChangeDirection(); return;}if (GameObjectManager.IsCollidedBoss(rect)) // Boss{ChangeDirection(); return;}}private void AutoChangeDirection() // 自动转向功能{changeDirCount++; // 计数器加1if (changeDirCount < ChangeDirSpeed) return; // 计数器小于生成速度,返回ChangeDirection(); // 改变方向changeDirCount = 0; // 计数器归零}private void Move() // 移动方法{switch (Dir){case Direction.Up:Y -= Speed;break;case Direction.Down:Y += Speed;break;case Direction.Left:X -= Speed;break;case Direction.Right:X += Speed;break;}}private void AttackCheck() // 攻击检查,原理同上{attackCount++; // 计数器加1if (attackCount < AttackSpeed) return;Attack();attackCount = 0;}public void Attack() // 攻击方法{// 发射子弹int x = this.X;int y = this.Y;switch (Dir){case Direction.Up:x = x + Width / 2;break;case Direction.Down:x = x + Width / 2;y = y + Height;break;case Direction.Left:y = y + Height / 2;break;case Direction.Right:x = x + Width;y = y + Height / 2;break;}GameObjectManager.CreateBullet(x, y, Tag.EnemyTank, Dir);}}
}
// 子弹




// 子弹类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 坦克大战.Properties;namespace 坦克大战
{enum Tag{MyTank,EnemyTank}class Bullet : Movething{public Tag Tag { set; get; } // 访问并获取Tagpublic bool IsDestroy { get; set; } // 建立IsDetroy属性public Bullet(int x, int y, int speed, Direction dir, Tag tag) // 子弹的基本属性{IsDestroy = false; // 不销毁this.X = x;this.Y = y;this.Speed = speed;BitmapDown = Resources.BulletDown;BitmapUp = Resources.BulletUp;BitmapRight = Resources.BulletRight;BitmapLeft = Resources.BulletLeft;this.Dir = dir;this.Tag = tag;this.X -= Width / 2;this.Y -= Height / 2;}// 子弹绘制图片过大,需要重新绘制public override void DrawSelf(){base.DrawSelf();}public override void Update(){MoveCheck(); // 移动检查Move();base.Update();}private void MoveCheck(){#region 检查子弹有没有超出窗体边界if (Dir == Direction.Up){if (Y + Height/2+3 < 0) // Y-Speed 将要移动到的位置{IsDestroy = true; return;}}else if (Dir == Direction.Down){if (Y + Height / 2 - 3 > 450){IsDestroy = true; return;}}else if (Dir == Direction.Left){if (X +Width/2-3 < 0){IsDestroy = true; return;}}else if (Dir == Direction.Right){if (X + Width/2+3 > 450){IsDestroy = true; return;}}#endregionRectangle rect = GetRectangle(); // 取得矩形位置rect.X = X + Width / 2 - 3;rect.Y = Y + Width / 2 - 3;rect.Width = 3;rect.Height = 3;// 1、墙;2、钢墙;3、坦克int xExplosion = this.X + Width / 2;int yExplosion = this.Y + Height / 2;NotMovething wall = null;if ((wall = GameObjectManager.IsCollidedWall(rect)) != null) // 是否撞Wall{IsDestroy = true; // 销毁GameObjectManager.DestroyWall(wall); // 调用销毁方法GameObjectManager.CreateExplosion(xExplosion, yExplosion); // 创建爆炸效果SoundManager.PlayBlast(); // 创建音效return;}if (GameObjectManager.IsCollidedSteel(rect) != null) // Steel{IsDestroy = true;GameObjectManager.CreateExplosion(xExplosion, yExplosion);return;}if (GameObjectManager.IsCollidedBoss(rect)){GameFramework.ChangeToGameOver(); // 游戏结束SoundManager.PlayBlast(); // 结束音效return;}//if (GameObjectManager.IsCollidedBoss(rect)) // Boss//{// ChangeDirection(); return;//}if (Tag == Tag.MyTank) {EnemyTank tank = null;if( (tank = GameObjectManager.IsCollidedEnemyTank(rect)) != null){IsDestroy = true;GameObjectManager.DestroyTank(tank); // 销毁坦克GameObjectManager.CreateExplosion(xExplosion, yExplosion); // 创建爆炸效果SoundManager.PlayHit(); // 爆炸音效return;}}else if(Tag== Tag.EnemyTank){MyTank mytank = null;if((mytank = GameObjectManager.IsCollidedMyTank(rect)) != null){IsDestroy = true;GameObjectManager.CreateExplosion(xExplosion, yExplosion);SoundManager.PlayBlast();mytank.TakeDamage();return;}}}private void Move() // 子弹移动方法{switch (Dir){case Direction.Up:Y -= Speed;break;case Direction.Down:Y += Speed;break;case Direction.Left:X -= Speed;break;case Direction.Right:X += Speed;break;}}}
}
// 爆炸效果

// 爆炸效果类
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 坦克大战.Properties;namespace 坦克大战
{class Explosion : GameObject {public bool IsNeedDestroy { get; set; } // 定义IsNeedDestroy属性//private int playSpeed = 2;//private int playCount = -1;private int playSpeed = 1; // 生成速度private int playCount = 0; // 生成速度计数器// private int index = -1;private int index = 0; // 为了能保证取到图片private Bitmap[] bmpArray = new Bitmap[] // 图片数组{Resources.EXP1, // 爆炸效果图1Resources.EXP2,Resources.EXP3,Resources.EXP4,Resources.EXP5};public Explosion(int x, int y) // 爆炸位置及效果遍历{foreach (Bitmap bmp in bmpArray){bmp.MakeTransparent(Color.Black); // 透明度为黑色}this.X = x - bmpArray[0].Width / 2;this.Y = y - bmpArray[0].Height / 2;IsNeedDestroy = false;}protected override Image GetImage() // 重写GetImage方法{if (index > 4) return bmpArray[4];return bmpArray[index];}public override void Update() // 重写更新数据方法{playCount++; // 计数器+1index = (playCount - 1) / playSpeed; //2帧一图if (index > 4){IsNeedDestroy = true;}base.Update();}}
}
// 主函数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 坦克大战
{static class Program{/// /// 应用程序的主入口点。/// [STAThread]static void Main(){Application.EnableVisualStyles(); // 启用应用程序的可视样式Application.SetCompatibleTextRenderingDefault(false);Application.Run(new Form1());}}
}
// 问题回顾

//
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
