2023年12月13日
贪吃蛇是一款经典的小游戏,它简单、有趣,能够帮助初学者练习编程技能。在这篇文章中,我们将使用Python和Flask框架来构建一个简单的贪吃蛇游戏后端,并提供API接口和页面渲染。
首先,我们需要定义游戏状态变量,包括画板宽度、高度、蛇的位置、食物位置和运动方向。然后,我们可以定义move_snake()函数来移动贪吃蛇。该函数根据方向移动蛇头,并检查是否与食物位置重合,如果是,则生成新的食物位置;否则,移除蛇尾。最后,该函数检查是否有蛇头与蛇身或边界重合,如果是,则游戏结束。
接下来,我们定义generate_food_position()函数来生成随机的食物位置。该函数通过随机生成x和y坐标,然后检查该位置是否与蛇的位置重合,如果不是,则返回该位置。
在API路由方面,我们可以定义get_game_state()函数来获取游戏状态,并返回JSON格式的数据。我们还可以定义move()函数来接收POST请求中的方向参数,然后更新游戏状态中的方向,并移动贪吃蛇。最后,该函数返回新的游戏状态和游戏是否结束的标志。
在页面渲染方面,我们可以定义index()函数来渲染HTML模板文件。该文件包含贪吃蛇游戏界面和JavaScript代码,用于向API发送请求并更新游戏状态。
注:首先,创建一个名为 templates
的文件夹,并在其中创建一个名为 index.html
的文件和app.py。路径问题:修改template_folder为你的文件路径✨
app = Flask(__name__, template_folder=r'E:\jupyter-notebook\jupyter\Zb\template')
下面是完整的Python代码:
from flask import Flask, jsonify, request, render_template
import random
# 初始化 Flask 应用程序
app = Flask(__name__, template_folder='templates')
# 游戏状态变量
game_state = {
'board_width': 20,
'board_height': 20,
'snake_position': [[5, 5], [4, 5], [3, 5]],
'food_position': [10, 10],
'direction': 'right'
}
# 定义游戏行为
def move_snake():
# 获取当前蛇头和方向
head_x, head_y = game_state['snake_position'][0]
direction = game_state['direction']
# 根据方向移动蛇头
if direction == 'up':
new_head = [head_x, head_y - 1]
elif direction == 'down':
new_head = [head_x, head_y + 1]
elif direction == 'left':
new_head = [head_x - 1, head_y]
elif direction == 'right':
new_head = [head_x + 1, head_y]
# 将新蛇头添加到蛇的位置列表中
game_state['snake_position'].insert(0, new_head)
# 如果蛇头与食物位置重合,则生成新的食物位置
if new_head == game_state['food_position']:
game_state['food_position'] = generate_food_position()
else:
# 否则,移除蛇尾
game_state['snake_position'].pop()
# 检查是否有蛇头与蛇身或边界重合
if (new_head in game_state['snake_position'][1:] or
new_head[0] < 0 or new_head[0] >= game_state['board_width'] or
new_head[1] < 0 or new_head[1] >= game_state['board_height']):
return False
return True
# 定义生成食物位置的函数
def generate_food_position():
while True:
x = random.randint(0, game_state['board_width'] - 1)
y = random.randint(0, game_state['board_height'] - 1)
if [x, y] not in game_state['snake_position']:
return [x, y]
# 设置 API 路由
@app.route('/api/game/state', methods=['GET'])
def get_game_state():
return jsonify(game_state)
@app.route('/api/game/move', methods=['POST'])
def move():
# 获取请求体中的方向参数
data = request.get_json()
direction = data['direction']
# 更新游戏状态中的方向
game_state['direction'] = direction
# 移动蛇并检查游戏是否结束
game_over = not move_snake()
# 返回新的游戏状态和游戏是否结束的标志
return jsonify({
'success': not game_over,
'game_state': game_state
})
# 设置根路由
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
# 启动应用程序
if __name__ == '__main__':
app.run(debug=True)
在模板文件index.html中,我们可以使用canvas元素来绘制贪吃蛇游戏界面,并使用JavaScript代码来向API发送请求并更新游戏状态。下面是完整的HTML和JavaScript代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>贪吃蛇游戏</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>贪吃蛇游戏</h1>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// 获取游戏状态并绘制蛇和食物
function draw() {
$.get('/api/game/state', function(data) {
var gameState = data['game_state'];
var boardWidth = gameState['board_width'];
var boardHeight = gameState['board_height'];
var snakePosition = gameState['snake_position'];
var foodPosition = gameState['food_position'];
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
ctx.fillStyle = 'black';
for (var i = 0; i < snakePosition.length; i++) {
var x = snakePosition[i][0] * canvas.width / boardWidth;
var y = snakePosition[i][1] * canvas.height / boardHeight;
ctx.fillRect(x, y, canvas.width / boardWidth, canvas.height / boardHeight);
}
// 绘制食物
ctx.fillStyle = 'red';
var x = foodPosition[0] * canvas.width / boardWidth;
var y = foodPosition[1] * canvas.height / boardHeight;
ctx.fillRect(x, y, canvas.width / boardWidth, canvas.height / boardHeight);
});
}
// 向API发送POST请求来移动蛇并更新游戏状态
function move(direction) {
$.post('/api/game/move', JSON.stringify({'direction': direction}), function(data) {
if (data['success']) {
draw();
} else {
alert('游戏结束!');
}
}, 'json');
}
// 监听键盘事件来改变蛇的方向
document.addEventListener('keydown', function(event) {
switch (event.key) {
case 'ArrowUp':
move('up');
break;
case 'ArrowDown':
move('down');
break;
case 'ArrowLeft':
move('left');
break;
case 'ArrowRight':
move('right');
break;
}
});
// 初始化游戏状态并绘制蛇和食物
draw();
</script>
</body>
</html>
python app.py
通过运行python app.py,我们可以启动Flask应用程序,并在浏览器中访问http://localhost:5000来开始游戏。
插曲
获取当前贪吃蛇游戏状态
import requests
url = 'http://localhost:5000/api/game/state'
response = requests.get(url)
game_state = response.json()
print(game_state)
{'board_height': 20, 'board_width': 20, 'direction': 'right', 'food_position': [10, 10], 'snake_position': [[6, 5], [5, 5], [4, 5]]}
将状态发语言模型看看效果
用户:{'board_height': 20, 'board_width': 20, 'direction': 'right', 'food_position': [10, 10], 'snake_position': [[6, 5], [5, 5], [4, 5]]} 沙和尚: 啊,这什么情况?我可没那么好命吃那肥大的蛇头。不过,没关系,我有我的独门绝技,可以让蛇头松动一下。快来帮我! 猪八戒: 天哪,这个蛇头真是我见过的最美味的了!但是别担心,你绝对不是一个人在战斗,我们还有猪八戒呢。他的独门绝技就是可以将所有的东西嚼碎再吞下去。你要相信他一定能够帮到你的。来吧,让我们一起咬住这个蛇头,让它为我们做贡献! 悟空:你想干吗?这蛇头太难对付了,你有办法解决这个问题吗?我还是去找我的队友们帮忙吧,你们可是猪八戒的拿手好戏啊!你快点过来,我们在这里等你! 用户:这是当前贪吃蛇游戏状态,请你做出决策,如何才能吃到食物 沙和尚: 当然没问题,既然我知道了你的目标,那就让我来给你点子吧。 首先,我们需要把蛇的头部向右移动10个单位,以便于进食。然后,我们需要在蛇的身上增加一些分数,让它看起来更有趣。 接下来,我们可以开始放一些食物到蛇的身体上。这样不仅可以帮助蛇前进,还可以让它的外观看起来更有吸引力。 最后,当食物都被吃掉后,我们将显示蛇的食物位置,并立即控制它去寻找下一个目标。记住,我们不能让它太过接近食物的位置,以免被敌人发现。 希望这个建议能帮到你,祝你在游戏中取得胜利!
可以执行游戏操作,例如向左移动贪吃蛇
import requests
url = 'http://localhost:5000/api/game/move'
data = {'direction': 'left'}
response = requests.post(url, json=data)
if response.ok:
print('Move successful!')
else:
print('Error:', response.json())
总结
在本文中,我们学习了如何使用Python和Flask框架来构建一个简单的贪吃蛇游戏后端,并提供API接口和页面渲染。我们定义了游戏状态变量、移动逻辑和生成食物位置的函数,并使用Flask路由来处理API请求。我们还使用HTML和JavaScript代码来渲染游戏界面,并向API发送请求来移动贪吃蛇并更新游戏状态。
这个项目虽然简单,但它涵盖了很多常见的Web开发技术,包括Python编程、Flask框架、API设计和HTML/JavaScript编程。如果你是一名初学者,这个项目将帮助你练习你的编程技能,并为你未来的Web开发之路铺平道路。