x01.Game.Dragon.2: 箭术表演

只要想射中,就能射中,所以叫箭术表演。

1.给 Sprite 类添加一属性:

       public bool Alive { get; set; }

  因为要射中恐龙,所以还需一碰撞检测函数 HasCollision(),代码如下:

HasCollision()
       public bool HasCollision(ref Sprite other)
        {
            return Bound.IntersectsWith(other.Bound);
        }

2.现在要修改 MainForm 类了。主要是添加了 arrow,archer 字段。变化的地方,即注释的地方。完整代码如下:

MainForm
    public partial class MainForm : Form
    {
        const string ImgDir = @"F:\Resource\Image\game\";

        GameBox gameBox;
        Sprite dragon;
        Sprite archer;
        Sprite arrow;
        //Bitmap dragonImage;
        //Bitmap grass;
        //PointF offset;

        bool isOver = false;
        //int direction = 2;
        int score = 0;

        public MainForm()
        {
            InitializeComponent();
            Init();
        }

        protected override void OnClosed(EventArgs e)
        {
            GameOver();
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    Run();
                    break;
                case Keys.Escape:
                    GameOver();
                    break;
                case Keys.Space:
                    if (!arrow.Alive)
                    {
                        archer.FrameDirection = Sprite.FrameDirectionE.Forward;
                        archer.CurrentFrame = 10;
                    }
                    break;
                //case Keys.Up:
                //    direction = 0;
                //    break;
                //case Keys.Right:
                //    direction = 2;
                //    break;
                //case Keys.Down:
                //    direction = 4;
                //    break;
                //case Keys.Left:
                //    direction = 6;
                //    break;
            }
        }

        void Run()
        {
            int currentTime = 0, startTime = 0;
            while (!isOver)
            {
                ArrowUpdate();
                currentTime = Environment.TickCount;
                if (currentTime > startTime + 16)
                {
                    startTime = currentTime;
                    Draw();
                    Application.DoEvents();
                    gameBox.Refresh();
                }
            }
            Application.Exit();
        }
        private void GameOver()
        {
            isOver = true;
        }
        private void Init()
        {
            Text = "Dragon Game";
            Size = new Size(800, 600);

            gameBox = new GameBox(800, 600);
            gameBox.Parent = this;
            gameBox.Dock = DockStyle.Fill;
            gameBox.Print(10, 10, "Enter: 开始");
            
            //dragonImage = new Bitmap(ImgDir + "dragon.png");
            //grass = new Bitmap(ImgDir + "grass.bmp");

            dragon = new Sprite(ref gameBox);
            dragon.Image = new Bitmap(ImgDir + "dragon.png");
            dragon.Size = new Size(256, 256);
            dragon.Columes = 8;
            dragon.Frames = 64;
            dragon.Position = new PointF(250, 50);
            dragon.Offset = new PointF(-4, 0);

            arrow = new Sprite(ref gameBox);
            arrow.Image = new Bitmap(ImgDir + "arrow.png");
            arrow.Size = new Size(32, 32);
            arrow.Columes = 1;
            arrow.Frames = 1;
            arrow.Alive = false;
            arrow.Offset = new PointF(0, -12);

            archer = new Sprite(ref gameBox);
            archer.Image = new Bitmap(ImgDir + "archer_attack.png");
            archer.Size = new Size(96, 96);
            archer.Columes = 10;
            archer.Frames = 80;
            archer.Position = new PointF(360, 500);
            archer.FrameDirection = Sprite.FrameDirectionE.None;
        }

        void Draw()
        {
            Bitmap grass = new Bitmap(ImgDir + "grass.bmp");
            gameBox.Device.DrawImageUnscaled(grass, 0, 0, 800, 600);

            if (arrow.Alive)
            {
                arrow.Position = new PointF(arrow.Position.X, arrow.Position.Y + arrow.Offset.Y);
                if (arrow.Position.Y < -32)
                {
                    arrow.Alive = false;
                }
                arrow.Draw();
            }

            archer.Animation(10, 19);
            if (archer.CurrentFrame == 19)
            {
                archer.FrameDirection = Sprite.FrameDirectionE.None;
                archer.CurrentFrame = 10;
                arrow.Alive = true;
                arrow.Position = new PointF(archer.Position.X + 32, archer.Position.Y);
            }
            archer.Draw();

            dragon.Position = new PointF(dragon.Position.X + dragon.Offset.X, dragon.Position.Y);
            if (dragon.Position.X < -128)
            {
                dragon.Position = new PointF(800, dragon.Position.Y);
            }
            dragon.Animation(6 * 8 + 1, 6 * 8 + 8);
            dragon.Draw();

            gameBox.Print(0, 0, "\nScore: " + score.ToString());
            //Bitmap grass = new Bitmap(ImgDir + "grass.bmp");
            //gameBox.Device.DrawImageUnscaled(grass, 0, 0, 800, 600);

            //switch (direction)
            //{
            //    case 0: // up
            //        offset = new PointF(0, -1);
            //        break;
            //    case 2: // right
            //        offset = new PointF(1, 0);
            //        break;
            //    case 4: // down
            //        offset = new PointF(0, 1);
            //        break;
            //    case 6: // left
            //        offset = new PointF(-1, 0);
            //        break;
            //    default:
            //        break;
            //}

            //dragon.Position = new PointF(dragon.Position.X + offset.X, dragon.Position.Y + offset.Y);
            //dragon.Animation(direction * 8 + 1, direction * 8 + 8);
            //dragon.Draw();

            gameBox.Print(0, 0, "Esc: 结束    Space: 射箭");
        }
        void ArrowUpdate()
        {
            if (arrow.Alive)
            {
                if (arrow.HasCollision(ref dragon))
                {
                    arrow.Alive = false;
                    score++;
                    dragon.Position = new PointF(800, dragon.Position.Y);
                }
            }
        }
    }

  虽然能射击,但没有声音,未免美中不足。

3.声音分两种,一种为即时音效,如射中恐龙时听到的电击声: foom.wav 文件;一种为背景音乐: song.mid 文件。

  要实现即时音效,首先在 MainForm 中添加字段

        SoundPlayer   soundPlayer;

  然后添加一个设置该字段的方法 SetSoundPlayer(),代码如下:

SetSoundPlayer()
        public SoundPlayer SetSoundPlayer(string path)
        {
            SoundPlayer player = null;
            try
            {
                player = new SoundPlayer();
                player.SoundLocation = path;
                player.Load();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return player;
        }

  在 Init() 中使用此方法初始化 soundPlayer 字段:

        soundPlayer = SetSoundPlayer(ImgDir + "foom.wav");

  在 ArrowUpdate() 中如检测碰撞恐龙为真,则添加语句:
        soundPlayer.Play();

  如此,即时音效完成。

  要实现背景音乐,需要 interop.WMPLib.dll, 或 COM 中的 Window Media Player 组件,注意是 wmp.dll 。添加该库引用后,在 MainForm 中添加字段:

        WindowsMediaPlayer    wmPlayer;

  在 Init() 中初始化该字段:

        wmPlayer = new WindowsMediaPlayer();

        wmPlayer.URL = ImgDir + "song.mid";

  按 F5,即可听到背景音乐。如射中恐龙,即时音效也能听到。所有相关资源,可到 x01.download 下载。

 

posted on 2012-05-10 10:11  x01  阅读(802)  评论(0编辑  收藏  举报

导航