使用c# 5分钟 创建一个Roguelike 游戏

原文链接不给了,之前贴链接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;
        }
    }


11.  添加以下几个生物类:


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.  完成之后跑起来应该是下面这个样子:






评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值