前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用 React 中制作一个贪吃蛇游戏?

如何使用 React 中制作一个贪吃蛇游戏?

作者头像
用户1418987
发布2023-11-03 08:18:21
4490
发布2023-11-03 08:18:21
举报
文章被收录于专栏:coder

在 React 中创建贪吃蛇游戏

Snake Game 使用 ReactJS 项目实现功能组件并相应地管理状态。开发的游戏允许用户使用箭头键控制蛇或触摸屏幕上显示的按钮来收集食物并增长长度。游戏的目标是在不与墙壁或蛇自己的身体碰撞的情况下吃尽可能多的食物。

最终输出预览: 让我们看看我们的最终项目会是什么样子。

创建贪吃蛇游戏的方法:

给定的代码代表使用 ReactJS 的贪吃蛇游戏项目。它涉及设置蛇、食物、按钮和菜单的组件。游戏以初始状态初始化,处理蛇运动的用户输入,检测碰撞,并相应地更新游戏板。渲染和用户界面的实现是为了显示游戏元素。游戏流程包括菜单和游戏玩法的过渡。

创建贪吃蛇游戏的步骤:

步骤 1: 在 VSCode IDE 中使用以下命令设置 React 项目。

代码语言:javascript
复制
npx create-react-app snack_game

步骤 2: 执行以下命令导航到新创建的项目文件夹。

代码语言:javascript
复制
cd snack_game

步骤 3: 创建一个名为 Components 的文件夹。我们将在此组件文件夹中创建各种组件及其样式文件,例如 Button.js、Food.js、Menu.js、Snake.js、Menu.css 和 Button.css。

贪吃蛇游戏的项目结构:

package.json中更新后的依赖项将如下所示:

代码语言:javascript
复制
"dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
}

**示例:**在上述目录结构中提到的App.jsindex.css文件中插入以下代码

App.js

代码语言:javascript
复制
// App.js 
import React, { Component } from "react"; 
import Snake from "./Components/Snake"; 
import Food from "./Components/Food"; 
import Button from "./Components/Button"; 
import Menu from "./Components/Menu"; 
import "./App.css"; 
const getRandomFood = () => { 
	let min = 1; 
	let max = 98; 
	let x = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2; 
	let y = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2; 
	return [x, y]; 
}; 

const initialState = { 
	food: getRandomFood(), 
	direction: "RIGHT", 
	speed: 100, 
	route: "menu", 
	snakeDots: [ 
		[0, 0], 
		[0, 2], 
	], 
}; 

class App extends Component { 
	constructor() { 
		super(); 
		this.state = initialState; 
	} 

	componentDidMount() { 
		setInterval(this.moveSnake, this.state.speed); 
		document.onkeydown = this.onKeyDown; 
	} 

	componentDidUpdate() { 
		this.onSnakeOutOfBounds(); 
		this.onSnakeCollapsed(); 
		this.onSnakeEats(); 
	} 

	onKeyDown = (e) => { 
		e.preventDefault(); 
		e = e || window.event; 
		switch (e.keyCode) { 
			case 37: 
				this.setState({ direction: "LEFT" }); 
				break; 
			case 38: 
				this.setState({ direction: "UP" }); 
				break; 
			case 39: 
				this.setState({ direction: "RIGHT" }); 
				break; 
			case 40: 
				this.setState({ direction: "DOWN" }); 
				break; 
		} 
	}; 

	moveSnake = () => { 
		let dots = [...this.state.snakeDots]; 
		let head = dots[dots.length - 1]; 
		if (this.state.route === "game") { 
			switch (this.state.direction) { 
				case "RIGHT": 
					head = [head[0] + 2, head[1]]; 
					break; 
				case "LEFT": 
					head = [head[0] - 2, head[1]]; 
					break; 
				case "DOWN": 
					head = [head[0], head[1] + 2]; 
					break; 
				case "UP": 
					head = [head[0], head[1] - 2]; 
					break; 
			} 
			dots.push(head); 
			dots.shift(); 
			this.setState({ 
				snakeDots: dots, 
			}); 
		} 
	}; 

	onSnakeOutOfBounds() { 
		let head = this.state.snakeDots[this.state.snakeDots.length - 1]; 
		if (this.state.route === "game") { 
			if ( 
				head[0] >= 100 || 
				head[1] >= 100 || 
				head[0] < 0 || 
				head[1] < 0 
			) { 
				this.gameOver(); 
			} 
		} 
	} 

