当前位置: 移动技术网 > IT编程>脚本编程>Python > Python:游戏:贪吃蛇(附源码)

Python:游戏:贪吃蛇(附源码)

2018年09月05日  | 移动技术网IT编程  | 我要评论

八年级上册英语视频,女神网,杨馥伟

贪吃蛇是个非常简单的游戏,适合练手。

首先分析一下这个游戏

1、蛇怎么画?

蛇是由一个个小方块组成的,那么我们可以用一个 list 记录每一个小方块的坐标,显示的时候将所有小方块画出来即可。

2、蛇怎么移动?

第一反应就是想蚯蚓蠕动一样,每一个方块向前移动一格,但这样做很麻烦,仔细想下,其实除了头尾,蛇的其他部分根本就没有动过,那就简单了,将下一格的坐标添加到 list 开头,并移除 list 的最后一个元素,就相当于蛇向前移动了一格。

3、如何判定游戏结束?

蛇移动超出了游戏区的范围或者碰到了自己就算输了,超出范围很容易判断,碰到自己也容易,只要判断下一格的坐标是否已经包含在蛇的 list 中就可以了。

 

理清了这些问题,我们就可以开始编码了。

先看一下我的游戏截图

 

本例中,回车键:开始游戏,空格键:暂停 / 继续,方向键 或 wsad 键:控制移动方向。

每吃一个食物加10分,每增加100分速度加快一级,没有设置关卡,我玩到1100分,速度太快了,然后就 game over 了

"""贪吃蛇"""

import random
import sys
import time
import pygame
from pygame.locals import *
from collections import deque

screen_width = 600
screen_height = 480
size = 20


def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgtext = font.render(text, true, fcolor)
    screen.blit(imgtext, (x, y))


def main():
    pygame.init()
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption('贪吃蛇')

    light = (100, 100, 100)  # 蛇的颜色
    dark = (200, 200, 200)   # 食物颜色

    font1 = pygame.font.sysfont('simhei', 24)  # 得分的字体
    font2 = pygame.font.font(none, 72)  # game over 的字体
    red = (200, 30, 30)                 # game over 的字体颜色
    fwidth, fheight = font2.size('game over')
    line_width = 1                      # 网格线宽度
    black = (0, 0, 0)                   # 网格线颜色
    bgcolor = (40, 40, 60)              # 背景色

    # 方向,起始向右
    pos_x = 1
    pos_y = 0
    # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接game over
    # b 变量就是用于防止这种情况的发生
    b = true
    # 范围
    scope_x = (0, screen_width // size - 1)
    scope_y = (2, screen_height // size - 1)
    # 蛇
    snake = deque()
    # 食物
    food_x = 0
    food_y = 0

    # 初始化蛇
    def _init_snake():
        nonlocal snake
        snake.clear()
        snake.append((2, scope_y[0]))
        snake.append((1, scope_y[0]))
        snake.append((0, scope_y[0]))

    # 食物
    def _create_food():
        nonlocal food_x, food_y
        food_x = random.randint(scope_x[0], scope_x[1])
        food_y = random.randint(scope_y[0], scope_y[1])
        while (food_x, food_y) in snake:
            # 为了防止食物出到蛇身上
            food_x = random.randint(scope_x[0], scope_x[1])
            food_y = random.randint(scope_y[0], scope_y[1])

    _init_snake()
    _create_food()

    game_over = true
    start = false       # 是否开始,当start = true,game_over = true 时,才显示 game over
    score = 0           # 得分
    orispeed = 0.5      # 原始速度
    speed = orispeed
    last_move_time = none
    pause = false       # 暂停

    while true:
        for event in pygame.event.get():
            if event.type == quit:
                sys.exit()
            elif event.type == keydown:
                if event.key == k_return:
                    if game_over:
                        start = true
                        game_over = false
                        b = true
                        _init_snake()
                        _create_food()
                        pos_x = 1
                        pos_y = 0
                        # 得分
                        score = 0
                        last_move_time = time.time()
                elif event.key == k_space:
                    if not game_over:
                        pause = not pause
                elif event.key in (k_w, k_up):
                    # 这个判断是为了防止蛇向上移时按了向下键,导致直接 game over
                    if b and not pos_y:
                        pos_x = 0
                        pos_y = -1
                        b = false
                elif event.key in (k_s, k_down):
                    if b and not pos_y:
                        pos_x = 0
                        pos_y = 1
                        b = false
                elif event.key in (k_a, k_left):
                    if b and not pos_x:
                        pos_x = -1
                        pos_y = 0
                        b = false
                elif event.key in (k_d, k_right):
                    if b and not pos_x:
                        pos_x = 1
                        pos_y = 0
                        b = false

        # 填充背景色
        screen.fill(bgcolor)
        # 画网格线 竖线
        for x in range(size, screen_width, size):
            pygame.draw.line(screen, black, (x, scope_y[0] * size), (x, screen_height), line_width)
        # 画网格线 横线
        for y in range(scope_y[0] * size, screen_height, size):
            pygame.draw.line(screen, black, (0, y), (screen_width, y), line_width)

        if game_over:
            if start:
                print_text(screen, font2, (screen_width - fwidth)//2, (screen_height - fheight)//2, 'game over', red)
        else:
            curtime = time.time()
            if curtime - last_move_time > speed:
                if not pause:
                    b = true
                    last_move_time = curtime
                    next_s = (snake[0][0] + pos_x, snake[0][1] + pos_y)
                    if next_s[0] == food_x and next_s[1] == food_y:
                        # 吃到了食物
                        _create_food()
                        snake.appendleft(next_s)
                        score += 10
                        speed = orispeed - 0.03 * (score // 100)
                    else:
                        if scope_x[0] <= next_s[0] <= scope_x[1] and scope_y[0] <= next_s[1] <= scope_y[1] \
                                and next_s not in snake:
                            snake.appendleft(next_s)
                            snake.pop()
                        else:
                            game_over = true

        # 画食物
        if not game_over:
            # 避免 game over 的时候把 game over 的字给遮住了
            pygame.draw.rect(screen, light, (food_x * size, food_y * size, size, size), 0)

        # 画蛇
        for s in snake:
            pygame.draw.rect(screen, dark, (s[0] * size + line_width, s[1] * size + line_width,
                                            size - line_width * 2, size - line_width * 2), 0)

        print_text(screen, font1, 30, 7, f'速度: {score//100}')
        print_text(screen, font1, 450, 7, f'得分: {score}')

        pygame.display.update()


if __name__ == '__main__':
    main()

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网