pygame 入门实例教程 1 - 复古方块赛车游戏

作者自我介绍:大爽歌, b站小UP主直播编程+红警三python1对1辅导老师

本教程步骤明确,过程清晰简明,最终代码量250行上下适合学习pygame的新手
项目代码已上传到我的github: https://github.com/BigShuang/simple-brick-games-by-pygame
本文分7部分,每一部分最终代码均存到项目仓库下的1 car racing
游戏已录制成视频,投稿至本人b站:点击前往b站观看游戏视频

游戏运行效果,截图如下
在这里插入图片描述

〇 - 初始准备工作

  • 本项目使用的python3版本*(如果你用python2,我不知会怎么样)*
  • Ide推荐大家选择pycharm*(不同ide应该没影响)*
  • 需要安装第三方库pygame,安装方法(windows电脑,mac系统本人实测与pygame不兼容,强行运行本项目卡成ppt)

电脑打开cmd命令窗口,输入pip install pygame
如果电脑上安的是pip3则是pip3 install pygame

补充说明:
由于众所周知的原因,安装过程中下载可能十分缓慢,甚至由此导致安装失败
此时建议大家尝试使用镜像下载

—国内源—
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/

使用办法 pip install xxxx -i jinxiangurl
具体到pygame,则是:

pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple

一、实现基础窗口

0 - 新建car_racing.py文件,内容如下
import pygame

WIN_WIDTH = 600  # 窗口宽度
WIN_HEIGHT = 900  # 窗口高度

pygame.init() # pygame初始化,必须有,且必须在开头
# 创建主窗体
win=pygame.display.set_mode((WIN_WIDTH,WIN_HEIGHT))

此时运行car_racing.py,会发现一个一闪而逝的窗口,

1 - 进一步,我们自然而然的就要思考这些问题
  • 游戏窗口大小设置为多少合适?
    由于是方块游戏,所以可以根据方格尺寸、行格字数、列格子数去计算出窗口的宽高
  • 怎么维持住这个窗口?
    通过while循环去实现
  • 但是简单的循环只是单纯的将界面卡住,怎么实现刷新?
    在循环体内使用pygame.display.update()语句进行界面的更新
  • 循环的刷新频率不做节制的话,界面会飞速刷新导致卡死,怎么办?
    pygame有专门的对象pygame.time.Clock用于去控制循环刷新的频率,创建pygame.time.Clock对象后,调用该对象的tick()方法,函数参数为每秒刷新次数,就可以设置循环每秒刷新频率,术语叫做帧率

可前往官方文档观看pygame.time.Clock的更多细节,https://www.pygame.org/docs/ref/time.html#pygame.time.Clock

  • 根据上面的思路,修改car_racing.py后如下
import pygame

C, R = 11, 20  # 11列, 20行
CELL_SIZE = 40  # 格子尺寸

FPS=60  # 游戏帧率
WIN_WIDTH = CELL_SIZE * C  # 窗口宽度
WIN_HEIGHT = CELL_SIZE * R  # 窗口高度

pygame.init() # pygame初始化,必须有,且必须在开头
# 创建主窗体
clock = pygame.time.Clock() # 用于控制循环刷新频率的对象
win = pygame.display.set_mode((WIN_WIDTH,WIN_HEIGHT))

while True:
    clock.tick(FPS) # 控制循环刷新频率,每秒刷新FPS对应的值的次数
    pygame.display.update()

此时运行car_racing.py, 就可以得到一个最最最基础的窗口了,

2 - 但是,这个窗口有个大问题, 此时窗口的关闭按钮很容易出bug(卡死)

所以需要自己去重新实现这个窗口关闭功能,需要在循环体内添加如下代码

# 获取所有事件
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        # 判断当前事件是否为点击右上角退出键
        pygame.quit()
        sys.exit() # 需要提前 import sys

同时我们一般会希望能够设置下背景的颜色
比如,这个游戏的背景色是轻灰色(200, 200, 200)
那么设置背景的代码为

bg_color = (200, 200, 200)
win.fill(bg_color)

不过需要注意的是,这段代码放在不同的位置会产生不同的效果。
放在while循环之前,代表只绘制一次背景,会被后面绘制的东西遮住。
放在while循环中,则是每一帧都会绘制一次背景,一般用于去覆盖掉那些希望删掉的元素。

本阶段最后car_racing.py如下

import pygame
import sys

FPS=60 # 游戏帧率
WINWIDTH = 600  # 窗口宽度
WINHEIGHT = 900  # 窗口高度

pygame.init() # pygame初始化,必须有,且必须在开头
# 创建主窗体
clock = pygame.time.Clock() # 用于控制循环刷新频率的对象
win = pygame.display.set_mode((WINWIDTH,WINHEIGHT))

bg_color = (200, 200, 200)
win.fill(bg_color)

while True:
    # 获取所有事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # 判断当前事件是否为点击右上角退出键
            pygame.quit()
            sys.exit()

    clock.tick(FPS) # 控制循环刷新频率,每秒刷新FPS对应的值的次数
    pygame.display.update()

到这里,基础窗口就完成了~

二、实现基础方块绘制

1 最基础的绘制方法

pygame里面,绘制一个小方格实际上是很简单的。
新建一个方格色块(放在while循环之前)

area = pygame.Surface((CELL_SIZE, CELL_SIZE))
enemy_color = (50, 50, 50)
area.fill(enemy_color)

再将方格色块放在窗口对象上(放在while循环中,clock.tick(FPS)之前)

win.blit(area, (CELL_SIZE, 0))

此时运行,效果如图
在这里插入图片描述

不过这个绘制方法的问题在于, 后面的移动操作管理起来颇为不便。
要在while循环中编写各种代码来实现area这个色块的位置变换的话,代码写起来麻烦,管理起来也乱。

pygame 给我们提供了一个Sprite类,用于实现可以移动的二维图像对象。

我们将继承这个类,并封装一些需要的方法,方便移动以及管理。

2 使用pygame的Sprite类

In computer graphics, a sprite is a two-dimensional bitmap that is integrated into a larger scene, most often in a 2D video game.
在计算机图形学中,精灵是一种二维位图,它被集成到一个更大的场景中,通常在二维视频游戏中。
个人理解,sprite是一个计算机术语,代表界面中可以移动的二维位图。

继承Sprite, 新建Block类如下(在新建win对象,应该是14行,后面添加如下代码)

class Block(pygame.sprite.Sprite):
    def __init__(self, c, r, color):
        super().__init__()

        self.cr = [c, r]
        self.x = c * CELL_SIZE
        self.y = r * CELL_SIZE

        self.image  = pygame.Surface((CELL_SIZE, CELL_SIZE))
        self.image.fill(color)

        self.rect = self.image.get_rect()
        self.rect.move_ip(self.x, self.y)

删掉前面 1 最基础的绘制方法中, area的相关代码

在while循环之前, 添加如下代码

enemy_color = (50, 50, 50)
block = Block(1, 1, enemy_color)
win.blit(block.image, block.rect)

此时运行效果和1中相同。

三 基础方块移动

1 给Block添加移动方法

首先,给Block 类添加移动到指定行列的类方法如下

    def move_cr(self, c, r):
        self.cr[0] = c
        self.cr[1] = r
        self.x = c * CELL_SIZE
        self.y = r * CELL_SIZE
        self.rect.left = self.x
        self.rect.top = self.y

但是这个方法还是不够的的,
因为游戏中的移动,一般都是操作上下左右来移动。

那么,我们需要把上下左右,转换成c、r的变换。
所以建立字典如下

DIRECTIONS = {
   
   
    "UP": (0, -1),  # (dc, dr)
    "DOWN": (0, 1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值