Python 代码打造经典贪吃蛇游戏,带你回味童年的快乐记忆

liftword3周前 (04-10)技术文章10

贪吃蛇是一款经典的小游戏。初始是像素版本,后来又衍生出3D版本、多人对战版本等。玩家使用方向键操控一条长长的蛇不断吞下豆子,同时蛇身随着吞下的豆子不断变长,当蛇头撞到蛇身或障壁时游戏结束。

本文分享在 Python Tkinter 中创建一个流行的可以计分的贪吃蛇游戏代码。

代码中使用了 tkinter、random 、Pillow 三个库,以及一张 PNG 图片作为豆子,图片是名为 game.png,长宽均为 13px 的黑色方块,请自行准备。

from tkinter import *
from random import randint
from PIL import Image, ImageTk

movement = 20
steps_per_sec = 10
speed = 1100 // steps_per_sec

class Snake(Canvas):
    def __init__(self):
        super().__init__(
            width=700, 
            height=400, 
            background='#53ff1a', 
            highlightthickness=0
        )

        self.snake_pos = [(100, 80), (80, 100), (80, 100)]
        self.food_pos = self.set_new_food_pos()
        self.direction = 'Right'
        self.score = 0
        self.load_img()
        self.create_objects()
        self.bind_all('', self.on_key_press)
        self.pack()
        self.after(speed, self.perform_actions)

    def load_img(self):
        try:
            self.snake_body = ImageTk.PhotoImage(Image.open('game.png'))
            self.food = ImageTk.PhotoImage(Image.open('game.png'))
        except IOError as error:
            ws.destroy()
            raise
    def create_objects(self):
        self.create_text(
            35, 
            12, 
            text=f'得分: {self.score}', 
            tag='score', 
            fill='black', 
            font=10
        )

        for x_position, y_position in self.snake_pos:
            self.create_image(
                x_position, 
                y_position, 
                image=self.snake_body, 
                tag='snake'
            )

        self.create_image(
            *self.food_pos, 
            image=self.food, 
            tag='food'
            )
        self.create_rectangle(
            7, 
            27, 
            690, 
            690, 
            outline='#d9d8d7'
            )
    def finish_game(self):
        self.delete(ALL)
        self.create_text(
            self.winfo_width() / 2,
            self.winfo_height() / 2,
            text=f'游戏结束,得分:{self.score}!',
            fill='black',
            font=20
        )

    def consume_food(self):
        if self.snake_pos[0] == self.food_pos:
            self.score += 10
            self.snake_pos.append(self.snake_pos[-1])

            self.create_image(
                *self.snake_pos[-1], 
                image=self.snake_body, 
                tag='snake'
            )
            self.food_pos = self.set_new_food_pos()
            self.coords(
                self.find_withtag('food'), 
                *self.food_pos
                )

            score = self.find_withtag('score')
            self.itemconfigure(
                score, 
                text=f'得分: {self.score}', 
                tag='score'
                )
    
    def boundry(self):
        head_x_position, head_y_position = self.snake_pos[0]

        return (
            head_x_position in (0, 700)
            or head_y_position in (20, 400)
            or (head_x_position, head_y_position) in self.snake_pos[1:]
        )
    def snake_movement(self):
        head_x_position, head_y_position = self.snake_pos[0]

        if self.direction == 'Left':
            new_head_position = (head_x_position - movement, head_y_position)
        elif self.direction == 'Right':
            new_head_position = (head_x_position + movement, head_y_position)
        elif self.direction == 'Down':
            new_head_position = (head_x_position, head_y_position + movement)
        elif self.direction == 'Up':
            new_head_position = (head_x_position, head_y_position - movement)

        self.snake_pos = [new_head_position] + self.snake_pos[:-1]

        for segment, position in zip(self.find_withtag('snake'), self.snake_pos):
            self.coords(segment, position)

    def on_key_press(self, e):
        new_direction = e.keysym

        all_directions = (
            'Up', 
            'Down', 
            'Left', 
            'Right'
            )
        opposites = (
            {'Up', 'Down'}, 
            {'Left', 'Right'}
            )

        if (
            new_direction in all_directions
            and {new_direction, self.direction} not in opposites
        ):
            self.direction = new_direction

    def perform_actions(self):
        if self.boundry():
            self.finish_game()

        self.consume_food()
        self.snake_movement()

        self.after(speed, self.perform_actions)

    def set_new_food_pos(self):
        while True:
            x_position = randint(1, 29) * movement
            y_position = randint(3, 30) * movement
            food_pos = (x_position, y_position)

            if food_pos not in self.snake_pos:
                return food_pos

ws = Tk()
ws.title('贪吃蛇')
ws.resizable(False, False)
board = Snake()
ws.mainloop()

相关文章

用Python做一个贪吃蛇小游戏:零基础保姆级教程(附完整代码)

导语:只要你会用电脑打字,就能跟着这篇教程做出经典贪吃蛇游戏!从安装软件到代码调试,每个步骤都有详细截图和解释,遇到问题看文末解决方案,现在就开始你的第一个游戏开发吧!一、准备开发环境(10分钟)1....

使用Python+OpenCV代码制作贪吃蛇小游戏,你也可以打造自己的AI

前言今天和大家分享一下如何使用 mediapipe+opencv 自制贪吃蛇小游戏。先放张图看效果。规则:食指指尖控制蛇头,指尖每接触到黄色方块,计数加一,蛇身变长,方块随机切换位置。如果指尖停止移动...

别玩手机了!用 Python 写个贪吃蛇小游戏吧!

大家好呀!今天给大家带来一个经典又有趣的Python小项目——贪吃蛇游戏!这可是小时候必备的街机游戏之一,现在我们用Python完全可以自己做出来!通过键盘控制方向,让小蛇吃到食物变长,看看你能达到什...

使用字节跳动的TRAE编写贪吃蛇音乐版简直太轻松了

字节跳动的国内版发行不久就开始下载来试试,还是老本行,先试试贪吃蛇游戏,当然这次改用python编写,我没编过python程序,可以说是小白,不过介于python程序功能强大,编写难度不大,因此决定...

零基础学习编程:用Python和Pygame实现贪吃蛇游戏

预计阅读时间:15分钟介绍编程是一门有趣且有用的技能,它可以帮助我们解决问题、创造新的东西,并提升我们的逻辑思维能力。本教程将带你从零开始学习编程,使用Python语言和Pygame库来实现经典的贪吃...