赞
踩
(可观看CSharp核心--52集进行了解)
控制方向的是:WSAD
确定键是:J
结合自己所学进行开发(UML类图是老师提供的,因为自己暂时还不太会绘制,主要是代码逻辑还不够清晰)
检测键盘是否激活
Console.KeyAvailable == true;
按照UML类图逐个去写逐个去实现(但是有些模块我没有用上)
主要精力是放在了功能实现上
下面是我实现的过程
(我先确定了开始着手的地方--游戏类,因为它是所有类和方法的汇聚地)
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
-
- //游戏类
-
- namespace 自个先写CSharp核心小项目_贪吃蛇_
- {
- enum E_Scene
- {
- BeginID,
- GamingID,
- FinishID,
- }
-
- class Game
- {
- public static int x;
- public static int y;
- public static E_Scene scene = new E_Scene();
- Begin begin = new Begin();
- Finish finish = new Finish();
-
- public Game()
- {
- x = 100;
- y = 30;
- scene = E_Scene.BeginID;
- }
-
- //初始化控制台
- public void Consoles()
- {
- //隐藏光标
- Console.CursorVisible = false;
- //设置舞台大小
- Console.SetWindowSize(x, y);
- Console.SetBufferSize(x, y);
-
- }
-
- //游戏主循环
- public void MajorCycle()
- {
- while (true)
- {
- //思考一下,为什么把开始场景和结束场景的类申明放在外面,而游戏场景的类申明放循环里面
- //因为开始结束场景是一成不变的,只需申明一次就够用了
- //而游戏场景进入一次就会执行出结果出来,每次结果都将不一样,所以每次都得重新申明
- switch (scene)
- {
- case E_Scene.BeginID:
- Console.Clear();
- begin.newers();
- break;
- case E_Scene.GamingID:
- Console.Clear();
- GameScene gameScene = new GameScene();
- gameScene.newers();
- break;
- case E_Scene.FinishID:
- Console.Clear();
- finish.newers();
- break;
- default:
- break;
- }
- }
- }
-
- //场景切换
- public void SceneMove()
- {
-
- }
-
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- //开始场景
-
- namespace 自个先写CSharp核心小项目_贪吃蛇_
- {
- class Begin : BeginAndFinish
- {
- public Begin()
- {
- str = "贪吃蛇";
- str1 = "开始游戏";
- str2 = "结束游戏";
- }
-
- //重写更新方法
- public override void newers()
- {
- Console.SetCursorPosition(48, 10);
- Console.ForegroundColor = ConsoleColor.White;
- Console.WriteLine(str);
- Console.SetCursorPosition(47, 13);
- Console.ForegroundColor = key == 1 ? ConsoleColor.Red : ConsoleColor.White;
- Console.WriteLine(str1);
- Console.SetCursorPosition(47, 15);
- Console.ForegroundColor = key == 2 ? ConsoleColor.Red : ConsoleColor.White;
- Console.WriteLine(str2);
-
- char c = Console.ReadKey(true).KeyChar;
- switch (c)
- {
- case 'W':
- case 'w':
- key = 1;
- break;
- case 'S':
- case 's':
- key = 2;
- break;
- case 'J':
- case 'j':
- if (key == 2)
- {
- //关闭控制台
- Environment.Exit(0);
- }
- Game.scene = (E_Scene)key;
- break;
- default:
- break;
- }
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- //结束场景
-
- namespace 自个先写CSharp核心小项目_贪吃蛇_
- {
- class Finish : BeginAndFinish
- {
- string str0;
- public static int num;
-
- public Finish()
- {
- key = 0;
- str = "游戏结束";
- str0 = "本次游戏的长度为:";
- str1 = "回到开始界面";
- str2 = "结束游戏";
- }
-
- //重写更新方法
- public override void newers()
- {
- Console.SetCursorPosition(47, 10);
- Console.ForegroundColor = ConsoleColor.White;
- Console.WriteLine(str);
- Console.SetCursorPosition(42, 12);
- Console.ForegroundColor = ConsoleColor.White;
- Console.WriteLine(str0 + num);
- Console.SetCursorPosition(45, 15);
- Console.ForegroundColor = key == 0 ? ConsoleColor.Red : ConsoleColor.White;
- Console.WriteLine(str1);
- Console.SetCursorPosition(47, 17);
- Console.ForegroundColor = key == 2 ? ConsoleColor.Red : ConsoleColor.White;
- Console.WriteLine(str2);
-
- char c = Console.ReadKey(true).KeyChar;
- switch (c)
- {
- case 'W':
- case 'w':
- key = 0;
- break;
- case 'S':
- case 's':
- key = 2;
- break;
- case 'J':
- case 'j':
- if (key == 2)
- {
- //关闭控制台
- Environment.Exit(0);
- }
- Game.scene = (E_Scene)key;
- break;
- default:
- break;
- }
- }
-
- }
- }
(这里面其实可以把这些方法提取到开始和结束场景基类里面的,但我懒,没有去整!!!)
(第二个大类,游戏里的墙壁、食物、蛇、各种方法等等都汇聚在这个类中)
(讲真的这个类没怎么用上,具体怎么用我还得看看老师是怎么用的)
(这个是完全没有用上!!)
蛇身体类--没用上
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- //蛇类
-
- namespace 自个先写CSharp核心小项目_贪吃蛇_
- {
- //移动方向枚举
- enum E_Move
- {
- Up,
- Down,
- Left,
- Right,
- }
-
- class Snake
- {
- string snakeHead = "●";
- string snakeBody = "◎";
- int x = 10;
- int y = 5;
- E_Move move = E_Move.Down;
- char c;
- Foods foods = new Foods();
- int bodyNum = 0;
- //标识符
- int[] num1 = new int[10000];
- int[] num2 = new int[10000];
- //打印出长度
- public string longs = "当前长度为:";
-
- //蛇绘制
- public void SnakePlan()
- {
- //打印长度
- Console.SetCursorPosition(2, 1);
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine(longs + bodyNum);
-
- Finish.num = bodyNum;
-
- //蛇头的绘制
- Console.SetCursorPosition(x, y);
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine(snakeHead);
-
- //蛇身的绘制
- for (int i = 0; i < bodyNum; i++)
- {
- Console.SetCursorPosition(num1[i], num2[i]);
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine(snakeBody);
- }
- }
-
- //蛇清除
- public void SnakeClear()
- {
- //打印长度清除
- Console.SetCursorPosition(2, 1);
- Console.WriteLine(" ");
- //蛇头的清除
- Console.SetCursorPosition(x, y);
- Console.WriteLine(" ");
-
- //蛇身的清除
- for (int i = 0; i < bodyNum; i++)
- {
- Console.SetCursorPosition(num1[i], num2[i]);
- Console.WriteLine(" ");
- }
- }
-
- //蛇转向
- public void SnakeTurn()
- {
- //老师漏讲的知识点,Console.KeyAvailable -- 检测键盘是否被激活
- if (Console.KeyAvailable == true)
- {
- c = Console.ReadKey(true).KeyChar;
- switch (c)
- {
- case 'W':
- case 'w':
- if (move == E_Move.Down && bodyNum != 0)
- {
- move = E_Move.Down;
- }
- else
- {
- move = E_Move.Up;
- }
- break;
- case 'S':
- case 's':
- if (move == E_Move.Up && bodyNum != 0)
- {
- move = E_Move.Up;
- }
- else
- {
- move = E_Move.Down;
- }
- break;
- case 'A':
- case 'a':
- if (move == E_Move.Right && bodyNum != 0)
- {
- move = E_Move.Right;
- }
- else
- {
- move = E_Move.Left;
- }
- break;
- case 'D':
- case 'd':
- if (move == E_Move.Left && bodyNum != 0)
- {
- move = E_Move.Left;
- }
- else
- {
- move = E_Move.Right;
- }
- break;
- default:
- break;
- }
- }
-
- }
-
- //吃食物
-
- //死亡
-
-
-
-
- //蛇移动 -- (包含了蛇绘制、蛇转向、吃食物)
- public void SnakeMove()
- {
- if(foods.x == 0 || foods.y == 0)
- {
- foods.Plan();
- }
- SnakeTurn();
- switch (move)
- {
- case E_Move.Up:
- SnakeClear();
- y -= 1;
- //判断是否死亡
- //撞墙死亡
- if (y == 0)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- //撞身体死亡
- for (int i = 0; i < bodyNum; i++)
- {
- if(num1[i] == x && num2[i] == y)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- }
-
- if (foods.x == x && foods.y == y)
- {
- foods.Plan();
- //给个判断,让生成的food不会出现在有蛇身体的位置上
- for (int i = 0; i < bodyNum; i++)
- {
- if (foods.x == num1[i] && foods.y == num2[i])
- {
- Console.SetCursorPosition(foods.x, foods.y);
- Console.WriteLine(" ");
- foods.Plan();
- i = 0;
- }
- }
-
- bodyNum += 1;
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x;
- num2[0] = y + 1;
- }
- else
- {
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x;
- num2[0] = y + 1;
- }
- SnakePlan();
-
- break;
- case E_Move.Down:
- SnakeClear();
- y += 1;
- //判断是否死亡
- //撞墙死亡
- if (y == 29)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- //撞身体死亡
- for (int i = 0; i < bodyNum; i++)
- {
- if (num1[i] == x && num2[i] == y)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- }
-
- if (foods.x == x && foods.y == y)
- {
- foods.Plan();
- //给个判断,让生成的food不会出现在有蛇身体的位置上
- for (int i = 0; i < bodyNum; i++)
- {
- if (foods.x == num1[i] && foods.y == num2[i])
- {
- Console.SetCursorPosition(foods.x, foods.y);
- Console.WriteLine(" ");
- foods.Plan();
- i = 0;
- }
- }
-
- bodyNum += 1;
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x;
- num2[0] = y - 1;
- }
- else
- {
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x;
- num2[0] = y - 1;
- }
- SnakePlan();
- break;
- case E_Move.Left:
- SnakeClear();
- x -= 2;
- //判断是否死亡
- //撞墙死亡
- if (x == 0)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- //撞身体死亡
- for (int i = 0; i < bodyNum; i++)
- {
- if (num1[i] == x && num2[i] == y)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- }
-
- if (foods.x == x && foods.y == y)
- {
- foods.Plan();
- //给个判断,让生成的food不会出现在有蛇身体的位置上
- for (int i = 0; i < bodyNum; i++)
- {
- if (foods.x == num1[i] && foods.y == num2[i])
- {
- Console.SetCursorPosition(foods.x, foods.y);
- Console.WriteLine(" ");
- foods.Plan();
- i = 0;
- }
- }
-
- bodyNum += 1;
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x + 2;
- num2[0] = y;
- }
- else
- {
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x + 2;
- num2[0] = y;
- }
- SnakePlan();
- break;
- case E_Move.Right:
- SnakeClear();
- x += 2;
- //判断是否死亡
- //撞墙死亡
- if (x == 98)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- //撞身体死亡
- for (int i = 0; i < bodyNum; i++)
- {
- if (num1[i] == x && num2[i] == y)
- {
- Game.scene = E_Scene.FinishID;
- GameScene.bo = false;
- break;
- }
- }
-
- if (foods.x == x && foods.y == y)
- {
- foods.Plan();
- //给个判断,让生成的food不会出现在有蛇身体的位置上
- for (int i = 0; i < bodyNum; i++)
- {
- if (foods.x == num1[i] && foods.y == num2[i])
- {
- Console.SetCursorPosition(foods.x, foods.y);
- Console.WriteLine(" ");
- foods.Plan();
- i = 0;
- }
- }
-
- bodyNum += 1;
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x - 2;
- num2[0] = y;
- }
- else
- {
- for (int i = bodyNum - 1; i > 0; i--)
- {
- num1[i] = num1[i - 1];
- num2[i] = num2[i - 1];
- }
- num1[0] = x - 2;
- num2[0] = y;
- }
- SnakePlan();
- break;
- default:
- break;
- }
- }
-
- }
- }
C#核心实践项目(自个先写)--贪吃蛇
代码有点屎山,but跑起来就好!!!
还是知识点运用的不够,很多没用上。
场景类型枚举 ---- E_SceneType
将Game类中的nowScene 改为静态的
将Game类中的场景切换方法也改静态的
Game中的调用也改
在GameScene实现Map中的方法
到这里可以实现的功能有:三个场景
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using 贪吃蛇.Lesson3;
- using 贪吃蛇.Lesson4;
-
- namespace 贪吃蛇.Lesson6
- {
- /// <summary>
- /// 蛇的移动方向
- /// </summary>
- enum E_MoveDir
- {
- Up,
- Down,
- Left,
- Right,
- }
-
- class Snake : IDraw
- {
- SnakeBody[] bodys;
- //记录当前蛇的长度
- int nowNum;
- //当前移动方向
- E_MoveDir dir;
-
- public Snake(int x, int y)
- {
- //粗暴的方法 直接申明200个空间 来装蛇身体的数组
- bodys = new SnakeBody[200];
-
- bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
- nowNum = 1;
-
- dir = E_MoveDir.Down;
- }
-
- public void Draw()
- {
- //画一节一节的身子
- for (int i = 0; i < nowNum; i++)
- {
- bodys[i].Draw();
- }
- }
-
- #region Lesson7 蛇的移动
- public void Move()
- {
- //移动前
- //擦除最后一个位置
- Console.SetCursorPosition(bodys[nowNum - 1].pos.x, bodys[nowNum - 1].pos.y);
- Console.WriteLine(" ");
-
- //再移动
- switch (dir)
- {
- case E_MoveDir.Up:
- --bodys[0].pos.y;
- break;
- case E_MoveDir.Down:
- ++bodys[0].pos.y;
- break;
- case E_MoveDir.Left:
- bodys[0].pos.x -= 2;
- break;
- case E_MoveDir.Right:
- bodys[0].pos.x += 2;
- break;
- default:
- break;
- }
-
- }
-
- #endregion
-
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using 贪吃蛇.Lesson3;
- using 贪吃蛇.Lesson4;
-
- namespace 贪吃蛇.Lesson6
- {
- /// <summary>
- /// 蛇的移动方向
- /// </summary>
- enum E_MoveDir
- {
- Up,
- Down,
- Left,
- Right,
- }
-
- class Snake : IDraw
- {
- SnakeBody[] bodys;
- //记录当前蛇的长度
- int nowNum;
- //当前移动方向
- E_MoveDir dir;
-
- public Snake(int x, int y)
- {
- //粗暴的方法 直接申明200个空间 来装蛇身体的数组
- bodys = new SnakeBody[200];
-
- bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
- nowNum = 1;
-
- dir = E_MoveDir.Down;
- }
-
- public void Draw()
- {
- //画一节一节的身子
- for (int i = 0; i < nowNum; i++)
- {
- bodys[i].Draw();
- }
- }
-
- #region Lesson7 蛇的移动
- public void Move()
- {
- //移动前
- //擦除最后一个位置
- Console.SetCursorPosition(bodys[nowNum - 1].pos.x, bodys[nowNum - 1].pos.y);
- Console.WriteLine(" ");
-
- //再移动
- switch (dir)
- {
- case E_MoveDir.Up:
- --bodys[0].pos.y;
- break;
- case E_MoveDir.Down:
- ++bodys[0].pos.y;
- break;
- case E_MoveDir.Left:
- bodys[0].pos.x -= 2;
- break;
- case E_MoveDir.Right:
- bodys[0].pos.x += 2;
- break;
- default:
- break;
- }
-
- }
-
- #endregion
-
- #region Lesson8 改变方向
- public void ChangeDir(E_MoveDir dir)
- {
- //只有头部的时候 可以直接左转右 右转左 上转下 下转上
- //有身体时 这些情况就不能直接转
- if (this.dir == dir ||
- nowNum > 1 &&
- (this.dir == E_MoveDir.Up && dir == E_MoveDir.Down ||
- this.dir == E_MoveDir.Down && dir == E_MoveDir.Up ||
- this.dir == E_MoveDir.Left && dir == E_MoveDir.Right ||
- this.dir == E_MoveDir.Right && dir == E_MoveDir.Left))
- {
- return;
- }
-
- //只要没有 return 就记录外面传入的方向 之后就会按照这个方向去移动
- this.dir = dir;
- }
- #endregion
-
- }
- }
在GameScene里面实现调用
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using 贪吃蛇.Lesson3;
- using 贪吃蛇.Lesson4;
- using 贪吃蛇.Lesson5;
-
- namespace 贪吃蛇.Lesson6
- {
- /// <summary>
- /// 蛇的移动方向
- /// </summary>
- enum E_MoveDir
- {
- Up,
- Down,
- Left,
- Right,
- }
-
- class Snake : IDraw
- {
- SnakeBody[] bodys;
- //记录当前蛇的长度
- int nowNum;
- //当前移动方向
- E_MoveDir dir;
-
- public Snake(int x, int y)
- {
- //粗暴的方法 直接申明200个空间 来装蛇身体的数组
- bodys = new SnakeBody[200];
-
- bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
- nowNum = 1;
-
- dir = E_MoveDir.Down;
- }
-
- public void Draw()
- {
- //画一节一节的身子
- for (int i = 0; i < nowNum; i++)
- {
- bodys[i].Draw();
- }
- }
-
- #region Lesson7 蛇的移动
- public void Move()
- {
- //移动前
- //擦除最后一个位置
- Console.SetCursorPosition(bodys[nowNum - 1].pos.x, bodys[nowNum - 1].pos.y);
- Console.WriteLine(" ");
-
- //再移动
- switch (dir)
- {
- case E_MoveDir.Up:
- --bodys[0].pos.y;
- break;
- case E_MoveDir.Down:
- ++bodys[0].pos.y;
- break;
- case E_MoveDir.Left:
- bodys[0].pos.x -= 2;
- break;
- case E_MoveDir.Right:
- bodys[0].pos.x += 2;
- break;
- default:
- break;
- }
-
- }
-
- #endregion
-
- #region Lesson8 改变方向
- public void ChangeDir(E_MoveDir dir)
- {
- //只有头部的时候 可以直接左转右 右转左 上转下 下转上
- //有身体时 这些情况就不能直接转
- if (this.dir == dir ||
- nowNum > 1 &&
- (this.dir == E_MoveDir.Up && dir == E_MoveDir.Down ||
- this.dir == E_MoveDir.Down && dir == E_MoveDir.Up ||
- this.dir == E_MoveDir.Left && dir == E_MoveDir.Right ||
- this.dir == E_MoveDir.Right && dir == E_MoveDir.Left))
- {
- return;
- }
-
- //只要没有 return 就记录外面传入的方向 之后就会按照这个方向去移动
- this.dir = dir;
- }
- #endregion
-
- #region Lesson9 撞墙撞身体结束逻辑
- public bool CheckEnd(Map map)
- {
- for (int i = 0; i < map.walls.Length; i++)
- {
- if (bodys[0].pos == map.walls[i].pos)
- {
- return true;
- }
- }
-
- for (int i = 1; i < nowNum; i++)
- {
- if (bodys[0].pos == bodys[i].pos)
- {
- return true;
- }
- }
-
- return false;
- }
- #endregion
-
- }
- }
GameScene中调用
Snake类里面添加的相关方法 -- (Lesson10 部分)
GameScene类中调用
Snake类中添加方法
(加了Lesson11--长身体AddBody方法,在Lesson10吃食物方法里面调用了AddBody方法,然后在Lesson7中添加了蛇尾跟着蛇头移动的逻辑处理)
至此跟着老师进行的制作的功能都已实现
C#核心实践--贪吃蛇(老师实现的)
完整代码在资源里。
还是得多敲多练,多想想怎么让代码更精简,逻辑怎么更清晰!
多挤些时间啊!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。