// 窗口
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); // 将临时画布的图像绘制到图bmpG
GameFramework.g = bmpG; // 将图bmpG传递给GameFramework的静态图g
// 阻塞现象的解决方法:线程
//Thread t = new Thread(new ThreadStart(GameMainThread));
t = new Thread(new ThreadStart(GameMainThread)); // 声明调用一个线程t
t.Start(); // 线程开始运行
}
private static void GameMainThread()
{
// GameFramework
GameFramework.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; // 定义静态图g
private 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给图bmp
bmp.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<NotMovething> wallList = new List<NotMovething>(); // 定义一个红墙列表
private static List<NotMovething> steelList = new List<NotMovething>(); // 定义一个铁墙列表
private static NotMovething boss; // 定义一个boss
private static MyTank myTank; // 定义我的坦克
private static List<EnemyTank> tankList = new List<EnemyTank>(); // 定义一个敌人坦克列表
private static List<Bullet> bulletList = new List<Bullet>(); // 定义一个子弹列表
// private static Object _bulletLock = new Object();
private static List<Explosion> expList = new List<Explosion>(); // 定义一个爆炸列表
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,标志为tag
bulletList.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<Bullet> needToDestroy = new List<Bullet>(); // 需要销毁的子弹集合
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 <Explosion> needToDestroy = new List<Explosion>();
foreach (Explosion exp in expList)
{
if (exp.IsNeedDestroy == true)
{
needToDestroy