复习多线程
Thread childThread1 = new Thread(new ThreadStart(ChildThreadMethod));//创建子线程
childThread1.Start();//开启子线程
GDI绘制图片、线段和文字
#region 绘制线和字符串、和图片
Graphics g = this.CreateGraphics(); //画布初始化
g.DrawString("www.baidu.com", new Font("宋体", 20),
new SolidBrush(Color.Red), new Point(100, 100));//绘制字符串
// RGB red green blue
Pen p = new Pen(Color.Black);
g.DrawLine(p, new Point(50, 50), new Point(100, 100));//画线段
//g.DrawString("www.4399.com",
// new Font("隶书", 20),
// new SolidBrush(Color.Red),
// new Point(100, 100));
Image image = Properties.Resources.Boss;
g.DrawImage(image, 200, 200); //绘制图片,调用resource图片资源
#endregion
开发流程
编写游戏逻辑
主线程(确定帧率)
编写生命周期 Start( ) --> Update( )
update( )更新每一帧需要的游戏逻辑
private static void GameMainThread() //绘制游戏主线程【确定帧率】
{
//GameFramework
GameFramework.Start();
int sleepTime = 1000 / 60;//1000ms除以60,1/60秒
//60
while (true)
{
GameFramework.g.Clear(Color.Black);//使用黑色背景
GameFramework.Update();// 60帧(每秒运行60次update)
windowG.DrawImage(tempBmp, 0, 0);
Thread.Sleep(sleepTime);//休息1/60s
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e) //线程关闭
{
t.Abort();
}
下面给出gameobject的业务逻辑
GameObject.cs
abstract class GameObject
{
//private int x;
//public int x {
// get
// {
// return x;
// }
// set
// {
// value = x;
// }
//}
public int X { get; set; } //绘制时期的x,y坐标
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
protected 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;
}
}
添加游戏元素(静态【墙面】)
GameObjectManager.cs
//创建环境方法
private static void CreateWall(int x,int y,int count,Image img, List<NotMovething> wallList)
{
int xPosition = x * 30;
int yPosition = y * 30;
for(int i = yPosition; i < yPosition + count * 30; i += 15)
{
// i xPosition i xPosition+15
NotMovething wall1 = new NotMovething(xPosition, i, img);
NotMovething wall2 = new NotMovething(xPosition+15, i, img);
wallList.Add(wall1);
wallList.Add(wall2);
}
}
public void static CreateMap(){
CreateWall(1, 1, 5, Resources.wall ,wallList);//从1,1起竖排创建5个砖块墙
}
在GameFramework.cs中添加
CreateMap 加入 start()
CreateWall 加入update()
解决生成墙面闪烁的问题,原因:墙面和黑色背景是交替出现的
重点:画布的粉刷工作(清空工作)
游戏元素是update()实时更新在新的位置上的,通过粉刷画布实现。
解决闪烁的方法:
每帧创建新的画布,然后铺上图片,然后一次性覆盖窗体初始化画布。
添加Moving类对象(tank)
添加鼠标操作、事件流
//事件 消息 事件消息
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
GameObjectManager.KeyDown(e);
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
GameObjectManager.KeyUp(e);
}
mytank.cs
public void KeyDown(KeyEventArgs args)
{
switch (args.KeyCode)
{
case Keys.W:
Dir = Direction.Up;
IsMoving = true;
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 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;
}
}
玩家坦克移动
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;
}
}
碰撞检测
- 是否超出边界
#region 检查有没有超过窗体边界
if (Dir == Direction.Up)
{
if (Y - Speed < 0)
{
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();
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(rect) != null)
{
IsMoving = false; return;
}
if (GameObjectManager.IsCollidedSteel(rect) != null)
{
IsMoving = false; return;
}
if (GameObjectManager.IsCollidedBoss(rect))
{
IsMoving = false; return;
}
tank转向(切图片)
protected override Image GetImage()
{
Bitmap bitmap = null;
switch (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 bitmap;
}
实机演示画面