效果图
代码
import pygame
import random
from pygame.locals import *
# Pygame 提供一个叫做 Sprites 的基础类,为了画图。Surface 看作一张白纸,Rects 是 Surface 中矩形区域的表示。
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player, self).__init__()
self.image = pygame.image.load('jet.png').convert()
self.image.set_colorkey((255, 255, 255), RLEACCEL)
self.rect = self.image.get_rect()
# 定义按键
def update(self, pressed_keys):
if pressed_keys[K_UP]:
self.rect.move_ip(0, -2)
if pressed_keys[K_DOWN]:
self.rect.move_ip(0, 2)
if pressed_keys[K_LEFT]:
self.rect.move_ip(-2, 0)
if pressed_keys[K_RIGHT]:
self.rect.move_ip(2, 0)
# 超出屏幕范围的进行纠正
if self.rect.left < 0:
self.rect.left = 0
elif self.rect.right > 800:
self.rect.right = 800
if self.rect.top <= 0:
self.rect.top = 0
elif self.rect.bottom >= 600:
self.rect.bottom = 600
# 定义敌人类
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super(Enemy, self).__init__()
self.image = pygame.image.load('missile.png').convert()
self.image.set_colorkey((255, 255, 255), RLEACCEL)
self.rect = self.image.get_rect(
center=(random.randint(820, 900), random.randint(0, 600)))
self.speed = random.randint(1, 2)
def update(self):
self.rect.move_ip(-self.speed, 0)
# 如果超出边框,就删除,不会再被渲染出来
if self.rect.right < 0:
self.kill()
# 定义背景类
class Cloud(pygame.sprite.Sprite):
def __init__(self):
super(Cloud, self).__init__()
self.image = pygame.image.load('cloud.png').convert()
self.image.set_colorkey((0, 0, 0), RLEACCEL)
self.rect = self.image.get_rect(center=(
random.randint(820, 900), random.randint(0, 600))
)
def update(self):
self.rect.move_ip(-2, 0)
if self.rect.right < 0:
self.kill()
# 初始化 pygame
pygame.init()
# 创造一个画布,并传递宽度和高度
screen = pygame.display.set_mode((800, 600))
# 创建自定义事件
ADDENEMY = pygame.USEREVENT + 1
pygame.time.set_timer(ADDENEMY, 1000)
ADDCLOUD = pygame.USEREVENT + 2
pygame.time.set_timer(ADDCLOUD, 1000)
# 创建一个类
player = Player()
background = pygame.Surface(screen.get_size())
background.fill((135, 206, 250))
# Group 是 Sprite 的集合
enemies = pygame.sprite.Group()
clouds = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
# 游戏主循环
running = True
while running:
# 遍历事件队列
for event in pygame.event.get():
# 检测 KEYDOWN 事件: KEYDOWN 是 pygame.locals 中定义的常量,pygame.locals文件开始已经导入
if event.type == KEYDOWN:
# 如果按下 Esc 那么主循环终止
if event.key == K_ESCAPE:
running = False
# 检测 QUIT : 如果 QUIT, 终止主循环
elif event.type == QUIT:
running = False
elif event.type == ADDENEMY:
new_enemy = Enemy()
enemies.add(new_enemy)
all_sprites.add(new_enemy)
elif event.type == ADDCLOUD:
new_cloud = Cloud()
all_sprites.add(new_cloud)
clouds.add(new_cloud)
screen.blit(background, (0, 0))
pressed_keys = pygame.key.get_pressed()
player.update(pressed_keys)
enemies.update()
clouds.update()
for entity in all_sprites:
screen.blit(entity.image, entity.rect)
if pygame.sprite.spritecollideany(player, enemies):
player.kill()
pygame.display.flip()
知识点
只在这里简述,自己明白就行。具体的或者不明白的参考最后的链接
Blit 和 Flip
将创建的 Surface 绘制(Blit)到另一个 Surface 上,blit()有两个参数:要画的 Surface 和 在源 Surface 上的坐标。注意在 blit 之后的 pygame.display.filp() 的调用。Flip将会更新自上次 flip 后的整个屏幕,两次 flip 之间发生的修改都将在屏幕上显示,没有调用flip()那就什么也不会出现。
用户输入
pygame 的一个事件方法,pygame.event.get_pressed()。get_pressed()方法返回一个队列,其中包含了所有按键事件组成的字典,我们将把它放在主循环中,这样我们将获得每一帧上的按键。
Sprites
Sprites 是屏幕上事物的二维表达。本质上来讲,Sprite 就是一个图片,Pygame 提供一个叫做 Sprites 的基础类,它就是用来扩展的,可以包含想要在屏幕上呈现的对象一个或多个图形表示。
Groups
Groups 是 Sprite 的集合,sprite.Group 有一些内建的方法,有助于解决冲突和更新问题,所以建议采用这种方法。使用add()向里面添加Sprites
自定义事件
我们创建一个自定义事件,它隔几秒钟就会触发创建一批敌人。我们要监听该事件,方式和监听按键或退出事件一样
冲突
pygame.sprite 提供一个函数 spritecollideany() ,它接受一个 Sprite 对象和一个 Sprite.Group ,检测 Sprite 对象是否和 Sprite Group 中的其他 Sprites 冲突。
if pygame.sprite.spritecollideany(player,enemies):
player.kill()
图片
我们想用一张图片替代 Surface 对象。我们将使用 pygame.image.load() 导入图片的路径。load() 方法将会返回一个 Surface 对象。我们然后在这个 Surface 对象上调用 convert() 创建副本,这样可以更快地将它画在屏幕上。
接下来,我们在图片上调用 set_colorkey() 方法。set_colorkey用于设置图片的颜色,如果不设置 Pygame 会将图片设置为透明。这里我选用白色,因为和飞机的背景色一致。RLEACCEL 是一个可选参数,它有助于 PyGame 在非加速显示器上更快地渲染。
class Player(pygame.sprite.Sprite):
def __init__(self):
super(Player,self).__init__()
self.image = pygame.image.load('jet.png').convert()
self.image.set_colorkey((255,255,255),RLEACCEL)
self.rect = self.image.get_rect()