Python3 tkinter实现贪吃蛇

from tkinter import *
import random


class SnakeGame:

    def __init__(self):
        # moving step for snake and food
        self.step = 15
        # game score
        self.gamescore = -10
        self.level = 0
        # to initialize the snake in the range of (x1,y1,x2,y2)
        r = random.randrange(400, 600, self.step)
        self.snakeX = [r, r + self.step, r + self.step * 2]
        self.snakeY = [r, r, r]

        # to initialize the moving direction
        self.snakeDirection = 'left'
        self.snakeMove = [-1, 0]
        # to draw the game frame 
        window = Tk()
        window.geometry("600x400+10+10")
        window.maxsize(600, 400)
        window.minsize(600, 400)
        window.title("Snake game")

        self.frame1 = Frame(window, height=371, width=600)
        self.frame2 = Frame(window, width=600, height=371, bg="white")
        self.canvas = Canvas(self.frame1, width=600, height=371, bg="grey")
        self.score_label = Label(self.frame2, text="Score:")

        self.frame1.pack()
        self.frame2.pack(fill=BOTH)
        self.score_label.pack(side=LEFT)
        self.canvas.pack(fill=BOTH)

        self.draw_wall()
        self.draw_score()
        self.draw_food()
        self.draw_snake()

        self.play()

        window.mainloop()

    "=== View Part ==="

    def draw_wall(self):
        self.canvas.create_line(10, 10, 582, 10, fill='blue', width=5)
        self.canvas.create_line(10, 359, 582, 359, fill='blue', width=5)
        self.canvas.create_line(10, 10, 10, 359, fill='blue', width=5)
        self.canvas.create_line(582, 10, 582, 359, fill='blue', width=5)

    def draw_score(self):
        self.score()  # score model
        self.score_label.config(self.score_label,
                                text="Score:  " + str(self.gamescore) + "     level:  " + str(self.level))

    def draw_food(self):
        self.canvas.delete("food")
        self.foodx, self.foody = self.random_food()  # food model
        self.canvas.create_rectangle(self.foodx, self.foody, self.foodx + 15, self.foody + 15, fill="red", tags="food")

    def draw_snake(self):
        self.canvas.delete("snake")
        x, y = self.snake()  # snake model
        for i in range(len(x)):  # snake view
            self.canvas.create_rectangle(x[i], y[i], x[i] + self.step, y[i] + self.step, fill="orange", tags='snake')

    "=== Model Part ==="

    # food model
    def random_food(self):
        return random.randrange(11, 570, self.step), random.randrange(11, 340, self.step)

    # snake model
    def snake(self):
        for i in range(len(self.snakeX) - 1, 0, -1):
            self.snakeX[i] = self.snakeX[i - 1]
            self.snakeY[i] = self.snakeY[i - 1]
        self.snakeX[0] += self.snakeMove[0] * self.step
        self.snakeY[0] += self.snakeMove[1] * self.step
        return self.snakeX, self.snakeY

    # score model
    def score(self):
        self.gamescore = self.gamescore + 10
        if self.gamescore % 100 == 0:
            self.level = self.gamescore // 100 + 1
        return self.score, self.level

    "=== Control Part ==="

    def iseated(self):
        if self.snakeX[0] == self.foodx and self.snakeY[0] == self.foody:
            return True
        else:
            return False

    def isdead(self):
        # 判断是否头触墙以及是否咬到自身
        if self.snakeX[0] < 8 or self.snakeX[0] > 580 or self.snakeY[0] < 8 or self.snakeY[0] > 350:
            return self.gameover

        for i in range(1, len(self.snakeX)):
            if self.snakeX[0] == self.snakeX[i] and self.snakeY[0] == self.snakeY[i]:
                return self.gameover
        else:
            return False

    def move(self, event):
        # left:[-1,0],right:[1,0],up:[0,1],down:[0,-1]

        if (event.keycode == 39 or event.keycode == 68) and self.snakeDirection != 'left':
            self.snakeMove = [1, 0]
            self.snakeDirection = "right"
        elif (event.keycode == 38 or event.keycode == 87) and self.snakeDirection != 'down':
            self.snakeMove = [0, -1]
            self.snakeDirection = "up"
        elif (event.keycode == 37 or event.keycode == 65) and self.snakeDirection != 'right':
            self.snakeMove = [-1, 0]
            self.snakeDirection = "left"
        elif (event.keycode == 40 or event.keycode == 83) and self.snakeDirection != 'up':
            self.snakeMove = [0, 1]
            self.snakeDirection = "down"
        else:
            pass

    #       above codes can be insteaded by the following codes

    #        if (event.keysym == 'Right' or event.keysym == 'd') and self.snakeDirection != 'left':
    #            self.snakeMove = [1,0]
    #            self.snakeDirection = "right"
    #        elif (event.keysym == 'Up' or event.keysym == 'w') and self.snakeDirection != 'down':
    #            self.snakeMove = [0,-1]
    #            self.snakeDirection = "up"
    #        elif (event.keysym == 'Left' or event.keysym == 'a') and self.snakeDirection != 'right':
    #            self.snakeMove = [-1,0]
    #            self.snakeDirection = "left"
    #        elif (event.keysym == 'Down' or event.keysym == 's') and self.snakeDirection != 'up':
    #            self.snakeMove = [0,1]
    #            self.snakeDirection = "down"
    #        else:
    #            pass

    def play(self):
        self.canvas.bind_all("", self.move)
        self.canvas.focus_set()

        while True:
            if self.isdead():
                self.gameover()
                break
            elif self.iseated():
                self.snakeX[0] += self.snakeMove[0] * self.step
                self.snakeY[0] += self.snakeMove[1] * self.step
                self.snakeX.insert(1, self.foodx)
                self.snakeY.insert(1, self.foody)

                self.draw_score()
                self.draw_food()
                self.draw_snake()
            else:
                self.draw_snake()
                self.canvas.after(200)
                self.canvas.update()

    def gameover(self):
        #        self.canvas.delete("food","snake")
        self.canvas.unbind_all("")
        self.canvas.bind_all("", self.restart)
        self.canvas.create_text(270, 180, text="                   Game Over!\n \
        Press any key to continue", font='Helvetica -30 bold', tags='text')

    def restart(self, event):
        self.canvas.delete("food", "snake", "text")
        self.canvas.unbind_all('')

        # to initialize the snake in the range of (191,191,341,341)                
        r = random.randrange(191, 191 + 15 * 10, self.step)
        self.snakeX = [r, r + self.step, r + self.step * 2]
        self.snakeY = [r, r, r]

        # to initialize the moving direction
        self.snakeDirection = 'left'
        self.snakeMove = [-1, 0]

        # reset the score to zero 
        self.gamescore = -10
        self.draw_score()

        # to initialize the game (food and snake)
        self.draw_food()
        self.draw_snake()

        # to play the game
        self.play()


SnakeGame()

值得注意的是关于Python3中tkinter将键绑定到按钮的方式

#python 3.x
#键盘事件
canvas.bind_all("",echo_event)
#如果绑定指定的键盘,则"" 或者""都可以,具体到指定键的话后面加入下划线和指定的键就好了,如:绑定小写字母t和Left键
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
#鼠标事件
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)
canvas.bind_all("",echo_event)

详细绑定信息可以看Python Tkinter command和bind事件处理(绑定)用法详解

你可能感兴趣的:(Python,python)