Head First C#(冒险游戏)

冒险游戏的界面如上图所示,就是简单的闯关游戏,一共有5种道具和3种怪物

道具分别为:剑、弓箭、锤子、蓝药水和红药水

怪物分别为:蝙蝠、幽灵、食尸鬼

类图视图如下所示,怪物类、道具类和玩家类继承于移动类。

代码实现如下:

namespace 冒险游戏
{
    public partial class Form1 : Form
    {
        private Game game;
        private Random random = new Random();
    
        public Form1()
        {
            InitializeComponent();
        }

        public void UpdateCharacters()
        {
            Player.Visible = true;
            Player.Location = game.PlayerLocation;
            lbPlayer.Text = game.PlayerHitPoints.ToString();
           
            //显示和隐藏生成的敌人
            #region Enemy                  
            int enemiesShown = game.Enemies.Count;
            
            foreach (Enemy enemy in game.Enemies)
            {
                if (enemy is Bat)
                {
                    bat.Location = enemy.Location;
                    lbBat.Text = enemy.HitPoints.ToString();
                    if (enemy.HitPoints > 0)
                    {                       
                        bat.Visible = true;
                    }
                    else
                    {
                        enemiesShown--;
                        bat.Visible = false;
                        game.Enemies.Remove(enemy);
                        break;
                    }
                }

                if (enemy is Ghost)
                {
                    ghost.Location = enemy.Location;
                    lbGhost.Text = enemy.HitPoints.ToString();
                    if (enemy.HitPoints > 0)
                    {                     
                        ghost.Visible = true;
                    }
                    else
                    {
                        enemiesShown--;
                        ghost.Visible = false;
                        game.Enemies.Remove(enemy);
                        break;
                    }
                }

                if (enemy is Ghoul)
                {
                    ghoul.Location = enemy.Location;
                    lbGhoul.Text = enemy.HitPoints.ToString();
                    if (enemy.HitPoints > 0)
                    {                       
                        ghoul.Visible = true;
                    }
                    else
                    {
                        enemiesShown--;
                        ghoul.Visible = false;
                        game.Enemies.Remove(enemy);
                        break;
                    }
                }
            }
            
            #endregion

            //显示和隐藏道具
            #region inventory                      
            Control weaponControl = null;
            switch (game.WeaponInRoom.Name)
            { 
                case "Sword":
                    weaponControl = sword;
                    break;
                case "BluePotion":
                    weaponControl = bluePotion;
                    break;
                case "RedPotion":
                    weaponControl = redPotion;
                    break;
                case "Bow":
                    weaponControl = bow;
                    break;
                case "Mac":
                    weaponControl=mac;
                    break;
                default: break;
            }
            if (weaponControl != null)
            {
                weaponControl.Visible = true;
                weaponControl.Location = game.WeaponInRoom.Location;
            }
            if (game.WeaponInRoom.PickedUp)
            {
                weaponControl.Visible = false;        
            }   
            foreach (string weapon in game.PlayerWeapons)
            {
                switch (weapon)
                {
                    case "Sword":
                        picSword.Visible = true;
                        break;
                    case "BluePotion":
                        picBluePotion.Visible = true;
                        break;
                    case "RedPotion":
                        picRedPotion.Visible = true;
                        break;
                    case "Bow":
                        picBow.Visible = true;
                        break;
                    case "Mac":
                        picMac.Visible = true;
                        break;
                    default: break;
                }
            }
            if (!game.CheckPlayerInventory("BluePotion"))
            {
                picBluePotion.Visible = false;
            }
            if (!game.CheckPlayerInventory("RedPotion"))
            {
                picRedPotion.Visible = false;
            }
            #endregion


            //自己血量不足游戏结束
            if (game.PlayerHitPoints <= 0)
            {
                MessageBox.Show("You died");
                Application.Exit();
            }

            //没有敌人到下一关
            if (enemiesShown < 1)
            {
                MessageBox.Show("You have defeatead the enemies on this level");
                lbBat.Text = "";
                lbGhost.Text = "";
                lbGhoul.Text = "";
                if (!game.NewLevel(random))
                {
                    Application.Exit();
                    return;
                }
                weaponControl.Visible = false;
                UpdateCharacters();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            game = new Game(new Rectangle(78, 57, 420, 155));
            game.NewLevel(random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向下移动
        /// </summary>
        private void btnM_Right_Click(object sender, EventArgs e)
        {
            game.Move(Direction.Right,random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向下移动
        /// </summary>
        private void btnM_Down_Click(object sender, EventArgs e)
        {
            game.Move(Direction.Down,random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向左移动
        /// </summary>
        private void btnM_Left_Click(object sender, EventArgs e)
        {
            game.Move(Direction.Left,random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向上移动
        /// </summary>
        private void btnM_Up_Click(object sender, EventArgs e)
        {
            game.Move(Direction.Up,random);
            UpdateCharacters();
        }

        /// <summary>
        /// 装备物品
        /// </summary>
        private void picSword_Click(object sender, EventArgs e)
        {          
            foreach (Control pic in this.Controls)
            {
                if (pic is PictureBox)
                {
                    ((PictureBox)pic).BorderStyle = BorderStyle.None;            
                     game.Equip(((PictureBox)sender).Tag.ToString());
                     if (((PictureBox)sender).Tag.ToString().Contains("Potion"))
                     {
                         panelAttrack.Visible = false;
                         btnDrink.Visible = true;
                     }
                     else
                     {
                         panelAttrack.Visible = true;
                         btnDrink.Visible = false;
                     }
                }
            }
            ((PictureBox)sender).BorderStyle = BorderStyle.FixedSingle;
        }

        /// <summary>
        /// 用上下左右键盘移动
        /// </summary>
        protected override bool  ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            { 
                case Keys.Up:
                    btnM_Up_Click(null, null);
                    break;
                case Keys.Left:
                    btnM_Left_Click(null, null);
                    break;
                case Keys.Right:
                    btnM_Right_Click(null, null);
                    break;
                case Keys.Down:
                    btnM_Down_Click(null,null);
                    break;
                default:
                    break;
            }       
            return true;
        }

        /// <summary>
        /// 向上攻击
        /// </summary>
        private void btnA_Up_Click(object sender, EventArgs e)
        {
            game.Attack(Direction.Up,random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向左攻击
        /// </summary>
        private void btnA_Left_Click(object sender, EventArgs e)
        {
            game.Attack(Direction.Left, random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向左攻击
        /// </summary>
        private void btnA_Down_Click(object sender, EventArgs e)
        {
            game.Attack(Direction.Down, random);
            UpdateCharacters();
        }

        /// <summary>
        /// 向右攻击
        /// </summary>
        private void btnA_Right_Click(object sender, EventArgs e)
        {
            game.Attack(Direction.Right, random);
            UpdateCharacters();
        }

        /// <summary>
        /// 吃药
        /// </summary>
        private void btnDrink_Click(object sender, EventArgs e)
        {
            game.Attack(Direction.Right, random);
            game.Equip(null);
            UpdateCharacters();
            btnDrink.Visible = false;
            panelAttrack.Visible = true;
        } 
    }

    /// <summary>
    /// 方向
    /// </summary>
    public enum Direction
    {
        Up, Left, Right, Down
    }

    /// <summary>
    /// 游戏类
    /// </summary>
    public class Game
    {
        public List<Enemy> Enemies;
        public Weapon WeaponInRoom;

        private Player player;
        public Point PlayerLocation { get { return player.Location; } }
        public int PlayerHitPoints { get { return player.HitPoints; } }
        public List<string> PlayerWeapons { get { return player.Weapons; } }

        private int level = 0;
        public int Level { get { return level; } }

        private Rectangle boundaries;
        public Rectangle Boundaries { get { return boundaries; } }

        public Game(Rectangle boundaries)
        {
            this.boundaries = boundaries;
            player = new Player(this,new Point(boundaries.Left+10,boundaries.Top+70),boundaries);
        }

        public void Move(Direction direction,Random random)
        {
            player.Move(direction);
            foreach (Enemy enemy in Enemies)
                enemy.Move(random);
        }

        public void Equip(string weaponName)
        {
            player.Equip(weaponName);
        }

        /// <summary>
        /// 玩家道具栏里是否有某武器
        /// </summary>
        public bool CheckPlayerInventory(string weaponName)
        {
            return player.Weapons.Contains(weaponName);
        }

        public void HitPlayer(int maxDamage,Random random)
        { 
            player.Hit(maxDamage,random); 
        }

        public void IncreasePlayerHealth(int health,Random random)
        {
            player.IncreaseHeath(health,random);
        }

        public void Attack(Direction direction,Random random)
        {
            player.Attract(direction,random);
            foreach (Enemy enemy in Enemies)
                enemy.Move(random);

        }

        private Point GetRandomLocation(Random random)
        {
            return new Point(boundaries.Left + random.Next(boundaries.Right / 10 - boundaries.Left / 10) * 10,
                boundaries.Top +
            random.Next(boundaries.Bottom / 10 - boundaries.Top / 10) * 10);
        }

        public bool NewLevel(Random random)
        {
            level++;
            switch (level)
            { 
                case 1:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Bat(this,GetRandomLocation(random),boundaries));
                    WeaponInRoom = new Sword(this,GetRandomLocation(random));
                    break;
                case 2:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghost(this, GetRandomLocation(random), boundaries));
                    WeaponInRoom = new BluePotion(this, GetRandomLocation(random));                   
                    break;
                case 3:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghoul(this, GetRandomLocation(random), boundaries));
                    WeaponInRoom = new Bow(this,GetRandomLocation(random));
                    break;
                case 4:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Bat(this, GetRandomLocation(random), boundaries));
                    Enemies.Add(new Ghost(this, GetRandomLocation(random), boundaries));
                    if(!CheckPlayerInventory("Bow"))
                        WeaponInRoom = new Bow(this, GetRandomLocation(random));
                    else
                        WeaponInRoom = new BluePotion(this, GetRandomLocation(random));
                    break;
                case 5:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Bat(this, GetRandomLocation(random), boundaries));
                    Enemies.Add(new Ghoul(this, GetRandomLocation(random), boundaries));
                    WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                    break;
                case 6:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghost(this, GetRandomLocation(random), boundaries));
                    Enemies.Add(new Ghoul(this, GetRandomLocation(random), boundaries));
                    WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    break;
                case 7:
                    Enemies = new List<Enemy>();
                    Enemies.Add(new Ghost(this, GetRandomLocation(random), boundaries));
                    Enemies.Add(new Ghoul(this, GetRandomLocation(random), boundaries));
                    Enemies.Add(new Bat(this, GetRandomLocation(random), boundaries));
                    if (!CheckPlayerInventory("Mac"))
                        WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    else
                        WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                    break;
                case 8:
                    MessageBox.Show("恭喜你通关了");
                    return false;                                          
            }
            return true;
        }
    }

    /// <summary>
    /// 移动类,敌人和自己的移动都继承这个类
    /// </summary>
    public abstract class Mover
    {
        private const int MoveInterval = 10;
        protected Point location;
        public Point Location { get { return location; } }
        protected Game game;

        public Mover(Game game, Point location)
        {
            this.game = game;
            this.location = location;
        }

        /// <summary>
        /// 用弓箭看是否在一条直线上并且在射程内
        /// </summary>
        public bool Nearby(Direction direnction,Point locationToCheck, int distance)
        {
            switch (direnction)
            { 
                case Direction.Down:
                    if (game.PlayerLocation.X == locationToCheck.X && Math.Abs(game.PlayerLocation.Y - locationToCheck.Y) < distance && game.PlayerLocation.Y < locationToCheck.Y)
                        return true;
                    break;
                case Direction.Up:
                    if (game.PlayerLocation.X == locationToCheck.X && Math.Abs(game.PlayerLocation.Y - locationToCheck.Y) < distance && game.PlayerLocation.Y > locationToCheck.Y)
                    return true;
                break;
                case Direction.Left:
                if (game.PlayerLocation.Y == locationToCheck.Y && Math.Abs(game.PlayerLocation.X - locationToCheck.X) < distance && game.PlayerLocation.X > locationToCheck.X)
                    return true;
                break;
                case Direction.Right:
                if (game.PlayerLocation.Y == locationToCheck.Y && Math.Abs(game.PlayerLocation.X - locationToCheck.X) < distance && game.PlayerLocation.X < locationToCheck.X)
                return true;
                break;
            }       
            return false;
        }

        /// <summary>
        /// 剑和锤判断怪物是否在武器攻击半径内
        /// </summary>
        public bool Nearby(Point location, Point locationToCheck, int radius)
        {
            if (Math.Sqrt(Math.Abs(location.X - locationToCheck.X) * Math.Abs(location.X - locationToCheck.X) +
                Math.Abs(location.Y - locationToCheck.Y) * Math.Abs(location.Y - locationToCheck.Y)) <= radius)
                return true;
            else
                return false;
        }

        public Point Move(Direction direction, Rectangle boundaries)
        {
            Point newLocation = location;
            switch (direction) 
            {
                case Direction.Up:
                    if(newLocation.Y-MoveInterval>=boundaries.Top)
                        newLocation.Y-=MoveInterval;
                    break;
                case Direction.Down:
                    if (newLocation.Y + MoveInterval <= boundaries.Bottom)
                        newLocation.Y += MoveInterval;
                    break;
                case Direction.Left:
                    if (newLocation.X - MoveInterval >= boundaries.Left)
                        newLocation.X -= MoveInterval;
                    break;
                case Direction.Right:
                    if (newLocation.X + MoveInterval <= boundaries.Right)
                        newLocation.X += MoveInterval;
                    break;
                default: break;

            }
            return newLocation;
        }
    }

    public class Player : Mover
    {
        private Weapon equippedWeapon;
        private int hitPoints;
        public int HitPoints { get { return hitPoints; } }

        private List<Weapon> inventory = new List<Weapon>();
        public List<string> Weapons
        {
            get 
            {
                List<string> names = new List<string>();
                foreach (Weapon weapon in inventory)
                    names.Add(weapon.Name);
                return names;
            }
        }

        public Player(Game game, Point location, Rectangle boundaries)
            : base(game, location)
        { hitPoints = 10; }

        public void IncreaseHeath(int health,Random random)
        {
            hitPoints += random.Next(1,health);     
        }

        public void Hit(int maxDamage,Random random)
        {
            hitPoints -= random.Next(1,maxDamage);
        }

        public void Equip(string weaponName)
        {
            if (weaponName == null)
            {
                equippedWeapon = null;
                return;
            }
            foreach (Weapon weapon in inventory)
            {
                if (weapon.Name == weaponName)
                    equippedWeapon = weapon;
            }
        }

        public void Move(Direction direction)
        {
            base.location = Move(direction, game.Boundaries);
            if (!game.WeaponInRoom.PickedUp)
            {
                if (game.WeaponInRoom.Location == base.location)
                {
                    game.WeaponInRoom.PickUpWeapon();
                    inventory.Add(game.WeaponInRoom);           
                }
            }
        }

        public void Attract(Direction direction,Random random)
        {
            if (equippedWeapon != null)
            {
                equippedWeapon.Attack(direction,random);
                //如果装备物品是药品,接口就是区别装备和药品的方法
                if (equippedWeapon is IPotion)
                    inventory.Remove(equippedWeapon);
            }
        }
    }

    #region Enemy  
    public abstract class Enemy : Mover
    {
        private const int NearPlayerDistance = 30;
        private int hitPoints;
        public int HitPoints { get { return hitPoints; } }
        public bool Dead()
        {
            if (hitPoints <= 0)
                return true;
            else
                return false;
        }

        public Enemy(Game game, Point location, Rectangle boundaries, int hitPoints)
            : base(game, location)
        { this.hitPoints = hitPoints; }

        public abstract void Move(Random random);

        protected bool NearPlayer()
        {
            return (Nearby(location, game.PlayerLocation, NearPlayerDistance));
        }

        public void Hit(int maxDamage,Random random)
        {
            hitPoints -= random.Next(1, maxDamage);
        }

        protected Direction FindPlayerDirection(Point playerLocation)
        {
            Direction directionToMove;
            if (playerLocation.X > Location.X + 10)
                directionToMove = Direction.Right;
            else if (playerLocation.X < Location.X - 10)
                directionToMove = Direction.Left;
            else if (playerLocation.Y < Location.Y - 10)
                directionToMove = Direction.Up;
            else
                directionToMove = Direction.Down;
            return directionToMove;
        }
    }

    public class Bat : Enemy
    {
        //蝙蝠起始点数为6,有50%的几率朝着玩家飞,而另外50%的情况会随机的飞
        public Bat(Game game,Point location,Rectangle boundaries)
            : base(game, location, boundaries, 6)
        { }

        public override void Move(Random random)
        {
            if (NearPlayer())
            {
                game.HitPlayer(3, random);
                return;
            }

            if (random.Next(2) == 0)
            {
                Direction direction = FindPlayerDirection(game.PlayerLocation);
                this.location = Move(direction, game.Boundaries);
            }
            else
            {
                Direction direction = (Direction)random.Next(4);
                this.location = Move(direction, game.Boundaries);
            }          
        }
    }

    public class Ghost:Enemy
    {
        //幽灵起始点数为8,有1/3几率朝着玩家移动,另外情况原地不动
         public Ghost(Game game,Point location,Rectangle boundaries)
            : base(game, location, boundaries, 8)
        { }

         public override void Move(Random random)
         {
             if (NearPlayer())
             {
                 game.HitPlayer(4, random);
                 return;
             }
             if (random.Next(3) == 0)
             {
                 Direction direction = FindPlayerDirection(game.PlayerLocation);
                 this.location = Move(direction, game.Boundaries);
             }
            
         }  
    }

    public class Ghoul : Enemy
    {
        //食尸鬼起始点数为10,有2/3几率朝着玩家移动,另外情况原地不动
        public Ghoul(Game game, Point location, Rectangle boundaries)
            : base(game, location, boundaries, 10)
        { }

        public override void Move(Random random)
        {
            if (NearPlayer())
            {
                game.HitPlayer(5, random);
                return;
            }
            if (random.Next(3) != 0)
            {
                Direction direction = FindPlayerDirection(game.PlayerLocation);
                this.location=Move(direction,game.Boundaries);
            }
            
        }
    }
    #endregion

    #region Weapon
    /// <summary>
    /// 武器类
    /// </summary>
    public abstract class Weapon:Mover
    {
        public abstract string Name { get;  }
        public abstract void Attack(Direction direction,Random random);
        private bool pickedUp;
        public bool PickedUp { get { return pickedUp; } }

        public Weapon(Game game, Point location):base(game,location)
        {          
            pickedUp = false;
        }

        public void PickUpWeapon() { pickedUp = true; }

        /// <summary>
        /// 弓箭
        /// </summary>
        protected bool DamageEnemy(Direction direction, int distance, int damage,Random random)
        {
            Point target = game.PlayerLocation;       
            foreach (Enemy enemy in game.Enemies)
            {
                if (Nearby(direction,enemy.Location,distance))
                {
                    enemy.Hit(damage,random);
                    return true;
                }
            }            
            return false;
        }

        /// <summary>
        /// 剑和锤
        /// </summary>
        protected bool DamageEnemy(int radius, int damage, Random random)
        {
            Point target = game.PlayerLocation;
            foreach (Enemy enemy in game.Enemies)
            {
                if (Nearby(enemy.Location, target, radius))
                {
                    enemy.Hit(damage, random);
                    return true;
                }
            }
            return false;
        }
    }

    /// <summary>
    /// 药品接口
    /// </summary>
    public interface IPotion
    {
        bool Used { get; }
    }

    /// <summary>
    /// 剑
    /// </summary>
    public class Sword : Weapon
    {
        public Sword(Game game, Point location)
            : base(game, location)
        { }

        public override string Name
        {
            get
            {
                return "Sword";
            }         
        }

        public override void Attack(Direction direction,Random random)
        {
            DamageEnemy(60, 4,random);
        }
    }

    /// <summary>
    /// 弓箭
    /// </summary>
    public class Bow : Weapon
    {
        public Bow(Game game, Point location)
            : base(game, location)
        { }

        public override string Name
        {
            get 
            {
                return "Bow";
            }
        }

        public override void Attack(Direction direction, Random random)
        {
            DamageEnemy(direction, 90, 2, random);
        }
    }

    /// <summary>
    /// 锤
    /// </summary>
    public class Mace : Weapon
    {
        public Mace(Game game, Point location)
            : base(game, location)
        { }

        public override string Name
        {
            get { return "Mac"; }
        }

        public override void Attack(Direction direction, Random random)
        {
            DamageEnemy(50, 7, random);
        }
    }

    /// <summary>
    /// 蓝色药水
    /// </summary>
    public class BluePotion : Weapon, IPotion
    {
        private bool used=false;
        public BluePotion(Game game, Point location)
            : base(game, location)
        { }

        public override string Name
        {
            get { return "BluePotion"; }
        }

        public override void Attack(Direction direction, Random random)
        {
            game.IncreasePlayerHealth(6,random);
            used=true;
        }

        public bool Used
        {
            get { return used; }
        }
    }

    /// <summary>
    /// 红色药水
    /// </summary>
    public class RedPotion : Weapon, IPotion
    {
        private bool used = false;
        public RedPotion(Game game, Point location)
            : base(game, location)
        { }

        public override string Name
        {
            get { return "RedPotion"; }
        }

        public override void Attack(Direction direction, Random random)
        {
            game.IncreasePlayerHealth(11, random);
            used = true;
        }

        public bool Used
        {
            get { return used; }
        }
    }
    #endregion
}


 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值