原文链接不给了,之前贴链接blog被封了
本文章是简单翻译了原文,如果不知道什么是Roguelike游戏的,请自行百度。。。原因同上
因为原文的代码有些问题,,所以本人做了一些修改,使他能够跑起来。
1. 打开VS2010(其他的版本也可以).
2. 文件->新建项目.
3. 选择c#控制台项目.
4. 命名项目为 ReallyReallyRealySimpleRogueLike.
5. 右键引用->添加引用.
6. 点击.net,选择System.Drawing.
7. 在Program.cs 的最上面添加using System.Drawing.
8. 将Program.cs里的代码改为以下这样:
class Program
{
static void Main(string[] args)
{
Dungeon dungeon = new Dungeon(Constants.DungeonWidth, Constants.DungeonHeight);
string displayText = Constants.IntroductionText;
while (dungeon.IsGameActive)
{
dungeon.DrawToConsole();
Console.WriteLine(displayText);
Console.Write(Constants.CursorImage);
displayText = dungeon.ExecuteCommand(Console.ReadKey());
}
Console.WriteLine(ConcludeGame(dungeon));
Console.ReadLine();
}
private static string ConcludeGame(Dungeon dungeon)
{
return (dungeon.player.Hits > 0) ? Constants.PlayerWinsText : Constants.MonsterWinsText;
}
}
9. 添加一个Dungeon类:
class Dungeon
{
Random r;
public Player player;
List<Monster> monsters;
List<Sword> swords;
List<Wall> walls;
public Tile[,] Tiles;
private int xMax;
private int yMax;
public enum Direction
{
North,
South,
East,
West
}
public bool IsGameActive
{
get
{
return (player.Hits > 0 && monsters.Any(m => m.Hits > 0));
}
}
public Dungeon(int xMax, int yMax)
{
monsters = new List<Monster>();
walls = new List<Wall>();
swords = new List<Sword>();
this.xMax = xMax;
this.yMax = yMax;
Tiles = new Tile[xMax, yMax];
BuildRandomDungeon();
SetDungeonTiles();
}
public string ExecuteCommand(ConsoleKeyInfo command)
{
string commandResult = ProcessCommand(command);
ProcessMonsters();
SetDungeonTiles();
return commandResult;
}
private void ProcessMonsters()
{
if (monsters != null && monsters.Count > 0)
{
monsters.Where(m => m.Hits >= 0).ToList().ForEach(m =>
{
MoveMonsterToPlayer(m);
});
}
}
private void MoveMonsterToPlayer(Monster monster)
{
if (player.X != monster.X)
{
if (player.X > monster.X)
{
monster.X++;
}
else
{
monster.X--;
}
}
else if (player.Y != monster.Y)
{
if (player.Y > monster.Y)
{
monster.Y++;
}
else
{
monster.Y--;
}
}
else
{
ResolveCombat(monster);
}
}
private void BuildRandomDungeon()
{
r = new Random();
SetAllDungeonSquaresToTiles();
for (int i = 0; i < xMax; i++)
{
Wall top = new Wall(i, 0);
walls.Add(top);
Wall bottom = new Wall(i, yMax - 1);
walls.Add(bottom);
}
for (int i = 0; i < yMax; i++)
{
Wall left = new Wall(0, i);
walls.Add(left);
Wall right = new Wall(xMax - 1, i);
walls.Add(right);
}
for (int i = 0; i < Constants.NumberOfSwords; i++)
{
Sword s = new Sword(GetValidRandomPoint());
swords.Add(s);
}
for (int i = 0; i < Constants.NumberOfMonsters; i++)
{
Monster m = new Monster(GetValidRandomPoint());
monsters.Add(m);
}
player = new Player(GetValidRandomPoint());
}
private void ResolveCombat(Monster monster)
{
if (player.Inventory.Any())
{
monster.Die();
}
else
{
player.Die();
}
}
private Point GetValidRandomPoint()
{
Point p=new Point(r.Next(1,xMax-1), r.Next(1,yMax-1));
while(Tiles[p.X,p.Y].ImageCharacter!=Constants.TileImage)
{
p = new Point(r.Next(1,xMax-1), r.Next(1,yMax-1));
}
return p;
}
public string ProcessCommand(ConsoleKeyInfo command)
{
string output = string.Empty;
switch (command.Key)
{
case ConsoleKey.UpArrow:
case ConsoleKey.DownArrow:
case ConsoleKey.RightArrow:
case ConsoleKey.LeftArrow:
output = GetNewLocation(command, new Point(player.X, player.Y));
break;
case ConsoleKey.F1:
output = Constants.NoHelpText;
break;
}
return output;
}
private string GetNewLocation(ConsoleKeyInfo command, Point move)
{
switch (command.Key)
{
case ConsoleKey.UpArrow:
move.Y -= 1;
break;
case ConsoleKey.DownArrow:
move.Y += 1;
break;
case ConsoleKey.RightArrow:
move.X += 1;
break;
case ConsoleKey.LeftArrow:
move.X -= 1;
break;
}
if (!IsInvalidValidMove(move.X, move.Y))
{
player.X = move.X;
player.Y = move.Y;
if (Tiles[move.X, move.Y] is Sword && player.Inventory.Count == 0)
{
Sword sword = (Sword)Tiles[move.X, move.Y];
player.Inventory.Add(sword);
swords.Remove(sword);
}
return Constants.OKCommandText;
}
else
return Constants.InvalidMoveText;
}
public bool IsInvalidValidMove(int x, int y)
{
return (x == 0 || x == Constants.DungeonWidth - 1 || y == Constants.DungeonHeight - 1 || y == 0);
}
public void SetDungeonTiles()
{
//Draw the empty dungeon
SetAllDungeonSquaresToTiles();
SetAllDungeonObjectsToTiles();
}
private void SetAllDungeonObjectsToTiles()
{
//Now draw each of the parts of the dungeon
walls.ForEach(w => Tiles[w.X, w.Y] = w);
swords.ForEach(s => Tiles[s.X, s.Y] = s);
monsters.ForEach(m => Tiles[m.X, m.Y] = m);
Tiles[player.X, player.Y] = player;
}
private void SetAllDungeonSquaresToTiles()
{
for (int i = 0; i < yMax; i++)
{
for (int j = 0; j < xMax; j++)
{
Tiles[j, i] = new Tile(i, j);
}
}
}
public void DrawToConsole()
{
Console.Clear();
for (int i = 0; i < yMax; i++)
{
for (int j = 0; j < xMax; j++)
{
Console.ForegroundColor = Tiles[j, i].Color;
Console.Write(Tiles[j, i].ImageCharacter);
}
Console.WriteLine();
}
}
}
10. 添加一个Tile类,在这个cs文件里,有wall和sword类:
public class Tile
{
public string name { get; set; }
public string ImageCharacter { get; set; }
public ConsoleColor Color { get; set; }
public int X { get; set; }
public int Y { get; set; }
public Tile() { }
public Tile(int x, int y)
: base()
{
this.X = x;
this.Y = y;
ImageCharacter = Constants.TileImage;
Color = Constants.TileColor;
}
}
public class Wall : Tile
{
public Wall(int x, int y)
: base(x, y)
{
ImageCharacter = Constants.WallImage;
this.Color = Constants.WallColor;
}
}
public class Sword : Tile
{
public Sword(Point p)
{
ImageCharacter = Constants.SwordImage;
this.Color = Constants.SwordColor;
X = p.X;
Y = p.Y;
}
}
public class Creature : Tile
{
public int Hits { get; set; }
public void Die()
{
Hits = 0;
}
}
public class Player : Creature
{
public Player(Point p)
{
ImageCharacter = Constants.PlayerImage;
Color = Constants.PlayerColor;
Inventory = new List<Tile>();
X = p.X;
Y = p.Y;
Hits = Constants.StartingHitPoints;
}
public List<Tile> Inventory { get; set; }
}
public class Monster : Creature
{
public Monster(Point p)
{
ImageCharacter = Constants.MonsterImage;
Color = Constants.MonsterColor;
X = p.X;
Y = p.Y;
Hits = Constants.StartingHitPoints;
}
}
12. 添加一个类来存储常量:
public static class Constants
{
public readonly static int DungeonHeight = 20;
public readonly static int DungeonWidth = 20;
public readonly static int NumberOfSwords = 5;
public readonly static int MonsterDamage = 2;
public readonly static int NumberOfMonsters = 1;
public readonly static int StartingHitPoints = 10;
public readonly static string TileImage = ".";
public readonly static string WallImage = "#";
public readonly static string PlayerImage = "@";
public readonly static string SwordImage = "s";
public readonly static string StepsImage = "S";
public readonly static string MonsterImage = "M";
public readonly static string CursorImage = ">";
public readonly static ConsoleColor MonsterColor = ConsoleColor.Blue;
public readonly static ConsoleColor PlayerColor = ConsoleColor.Gray;
public readonly static ConsoleColor WallColor = ConsoleColor.DarkCyan;
public readonly static ConsoleColor SwordColor = ConsoleColor.Yellow;
public readonly static ConsoleColor TileColor = ConsoleColor.White;
public readonly static string InvalidCommandText = "That is not a valid command";
public readonly static string OKCommandText = "OK";
public readonly static string InvalidMoveText = "That is not a valid move";
public readonly static string IntroductionText = "Welcome to the dungeon - grab a sword kill the monster(s) win the game";
public readonly static string PlayerWinsText = "Player kills monster and wins";
public readonly static string MonsterWinsText = "Monster kills player and wins";
public readonly static string NoHelpText = "No help text";
}
13. 完成之后跑起来应该是下面这个样子: