用PyGame写个飞机游戏

本文介绍如何使用Python的PyGame库开发一个简单的飞行射击游戏。内容包括游戏主循环的建立、背景图像的滚动、主角和敌人飞机的创建、碰撞检测以及手柄支持的添加。通过一步步的代码示例,展示了从无到有构建游戏的过程。
摘要由CSDN通过智能技术生成

在树莓派和python社区,pygame是爱好者们常用的开发复古小游戏的工具,通过简单的python代码就可以给自己写个游戏啦。下面的截图是我写的飞机射击游戏:

移动、射击
在这里插入图片描述
吃到一个强力道具
在这里插入图片描述Game Over
在这里插入图片描述

1 游戏主循环

首先通过pip把pygame库装好pip install pygame ;然后我们先写个最简单的游戏主体,如果你经常玩游戏的话,应该知道“帧”这个概念吧,我们的游戏主题就是一个循环结构,每一次循环都是在更新一个游戏帧的内容:

import pygame
from pygame.locals import (
    RLEACCEL,
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
    K_SPACE,
    K_p,
    JOYAXISMOTION,
    JOYBALLMOTION,
    JOYBUTTONDOWN,
    JOYBUTTONUP,
    JOYHATMOTION,
)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()

running = True

while running:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False

    pygame.display.flip()
    clock.tick(FPS)

set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))这个方法创建了一个800X600的游戏屏幕,然后就进入一个主循环;每个主循环内会首先对可能的游戏事件进行处理,上面只对按下“ESC”按钮和关闭窗口进行了处理,就是把running置成False来终止循环;在循环的最后,pygame.display.flip()这句代码会把屏幕的内容进行更新;此外我们设置了一个FPS变量,并在每个循环最后执行clock.tick(FPS),这是为了控制一下帧率,FPS为60就是说每秒刷新60帧,如果不加这个帧速控制,电脑执行的太快,游戏效果会太过“灵活”
现在执行这个程序,只会出现一个黑色的窗口,因为我们什么元素也没加呢;按下ESC可以关闭掉窗口

2 游戏背景

现在让我们先给游戏加上一个背景,因为是飞行设计游戏,我们找一幅太空背景的图片,然后在程序里加载并显示

import pygame
from pygame.locals import (
    RLEACCEL,
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
    K_SPACE,
    K_p,
    JOYAXISMOTION,
    JOYBALLMOTION,
    JOYBUTTONDOWN,
    JOYBUTTONUP,
    JOYHATMOTION,
)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

background = pygame.image.load('./images/blue.png') #加载背景图片
background_rect = background.get_rect()

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()

running = True

while running:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False

    screen.blit(background, (background_rect))#把背景图片显示在游戏屏幕上
    pygame.display.flip()
    clock.tick(FPS)

再次执行程序, 现在窗口不再是无聊的黑色了:
在这里插入图片描述不过一个静态的背景还是太单调了,作为一个射击游戏,背景要有卷轴移动效果才行。我们通过一个小技巧来实现背景的卷轴效果。卷轴效果实际就是在每一帧里把背景图片向下面移动一点点,这样人眼就感觉背景动起来了,不过有个问题,只把这个背景图向下移动,屏幕上面的部分就没有图片覆盖又变成黑色了,因此我们采取用两张相同的背景图交替渲染的方式:
在这里插入图片描述更新下代码:

import pygame
from pygame.locals import (
    RLEACCEL,
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
    K_SPACE,
    K_p,
    JOYAXISMOTION,
    JOYBALLMOTION,
    JOYBUTTONDOWN,
    JOYBUTTONUP,
    JOYHATMOTION,
)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
bgY1 = 0 #第一幅背景图的Y轴坐标
bgY2 = -SCREEN_HEIGHT #第二幅背景图的Y轴坐标
BACKGROUND_SCROLL_SPEED=0.5 #背景的移动速度

background = pygame.image.load('./images/blue.png')
background_rect = background.get_rect()

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()

running = True

while running:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False


    screen.blit(background, (0, bgY1))  #绘制第一幅背景图
    screen.blit(background, (0, bgY2))  #绘制第二幅背景图, 刚开始的时候,第二幅背景图实际上绘制在窗口外面上方的
    
    bgY1 += BACKGROUND_SCROLL_SPEED #更新两副背景图的Y轴坐标
    bgY2 += BACKGROUND_SCROLL_SPEED
    if bgY1 > SCREEN_HEIGHT:
        bgY1 = -SCREEN_HEIGHT  #当一副背景图完全向下离开窗口区域时,把它的Y轴坐标重新定位到最上方
    if bgY2 > SCREEN_HEIGHT:
        bgY2 = -SCREEN_HEIGHT
    #screen.blit(background, (background_rect))
    pygame.display.flip()
    clock.tick(FPS)

看看效果:
在这里插入图片描述

3 添加主角飞机和敌人

现在可以创建我们要控制的主角了。首先需要了解"精灵"(Spirit)的概念,精灵是游戏开发中相对高层的抽象,每个具体的游戏对象都是一个精灵实例,一个精灵其实就是一个图形块,我们需要给它填充图形、赋予行为。
先定义一个Player类来代表玩家, 它继承自Sprite类。我们给它加载一副飞机图片:

player_img = pygame.transform.scale(pygame.image.load('./images/playerShip1_orange.png'),(61,41)) #加载玩家飞机的图片并调整大小

class Player(pygame.sprite.Sprite): #定义Player类, 继承自Sprite类
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = player_img
        self.rect = self.image.get_rect()
        self.rect.centerx = int(SCREEN_WIDTH/2) #初始位置
        self.rect.bottom = SCREEN_HEIGHT

实例化这个Player对象,并且加到一个Sprite队列里; 在游戏主循环内把所有的Sprite对象渲染在背景图之上

import pygame
from pygame.locals import (
    RLEACCEL,
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
    K_SPACE,
    K_p,
    JOYAXISMOTION,
    JOYBALLMOTION,
    JOYBUTTONDOWN,
    JOYBUTTONUP,
    JOYHATMOTION,
)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
bgY1 = 0 
bgY2 = -SCREEN_HEIGHT
BACKGROUND_SCROLL_SPEED=0.5

background = pygame.image.load('./images/blue.png')
background_rect = background.get_rect()
player_img = pygame.transform.scale(pygame.image.load('./images/playerShip1_orange.png'),(61,41)) #加载玩家飞机的图片并调整大小

class Player(pygame.sprite.Sprite): #定义Player类, 继承自Sprite类
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = player_img
        self.rect = self.image.get_rect()
        self.rect.centerx = int(SCREEN_WIDTH/2) #初始位置
        self.rect.bottom = SCREEN_HEIGHT
        
pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
player = Player() #实例化玩家飞机
all_sprites = pygame.sprite.Group() #存放所有精灵的引用
all_sprites.add(player)

clock = pygame.time.Clock()

running = True

while running:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False


    screen.blit(background, (0, bgY1))  
    screen.blit(background, (0, bgY2)) 
    
    bgY1 += BACKGROUND_SCROLL_SPEED
    bgY2 += BACKGROUND_SCROLL_SPEED
    if bgY1 > SCREEN_HEIGHT:
        bgY1 = -SCREEN_HEIGHT
    if bgY2 > SCREEN_HEIGHT:
        bgY2 = -SCREEN_HEIGHT
    
    all_sprites.draw(screen) #在背景之上渲染所有精灵

    pygame.display.flip()
    clock.tick(FPS)

现在运行程序,可以看到玩家飞机出现在屏幕正下方。现在给飞机添加动作行为, 我们计划用上下左右的箭头来控制飞机各方向移动,在PyGame中,小键盘的上下左右按键对应的了K_UP、K_DOWN、K_LEFT和K_RIGHT事件,我们在Player类中添加update方法,根据事件类型进行相应的处理;同时在游戏主循环内我们实时更新玩家飞机的动作:

import pygame
from pygame.locals import (
    RLEACCEL,
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
    K_SPACE,
    K_p,
    JOYAXISMOTION,
    JOYBALLMOTION,
    JOYBUTTONDOWN,
    JOYBUTTONUP,
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值