码迷,mamicode.com
首页 > 编程语言 > 详细

Python学习实践一

时间:2020-07-30 14:24:28      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:surface   eset   imp   就是   ret   timer   for   object   import   

贪吃蛇小游戏

pycharm——pygame

game.py

import pygame  # 导包
from game_items import *  # 导类和变量

class Game(object):  # 这里的object类,意为顶级/基础类。
    def __init__(self):
        self.main_window = pygame.display.set_mode((640, 480))
        self.main_name = pygame.display.set_caption(贪吃蛇)

        self.score_label = Label()  # 得分标签

        self.tip_label = Label(24, False)  # 暂停&游戏结束的标签

        self.is_game_over = True  # 游戏是否结束
        self.is_pause = False  # 游戏是否暂停

        self.food = Food()

        self.snake = Snake()

    def start(self):
        clock = pygame.time.Clock()  # 游戏时钟

        while True:
            self.main_window.fill(BACKGROUND_COLOR)

            # 事件监听
            for event in pygame.event.get():
                if event.type == pygame.QUIT:  # 退出
                    return
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        return

                    elif event.key == pygame.K_SPACE:
                        if self.is_game_over:
                            self.reset_game()
                        else:
                            self.is_pause = not self.is_pause
                if not self.is_pause and not self.is_game_over:
                    if event.type == FOOD_UPDATE_EVENT:
                        self.food.random_rect()
                    elif event.type == SNAKE_UPDATE_EVENT:
                        self.is_game_over = not self.snake.update()
                    elif event.type == pygame.KEYDOWN:
                        if event.key in (pygame.K_RIGHT, pygame.K_DOWN, pygame.K_LEFT, pygame.K_UP):
                            self.snake.change_dir(event.key)

            # 绘制得分标签
            self.score_label.draw(分数: %d % self.snake.score, self.main_window)
            # 绘制暂停&游戏结束标签
            if self.is_game_over:
                self.tip_label.draw(游戏结束,按空格从新开始游戏。, self.main_window)
            elif self.is_pause:
                self.tip_label.draw(游戏暂停,按空格键继续。, self.main_window)
            #  更新显示内容(不能缺少)
            else:
                if self.snake.has_eat(self.food):
                    self.food.random_rect()

            self.food.draw(self.main_window)

            self.snake.draw(self.main_window)

            pygame.display.update()
            clock.tick(60)  # 刷新频率(帧数)

    def reset_game(self):
        """重置游戏分数"""

        self.is_pause = False
        self.is_game_over = False

        self.snake.reset_snake()
        self.food.random_rect()

if __name__ == __main__:

    pygame.init()  # 初始化pygame模块

    #游戏代码
    Game().start()

    pygame.quit()  # 释放pygame模块

game_items.py

import pygame
import random

BACKGROUND_COLOR = (232, 232, 232)
SCORE_TEXT_COLOR = (192, 192, 192)
TIP_TEXT_COLOR = (64, 64, 64)
SCREEN_RECT = pygame.Rect(0, 0, 640, 480)
RECT_SIZE = 20
FOOD_UPDATE_EVENT = pygame.USEREVENT  # 食物更新事件
SNAKE_UPDATE_EVENT = pygame.USEREVENT + 1  # 蛇更新事件

class Label(object):
    def __init__(self, size=48, is_score=True):
        """
        标签类
        :param is_score 表示是否显示分数
        """
        self.fond = pygame.font.SysFont(simhei, size)  # 返回一个fond对象
        self.is_score = is_score

    def draw(self, text, window):
        # 渲染字体
        color =SCORE_TEXT_COLOR if self.is_score else TIP_TEXT_COLOR
        text_surface = self.fond.render(text, True, color)  # self.fond 就是__init__内的对象属性 self.fond
        # 获取文本的矩形 一
        # text_rect = text_surface.get_rect()  # 凭借get_rect获取文本矩阵区域
        # window_rect = window.get_rect()
        # text_rect.y = window_rect.height - text_rect.height
        # text_rect.x = window_rect.width - text_rect.width
        # 获取文本的矩形 二
        text_rect = text_surface.get_rect()
        window_rect = window.get_rect()
        if self.is_score:
            text_rect.bottomleft = window_rect.bottomleft  # mid+方位/top+方位/bottom+方位
        else:
            text_rect.center = window_rect.center
        # 绘制文本内容到窗口
        window.blit(text_surface, text_rect)

