GDI+概述
参考文章:https://www.cnblogs.com/funiyi816/p/17122625.html
https://www.cnblogs.com/xiaowie/p/8819684.html
编写图形程序时需要使用GDI(Graphics Device Interface,图形设备接口),
从程序设计的角度看,GDI包括两部分:
一部分是GDI对象,
另一部分是GDI函数。
GDI对象定义了GDI函数使用的工具和环境变量,而GDI函数使用GDI对象绘制各种图形,
在C#中,进行图形程序编写时用到的是GDI+(Graphice Device Interface Plus图形设备接口)版本,
GDI+是GDI的进一步扩展,它使我们编程更加方便。
命名空间和相关类
命名空间:
-
System.Drawing:这个主要的GDI+命名空间定义了许多类型,实现基本的绘图类型(字体,钢笔,基本画笔等)和无所不能的Graphics对象。
- System.Drawing2D:这个命名空间提供高级的二维和失量图像功能。
-
System.Drawing.Imaging:这个命名空间定义了一些类型实现图形图像的操作。
-
System.Drawing.Text:这个命名空间提供了操作字体集合的功能。
-
System.Drawing.Printing:这个命名空间定义了一些类型实现在打印纸上绘制图像,和打印机交互以及格式化某个打印任务的总体外观等功能。
相关类:
- Graphics类:Graphics类封装一个GDI+绘图图面,提供将对象绘制到显示设备的方法,Graphics与特定的设备上下文关联。画图方法都被包括在Graphics类中,在画任何对象(例如:Circle,Rectangle)时,我们首先要创建一个Graphics类实例,这个实例相当于建立了一块画布,有了画布才可以用各种画图方法进行绘图。
-
Pen类:画笔,定义用于绘制直线和曲线的对象。
- Brush类:画刷:定义用于填充图形形状(如矩形、椭圆、饼形、多边形和封闭路径)的内部的对象。只是一个抽象基类。
- Font类:字体Font类有两个构造函数:
第一个是new Font(字体名称,字号),例如,label1.Font=new Font("黑体",9)。
第二个是new Font(字体名称,字号,字体风格),其中第三个参数是枚举类型。
- Image类:Image类和Printing类都是常用的操作图像和打印的类,它们提供了丰富的方法和属性,可以方便地实现各种图像的处理和打印。
Graphics类常用方法:
- 画线条
DrawLine 绘制一条连接由坐标对象指定的两个点的线条
DrawLines 绘制一列连接一组Point结构的线段
DrawBezier 绘制由四个Point结构定义的贝塞尔样条
DrawBeziers 从Point结构的数组绘制一系列贝塞尔样条
DrawCurve 绘制经过一组指定的Point结构的基数样条 - 画可填充线条
DrawEllipse 绘制一个由一对坐标、宽度和高度指定的椭圆
DrawPath 绘制GraphicsPath对象
DrawPie 绘制一个扇形,该扇形由一个坐标对象,宽度和高度,以及两条射线所指定的椭圆指定
DrawPolygon 绘制由一组Point结构定义的多边形
DrawRectangle 绘制由坐标对。宽度和高度指定的矩形
DrawRectangles 绘制一系列由Rectangle结构指定的矩形
DrawArc 绘制一段弧线,它表示由一对坐标、宽高指定的椭圆部分 - 填充区域
FillEllipse 填充边框所定义的椭圆内部,该边框由一对坐标、一个高度和一个宽度指定
FillPath 填充GraphicsPath对象的内部
FillPie 填充扇形内部
FillPolygon 填充多边形内部
FillRectangle 填充由一对坐标、一个宽度和一个高度指定的矩形内部
FillRectangles 填充由Rectangle结构指定的一些列矩阵的内部
FillRegion 填充Region对象的内部 - 画字符串、图画、图标
DrawString 在指定位置并且用指定的Brush和Font对象绘制指定的文本字符串
DrawIcon 在指定坐标处绘制由指定的Icon对象表示的图像
DrawImage 在指定的位置并且按原始大小绘制指定的Image对象 - 其他
MeasureString(String, Font) 测量用指定的 Font 绘制的指定字符串。
FromImage 从指定的Image对象创建行的Graphics对象
Save 保存此Graphics对象的当前状态,并且GraphicsState对象标识保存的状态
Clear 清除整个绘图面并以指定背景色填充
Dispose 释放由此Graphics对象使用的所有资源
绘制图形(线型,字符串,图片)
开始实操之前我们要先了解winform的坐标结构:
坐标系统:
GDI+定义了三种坐标系统,并提供了三种坐标转换的方法Graphics.TransformPoints()。
- 全局坐标系统。
- 页面(Page)坐标系统:左上角为原点,横向x轴向右为正方向,纵向y轴向下为正方向。单位为像素。这是默认的坐标系统。
- 设备坐标系统:可以指定特定测量单位的页面(Page)坐标系统。如果单位为像素,和页面(Page)坐标系统相同。
点结构有两个成员:X,Y,表示点的x轴和y轴的坐标。其常用构造函数如下:
Point p1=new Point(int X,int Y);//X,Y为整数 PointF p2=new PointF(float X,floa Y);//X,Y为浮点数
Size和SizeF用来表示尺寸大小,有两个成员:Width和Height。常用构造函数如下:
public Size(int width,int height); public SizeF(float width,float height);
结构Rectangle和RectangleF用来表示一个矩形,常用构造函数如下:
//参数为矩形左上角坐标的点结构location和代表矩形宽和高的Size结构size Rectangle(Point location,Size size);//参数也可为PointF和SizeF //参数为矩形左上角x和y坐标,宽,高 Rectangle(int X,int Y,int width,int height);//X和Y也可为float
画直线
//画实线 Pen pen = new Pen(Color.Red, 3); //确定线的首位位置 Point point1 = new Point(10, 50); Point point2 = new Point(250, 50); Graphics g = this.CreateGraphics(); g.DrawLine(pen, point1, point2);
画刷
Rectangle rect1 = new Rectangle(20, 80, 250, 100); // (实心实心刷) SolidBrush sbrush = new SolidBrush(Color.DarkOrchid); //(纹理刷) TextureBrush textureBrush = new TextureBrush(new Bitmap(@"e:/123.jpg")); //(梯度、线性渐进刷) LinearGradientBrush lbrush = new LinearGradientBrush(rect1, Color.DarkOrange, Color.Aquamarine, 45); //(阴影刷) HatchBrush hbrush = new HatchBrush(HatchStyle.DiagonalCross, Color.DarkOrange, Color.Aquamarine); e.Graphics.FillRectangle(sbrush, rect1); // (实心刷) e.Graphics.FillRectangle(textureBrush, rect1); //(纹理刷) e.Graphics.FillRectangle(lbrush, rect1); //(梯度刷) e.Graphics.FillRectangle(hbrush, rect1); //(阴影刷)
写字
//当整个窗体被重新绘制时调用的方法 Graphics g = this.CreateGraphics(); Pen p = new Pen(Color.Green); g.DrawLine(p,new Point(50,50),new Point(200,100)); ///第一个是new Font(字体名称,字号),例如,label1.Font=new Font("黑体",9)。 //第二个是new Font(字体名称, 字号,字体风格),其中第三个参数是枚举类型。 g.DrawString("好好学习", new Font("隶书", 20), new SolidBrush(Color.Blue), new Point(200, 100)); g.DrawString("好好学习", new Font("隶书", 20,FontStyle.Strikeout), new SolidBrush(Color.Blue), new Point(200, 100));
画图
private void Form1_Paint(object sender, PaintEventArgs e) { //当整个窗体被重新绘制时调用的方法 Graphics g = this.CreateGraphics(); g.DrawImage(Properties.Resources.Boss, new Point(210, 110)); Pen p = new Pen(Color.Green); g.DrawLine(p,new Point(50,50),new Point(200,100)); }
实例:坦克大战
利用用GDI+制作一款小游戏,效果图如下:
代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Media; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using TankWarHH.Properties; using static System.Windows.Forms.VisualStyles.VisualStyleElement; using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar; namespace TankWarHH { public partial class Form1 : Form { private Thread t; private static Graphics windowG; private static Bitmap backBmp; public Form1() { InitializeComponent(); this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; windowG=this.CreateGraphics(); backBmp = new Bitmap(900, 900); GameFrameWork.g = Graphics.FromImage(backBmp); t = new Thread(new ThreadStart(GameMainThread)); t.Start(); } private static void GameMainThread() { //GameFrameWork GameFrameWork.Start(); int sleepTime = 1000 / 60; while (true) { GameFrameWork.g.Clear(Color.Black); GameFrameWork.Update(); windowG.DrawImage(backBmp, 0, 0); Thread.Sleep(sleepTime); } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { t.Abort(); } private void Form1_KeyDown(object sender, KeyEventArgs e) { GameObjectManage.KeyDown(e); } private void Form1_KeyUp(object sender, KeyEventArgs e) { GameObjectManage.KeyUp(e); } } public enum GameState { Running, GameOver } public class GameFrameWork { public static Graphics g; public static GameState gameState = GameState.Running; public static void Start() { SoundMananger.InitSound(); GameObjectManage.Start(); GameObjectManage.GreateMap(); GameObjectManage.CreateMyTank(); SoundMananger.PlayStart(); } public static void Update() { if(gameState == GameState.Running) { GameObjectManage.Update(); } else if (gameState == GameState.GameOver) { GameOverUpdate(); } } private static void GameOverUpdate() { Bitmap bmp = Properties.Resources.GameOver; bmp.MakeTransparent(Color.Black); int x = 840 / 2 - Properties.Resources.GameOver.Width / 2; int y = 830 / 2 - Properties.Resources.GameOver.Height / 2; g.DrawImage(bmp, x, y); } public static void End() { gameState=GameState.GameOver; } } public abstract class GameObject { public int X { get; set; } public int Y { get; set; } public int width { get; set; } public int height { get; set; } public abstract Image GetImage(); public virtual void DrawSelf() { Graphics g=GameFrameWork.g; g.DrawImage(GetImage(), new Point(X, Y)); } public virtual void Update() { DrawSelf(); } public Rectangle GetRectangle() { Rectangle rectangle = new Rectangle(X, Y, width, height); return rectangle; } } public class NotMovething : GameObject { public Image image { get; set; } public override Image GetImage() { return image; } public NotMovething(int x, int y,Image img) { this.X = x; this.Y = y; this.image = img; this.height = img.Height; this.width = img.Width; } } public enum Direction { Up, Down, Left, Right } public class Movething : GameObject { public object _lock=new object(); public bool IsMoving { get; set; } public Bitmap Up { get; set; } public Bitmap Down { get; set; } public Bitmap Left { get; set; } public Bitmap Right { get; set; } public int Speen { get; set; } public Direction dir; public Direction Dir { get { return dir; } set{ dir = value; Bitmap bitmap = null; lock( _lock ) { switch (dir) { case Direction.Up: bitmap = Up; break; case Direction.Down: bitmap = Down; break; case Direction.Left: bitmap = Left; break; case Direction.Right: bitmap = Right; break; default: bitmap = Up; break; } width = bitmap.Width; height = bitmap.Height; } } } public override Image GetImage() { Bitmap bitmap = null; lock(_lock) { switch (Dir) { case Direction.Up: bitmap = Up; break; case Direction.Down: bitmap = Down; break; case Direction.Left: bitmap = Left; break; case Direction.Right: bitmap = Right; break; default: return Up; } } bitmap.MakeTransparent(Color.Black); return bitmap; } } public class MyTake : Movething { public int HP { get; set; } private int originalX; private int originalY; public MyTake(int x,int y,int speed,Direction dir) { this.X= x; this.Y= y; originalX = x; originalY = y; this.Speen = speed; Up = Resources.MyTankUp; Down=Resources.MyTankDown; Left = Resources.MyTankLeft; Right = Resources.MyTankRight; this.Dir = dir; HP = 4; } internal void KeyDown(KeyEventArgs args) { switch (args.KeyCode) { case Keys.W: if(Dir!=Direction.Up) Dir = Direction.Up; IsMoving = true; break; case Keys.S: if (Dir != Direction.Down) Dir = Direction.Down; IsMoving = true; break; case Keys.A: if (Dir != Direction.Left) Dir = Direction.Left; IsMoving = true; break; case Keys.D: if (Dir != Direction.Right) Dir = Direction.Right; IsMoving = true; break; } } public void MoveCheck() { switch (Dir) { case Direction.Up: if (Y - Speen < 0) IsMoving = false; break; case Direction.Down: if ((Y + Speen + height) > 790) IsMoving = false; break; case Direction.Right: if ((X + Speen + width) > 810) IsMoving = false; break; case Direction.Left: if (X - Speen < 0) IsMoving = false; break; } Rectangle rectank = this.GetRectangle(); switch (Dir) { case Direction.Up: rectank.Y -= Speen; break; case Direction.Down: rectank.Y += Speen; break; case Direction.Right: rectank.X += Speen; break; case Direction.Left: rectank.X -= Speen; break; } if (GameObjectManage.IsCollidedWall(rectank) != null) { IsMoving = false; } if(GameObjectManage.IsCollidedSteel(rectank) != null) { IsMoving = false; } if (GameObjectManage.IsCollidedEnemyTank(rectank) != null) { GameObjectManage.CreateExplosion(rectank.X, rectank.Y); this.TakeDamage(); return; } } public void Move() { if (!IsMoving) { return; } switch (Dir) { case Direction.Up: Y -= this.Speen; break; case Direction.Down: Y += Speen; break; case Direction.Left: X -= Speen; break; case Direction.Right: X += Speen; break; } } public override void Update() { MoveCheck(); Move(); base.Update(); } private void Attack() { SoundMananger.PlayFire(); int x=this.X; int y=this.Y; switch (Dir) { case Direction.Up: y = this.Y - height; break; case Direction.Down: y = this.Y + height; break; case Direction.Right: x += width; break; case Direction.Left: x -= width; break; } GameObjectManage.CreateBullet(Tag.MyTank, x, y, this.Dir); } internal 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; case Keys.Space: Attack(); break; } } internal void TakeDamage() { HP--; if (HP <= 0) { X = originalX; Y = originalY; HP = 4; SoundMananger.PlayAdd(); } } } public class EnemyTank : Movething { public int ChangeDirSpeed = 120; public int ChangeDirCpunt = 0; public int HP { get;set; } public int AttackSpeed = 30; private int AttackCount = 0; private Random r = new Random(); public EnemyTank(int x, int y, int speed, Direction dir, Bitmap bmpUp, Bitmap bmpDown, Bitmap bmpLeft, Bitmap bmpRight,int HP) { this.X = x; this.Y = y; this.Speen = speed; Up = bmpUp; Down = bmpDown; Left = bmpLeft; Right = bmpRight; this.Dir = dir; this.HP = HP; } internal void EnemtTankDamage() { HP--; } public override void Update() { MoveCheck(); Move(); AttackCheck(); AutoChangeDir(); base.Update(); } private void AutoChangeDir() { ChangeDirCpunt++; if (ChangeDirCpunt < ChangeDirSpeed) return; if (r.Next(0, 1) == 0) { ChangeDirection(); ChangeDirCpunt = 0; } } private void AttackCheck() { AttackCount++; if (AttackCount < AttackSpeed) return; Attack(); AttackCount = 0; } public override void DrawSelf() { lock(_lock) { base.DrawSelf(); } } private void Attack() { int x = this.X; int y = this.Y; switch (Dir) { case Direction.Up: y = this.Y - height; break; case Direction.Down: y = this.Y + height; break; case Direction.Right: x += width; break; case Direction.Left: x -= width; break; } GameObjectManage.CreateBullet(Tag.EnemyTank, x, y, this.Dir); } private void MoveCheck() { if (Dir == Direction.Up) { if (Y - Speen < 0) { ChangeDirection(); } } else if (Dir == Direction.Down) { if (Y + Speen + height > 780) { ChangeDirection(); } } else if (Dir == Direction.Left) { if (X - Speen < 0) { ChangeDirection(); } } else if (Dir == Direction.Right) { if (X + Speen + width > 790) { ChangeDirection(); } } Rectangle rectank = this.GetRectangle(); switch (Dir) { case Direction.Up: rectank.Y -= Speen; break; case Direction.Down: rectank.Y += Speen; break; case Direction.Right: rectank.X += Speen; break; case Direction.Left: rectank.X -= Speen; break; } if (GameObjectManage.IsCollidedWall(rectank) != null) { ChangeDirection(); return; } if(GameObjectManage.IsCollidedSteel(rectank) != null) { ChangeDirection(); return; } } private void ChangeDirection() { while (true) { int i = r.Next(0, 4); Direction dir = Direction.Up; switch (i) { case 1: dir = Direction.Left; break; case 2: dir = Direction.Right; break; case 3: dir = Direction.Down; break; } if (dir == Dir) { continue; } { Dir = dir; break; } } MoveCheck(); } private void Move() { switch (Dir) { case Direction.Up: Y -= Speen; break; case Direction.Down: Y += Speen; break; case Direction.Left: X -= Speen; break; case Direction.Right: X += Speen; break; } } } public enum Tag { MyTank, EnemyTank } public class Bullet : Movething { public bool IsDestroy { get; set; } public Tag tag { get;set; } public Bullet(int x, int y, int speed, Direction dir,Tag tag) { IsDestroy = false; this.X = x; this.Y = y; this.Speen = speed; Up = Resources.BulletUp; Down = Resources.BulletDown; Left = Resources.BulletLeft; Right = Resources.BulletRight; this.Dir = dir; this.tag = tag; } public override void DrawSelf() { base.DrawSelf(); } public override void Update() { MoveCheck();//移动检查 Move(); base.Update(); } private void MoveCheck() { if (Dir == Direction.Up) { if (Y + height - Speen < 0) { IsDestroy = true; return; } } else if (Dir == Direction.Down) { if (Y + Speen + height > 810) { IsDestroy = true; return; } } else if (Dir == Direction.Left) { if (X + width - Speen < 0) { IsDestroy = true; return; } } else if (Dir == Direction.Right) { if (X + Speen + width > 810) { IsDestroy = true; return; } } Rectangle rect = this.GetRectangle(); rect.X = X + width / 2 - 3; rect.Y = Y + height / 2 - 3; rect.Height = 3; rect.Width = 3; int xExplosion = this.X + width / 2; int yExplosion = this.Y + height / 2; NotMovething wall = null; if ((wall = GameObjectManage.IsCollidedWall(rect)) != null) { IsDestroy = true; GameObjectManage.DestortyWall(wall); GameObjectManage.CreateExplosion(xExplosion, yExplosion); SoundMananger.PlayBlast();return; } if (GameObjectManage.IsCollidedSteel(rect) != null) { IsDestroy = true; GameObjectManage.CreateExplosion(xExplosion, yExplosion); return; } if (GameObjectManage.IsCollidedBoss(rect)) { IsDestroy=true; GameObjectManage.CreateExplosion(xExplosion, yExplosion); SoundMananger.PlayBlast(); GameFrameWork.End(); return; } if(tag==Tag.MyTank) { EnemyTank tank = null; if ((tank = GameObjectManage.IsCollidedEnemyTank(rect)) != null) { IsDestroy = true; tank.EnemtTankDamage(); GameObjectManage.DestroyTank(tank); GameObjectManage.CreateExplosion(xExplosion, yExplosion); SoundMananger.PlayHit(); return; } } else if(tag==Tag.EnemyTank) { MyTake mytank = null; if ((mytank = GameObjectManage.IsCollidedMyTank(rect)) != null) { IsDestroy = true; GameObjectManage.CreateExplosion(xExplosion, yExplosion); SoundMananger.PlayBlast(); mytank.TakeDamage(); return; } } } private void Move() { switch (Dir) { case Direction.Up: Y -= Speen; break; case Direction.Down: Y += Speen; break; case Direction.Left: X -= Speen; break; case Direction.Right: X += Speen; break; } } } public class Explosion : GameObject { public bool IsNeedDestroy { get; set; } private int playSpeed = 1; private int playCount = 0;// 1 /2 = 0 private int index = 0; private Bitmap[] bmpArray = new Bitmap[] { Resources.EXP1, Resources.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; } public override Image GetImage() { if (index > 4) return bmpArray[4]; return bmpArray[index]; } public override void Update() { playCount++; index = (playCount - 1) / playSpeed;// 1-1/2=0 2-1/1 = 1 if (index > 4) { IsNeedDestroy = true; } base.Update(); } } public class SoundMananger { 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(); } } public class GameObjectManage { private static List<NotMovething> walllist=new List<NotMovething> (); private static List<NotMovething> steellist=new List<NotMovething> (); private static List<EnemyTank> tanklist = new List<EnemyTank>(); private static List<Bullet> bullets = new List<Bullet>(); private static List<Explosion> expList = new List<Explosion>(); private static NotMovething boss; private static MyTake mytake; private static int enemyBornSpeen = 60; private static int enemyBormCount = 60; private static Point[] points = new Point[6]; private static object _bulletlock = new object(); public static void Start() { points[0] = new Point(0, 0); points[1] = new Point(5, 0); points[2] = new Point(10, 0); points[3] = new Point(15 * 30, 0); points[4] = new Point(20 * 30, 0); points[5] = new Point(25 * 30, 0); } private static void CheckAndDestroyBullet() { lock (_bulletlock) { List<Bullet> needToDestroy = new List<Bullet>(); foreach (Bullet bullet in bullets) { if (bullet.IsDestroy == true) { needToDestroy.Add(bullet); } } foreach (Bullet bullet in needToDestroy) { bullets.Remove(bullet); } } } public static NotMovething IsCollidedWall(Rectangle rt) { foreach(var 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) { return boss.GetRectangle().IntersectsWith(rt); } public static void Update() { foreach (var wall in walllist) { wall.Update(); } foreach (var steel in steellist) { steel.Update(); } foreach (var tank in tanklist) { tank.Update(); } CheckAndDestroyBullet(); lock (_bulletlock) { foreach (var bullet in bullets) { bullet.Update(); } } foreach (Explosion exp in expList) { exp.Update(); } CheckAndDestroyExplosion(); boss.Update(); mytake.Update(); EnemyBorn(); } private static void CheckAndDestroyExplosion() { List<Explosion> needToDestroy = new List<Explosion>(); foreach (Explosion exp in expList) { if (exp.IsNeedDestroy == true) { needToDestroy.Add(exp); } } foreach (Explosion exp in needToDestroy) { expList.Remove(exp); } } public static void CreateBullet(Tag tag,int x,int y,Direction dir) { Bullet bullet = new Bullet(x, y, 5, dir, tag); lock (_bulletlock) { bullets.Add(bullet); } } private static void EnemyBorn() { enemyBormCount++; if (enemyBormCount < enemyBornSpeen) return; Random rd=new Random(); int index = rd.Next(0, 6); Point point = points[index]; int enemyType = rd.Next(1, 5); switch (enemyType) { case 1: CreateGrayEnemyTank(point.X, point.Y, 2); break; case 2: CreateGreenEnemyTank(point.X, point.Y, 2); break; case 3: CreateQuickEnemyTank(point.X, point.Y, 3); break; case 4: CreateSlowEnemyTank(index, point.Y, 1); break; } enemyBormCount = 0; } private static void CreateGreenEnemyTank(int x,int y,int speen) { EnemyTank enemy = new EnemyTank(x, y, speen, Direction.Down, Resources.GreenUp, Resources.GreenDown, Resources.GreenLeft, Resources.GreenRight,2); tanklist.Add(enemy); } private static void CreateSlowEnemyTank(int x, int y, int speen) { EnemyTank enemy = new EnemyTank(x, y, speen, Direction.Down, Resources.SlowUp, Resources.SlowDown, Resources.SlowLeft, Resources.SlowRight,4); tanklist.Add(enemy); } private static void CreateQuickEnemyTank(int x, int y, int speen) { EnemyTank enemy = new EnemyTank(x, y, speen, Direction.Down, Resources.QuickUp, Resources.QuickDown, Resources.QuickLeft, Resources.QuickRight, 2); tanklist.Add(enemy); } private static void CreateGrayEnemyTank(int x, int y, int speen) { EnemyTank enemy = new EnemyTank(x, y, speen, Direction.Down, Resources.GrayUp, Resources.GrayDown, Resources.GrayLeft, Resources.GrayRight,3); tanklist.Add(enemy); } public static void DrawMyTank() { mytake.DrawSelf(); } public static void GreateMap() { for(int i = 1; i < (815 / 30); i += 2) { walllist.AddRange(GreateWall(i, 1, 5, Resources.wall)); } for(int i=2; i < (785 / 30); i += 2) { walllist.AddRange(GreateWall(i, 7, 3, Resources.wall)); } for (int i = 2; i < (785 / 30); i += 4) { steellist.AddRange(GreateWall(i, 2, 3, Resources.steel)); } for (int i = 1; i < 24; i += 5) { walllist.AddRange(GreateWall(i, 11, 2, Resources.wall)); walllist.AddRange(GreateWall(i+1, 11, 2, Resources.wall)); walllist.AddRange(GreateWall(i+2, 11, 2, Resources.wall)); } steellist.AddRange(GreateWall(2, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(3, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(4, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(5, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(7, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(8, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(9, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(10, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(12, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(13, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(14, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(15, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(17, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(18, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(19, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(20, 14, 1, Resources.wall)); steellist.AddRange(GreateWall(22, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(23, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(24, 14, 1, Resources.steel)); steellist.AddRange(GreateWall(25, 14, 1, Resources.steel)); for (int i = 1; i < (815 / 30); i += 2) { walllist.AddRange(GreateWall(i, 16, 5, Resources.wall)); } for (int i = 2; i < (785 / 30); i += 2) { if (i != 12 && i != 14 && i != 10 && i != 16) { walllist.AddRange(GreateWall(i, 22, 4, Resources.wall)); } if (i == 10 || i == 16) { walllist.AddRange(GreateWall(i, 22, 2, Resources.wall)); } } walllist.AddRange(CreateBosswall(12, 24, 2, Resources.wall)); walllist.AddRange(CreateBosswall2(14, 24, 2, Resources.wall)); walllist.AddRange(GreateWall(12, 23, 1, Resources.wall)); walllist.AddRange(GreateWall(13, 23, 1, Resources.wall)); walllist.AddRange(GreateWall(14, 23, 1, Resources.wall)); CreateBoss(13, 25, Resources.Boss); } public static void CreateMyTank() { int x = 11 * 30; int y = 25 * 30; mytake = new MyTake(x, y, 2, Direction.Up); } private static List<NotMovething> GreateWall(int x,int y,int count,Image image) { List<NotMovething> walllist = new List<NotMovething>(); int xposition = x * 30; int yposition = y * 30; for (int i = yposition; i < yposition + count * 30; i += 15) { NotMovething wall = new NotMovething(xposition, i, image); NotMovething wall2 = new NotMovething(xposition + 15, i, image); walllist.Add(wall); walllist.Add(wall2); } return walllist; } private static List<NotMovething> CreateBosswall(int x, int y, int count, Image image) { int xposition = x * 30; int yposition = y * 30; for (int i = yposition; i < yposition + count * 30; i += 15) { NotMovething wall = new NotMovething(xposition, i, image); walllist.Add(wall); } return walllist; } private static List<NotMovething> CreateBosswall2(int x, int y, int count, Image image) { int xposition = x * 30; int yposition = y * 30; for (int i = yposition; i < yposition + count * 30; i += 15) { NotMovething wall2 = new NotMovething(xposition + 15, i, image); walllist.Add(wall2); } return walllist; } private static void CreateBoss(int x, int y, Image img) { int xPosition = x * 30; int yPosition = y * 30; boss = new NotMovething(xPosition, yPosition, img); } internal static void KeyDown(KeyEventArgs args) { mytake.KeyDown(args); } internal static void KeyUp(KeyEventArgs args) { mytake.KeyUp(args); } internal static void DestortyWall(NotMovething wall) { List<NotMovething> movewall= walllist.Where(e => e.X == wall.X && e.Y == wall.Y).ToList(); movewall.ForEach(x=>walllist.Remove(x)); } internal static void CreateExplosion(int xExplosion, int yExplosion) { Explosion exp = new Explosion(xExplosion, yExplosion); expList.Add(exp); } internal static void DestroyTank(EnemyTank tank) { if(tank.HP==0) tanklist.Remove(tank); } internal static EnemyTank IsCollidedEnemyTank(Rectangle rect) { foreach (EnemyTank tank in tanklist) { if (tank.GetRectangle().IntersectsWith(rect)) { return tank; } } return null; } internal static MyTake IsCollidedMyTank(Rectangle rect) { if (mytake.GetRectangle().IntersectsWith(rect)) return mytake; else return null; } } }
源代码文件:
https://files.cnblogs.com/files/blogs/795873/TankWarHH.rar?t=1691686924&download=true
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了