C#贪吃蛇
文章目录
Program.cs
using 贪吃蛇.Text1;
Game game = new Game();
game.start();
Text1
Game.cs
using 贪吃蛇.Text2;
namespace 贪吃蛇.Text1
{
enum E_SceneType
{
Begin,
Game,
End,
}
internal class Game
{
public const int w = 80;
public const int h = 20;
public static ISceneUpdate nowScene;
public Game()
{
Console.CursorVisible = false;
Console.SetWindowSize(w, h);
Console.SetBufferSize(w, h);
ChangeScene(E_SceneType.Begin);
}
public void start()
{
while (true)
{
if (nowScene != null)
{
nowScene.Update();
}
}
}
public static void ChangeScene(E_SceneType type)
{
Console.Clear();
switch (type)
{
case E_SceneType.Begin:
nowScene = new BeginScene();
break;
case E_SceneType.Game:
nowScene = new GameScene();
break;
case E_SceneType.End:
nowScene = new EndScene();
break;
}
}
}
}
ISceneUpdate.cs
namespace 贪吃蛇.Text1
{
/// <summary>
/// 场景更新接口
/// </summary>
internal interface ISceneUpdate
{
void Update();
}
}
Text2
BeginScene.cs
using 贪吃蛇.Text1;
namespace 贪吃蛇.Text2
{
internal class BeginScene : BegionOrEndScene
{
public BeginScene()
{
strTitle = "贪吃蛇";
strOne = "开始游戏";
}
public override void EnterJDoSomthing()
{
if (nowSelIndex == 0)
{
Game.ChangeScene(E_SceneType.Game);
}
else
{
Environment.Exit(0);
}
}
}
}
BegionOrEndScene.cs
using 贪吃蛇.Text1;
namespace 贪吃蛇.Text2
{
abstract internal class BegionOrEndScene : ISceneUpdate
{
protected int nowSelIndex = 0;
protected string strTitle;
protected string strOne;
public abstract void EnterJDoSomthing();
public void Update()
{
Console.ForegroundColor = ConsoleColor.White;
Console.SetCursorPosition(Game.w / 2 - strTitle.Length, 5);
Console.Write(strTitle);
Console.SetCursorPosition(Game.w / 2 - strOne.Length, 8);
Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
Console.Write(strOne);
Console.SetCursorPosition(Game.w / 2 - 4, 10);
Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
Console.Write("结束游戏");
switch(Console.ReadKey(true).Key)
{
case ConsoleKey.W:
nowSelIndex--;
if (nowSelIndex < 0)
{
nowSelIndex = 1;
}
break;
case ConsoleKey.S:
nowSelIndex++;
if (nowSelIndex > 1)
{
nowSelIndex = 0;
}
break;
case ConsoleKey.J:
EnterJDoSomthing();
break;
}
}
}
}
EndScene.cs
using 贪吃蛇.Text1;
namespace 贪吃蛇.Text2
{
internal class EndScene : BegionOrEndScene
{
public EndScene()
{
strTitle = "结束游戏";
strOne = "回到开始界面";
}
public override void EnterJDoSomthing()
{
if(nowSelIndex == 0)
{
Game.ChangeScene(E_SceneType.Begin);
}
else
{
Environment.Exit(0);
}
}
}
}
GameScene.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text4;
using 贪吃蛇.Text5;
using 贪吃蛇.Text6;
namespace 贪吃蛇.Text2
{
internal class GameScene : ISceneUpdate
{
Map map;
Snake snake;
Food food;
int updateIndex = 0;
public GameScene()
{
map = new Map();
snake = new Snake(40,10);
food = new Food(snake);
}
public void Update()
{
if (updateIndex % 4444 == 0)
{
map.Draw();
food.Draw();
snake.Move();
snake.Draw();
if (snake.CheckEnd(map))
{
Game.ChangeScene(E_SceneType.End);
}
//蛇吃食物
snake.CheckEatFood(food);
updateIndex = 0;
}
updateIndex++;
//Console.KeyAvailable判断键盘有没有输入,如果有为ture
if (Console.KeyAvailable)
{
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.W:
snake.ChangeDir(E_MoveDir.up);
break;
case ConsoleKey.S:
snake.ChangeDir(E_MoveDir.down);
break;
case ConsoleKey.A:
snake.ChangeDir(E_MoveDir.left);
break;
case ConsoleKey.D:
snake.ChangeDir(E_MoveDir.right);
break;
}
}
}
}
}
Text3
GameObject.cs
namespace 贪吃蛇.Text3
{
abstract internal class GameObject : IDraw
{
public Position pos;
public abstract void Draw();
}
}
IDraw.cs
namespace 贪吃蛇.Text3
{
internal interface IDraw
{
void Draw();
}
}
Position.cs
namespace 贪吃蛇.Text3
{
internal struct Position
{
public int x; public int y;
public Position(int x, int y)
{
this.x = x;
this.y = y;
}
public static bool operator ==(Position p1, Position p2)
{
if (p1.x == p2.x && p1.y == p2.y)
{
return true;
}
return false;
}
public static bool operator !=(Position p1, Position p2)
{
if (p1.x == p2.x && p1.y == p2.y)
{
return false;
}
return true;
}
}
}
Text4
Food.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text3;
using 贪吃蛇.Text6;
namespace 贪吃蛇.Text4
{
internal class Food : GameObject
{
public Food(Snake snake)
{
RandomPos(snake);
}
public override void Draw()
{
Console.SetCursorPosition(pos.x,pos.y);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("◆");
}
//随机食物位置
public void RandomPos(Snake snake)
{
//得到蛇位置信息
Random random = new Random();
int x = random.Next(2, Game.w / 2 - 1) * 2;
int y = random.Next(1, Game.h - 2);
pos = new Position(x,y);
if (snake.CheckFoodPos(pos))
{
//再随机
RandomPos(snake);
}
}
}
}
SnakeBody.cs
using 贪吃蛇.Text3;
namespace 贪吃蛇.Text4
{
enum E_SnakeBody_Type
{
Head,
Body,
}
internal class SnakeBody : GameObject
{
private E_SnakeBody_Type type;
public SnakeBody(E_SnakeBody_Type type,int x,int y)
{
this.type = type;
pos = new Position(x,y);
}
public override void Draw()
{
Console.SetCursorPosition(pos.x, pos.y);
Console.ForegroundColor = type == E_SnakeBody_Type.Head ? ConsoleColor.Yellow : ConsoleColor.Green;
Console.Write(type == E_SnakeBody_Type.Head ? "●" : "⊙");
}
}
}
Wall.cs
using 贪吃蛇.Text3;
namespace 贪吃蛇.Text4
{
internal class Wall : GameObject
{
public Wall(int x, int y)
{
pos = new Position(x, y);
}
public override void Draw()
{
Console.SetCursorPosition(pos.x, pos.y);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("■");
}
}
}
Text5
Map.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text3;
using 贪吃蛇.Text4;
namespace 贪吃蛇.Text5
{
internal class Map : IDraw
{
public Wall[] Walls;
public Map()
{
Walls = new Wall[Game.w + (Game.h - 3) * 2];
int index = 0;
for (int i = 0; i < Game.w; i += 2)
{
Walls[index] = new Wall(i, 0);
index++;
}
for (int i = 0; i < Game.w; i += 2)
{
Walls[index] = new Wall(i, Game.h - 2);
index++;
}
for (int i = 1; i < Game.h - 2; i++)
{
Walls[index] = new Wall(0, i);
index++;
}
for (int i = 1; i < Game.h - 2; i++)
{
Walls[index] = new Wall(Game.w - 2, i);
index++;
}
}
public void Draw()
{
for (int i = 0; i < Walls.Length; i++)
{
Walls[i].Draw();
}
}
}
}
Text6
Snake.cs
using 贪吃蛇.Text3;
using 贪吃蛇.Text4;
using 贪吃蛇.Text5;
namespace 贪吃蛇.Text6
{
enum E_MoveDir
{
up,
down,
left,
right,
}
internal class Snake : IDraw
{
SnakeBody[] bodys;
//记录蛇长度
int nowNum;
//当前移动方向
E_MoveDir moveDir;
public Snake(int x, int y)
{
bodys = new SnakeBody[100];
bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
nowNum = 1;
moveDir = E_MoveDir.right;
}
public void Draw()
{
for (int i = 0; i < nowNum; i++)
{
bodys[i].Draw();
}
}
public void Move()
{
//移动前擦除最后一个位置
SnakeBody lastBody = bodys[nowNum - 1];
Console.SetCursorPosition(lastBody.pos.x, lastBody.pos.y);
Console.Write(" ");
//蛇头移动前,从蛇尾开始位置依次向前替代
for (int i = nowNum - 1; i > 0; i--)
{
bodys[i].pos = bodys[i - 1].pos;
}
switch (moveDir)
{
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;
}
}
public void ChangeDir(E_MoveDir dir)
{
if (dir == moveDir || nowNum > 1 && (
moveDir == E_MoveDir.left && dir == E_MoveDir.right ||
moveDir == E_MoveDir.right && dir == E_MoveDir.left ||
moveDir == E_MoveDir.up && dir == E_MoveDir.down ||
moveDir == E_MoveDir.down && dir == E_MoveDir.up))
{
return;
}
moveDir = dir;
}
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;
}
public bool CheckFoodPos(Position p)
{
for (int i = 0; i < nowNum; i++)
{
if (bodys[i].pos == p)
{
return true;
}
}
return false;
}
public void CheckEatFood(Food food)
{
if (bodys[0].pos == food.pos)
{
//吃到食物再随机
food.RandomPos(this);
//长身体
AddBody();
}
}
private void AddBody()
{
SnakeBody frontBody = bodys[nowNum - 1];
bodys[nowNum] = new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x, frontBody.pos.y);
nowNum++;
}
}
}