class Food(object):
    def __init__(self):
        self.color = (255, 0, 0)
        self.score = 10
        self.rect = (0, 0, RECT_SIZE, RECT_SIZE)  # 食物位置,坐标以及宽高

        self.random_rect()

    def draw(self, window):
        pygame.draw.rect(window, self.color, self.rect)

        if self.rect.w < RECT_SIZE:  # 食物放大
            self.rect.inflate_ip(2, 2)

    def random_rect(self):
        col = SCREEN_RECT.w / RECT_SIZE - 1
        row = SCREEN_RECT.h / RECT_SIZE - 1

        x = random.randint(0, col) * RECT_SIZE
        y = random.randint(0, row) * RECT_SIZE

        self.rect = pygame.Rect(x, y, RECT_SIZE, RECT_SIZE)

        self.rect.inflate_ip(-RECT_SIZE, -RECT_SIZE)  # 宽高修改为零

        pygame.time.set_timer(FOOD_UPDATE_EVENT, 30000)

class Snake(object):
    def __init__(self):
        """初始化数据"""
        self.dir = pygame.K_RIGHT
        self.score = 0
        self.time_interval = 500
        self.color = (64, 64, 64)
        self.body_list = []

        self.reset_snake()

    def reset_snake(self):
        self.dir = pygame.K_RIGHT
        self.score = 0
        self.time_interval = 500

        self.body_list.clear()
        for _ in range(3):
            self.add_node()

    def add_node(self):
        if self.body_list:
            head = self.body_list[0].copy()
        else:
            head = pygame.Rect(-RECT_SIZE, 0, RECT_SIZE, RECT_SIZE)

        if self.dir == pygame.K_LEFT:
            head.x -= 20
        elif self.dir == pygame.K_RIGHT:
            head.x += 20
        elif self.dir == pygame.K_UP:
            head.y -= 20
        elif self.dir == pygame.K_DOWN:
            head.y += 20

        self.body_list.insert(0, head)

        pygame.time.set_timer(SNAKE_UPDATE_EVENT, self.time_interval)

    def draw(self, window):
        for idx, rect in enumerate(self.body_list):
            # 这里idx如果是头部 idx==0 为True 边框为1;如果是False就默认实心
            # 由于初始化方向向右,所以生成的格子是向右三个
            pygame.draw.rect(window, self.color, rect.inflate(-2, -2), idx == 0)
    # 看似格子在移动,实际是此消彼长,蛇并没有移动

    def update(self):
        # 备份上一步
        body_list_copy = self.body_list.copy()
        # 移动身体
        self.add_node()
        self.body_list.pop()  # 默认删除最后一个
        # 是否死亡
        if self.is_dead():
            self.body_list = body_list_copy
            return False

        return True


    def change_dir(self, to_dir):
        hor_dirs = (pygame.K_LEFT, pygame.K_RIGHT)
        var_dirs = (pygame.K_UP, pygame.K_DOWN)
        if ((self.dir in hor_dirs and to_dir not in hor_dirs) or
                (self.dir in var_dirs and to_dir not in var_dirs)):

            self.dir = to_dir

    def has_eat(self, food):
        if self.body_list[0].contains(food.rect):
            self.score += food.score
            if self.time_interval > 100:
                self.time_interval -= 50
            self.add_node()

            return True
        return False

    def is_dead(self):
        head = self.body_list[0]

        if not SCREEN_RECT.contains(head):
            return True

        for body in self.body_list[1:]:
            if head.contains(body):
                return True
        return False

主要学习pygame内的操作

窗口操作、绘制文本、渲染图像、摆放位置

事件的监听、画面的刷新与显示、反馈操作

存在不足,请多指教

Python学习实践一

标签:surface   eset   imp   就是   ret   timer   for   object   import   

原文地址:https://www.cnblogs.com/ks-2020-07-01/p/13403084.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!