马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
简介
通过焦点部门的学习,我们已经可以做一些复杂的项目了。
我们这次会用我们学到的面向对象知识写一个飞机大战(性能大概不太好,因为毕竟是控制台项目)
如果你有所不懂,建议多查多思索多问。
因为这次的项目比较难,博主会稍微讲细致一点。
基类计划:GameObject 抽象类
- abstract class GameObject
- {
- protected int x; // 坐标X(列)
- protected int y; // 坐标Y(行)
- protected bool isAlive; // 存活状态
- public GameObject(int x, int y)
- {
- this.x = x;
- this.y = y;
- this.isAlive = true; // 初始化时存活
- }
- // 只读属性:暴露坐标和存活状态(IsAlive可写)
- public int X { get { return x; } }
- public int Y { get { return y; } }
- public bool IsAlive { get { return isAlive; } set { isAlive = value; } }
- // 抽象方法:强制子类实现核心行为
- public abstract void Move(); // 移动逻辑
- public abstract void Draw(); // 绘制逻辑
- public abstract void Attack(); // 攻击逻辑
- }
复制代码
- 焦点作用:定义所有游戏对象(飞机、仇人、子弹、道具)的公共属性(坐标、存活状态)和必须实现的行为接口。
- 计划特点:
- protected 修饰的字段允许子类直接访问,避免过分封装。
- 抽象方法确保子类必须实现移动、绘制、攻击这三个焦点功能,实现多态性(如飞机和仇人的移动方式差别)。
玩家飞机:Aircraft 类
- class Aircraft : GameObject
- {
- public int health = 5; // 玩家生命值(初始5点)
- public List<Bullet> bullets = new List<Bullet>(); // 玩家发射的子弹列表
- public Aircraft(int x, int y) : base(x, y) { } // 调用基类构造函数初始化坐标
- public override void Move()
- {
- while (Console.KeyAvailable) // 处理所有未读取的按键(避免漏键)
- {
- ConsoleKeyInfo key = Console.ReadKey(true); // 读取按键并隐藏输入字符
- switch (key.Key)
- {
- case ConsoleKey.LeftArrow: if (x > 1) x--; break; // 左边界限制(x>1,避开左墙体)
- case ConsoleKey.RightArrow: if (x < Console.WindowWidth - 2) x++; break; // 右边界限制
- case ConsoleKey.UpArrow: if (y > 1) y--; break; // 上边界限制(避开顶部墙体)
- case ConsoleKey.DownArrow: if (y < Console.WindowHeight - 3) y++; break; // 下边界限制(避开底部墙体和分数栏)
- case ConsoleKey.Spacebar: Attack(); break; // 按下空格时调用攻击(发射子弹)
- }
- }
- }
- public override void Draw()
- {
- // 确保坐标在屏幕内,避免控制台异常
- if (x >= 0 && x < Console.WindowWidth && y >= 0 && y < Console.WindowHeight)
- {
- Console.SetCursorPosition(x, y);
- Console.Write("A"); // 用"A"字符表示玩家飞机
- }
- }
- public override void Attack()
- {
- bullets.Add(new Bullet(x, y - 1)); // 在飞机当前位置上方一格生成子弹(玩家子弹向上移动)
- }
- }
复制代码 关键逻辑:
- 移动控制:通过 Console.KeyAvailable 及时检测方向键,直接修改 x/y 坐标,并通过边界判断(如 x > 1)确保飞机不会移出墙体范围。
- 子弹发射:按下空格时,调用 Attack() 方法,在飞机上方(y-1)生成一颗非仇人子弹(isEnemyBullet=false)。
- 绘制逻辑:利用 Console.SetCursorPosition 定位后输出字符 "A",直观显示玩家位置
仇人范例:NormalEnemy 和 RandomMovingEnemy类
普通仇人:垂直移动 + 概率射击(NormalEnemy)
- class NormalEnemy : GameObject
- {
- public List<Bullet> enemyBullets = new List<Bullet>(); // 敌人发射的子弹列表
- public NormalEnemy(int x, int y) : base(x, y) { } // 初始化坐标
- public override void Move()
- {
- // 50%概率向下移动(通过随机数控制速度,避免频繁移动)
- if (new Random().Next(2) == 0)
- {
- y++; // 向下移动
- if (y >= Console.WindowHeight - 2) // 触达底部墙体时死亡
- isAlive = false;
- }
- }
- public override void Draw()
- {
- if (isAlive && y < Console.WindowHeight - 2 && x >= 0 && x < Console.WindowWidth)
- {
- Console.SetCursorPosition(x, y);
- Console.Write("E"); // 用"E"字符表示普通敌人
- }
- // 处理敌人子弹:移动、绘制、移除死亡子弹
- for (int i = enemyBullets.Count - 1; i >= 0; i--)
- {
- Bullet bullet = enemyBullets[i];
- bullet.Move(); // 子弹移动
- bullet.Draw(); // 子弹绘制
- if (!bullet.IsAlive) // 子弹超出屏幕则移除
- enemyBullets.RemoveAt(i);
- }
- }
- public override void Attack()
- {
- // 10%概率发射子弹(向下移动的敌人子弹)
- if (new Random().Next(100) < 10)
- enemyBullets.Add(new Bullet(x, y + 1, true)); // isEnemyBullet=true标识敌人子弹
- }
- }
复制代码 随机移动仇人:四方向随机移动 + 概率射击(RandomMovingEnemy)
- class RandomMovingEnemy : GameObject
- {
- public List<Bullet> enemyBullets = new List<Bullet>(); // 敌人子弹列表
- private Random random = new Random(); // 随机数生成器(成员变量,避免重复创建)
- public RandomMovingEnemy(int x, int y) : base(x, y) { }
- public override void Move()
- {
- // 50%概率随机移动(上下左右四方向)
- if (random.Next(2) == 0)
- {
- int direction = random.Next(4); // 0-3对应上下左右
- switch (direction)
- {
- case 0: if (y > 1) y--; break; // 上移(避开顶部墙体)
- case 1: if (y < Console.WindowHeight - 2) y++; break; // 下移(避开底部墙体)
- case 2: if (x > 1) x--; break; // 左移(避开左墙体)
- case 3: if (x < Console.WindowWidth - 2) x++; break; // 右移(避开右墙体)
- }
- }
- }
- public override void Draw()
- {
- // 逻辑与NormalEnemy类似,仅绘制字符为"R"
- if (isAlive && y < Console.WindowHeight - 2 && x >= 0 && x < Console.WindowWidth)
- {
- Console.SetCursorPosition(x, y);
- Console.Write("R"); // 用"R"字符表示随机移动敌人
- }
- // 子弹处理逻辑与NormalEnemy完全一致
- for (int i = enemyBullets.Count - 1; i >= 0; i--)
- {
- Bullet bullet = enemyBullets[i];
- bullet.Move();
- bullet.Draw();
- if (!bullet.IsAlive)
- enemyBullets.RemoveAt(i);
- }
- }
- public override void Attack()
- {
- // 与NormalEnemy相同:10%概率发射向下子弹
- if (random.Next(100) < 10)
- enemyBullets.Add(new Bullet(x, y + 1, true));
- }
- }
复制代码
- 计划差别:
- 移动方式:普通仇人仅垂直向下移动,随机仇人通过 Random.Next(4) 实现四方向随机移动,增加游戏难度。
- 性能细节:RandomMovingEnemy 中将 Random 作为成员变量,避免每次调用 Move() 时创建新实例
子弹与道具:Bullet 和 ClearScreenItem 类
子弹类:区分敌我子弹的移动方向(Bullet)
- class Bullet : GameObject
- {
- public bool isEnemyBullet; // 是否为敌人发射的子弹(决定移动方向)
- public Bullet(int x, int y, bool isEnemyBullet = false) : base(x, y)
- {
- this.isEnemyBullet = isEnemyBullet; // 默认为玩家子弹(false)
- }
- public override void Move()
- {
- if (isEnemyBullet)
-
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |