• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
学习笔记
Misaka的学习笔记
博客园    首页    新随笔    联系   管理    订阅  订阅
c#学习笔记-------------------GDI+绘图编程入门

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的进一步扩展,它使我们编程更加方便。

 

命名空间和相关类

命名空间:

  1. System.Drawing:这个主要的GDI+命名空间定义了许多类型,实现基本的绘图类型(字体,钢笔,基本画笔等)和无所不能的Graphics对象。

  2. System.Drawing2D:这个命名空间提供高级的二维和失量图像功能。
  3.  

    System.Drawing.Imaging:这个命名空间定义了一些类型实现图形图像的操作。

  4. System.Drawing.Text:这个命名空间提供了操作字体集合的功能。

  5.  System.Drawing.Printing:这个命名空间定义了一些类型实现在打印纸上绘制图像,和打印机交互以及格式化某个打印任务的总体外观等功能。

相关类:

  1. Graphics类:Graphics类封装一个GDI+绘图图面,提供将对象绘制到显示设备的方法,Graphics与特定的设备上下文关联。画图方法都被包括在Graphics类中,在画任何对象(例如:Circle,Rectangle)时,我们首先要创建一个Graphics类实例,这个实例相当于建立了一块画布,有了画布才可以用各种画图方法进行绘图。
  2. Pen类:画笔,定义用于绘制直线和曲线的对象。

  3. Brush类:画刷:定义用于填充图形形状(如矩形、椭圆、饼形、多边形和封闭路径)的内部的对象。只是一个抽象基类。
  4. Font类:字体Font类有两个构造函数:

    第一个是new Font(字体名称,字号),例如,label1.Font=new Font("黑体",9)。

    第二个是new Font(字体名称,字号,字体风格),其中第三个参数是枚举类型。

  5. 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

 

 

 

 
 
 
 
 
posted on 2023-08-10 00:46  我们打工人  阅读(657)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3