	onSnakeCollapsed() { 
		let snake = [...this.state.snakeDots]; 
		let head = snake[snake.length - 1]; 
		snake.pop(); 
		snake.forEach((dot) => { 
			if (head[0] == dot[0] && head[1] == dot[1]) { 
				this.gameOver(); 
			} 
		}); 
	} 

	onSnakeEats() { 
		let head = this.state.snakeDots[this.state.snakeDots.length - 1]; 
		let food = this.state.food; 
		if (head[0] == food[0] && head[1] == food[1]) { 
			this.setState({ 
				food: getRandomFood(), 
			}); 
			this.increaseSnake(); 
			this.increaseSpeed(); 
		} 
	} 

	increaseSnake() { 
		let newSnake = [...this.state.snakeDots]; 
		newSnake.unshift([]); 
		this.setState({ 
			snakeDots: newSnake, 
		}); 
	} 

	increaseSpeed() { 
		if (this.state.speed > 10) { 
			this.setState({ 
				speed: this.state.speed - 20, 
			}); 
		} 
	} 

	onRouteChange = () => { 
		this.setState({ 
			route: "game", 
		}); 
	}; 

	gameOver() { 
		alert(`GAME OVER, your score is ${this.state.snakeDots.length - 2}`); 
		this.setState(initialState); 
	} 

	onDown = () => { 
		let dots = [...this.state.snakeDots]; 
		let head = dots[dots.length - 1]; 

		head = [head[0], head[1] + 2]; 
		dots.push(head); 
		dots.shift(); 
		this.setState({ 
			direction: "DOWN", 
			snakeDots: dots, 
		}); 
	}; 

	onUp = () => { 
		let dots = [...this.state.snakeDots]; 
		let head = dots[dots.length - 1]; 

		head = [head[0], head[1] - 2]; 
		dots.push(head); 
		dots.shift(); 
		this.setState({ 
			direction: "UP", 
			snakeDots: dots, 
		}); 
	}; 

	onRight = () => { 
		let dots = [...this.state.snakeDots]; 
		let head = dots[dots.length - 1]; 

		head = [head[0] + 2, head[1]]; 
		dots.push(head); 
		dots.shift(); 
		this.setState({ 
			direction: "RIGHT", 
			snakeDots: dots, 
		}); 
	}; 

	onLeft = () => { 
		let dots = [...this.state.snakeDots]; 
		let head = dots[dots.length - 1]; 

		head = [head[0] - 2, head[1]]; 
		dots.push(head); 
		dots.shift(); 
		this.setState({ 
			direction: "LEFT", 
			snakeDots: dots, 
		}); 
	}; 

	render() { 
		const { route, snakeDots, food } = this.state; 
		return ( 
			<div> 
				{route === "menu" ? ( 
					<div> 
						<Menu onRouteChange={this.onRouteChange} /> 
					</div> 
				) : ( 
					<div> 
						<div className="game-area"> 
							<Snake snakeDots={snakeDots} /> 
							<Food dot={food} /> 
						</div> 
						<Button 
							onDown={this.onDown} 
							onLeft={this.onLeft} 
							onRight={this.onRight} 
							onUp={this.onUp} 
						/> 
					</div> 
				)} 
			</div> 
		); 
	} 
} 

export default App;

index.css

代码语言:javascript
复制
/* index.css */
body { 
	background-color: #1e1e1e; 
} 

.game-area { 
	position: relative; 
	width: 600px; 
	height: 500px; 
	border: 2px solid #dc042c; 
	border-radius: 10px; 
	margin: 50px auto; 
	display: flex; 
	flex-wrap: wrap; 
	box-shadow: 0 0 10px #abbfc0; 
} 

@media only screen and (max-width: 800px) { 
	.game-area { 
		position: relative; 
		width: 350px; 
		height: 300px; 
	} 

	.snake { 
		width: 12px; 
		height: 12px; 
	} 
} 

.snake { 
	position: absolute; 
	width: 2%; 
	height: 2%; 
	background-color: #dc042c; 
	border: 1px solid white; 
	z-index: 2; 
} 

.food { 
	position: absolute; 
	width: 12px; 
	height: 12px; 
	background-color: white; 
	border-radius: 20px; 
	z-index: 1; 
}

在不同的文件中编写以下提到的代码(每个代码块的第一行都提到了文件名)

  • Button.js: Button.js表示React功能组件,用于在snake游戏中渲染控制蛇移动的按钮。
  • Menu.js: Menu.js文件代码为Snake Game呈现菜单。它显示一个“开始游戏”按钮,并在单击时触发onRouteChange功能。菜单的样式使用“menu.CSS”文件中的CSS
  • Food.js 是一个React组件,它根据提供的坐标在游戏中呈现食物。
  • Snake.js:Snake.js文件代码是一个React组件,它在游戏中基于表示蛇点的坐标数组来渲染蛇。

//Button.js

代码语言:javascript
复制
//Button.js 
import React from "react"; 
import "./Button.css"; 

const Button = ({ onUp, onDown, onLeft, onRight }) => { 
	return ( 
		<div className="buttons"> 
			<div className="upwards"> 
				<input className="up" onClick={onUp} type="button" value="UP" /> 
			</div> 
			<div className="sideways"> 
				<input 
					className="left"
					onClick={onLeft} 
					type="button"
					value="LEFT"
				/> 
				<input 
					className="right"
					onClick={onRight} 
					type="button"
					value="RIGHT"
				/> 
			</div> 
			<div className="downwards"> 
				<input 
					className="down"
					onClick={onDown} 
					type="button"
					value="DOWN"
				/> 
			</div> 
		</div> 
	); 
}; 
export default Button;

Food.js

代码语言:javascript
复制
//Food.js 
import React from "react"; 

const Food = (props) => { 
	const style = { 
		left: `${props.dot[0]}%`, 
		top: `${props.dot[1]}%`, 
	}; 
	return <div className="food" style={style} />; 
}; 

export default Food;

Menu.js

代码语言:javascript
复制
//Menu.js 
import React from "react"; 
import "./Menu.css"; 

const Menu = ({ onRouteChange }) => { 
	return ( 
		<div className="wrapper"> 
			<div> 
				<input 
					onClick={onRouteChange} 
					className="start"
					type="button"
					value="start game"
				/> 
			</div> 
		</div> 
	); 
}; 

export default Menu;

Snake.js

代码语言:javascript
复制
//Snake.js 
import React from "react"; 

const Snake = (props) => { 
	return ( 
		<div> 
			{props.snakeDots.map((dot, i) => { 
				const style = { 
					left: `${dot[0]}%`, 
					top: `${dot[1]}%`, 
				}; 
				return <div className="snake" key={i} style={style} />; 
			})} 
		</div> 
	); 
}; 
export default Snake;

Button.css

代码语言:javascript
复制
/* Button.css */
.upwards, 
.downwards { 
	display: flex; 
	justify-content: center; 
} 

.sideways { 
	display: flex; 
	justify-content: center; 
	margin: 10px; 
} 

.left, 
.right { 
	margin: 50px; 
	padding: 20px; 
	border: 0px solid; 
	border-radius: 20px; 
	border: 1px solid white; 
	color: #dc042c; 
	background: #1e1e1e; 
	box-shadow: 5px -5px 10px rgba(0, 0, 0, 0.6); 
} 

.up, 
.down { 
	padding: 20px; 
	border: 0px solid; 
	border-radius: 20px; 
	border: 1px solid white; 
	color: #dc042c; 
	background: #1e1e1e; 
	box-shadow: 5px -5px 10px rgba(0, 0, 0, 0.6); 
}

Menu.css

代码语言:javascript
复制
/* Menu.css */
.wrapper { 
	position: relative; 
	width: 200px; 
	height: 250px; 
	border: 2px solid #dc042c; 
	/* border-radius: 10px; */
	margin: 50px auto; 
	margin-top: 200px; 
	display: flex; 
	flex-wrap: wrap; 
	justify-content: center; 
	/* box-shadow: 0 0 10px #abbfc0; */
} 

.start { 
	margin: 100px; 
	background: #1e1e1e; 
	color: white; 
	border-radius: 7px; 
	border: 0px; 
	padding: 10px; 
	font-size: 1.2em; 
	box-shadow: 0 0 70px #abbfc0; 
	font-family: "Courier New", Courier, monospace; 
}
启动我们的程序:
Step 1: 在命令行执行一下命令启动项目程序
代码语言:javascript
复制
npm start
Step 2: 在浏览器地址中打开一下地址 http://localhost:3000/
代码语言:javascript
复制
http://localhost:3000/
输出:
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在 React 中创建贪吃蛇游戏
    • 创建贪吃蛇游戏的方法:
      • 创建贪吃蛇游戏的步骤:
        • 贪吃蛇游戏的项目结构:
          • App.js
            • index.css
              • //Button.js
                • Food.js
                  • Menu.js
                    • Snake.js
                      • Button.css
                        • Menu.css
                          • 启动我们的程序:
                          • Step 1: 在命令行执行一下命令启动项目程序
                          • Step 2: 在浏览器地址中打开一下地址 http://localhost:3000/
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档