C#坦克大戰實現


記得在大學學java時,同學在下載了很多java的視頻,看到里面有些是介紹簡單游戲開發的,馬士兵老師講的,挺感興趣的。一起看了看視頻寫了寫程序。現在畢業了,因為工作中用的是C#,最近很想拿C#把以前寫的坦克大戰重寫下,來熟悉熟悉C#的基本語法。

程序很簡單,跟java代碼相比沒有多大改動

實現方法如下

1.在form中添加一個panel,在panel的 Paint方法中得到Graphics對象 

2.通過Graphics對象再panel畫出坦克,子彈等相關內容

3.添加timer控件 來控制panel的重畫 實現坦克,子彈的運動

4.根據電腦按下的方向鍵,確定出坦克的方向,panel重畫時根據坦克的方向修改坦克的X,Y軸坐標,來實現坦克的移動

5.通過Rectangle的IntersectsWith函數來進行碰撞檢測,實現子彈打擊坦克

 

具體實現代碼

1.在項目里面添加枚舉類型

    /// <summary>

    /// 表示方向的的枚舉類型

    /// </summary>

    public enum Direction { L, U, D, R, STOP }

2.添加子彈類的相關常量,屬性

        /// <summary>

        /// 子彈X軸的速度,單位PX

        /// </summary>

        public static int XSPEED = 10;

 

        /// <summary>

        /// 子彈Y軸的速度,單位PX

        /// </summary>

        public static int YSPEED = 10;

 

        /// <summary>

        /// 子彈的寬度

        /// </summary>

        public static int WIDTH = 10;

 

        /// <summary>

        /// 子彈的高度

        /// </summary>

        public static int HEIGHT = 10;

 

        /// <summary>

        /// 子彈的坐標

        /// </summary>

        int x, y;

 

        /// <summary>

        /// 子彈的方向

        /// </summary>

        Direction dir;

 

        /// <summary>

        /// 子彈的存活狀態

        /// </summary>

        private bool live = true;

 

        /// <summary>

        /// TankClient窗體實例

        /// </summary>

        private TankClient tankClient;

 

        /// <summary>

        /// 敵我雙方的標記

        /// </summary>

        private bool good;

3.添加draw方法來畫出子彈

        public void Draw(Graphics g)

        {

            if (!live)

            {

                tankClient.missiles.Remove(this);

                return;

            }

            //通過畫橢圓函數在界面上顯示子彈

            g.FillEllipse(Brushes.Black, x, y, Missile.WIDTH, Missile.HEIGHT);

            Move();

        }

4.添加子彈打擊坦克的方法

        public bool HitTank(Tank t)

        {

            //用IntersectsWith來檢測兩個矩形相碰撞

            if (GetRectangle().IntersectsWith((t.GetRectangle())) && t.Live && this.live && this.good != t.Good)

            {

                t.Live = false;

                this.live = false;

                return true;

            }

            return false;

        }

5.添加坦克類相關屬性,常量

 

        /// <summary>

        /// 坦克x軸的速度

        /// </summary>

        public static int XSPEED = 5;

 

        /// <summary>

        /// 坦克y軸的速度

        /// </summary>

        public static int YSPEED = 5;

 

        /// <summary>

        /// 坦克的寬度

        /// </summary>

        public static int WIDTH = 30;

 

        /// <summary>

        /// 坦克的高度

        /// </summary>

        public static int HEIGHT = 30;

 

        /// <summary>

        /// 坦克的坐標

        /// </summary>

        private int x, y;

 

        /// <summary>

        /// 標記上下左右鍵是否按下

        /// </summary>

        private bool l = false, u = false, r = false, d = false;

 

        /// <summary>

        /// 坦克的方向

        /// </summary>

        private Direction dir = Direction.STOP;

 

        /// <summary>

        /// 坦克炮筒方向

        /// </summary>

        private Direction ptDir = Direction.D;

 

        /// <summary>

        /// TankClient窗體實例

        /// </summary>

        TankClient tankClient;

 

        /// <summary>

        /// 標記敵我雙方

        /// </summary>

        private bool good;

 

        /// <summary>

        /// 控制敵人坦克不規則運行時使用

        /// </summary>

        private int step = 0;

 

        /// <summary>

        /// 標記坦克的存活狀態

        /// </summary>

        private bool live = true;

