C#学习-魔塔项目记录(2021.12.2)

继续魔塔项目的记录,今天主要做的是场景切换的功能。直接上代码:

 加了两个场景的类,一个是场景管理,一个是战斗场景(因为战斗场景后面会有一些逻辑判断预计比较复杂,单独拿出来写)

来看 SceneManager 里是什么内容

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Mota
{
    class SceneManager:Singlton<SceneManager>//场景管理肯定也要继承单例
    {
        List<GameMap> mapList = new List<GameMap>();
        //新建一个GameMap的List数组存放地图数据

        int curMapIndex = 0;//当前地图

        public void Init()
        {
            if (Directory.Exists("GameMap"))
            {
                string[] fileNames = Directory.GetFiles("GameMap");
                foreach (var fileName in fileNames)
                {
                    mapList.Add(new GameMap(fileName));
                }
            }
            else
            {
                Console.WriteLine("GameMap文件夹不存在!!!");
            }//读取文件夹"GameMap"里的内容

            PrintScene();//打印场景里的各种元素(目前有的)方法在下面
        }

        public void Update()
        {
            Singlton<Player>.Instance.Update();
        }//玩家的初始化从 GameManager 移到了这里,玩家跟着场景走


        public int GetcurMapData(Position p)
        {
           return mapList[curMapIndex].GetMapData(p);
        }//把 MapList 数据返回出去的方法


        public void PrintScene()
        {
            mapList[curMapIndex].PrintMap();//根据现在的地图下标打印地图
            mapList[curMapIndex].SetPlayerToStartPos();
            //把玩家放到初始位置,SetPlayerToStartPos()方法在 GameMap 类里
            Singlton<Player>.Instance.PrintPlayer(1);//打印玩家
        }


        public void MoveToNextMap()
        {
            Console.Clear();
            curMapIndex++;
            PrintScene();
        }//切换下个场景


        public void SwitchToBattleScene(int MonsterType)
        {
            Console.Clear();
            Singlton<BattleScene>.Instance.Init(MonsterType);
            InputManager.Instance.RemoveObserverList(Singlton<Player>.Instance);
        }//切换战斗场景时,把玩家移出观察者行列
    }
}

Player类的更新

using Mota;
using System;
using System.Collections.Generic;
using System.Text;

namespace Mota
{
    enum Direction
    {
        None,
        Up,
        Down,
        left,
        right
    }

    struct Position
    {
        public int x;
        public int y;
    }//2021.12.2更新:新建一个玩家位置结构体,用来存放玩家坐标

    class Player : IKeyDown//这里是输入管理的接口
    {
        Direction dir = Direction.None;


        public Position Pos
        {
            get;
            set;
        } = new Position() { x = 0, y = 0 };
        //2021.12.2更新:坐标的构造器

        public void Init()
        {
            InputManager.Instance.AddObserverList(this);
        }//把自己加入观察者数组


        public void Update()
        {
            Move();
        }
        //player自己的Update,更新自己的各项数据,
        //最后GameManager里只要调用这个玩家的Update就可以实现玩家的功能了
        //2021.12.2更新:玩家的 Update 已经移到 SceneManager 类里了


        public void Move()
        {
            Position p = Pos;

            switch (dir)
            {
                case Direction.None:
                    return;
                case Direction.Up:
                    p.x--;
                    break;
                case Direction.Down:
                    p.x++;
                    break;
                case Direction.left:
                    p.y--;
                    break;
                case Direction.right:
                    p.y++;
                    break;
                default:
                    break;
            }//2021.12.2更新:玩家移动的逻辑补完了

            int mapData = Singlton<SceneManager>.Instance.GetcurMapData(p);
            //2021.12.2更新:获取地图数据的方法,具体见 SceneManager 类

            switch (mapData)
            {
                case (int)GameMapElement.Wall:
                    return;
                case (int)GameMapElement.Door:
                    PrintPlayer(0);
                    Pos = p;
                    break;
                case (int)GameMapElement.UpStairs:
                    SceneManager.Instance.MoveToNextMap();
                    break;
                case (int)GameMapElement.Way:
                    PrintPlayer(0);
                    Pos = p;//如果可以移动,把当前位置改为移动过后的位置
                    break;
                case (int)GameMapElement.Monster:
                    PrintPlayer(0);
                    //战斗
                    SceneManager.Instance.SwitchToBattleScene(mapData);
                    Pos = p;
                    dir = Direction.None;
                    return;
            }//2021.12.2更新:根据地图元素进行判断人物移动的逻辑(战斗的逻辑和场景待补充)

            PrintPlayer(1);

            dir = Direction.None;
        }

