C# 开发贪吃蛇游戏

ops/2024/11/20 18:59:31/

 贪吃蛇大家都玩过,所以就不过多解释 这是一个Winfrom项目即贴既玩

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;namespace SnakeGame
{public partial class Form1 : Form{private const int GridSize = 10; // 每个格子的尺寸private const int WidthInGrid = 100;    // 游戏区域的宽度(格子数)private const int HeightInGrid = 70;   // 游戏区域的高度(格子数)private List<Rectangle> snake = new List<Rectangle>{new Rectangle(100, 100, GridSize, GridSize)  // 初始化蛇的起始位置};  // 蛇的身体部分(每个部分都是一个矩形)private Rectangle food;         // 食物的矩形区域private Random random;          // 用于生成随机数private int dx, dy;             // 蛇的移动方向private Timer timer;            // 游戏定时器private bool isGameOver;        // 游戏是否结束private int fastSpeed = 20;    // 按住方向键时的加速速度(定时器间隔)private int defaultSpeed = 100; // 默认的蛇的速度(定时器间隔)// 新增:记录蛇的当前大小private int snakeSegmentWidth = GridSize;private int snakeSegmentHeight = GridSize;public Form1(){InitializeComponent();Start();}public void Start(){label2.Visible = false;label1.Visible = false;button1.Visible = false;this.DoubleBuffered = true; // 开启双缓冲,减少闪烁// 根据格子数调整窗体尺寸this.Width = WidthInGrid * GridSize + 16;  // Form的宽度this.Height = HeightInGrid * GridSize + 39; // Form的高度random = new Random();timer = new Timer { Interval = defaultSpeed }; // 设置定时器初始速度timer.Tick += Timer_Tick;ResetGame();}private void ResetGame(){food = GenerateFood();dx = GridSize; // 初始时蛇向右移动dy = 0;isGameOver = false;timer.Start(); // 启动游戏定时器}private void Timer_Tick(object sender, EventArgs e){if (isGameOver){timer.Stop();label1.Visible = true;label1.Text = "Game Over";button1.Visible = true;button1.Enabled = true;label2.Visible = true;return;}// 计算蛇头的新位置var head = snake.First();var newHead = new Rectangle(head.X + dx, head.Y + dy, snakeSegmentWidth, snakeSegmentHeight);// 如果蛇头碰到墙壁或自己,游戏结束if (newHead.X < 0 || newHead.Y < 0 || newHead.X >= WidthInGrid * GridSize || newHead.Y >= HeightInGrid * GridSize || snake.Contains(newHead)){isGameOver = true;return;}if (snake.Count % 5 == 0){snakeSegmentWidth = (int)(GridSize + snake.Count);snakeSegmentHeight = (int)(GridSize + snake.Count);}// 将蛇头添加到蛇身前snake.Insert(0, newHead);// 如果蛇吃到食物,生成新食物并让蛇变长if (newHead.IntersectsWith(food)){food = GenerateFood();}else{// 否则去掉蛇尾snake.RemoveAt(snake.Count - 1);}// 重新绘制游戏画面Invalidate();}private Rectangle GenerateFood(){// 随机生成食物的位置,确保食物生成在窗体内int x = random.Next(0, WidthInGrid) * GridSize;int y = random.Next(0, HeightInGrid) * GridSize;return new Rectangle(x, y, GridSize, GridSize);}private void button1_Click(object sender, EventArgs e){label1.Visible = false;button1.Visible = false;button1.Enabled = false;isGameOver = false;label2.Visible = false;snakeSegmentWidth = GridSize;snakeSegmentHeight = GridSize;snake = new List<Rectangle>{new Rectangle(100, 100, GridSize, GridSize)  // 初始化蛇的起始位置};dx = GridSize; // 初始时蛇向右移动dy = 0;timer.Interval = defaultSpeed;timer.Start();}private void Form1_KeyDown(object sender, KeyEventArgs e){// 控制蛇的移动方向if (e.KeyCode == Keys.Up&& dy==0){dx = 0;dy = -GridSize;timer.Interval = fastSpeed; // 按住时加速}else if (e.KeyCode == Keys.Down && dy == 0){dx = 0;dy = GridSize;timer.Interval = fastSpeed; // 按住时加速}else if (e.KeyCode == Keys.Left && dx == 0){dx = -GridSize;dy = 0;timer.Interval = fastSpeed; // 按住时加速}else if (e.KeyCode == Keys.Right && dx == 0){dx = GridSize;dy = 0;timer.Interval = fastSpeed; // 按住时加速}}private void Form1_Paint(object sender, PaintEventArgs e){var g = e.Graphics;// 绘制蛇身for (int i = 0; i < snake.Count; i++){var segment = snake[i];// 蛇头(第一个部分)为黄色,其余为绿色if (i == 0){g.FillRectangle(Brushes.Yellow, segment); // 蛇头为黄色}else{g.FillRectangle(Brushes.Lime, segment); // 蛇身为绿色}}// 绘制食物g.FillRectangle(Brushes.Red, food);}private void Form1_KeyUp(object sender, KeyEventArgs e){// 松开方向键时恢复到默认速度if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right){timer.Interval = defaultSpeed; // 恢复原来的速度}}}
}


http://www.ppmy.cn/ops/135302.html

相关文章

在 macOS 和 Linux 中,波浪号 `~`的区别

文章目录 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~ 在 macO…

力扣-Hot100-数组【算法学习day.37】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…

深入解析TK技术下视频音频不同步的成因与解决方案

随着互联网和数字视频技术的飞速发展&#xff0c;音视频同步问题逐渐成为网络视频播放、直播、编辑等过程中不可忽视的技术难题。尤其是在采用TK&#xff08;Transmission Keying&#xff09;技术进行视频传输时&#xff0c;由于其特殊的时序同步要求&#xff0c;音视频不同步现…

Windows系统使用全功能的跨平台开源音乐服务器Navidrome搭建在线音乐库

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动Navidrome容器4. 公网远程访问本地Navidrome4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定公网地址远程访问 前言 在数字时代&#xff0c;拥有一个个性化、便捷的音乐库成为了许多人的需求。本文…

STM32G4的数模转换器(DAC)的应用

目录 概述 1 DAC模块介绍 2 STM32Cube配置参数 2.1 参数配置 2.2 项目架构 3 代码实现 3.1 接口函数 3.2 功能函数 3.3 波形源代码 4 DAC功能测试 4.1 测试方法介绍 4.2 波形测试 概述 本文主要介绍如何使用STM32G4的DAC模块功能&#xff0c;笔者使用STM32Cube工具…

数据爬取技术进阶:从表单提交到页面点击的实现

引言 随着互联网的迅速发展&#xff0c;数据需求日益多样化。简单的静态页面爬取已难以满足现代应用场景的需求&#xff0c;特别是在涉及到登录、表单提交、页面点击等交互操作的情况下&#xff0c;数据的获取变得更加复杂。为了解决这些难题&#xff0c;使用代理 IP 是必不可…

c++设计模式之适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09; 定义 适配器模式的目的是让不兼容的接口能够协同工作。通过定义一个适配器类&#xff0c;将原本接口不兼容的两种类的接口转化为一致的接口&#xff0c;使得原本无法交互的类可以互操作。 应用场景 当你希望将一些已经存在…

vscode 关闭绑定元素 隐式具有“any”类型这类错误

在vue的项目里面&#xff0c;经常看到any类型的报错&#xff0c;真的很烦的 在tsconfig.json中配置以下参数 “noImplicitAny”: false 就可以了 出现类型“never”上不存在属性“userName”。ts-plugin(2339) 配置该参数 modeuleResolution : node "compilerOptions&qu…