6.在tank類中實現畫坦克方法

        public void Draw(Graphics g)

        {

            if (!live)

            {

                if (!good)

                {

                    tankClient.tanks.Remove(this);

                }

                return;

            }

            if (good)

            {

                //通過FillEllipse來畫坦克

                g.FillEllipse(Brushes.Red, x, y, WIDTH, HEIGHT);

            }

            else

            {

                g.FillEllipse(Brushes.Blue, x, y, WIDTH, HEIGHT);

            }

            //根據炮筒坦克來畫出坦克的炮筒

            switch (ptDir)

            {

                case Direction.D:

                    g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y + HEIGHT);

                    break;

                case Direction.U:

                    g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y);

                    break;

                case Direction.L:

                    g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x, y + HEIGHT / 2);

                    break;

                case Direction.R:

                    g.DrawLine(Pens.Black, x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH, y + HEIGHT / 2);

                    break;

            }

            Move();

        }

7.鍵盤按鍵處理的相關代碼

        public void KeyPressed(KeyEventArgs e)

        {

            Keys key = e.KeyCode;

            switch (key)

            {

                case Keys.Right:

                    r = true;

                    break;

                case Keys.Left:

                    l = true;

                    break;

                case Keys.Up:

                    u = true;

                    break;

                case Keys.Down:

                    d = true;

                    break;

            }

            LocateDirection();

        }

8.tank發子彈的方法

        public Missile Fire()

        {

            if (!live) return null;

            int x = this.x + WIDTH / 2 - Missile.WIDTH / 2;

            int y = this.y + HEIGHT / 2 - Missile.HEIGHT / 2;

            Missile missile = new Missile(x, y, good, ptDir, tankClient);

            tankClient.missiles.Add(missile);

            return missile;

        }

 

9.主窗體類加入坦克 

            myTank = new Tank(50, 20, true, this);//放到前面 this不能用  //y軸比java的減少了30

            for (int i = 0; i < 15; i++)

            {

                //添加10個坦克x軸間距為40px

                tanks.Add(new Tank(50+40*(i+1),20,false,this)); //y軸比java的減少了30

            }

10.主窗體類中調用子彈打擊坦克的方法

            for (int i = 0; i < missiles.Count; i++)

            {

                Missile m = missiles[i];

                m.HitTank(myTank);

                m.HitTanks(tanks);

                m.Draw(g);

            }

11.主窗體處理按鍵代碼

        private void Form1_KeyDown(object sender, KeyEventArgs e)

        {

            myTank.KeyPressed(e);

        }

 

12.控制重畫代碼

        private void timer1_Tick(object sender, EventArgs e)

        {

            //間隔50毫秒控制panel的重畫

            panel1.Invalidate();

        }

 

13.這是主要代碼基本完成,但是游戲會有閃爍問題

可以通過雙緩沖來解決,C#解決時很省事,一個函數就能解決

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer |

                    ControlStyles.ResizeRedraw |

                    ControlStyles.AllPaintingInWmPaint, true);

 

 

順便改了個手機版本的但是手機版本的沒能解決雙緩沖問題,屏幕有些閃爍,朋友們可以自己改進

 

代碼下載   http://files.cnblogs.com/hehe108/tanker.rar

 

如果你發現有什么不合理的,需要改進的地方,郵件聯系328452421@qq.com(qq常年不在線,郵件聯系) 。相互交流 謝謝

 

 

 

 

 

作者:hehe108
出處:http://www.cnblogs.com/hehe108/ 
關於作者:菜鳥一枚。如有問題或建議,請多多賜教! 
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接
如有問題,可以通過   328452421@qq.com    聯系我,非常感謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM