今天学了很多东西。
早上用C#写了许多案例小项目,贪吃蛇是最好的一个。
下午我就开始练习unity了,刚开始写移动脚本发现绑定的世界坐标轴,大意了。
晚上收集了制作2D自上而下像素游戏的必要资源,创建了一个玩家NPC,还有wasd平滑移动,明天就要开始做动画了,包括攻击、死亡、射箭等。
以下是我的贪吃蛇代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Linq; //用于 .any()和 .First()等LINQ操作
using System.Threading; //用于Thread.Sleep()等线程操作
namespace study_5
{
//定义一个结构体来表示坐标点
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
//重写Equals和GetHashCode以便在List中正确比较Point对象
public override bool Equals(object obj)
{
if (obj is Point other)
{
return X == other.X && Y == other.Y;
}
return false;
}
public override int GetHashCode()
{
return HashCode.Combine(X, Y);
}
public static bool operator ==(Point p1, Point p2)
{
return p1.Equals(p2);
}
public static bool operator !=(Point p1, Point p2)
{
return !p1.Equals(p2);
}
}
//定义蛇的移动方向
public enum Direction
{
Up,
Down,
Left,
Right
}
class Program
{
//游戏设置
const int GameWidth = 50; //游戏区域宽度
const int GameHeight = 40; //游戏区域高度
const char SnakeChar = '■'; //蛇身体字符
const char FoodChar = '●'; //食物字符
const char BorderChar = '#'; //边框字符
static int Score = 0;
static int GameSpeed = 200; //游戏速度,单位毫秒,越小越快
//游戏状态
static List<Point> snake; //蛇的身体,List的第一个元素是蛇头
static Point food; //食物的位置
static Direction currentDirection; //当前蛇的移动方向
static bool gameOver; //游戏是否结束
static Random random = new Random(); //用于生成随机数
static void Main(string[] args)
{
Console.Title = "贪吃蛇";
Console.CursorVisible = false; //隐藏光标
//设置控制台窗口大小,注意缓冲区大小可能也需要调整
Console.SetWindowSize(GameWidth + 2, GameHeight + 3); // +2/+3是为了边框和分数显示
Console.SetBufferSize(GameWidth + 2, GameHeight + 3);
InitializeGame();
//游戏主循环
while (!gameOver)
{
if (Console.KeyAvailable) //如果有按键按下
{
HandleInput(Console.ReadKey(true).Key);
}
UpdateGame();
DrawGame();
Thread.Sleep(GameSpeed); //控制游戏速度
}
DisplayGameOver();
Console.ReadKey(); //等待按键后退出
}
//初始化游戏
static void InitializeGame()
{
snake = new List<Point>();
//初始蛇的位置和长度
int startX = GameWidth / 2;
int startY = GameHeight / 2;
snake.Add(new Point(startX, startY)); //蛇头
snake.Add(new Point(startX - 1, startY)); //蛇身
snake.Add(new Point(startX - 2, startY)); //蛇尾 (初始向右移动)
currentDirection = Direction.Right; //初始向右移动
GenerateFood();
Score = 0;
GameSpeed = 200; //重置速度
gameOver = false;
Console.Clear(); //清屏开始新游戏
}
//生成食物
static void GenerateFood()
{
//确保食物不会生成在蛇的身体上
do
{
food = new Point(random.Next(0, GameWidth), random.Next(0, GameHeight));
} while (snake.Contains(food)); //如果食物位置在蛇身上,则重新生成
}
//处理用户输入
static void HandleInput(ConsoleKey key)
{
switch (key)
{
case ConsoleKey.UpArrow:
if (currentDirection != Direction.Down) //防止蛇直接反向
currentDirection = Direction.Up;
break;
case ConsoleKey.DownArrow:
if (currentDirection != Direction.Up)
currentDirection = Direction.Down;
break;
case ConsoleKey.LeftArrow:
if (currentDirection != Direction.Right)
currentDirection = Direction.Left;
break;
case ConsoleKey.RightArrow:
if (currentDirection != Direction.Left)
currentDirection = Direction.Right;
break;
case ConsoleKey.Escape:
gameOver = true; //按Esc键退出游戏
break;
}
}
//更新游戏状态
static void UpdateGame()
{
if (gameOver)
{
return;
}
//计算新的蛇头位置
Point newHead = snake.First(); //获取当前蛇头
switch (currentDirection)
{
case Direction.Up:
newHead.Y--;
break;
case Direction.Down:
newHead.Y++;
break;
case Direction.Left:
newHead.X--;
break;
case Direction.Right:
newHead.X++;
break;
}
//检查碰撞
//撞墙
if (newHead.X < 0 || newHead.X >= GameWidth || newHead.Y < 0 || newHead.Y >= GameHeight)
{
gameOver = true; //撞墙,游戏结束
return;
}
//撞到自己
if (snake.Skip(1).Contains(newHead))
{
gameOver = true; //撞到自己,游戏结束
return;
}
//将新蛇头添加到蛇的身体列表的开头
snake.Insert(0, newHead);
//检查是否吃到食物
if (newHead == food)
{
Score += 10;
GenerateFood();
if (Score % 50 == 0 && GameSpeed > 50)
{
GameSpeed -= 20;
}
}
else
{
//没有吃到食物,移除蛇尾,保持长度不变
snake.RemoveAt(snake.Count - 1);
}
}
//绘制游戏画面
static void DrawGame()
{
Console.SetCursorPosition(0, 0);
//绘制边框
for (int i = 0; i < GameWidth + 2; i++)
{
Console.Write(BorderChar);
}
Console.WriteLine();
for (int y = 0; y < GameHeight; y++)
{
Console.Write(BorderChar); //绘制左边框
for (int x = 0; x < GameWidth; x++)
{
Point currentPoint = new Point(x, y);
if (snake.First() == currentPoint) //蛇头
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(SnakeChar);
Console.ResetColor();
}
else if (snake.Contains(currentPoint))
{
Console.Write(SnakeChar); //蛇身
}
else if (food == currentPoint)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(SnakeChar);
Console.ResetColor();
}
else
{
Console.Write(' '); //空白区域
}
}
Console.Write(BorderChar); //绘制右边框
Console.WriteLine();
}
//绘制底部边框
for (int i = 0; i < GameWidth + 2; i++)
{
Console.Write(BorderChar);
}
Console.WriteLine();
//绘制分数
Console.SetCursorPosition(0, GameHeight + 2); //在边框下方显示分数
Console.WriteLine($"分数:{Score} 速度:{(200 - GameSpeed) / (20 + 1)}");//显示速度分数
}
//显示游戏结束信息
static void DisplayGameOver()
{
Console.SetCursorPosition(GameWidth / 2 - 5, GameHeight / 2);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("游戏结束!");
Console.SetCursorPosition(GameWidth / 2 - 8, GameHeight / 2 + 1);
Console.WriteLine($"最终得分: {Score}");
Console.SetCursorPosition(GameWidth / 2 - 10, GameHeight / 2 + 2);
Console.WriteLine("按任意键重新开始...");
Console.ResetColor();
Console.ReadKey(); //等待按键
InitializeGame(); //重新初始化游戏,允许重新开始
}
}
}
Comments NOTHING