• 杨中科版C#射击游戏


    学习了杨中科版的C#射击游戏视频,大家可参考http://player.youku.com/player.php/sid/XMTUyNjQ3NjQ0/v.swf

    准备素材,一张飞机图片,一个WAV的飞机遇到子弹爆炸音效。
    1.创建一个WinForm应用程序
    Form窗体,拖一个panel控件,相当于战场。拖一个Timer控件,操纵飞机与子弹运行。
    panel控件中用到会三个事件,一个是Paint事件,用来触发调用画飞机和子弹。第一个是MouseClick事件,主要用来任意点击panel区域时,发射子弹。还有一个是Timer的Tick事件,用来控制飞机与子弹的移动。
    2.创建抽象类GameObject,用于子弹类,飞机类继承。子弹和飞机,共同拥有的属性,在panel上的X,Y的坐标,以及Draw()画子弹/飞机和Move()移动的方法。
    3.创建子弹Bullut与飞机Plane的类继承于抽象类GameObject;同时添加子弹自己的特有的属性和方法,例如,Bullet类自己的属性有bool isFired,判断是否发射子弹(子弹是当鼠标点击时才需要发射),Bullet类自己的方法有判断子弹是否击中飞机bool IsHit();
    Panel类自己有属性有HitTime子弹击中的次数,本游戏中子弹需击中两次方可爆炸,并发出爆炸音。
    bool IsVisble属性用于当子弹第一次击中飞机时,飞机开始闪烁,(闪烁实现的效果就是一会让飞机画在panel上,一会又把它隐藏掉),Panel类中自己的方法有Resart,当飞机飞到边界时或击碎时,飞机需从左边重新出现。
    4.新建一个GamePanel类,让它继承于Panel控件,解决游戏中在运行中飞机不停闪烁的问题(不是击中第一次后飞机闪烁)。应用了双缓冲。
    具体代码如下:

    Form1.cs
    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using Game.Properties;
    using System.Media;

    namespace Game
    {
        public partial class Form1 : Form
        {
            Plane plane;
            Bullet bullet;
            public Form1()
            {
                InitializeComponent();
                NewBullet();
                NewPlane();
            }

           //实例化一个子弹

            private void NewBullet()
            {
                bullet = new Bullet();
                bullet.isFired = false;
                bullet.rect = panelFiled.ClientRectangle;
                bullet.Y = panelFiled.ClientRectangle.Height;
            }
           //实例化一个飞机
            private void NewPlane()
            {
                plane = new Plane();
                plane.Restart();
                plane.rect= panelFiled.ClientRectangle;
                Random rad = new Random();
                plane.Y = rad.Next(0, 100)//飞机随机在左侧Y轴方向出现

            }

            private void panelFiled_Paint(object sender, PaintEventArgs e)
            {
               
                plane.Draw(e.Graphics);
                bullet.Draw(e.Graphics);
                      
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                bullet.Move();
                plane.Move();
                if (bullet.Ishit(plane) == true)//判断当子弹击中飞机时的情况
                {
                    NewBullet();
                    plane.HitTime++;
                    if (plane.HitTime == 2)//当两次击中时,发出爆炸声音
                    {
                        NewPlane();
                        SoundPlayer player = new SoundPlayer(Resources.BOMB);
                        player.Play();
                                    
                    }
                }
                panelFiled.Invalidate();
            }

            private void panelFiled_MouseClick(object sender, MouseEventArgs e)
            {
                bullet.isFired = true; //当鼠标开始点击中,发射子弹
                bullet.X = e.X;
                bullet.Y = panelFiled.ClientRectangle.Height;
                panelFiled.Invalidate();

            }

         
        }
     
    }
    //抽象类
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;

    namespace Game
    {
       
       
       abstract class GameObject
        {
            public int X { get; set; }
            public int Y { get; set; }
            public Rectangle rect { get; set; }
            public abstract void Draw(Graphics e);
            public abstract void Move();
        }
     

    }


    //子弹类
    using System.Drawing;
    using System;


    namespace Game
    {

        class Bullet:GameObject
        {
            public const int R = 5;//子弹的半径
            public bool isFired { get; set; }
            //画子弹
            public override void Draw(Graphics e)
            {
                if (isFired == false) //用来判断是否开始点击,没有点击不可自动发射子弹
                {
                    return;
                }
                e.FillEllipse(new SolidBrush(Color.Black), X, Y, R * 2, R * 2);
              
            }
            public override void Move()
            {
                if (isFired == false)
                {
                    return;
                }
                Y=Y-3;//向上移动
            }
            //判断子弹是否击中飞机,求出两物体之间的距离,如果小于小物体的半径之各则判断其相撞
            public bool Ishit(Plane plane)
            {
                int detalX = plane.X - X;
                int detalY = plane.Y - Y;
                double dist = Math.Sqrt(detalX * detalX + detalY * detalY);
                if (dist > Bullet.R + Plane.R)
                {
                    return false;

                }
                else
                    return true;
            }    
        }
    }

    //飞机类

    namespace Game
    {
        class Plane:GameObject
        {
            public const int R = 25;
            public int HitTime { get; set; }
            private bool isVisble;
            public int speed { get; set; }
            Random rad = new Random();
            public override void Draw(Graphics e)
            {
                if (HitTime == 1) //判断击中一次时,飞机开始闪烁,让其时而可见,时而消失
                {
                    isVisble = !isVisble;
                    if(!isVisble)
                    {
                        return;
                    }

                }
                e.DrawImage(Resources.plane, X, Y, R*2, R*2);
            }
           //飞机爆炸或都撞到右侧panel时,重新出现
            public void Restart()
            {
                speed = rad.Next(1, 3);
                Y = rad.Next(0, rect.Height);//重现出现的位置Y轴随机
                X = 0;
                HitTime = 0;//重现出现时击中次数为0
            }
            public override void Move()
            {
               //移动的速度
                X = X + speed;//向右移动
                if (X > rect.Width)
                {
                    Restart();
                }
            }
        }
    }

    //解决双缓冲的类
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace Game
    {
        class GamePanel:Panel
        {
            public GamePanel()
            {
                SetStyle(ControlStyles.UserPaint |
                    ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.OptimizedDoubleBuffer |
                    ControlStyles.ResizeRedraw |
                    ControlStyles.SupportsTransparentBackColor, true);
           }
        }
    }

  • 相关阅读:
    202103226-1 编程作业
    7 20210516-1 团队作业3—需求分析规格说明书
    原型设计作业
    案例分析作业
    202103226-1 编程作业
    阅读——《构建之法》
    第一周学习任务
    牛客app测评报告
    wordcount编程
    准备工作
  • 原文地址:https://www.cnblogs.com/agile2011/p/2055517.html
Copyright © 2020-2023  润新知