程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Head First C#(冒險游戲)

Head First C#(冒險游戲)

編輯:C#入門知識

 

\

冒險游戲的界面如上圖所示,就是簡單的闖關游戲,一共有5種道具和3種怪物

道具分別為:劍、弓箭、錘子、藍藥水和紅藥水

怪物分別為:蝙蝠、幽靈、食屍鬼

類圖視圖如下所示,怪物類、道具類和玩家類繼承於移動類。

 

\

代碼實現如下:

[csharp]
?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  

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
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved