冒险游戏的界面如上图所示,就是简单的闯关游戏,一共有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
}