少儿编程分享:手把手教你用Python编写战斗机游戏(三)

少儿编程分享:手把手教你用Python编写战斗机游戏(三)

首页枪战射击趣嗨战机更新时间:2024-04-29
现在,让我们加入一些敌人!

首先,我们要创建一个新的精灵类,叫Enemy,它的格式和前面我们创建的Player差不多。

def update(self):

self.rect.move_ip(-self.speed, 0)

if self.rect.right < 0:

self.kill()

不过Enemy和Player相比有些不同。首先,当我们对surface调用get_rect()方法时,我们将横坐标x设为了820,纵坐标y设为了一个用random.randit()产生的随机数。

Random是python的一个库(library),要使用这个库,需要在文件的开头用import random的命令将其导入。为什么要使用随机数呢?答案很简单:我们想要敌人从屏幕的右边缘出现(横坐标820),但具体出现在哪里会是随机的(纵坐标0-600)。我们还要使用random来给敌人设置一个随机的速度,让敌人有不同的行进速度。

针对敌人使用的update()方法不带参数(因为我们不需要对敌人进行任何操作),这个方法的作用只是将敌人以一定速度移动到屏幕的左边。最后的if表达式用于检测敌人的右边是否超过了屏幕的左边界(这时它们会直接从屏幕中消失)。如果它们超过了屏幕的左边界,我们就调用精灵类的自带方法kill()来把它们从精灵组内删除,这样我们就不需要对这些已经消失的图形进行渲染。


精灵组

pygame提供的另一个很有用的对象是精灵组。顾名思义,精灵组就是一组精灵。我们接下来要创建一个带有游戏中所有精灵的组,接着把Player加到这个组中(因为到目前为止我们所有的精灵就只有Player)。我们可以为敌人(enemies)创建另一个组。当我们调用精灵的kill()方法时,精灵就会从其所在的组中被移除。

enemies = pygame.sprite.Group()

all_sprites = pygame.sprite.Group()

all_sprites.add(player)

现在我们有了这个叫做all_sprites的组,现在让我们改变一下渲染设置,使得这个组里所有的对象都能被渲染。

for entity in all_sprites:

screen.blit(entity.surf, entity.rect)

现在,我们放入all_sprites里的所有东西都会被渲染。


自定义事件

现在我们为敌人设置了一个精灵组,但实际上屏幕上还没有敌人。所以我们要如何让敌人出现在屏幕上呢?我们可以在游戏一开始就创建一堆敌人,但这样的话玩游戏的人就很难撑过前几秒。所以,我们要创建一个自定义事件,这个事件每过几秒钟就会创建一个心的敌人。我们将会对这个事件进行侦听(listen,检测是否发生),就好像我们先前侦听是否有按键(key press)或者退出(quit)的事件发生一样。创建一个自定义事件很简单,只需要使用下面这行代码:

ADDENEMY = pygame.USEREVENT 1

就是这么简单!现在我们有了一个ADDENEMY事件,我们在游戏的主循环中对这个事件进行侦听。唯一需要记住的是,我们的自定义事件有一个独特的值,这个值必须备USEREVENT要大,这就是为什么我们把我们的新时间设为USEREVENT 1。实际上,这些事件本质上就是一些整数常数。USEREVENT有一个数值,而所有我们自定义的事件都需要有一个比USEREVENT大的数值(这是因为所有比USEREVENT大的数值都已经被自带内容所占据了)。

现在,我们要把刚才定义的事件插入到事件队列中。要在游戏的过程中创建这些事件,我们需要一个计时器。PyGame的time()对象可以设置计时器:

pygame.time.set_timer(ADDENEMY, 250)

这行代码告诉PyGame:每250毫秒(0.25秒)激发一次ADDENEMY事件。这行代码在我们游戏的主循环之外,但它仍能在整个游戏的过程中不断被激发。现在,我们需要加入一些代码用于事件侦听:

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

elif(event.type == ADDENEMY):

new_enemy = Enemy()

enemies.add(new_enemy)

all_sprites.add(new_enemy)

小提示

set_timer()只能用于向PyGame的时间队列中插入新事件,没有别的作用。

上面这段代码用于侦听ADDENEMY事件,如果事件被激发,程序将会创建一个新的Enemy类,并把这个新的类加到enemies精灵组中(我们之后将会用精灵组来检测游戏主角与敌人是否碰撞(collision))以及all_sprites组中(这样它就能够和其他东西一起得到渲染)。


碰撞检测

我们喜欢用PyGame来写游戏的其中一大原因是,PyGame有很多专门用于碰撞测试的方法,这让原本很难写的碰撞测试代码变得简单许多。在今天的教程中,我们要使用的是spritecollideany。Spritecollideany()方法将一个精灵对象和一个精灵组作为参数,并测验精灵对象是否与精灵组中的任何精灵相触碰。在这里,我们使用player精灵和enemies精灵组来测试游戏主角是否和任何敌人相碰撞,代码如下:

if pygame.sprite.spritecollideany(player, enemies):

player.kill()

上面的代码用于测试player精灵对象是否与enemies精灵组中的精灵相触碰,如果碰到了,我们就用kill()方法把player精灵移除。现在,所有的代码变成了这样:

# 导入pygame

import pygame

# 导入random,用于产生随机数

import random

# 导入pygame.locals

from pygame.locals import *

class Player(pygame.sprite.Sprite):

def __init__(self):

super(Player, self).__init__()

self.surf = pygame.Surface((75, 25))

self.surf.fill((255, 255, 255))

self.rect = self.surf.get_rect()

def update(self, pressed_keys):

if pressed_keys[K_UP]:

self.rect.move_ip(0, -5)

if pressed_keys[K_DOWN]:

self.rect.move_ip(0, 5)

if pressed_keys[K_LEFT]:

self.rect.move_ip(-5, 0)

if pressed_keys[K_RIGHT]:

self.rect.move_ip(5, 0)

#让player一直在屏幕上出现

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

def update(self):

self.rect.move_ip(-self.speed, 0)

if self.rect.right < 0:

self.kill()

# 初始化pygame

pygame.init()

# 创建screen对象

# 把它的尺寸定为800 x 600

screen = pygame.display.set_mode((800, 600))

# 创建一个自定义事件用于增加敌人

ADDENEMY = pygame.USEREVENT 1

pygame.time.set_timer(ADDENEMY, 250)

# 创建游戏主角,它现在只是一个矩形

player = Player()

background = pygame.Surface(screen.get_size())

background.fill((0, 0, 0))

enemies = pygame.sprite.Group()

all_sprites = pygame.sprite.Group()

all_sprites.add(player)

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

elif(event.type == ADDENEMY):

new_enemy = Enemy()

enemies.add(new_enemy)

all_sprites.add(new_enemy)

screen.blit(background, (0, 0))

pressed_keys = pygame.key.get_pressed()

player.update(pressed_keys)

enemies.update()

for entity in all_sprites:

screen.blit(entity.surf, entity.rect)

让我们运行一下游戏试试!

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved