代码水平仅仅够写大作业,大家就看个乐
作业需求:运用gui,数据库,matplotlib库
gui用ktinker绘制游戏开始界面,数据库储存每次游戏的得分,matplotlib绘制游戏得分变化,其他内容代码注释我写的很详细
上代码:
snake_game.py部分将游戏封装为一个类之后直接调用
# -*- coding: utf-8 -*-
import pygame
import random
import os
import sqlite3
class SnakeGame:
def __init__(self):
# 初始化 pygame
pygame.init()
# 定义一些颜色
self.WHITE = (255, 255, 255)
self.BLACK = (0, 0, 0)
self.RED = (255, 0, 0)
# 设置游戏窗口大小,文字大小,并创建游戏窗口
self.DISPLAY_WIDTH = 800
self.DISPLAY_HEIGHT = 600
self.font = pygame.font.SysFont("SimHei", 32)
self.text_surface_loose = self.font.render("前面的区域以后再来探索吧", True, (255, 255, 255))
self.game_display = pygame.display.set_mode((self.DISPLAY_WIDTH, self.DISPLAY_HEIGHT))
pygame.display.set_caption('Greedy Snake')
# 设置游戏时钟,用于控制帧率和速度
self.clock = pygame.time.Clock()
# 加载食物图片 方块/food 大小
self.BLOCK_SIZE = 20
self.FOOD_SIZE = self.BLOCK_SIZE * 3
self.current_dir = os.path.dirname(__file__)
self.file_path = os.path.join(self.current_dir, 'food.jpg')
self.food_image = pygame.image.load(self.file_path)
self.food_image = pygame.transform.scale(self.food_image, (self.FOOD_SIZE, self.FOOD_SIZE))
#定义得分
self.score = 0
# 定义生成食物的函数
def generate_food_location(self):
"""
在游戏窗口中随机生成一个食物的位置。
"""
x = round(random.randrange(0, self.DISPLAY_WIDTH - self.FOOD_SIZE) / self.FOOD_SIZE) * self.FOOD_SIZE
y = round(random.randrange(0, self.DISPLAY_HEIGHT - self.FOOD_SIZE) / self.FOOD_SIZE) * self.FOOD_SIZE
return (x, y)
# 定义绘制贪吃蛇的函数
def draw_snake(self, snake_list):
"""
在游戏窗口中绘制贪吃蛇。
"""
for block in snake_list:
pygame.draw.rect(self.game_display, self.BLACK, [block[0], block[1], self.BLOCK_SIZE, self.BLOCK_SIZE])
#存入得分
def save_score(self):
# 连接到数据库
conn = sqlite3.connect('scores.db')
cursor = conn.cursor()
# 将得分插入到数据库中
cursor.execute('INSERT INTO scores (score) VALUES (?)', (self.score,))
# 提交更改并关闭连接
conn.commit()
conn.close()
# 主游戏循环
def game_loop(self):
self.game_exit = False
self.game_over = False
# 定义初始贪吃蛇的位置和长度
self.x = self.DISPLAY_WIDTH / 2
self.y = self.DISPLAY_HEIGHT / 2
self.cx = 0
self.cy = 0
self.snake_list = [[self.x, self.y]]
self.snake_length = 1
# 定义初始食物的位置
self.food_x, self.food_y = self.generate_food_location()
# 定义初始得分和速度
self.score = 0
self.speed = 10
# 游戏循环
while not self.game_exit:
while not self.game_over:
# 处理游戏事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
# 玩家点击了关闭按钮
self.game_exit = True
if self.game_exit:
break
# 获取按键事件
keys = pygame.key.get_pressed()
# 根据按键事件移动贪吃蛇的头部
if keys[pygame.K_LEFT] and self.cx == 0:
self.cx = -self.BLOCK_SIZE
self.cy = 0
elif keys[pygame.K_RIGHT] and self.cx == 0:
self.cx = self.BLOCK_SIZE
self.cy = 0
elif keys[pygame.K_UP] and self.cy == 0:
self.cy = -self.BLOCK_SIZE
self.cx = 0
elif keys[pygame.K_DOWN] and self.cy == 0:
self.cy = self.BLOCK_SIZE
self.cx = 0
# 更新贪吃蛇的位置
self.x += self.cx
self.y += self.cy
self.snake_head = [self.x, self.y]
self.snake_list.append(self.snake_head)
# 如果贪吃蛇的头部与食物重合,生成一个新的食物位置,并增加贪吃蛇的长度和得分
if self.x <= self.food_x + 2 * self.BLOCK_SIZE and self.x >= self.food_x and \
self.y <= self.food_y + 2 * self.BLOCK_SIZE and self.y >= self.food_y:
self.food_x, self.food_y = self.generate_food_location()
self.snake_length += 1
self.score += 10
# 每次吃到食物后速度增加一点
self.speed += 1
# 贪吃蛇穿墙
if self.x >= self.DISPLAY_WIDTH:
self.x = 0
self.game_over = True
elif self.x <= 0:
self.x = self.DISPLAY_WIDTH
self.game_over = True
elif self.y >= self.DISPLAY_HEIGHT:
self.y = 0
self.game_over = True
elif self.y <= 0:
self.y = self.DISPLAY_HEIGHT
self.game_over = True
# 吃到身体
if self.snake_head in self.snake_list[:-2]:
self.game_over = True
# 如果贪吃蛇的长度超过了限制,移除它的尾部
if len(self.snake_list) > self.snake_length:
del self.snake_list[0]
# 绘制游戏窗口
self.game_display.fill(self.WHITE)
self.game_display.blit(self.food_image, (self.food_x, self.food_y))
self.draw_snake(self.snake_list)
self.text = self.font.render('Score: ' + str(self.score), True, self.BLACK)
self.game_display.blit(self.text, (10, 10))
pygame.display.update()
# 控制游戏速度
self.clock.tick(self.speed)
# loose 画面
if self.game_over:
self.save_score()
self.game_display.fill((0, 0, 0))
self.game_display.blit(self.text_surface_loose, (self.DISPLAY_WIDTH / 4, self.DISPLAY_HEIGHT / 2))
pygame.display.flip()
while True:
event = pygame.event.wait()
if event.type == pygame.QUIT:
pygame.quit()
# 退出 pygame
pygame.quit()
quit()
里面我在文件夹里有一个food图片当作贪吃蛇的食物图片,没错就是封面的有机食品(bush
文件封装了用到的函数func.py:
import tkinter as tk
from snake_game import SnakeGame
import sqlite3
import matplotlib.pyplot as plt
def get_scores_from_database():# 从数据库中查询得分数据
# 连接到数据库
conn = sqlite3.connect('scores.db')
cursor = conn.cursor()
# 从数据库中查询得分数据
cursor.execute('SELECT score FROM scores')
scores = cursor.fetchall()
# 关闭连接
conn.close()
return scores
def sorces_chart(): #得分曲线
# 获取得分数据
scores = get_scores_from_database()
# 生成横坐标(次数)
x = range(1, len(scores) + 1)
# 绘制折线图
plt.plot(x, scores)
plt.xlabel('次数')
plt.ylabel('得分')
plt.title('得分变化折线图')
plt.show()
def database_create():#创建数据库
# 连接到数据库(如果数据库文件不存在,将创建一个新的数据库文件)
conn = sqlite3.connect('scores.db')
# 创建一个游标对象
cursor = conn.cursor()
# 创建得分表(如果不存在)
cursor.execute('''
CREATE TABLE IF NOT EXISTS scores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
score INTEGER
)
''')
# 提交更改并关闭连接
conn.commit()
conn.close()
def print_scores():
scores = get_scores_from_database()
# 打印得分
for score in scores:
print(score[0])
def start_game():#开始游戏
game = SnakeGame()
game.game_loop()
def window_gui():#游戏开始界面
# 创建主窗口
window = tk.Tk()
window.title("Snake Game")
# 设置窗口大小
window.geometry("400x300") # 宽度为400像素,高度为300像素
# 创建开始游戏按钮
start_button = tk.Button(window, text="开始游戏", command=start_game)
start_button.pack()
#得分打印按钮
start_button = tk.Button(window, text="打印得分", command=print_scores)
start_button.pack()
#得分曲线按钮
start_button = tk.Button(window, text="打印曲线", command=sorces_chart)
start_button.pack()
# 运行主循环
window.mainloop()
最后就是运行了
run.py:
from func import database_create,window_gui
def main():
database_create()
window_gui()
if __name__ == '__main__':
main()
运行后大概是这样的:
还不知道matplotlib窗口怎么显示中文(@^@)
代码写下来还是挺好玩的,也期待能有伙伴开发出更有趣的玩法分享出来让菜鸟我学习学习