        public void ObserverOnKeyDown(ConsoleKey Key)
        {
            switch (Key)
            {
                case ConsoleKey.W:
                    dir = Direction.Up;
                    break;
                case ConsoleKey.S:
                    dir = Direction.Down;
                    break;
                case ConsoleKey.A:
                    dir = Direction.left;
                    break;
                case ConsoleKey.D:
                    dir = Direction.right;
                    break;
                default:
                    break;
            }//玩家作为键盘输入的观察者,按 W A S D 控制玩家移动
        }
        public void PrintPlayer(int isPrint)
        {
            if(isPrint == 0)
            {
                GameManager.Instance.SetCursor(Pos.x, Pos.y);
                Console.Write("  ");
            }
            else if (isPrint == 1)
            {
            GameManager.Instance.SetCursor(Pos.x, Pos.y);
            Console.Write("♂");
            }
        }//2021.12.2更新:打印人物的方法,这里加了一个0 1 用来判断移动,
         //如果可以移动,把玩家当前位置打空格,下一个位置和当前位置互换


    }

}

GameMap类更新:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Mota
{
    enum GameMapElement
    {
        Way = 0,
        Monster = 1,
        Wall = 10,
        UpStairs = 38,
        DownStairs = 39,
        Door = 46
    }
    
    
    class GameMap
    {
        int[,] mapDate;//定义一个二维数组接收地图数据
        int row;//定义一个二维数组接收地图数据
        int col;//地图的列数

        Position startPos;
        Position endPos;

        public GameMap(string path)
        {
            string[] lines = File.ReadAllLines(path);
            //调用 File 类里的 ReadAllLines 方法,
            //读取文件里的内容传入一个string数组(文件路径以参数形式传入)
            string[] line0 = lines[0].Split(",");//第零行按照“,”分隔,来读取地图行列
            row = int.Parse(line0[0]);
            col = int.Parse(line0[1]);
            startPos = new Position() { x = int.Parse(line0[2]), y = int.Parse(line0[3])};
            endPos = new Position() { x = int.Parse(line0[4]), y = int.Parse(line0[5]) };//2021.12.2更新:增加了初始和结束未知的坐标,也是通过读配置表来获取的(配置表有更新)

            mapDate = new int[row, col];

            for (int i = 0; i < row; i++)
            {
                string curLine = lines[i + 1];
                string[] datas = curLine.Split(",");
                //从第一行开始按照“,”分割来读取数据,一共有roe行
                //读取后把每一行的所有数据数据存入 datas 数组备用

                for (int j = 0; j < col; j++)
                {
                    mapDate[i, j] = int.Parse(datas[j]);
                    //把 datas 数组里的数据返回给mapData
                }
            }
        }

       /* 
        public void Init()
        {
            InputManager.Instance.AddObserverList(this);//把地图添加为观察者
        }
       */

        public int GetMapData(Position p)
        {
            return mapDate[p.x, p.y];
        }

        StringBuilder sb = new StringBuilder();
        //建一个 StringBuilder 打印地图(性能要比直接用 string 字符串打印好)

        public void PrintMap()
        {
            sb.Clear();
            for (int i = 0; i < mapDate.GetLength(0); i++)
            {
                for (int j = 0; j < mapDate.GetLength(1); j++)
                {
                    switch (mapDate[i,j])
                    {
                        case (int)GameMapElement.Wall:
                            sb.Append("■");
                            break;
                        case (int)GameMapElement.Door:
                            sb.Append("◇");
                            break;
                        case (int)GameMapElement.UpStairs:
                            sb.Append("△");
                            break;
                        case (int)GameMapElement.Way:
                            sb.Append("  ");
                            break;
                        case (int)GameMapElement.Monster:
                            sb.Append("¤");
                            break;
                        default:
                            Console.WriteLine("没有这种类型" + mapDate[i,j]);
                            break;
                    }
                }
                sb.Append("\n");
            }
            Console.WriteLine(sb);
        }//根据mapDate里的数据,往sb里追加各种地图元素,现在地图还不完整

        public override string ToString()
        {
            return sb.ToString();
        }


        public void SetPlayerToStartPos()
        {
            Singlton<Player>.Instance.Pos = startPos;
        }

        public void SetPlayerToEndPos()
        {
            Singlton<Player>.Instance.Pos = endPos;
        }
        //2021.12.2更新:两个方法,把人物坐标设到初始和结束位置

    }
    
}

 今天更新就这么多啦,感觉项目记录也不容易,不知不觉这都都凌晨1点了。。。已经是12.3号了。后面不一定能坚持,但是魔塔我会做完的,做完代码肯定会完整上传。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值