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

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

首页枪战射击趣嗨战机更新时间:2024-04-29


精灵(Sprite)

什么是精灵?在编程术语中,精灵是屏幕上某个2d物件。一般来讲,精灵很可能是一张图片。pygame中将精灵设置为一个基础的类,它能够保存一个或多个图像对象并将其显示在屏幕上。在这里,我们将把精灵类进行拓展,使用它自带(built in)的方法。我们需要创建一个新的Player对象。Player将用于拓展精灵类。Player现在有两个属性:surf和rect。像之前一样,我们将surf填充为白色。不过与之前不同的是,这次surface被画在Player上,而不是screen上。

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()

让我们把前面的所有代码放到一起吧:

# 导入pygame库

import pygame

# 导入pygame.locals

from pygame.locals import *

# 定义player对象

Define our player object and call super to give it all the properties and methods of pygame.sprite.Sprite

# 我们画在屏幕上的surface现在成了player的一个属性

The surface we draw on the screen is now a property of 'player'

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()

# 初始化pygame

pygame.init()

# 创建screen对象

# 把它的尺寸定为800 x 600

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

# 初始化游戏主角;现在它只是一个矩形

player = Player()

# 用于让主循环不断运行的变量

running = True

# 主循环

while running:

# 针对事件队列的for循环

for event in pygame.event.get():

# 检测是否有KEYDOWN事件,KEYDOWN是一个在pygame.locals中定义了的事件常量,这个库我们之前导入过

if event.type == KEYDOWN:

# 如果按了ESC键,把running的值设为False,并退出主循环

if event.key == K_ESCAPE:

running = False

# 检测是否有QUIT事件,如果有的话,把running的值设为False

elif event.type == QUIT:

running = False

# 把player画到画布上

screen.blit(player.surf, (400, 300))

# 更新窗口显示

pygame.display.flip()

现在运行这段代码,你将会看到屏幕中央附近有一个白色的矩形:

猜猜如果把screen.blit(player.surf, (400,300))改为screen.blit(player.surf, player.rect)会发生什么?我们来试一下。改变之后,试着在控制台打印player.rect。rect()的前两个属性是rect()矩形对象左上角的坐标。如果你向rect传递一个blit,这个坐标就会被用来画surface。在后面的教程中,我们将利用这些来让游戏主角动起来。


用户输入

有趣的事情要开始了!现在我们要控制游戏的主角了。先前我们已经讨论过用pygame.event.get()从时间队列中调出的keydown事件。现在我们要使用的是另一个事件方法(event method),pygame.event.get_pressed()。这里的get_pressed()方法将会返回事件列表中所有的keydown事件,并将这些事件储存在一个字典(dictionary)中。我们要把这个字典放到游戏的主循环中,这样我们在游戏的每一帧都能得到通过按键激发的事件。

pressed_keys = pygame.event.get_pressed()

现在我们要写一个方法,这个方法将上面提到的字典作为参数,并能通过玩家所按下的键来决定精灵的行为:

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)

K_UP, K_DOWN, K_LEFT和K_RIGHT对应键盘的上下左右键。这段代码能够检测玩家是否按下了上下左右键,如果按下的话,游戏主角就会进行相应的移动。Rect对象有两个自带的用于移动的方法,这里我们使用的是“原地移动 (move in place)”——move_ip(),使用这个方法能够直接移动现有的rect对象,而不需要进行复制。

把上面的代码加到我们创建的Player类下,然后把get_presed()放到主循环里。现在我们的代码会变成这样:

import pygame

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)

pygame.init()

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

player = 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

pressed_keys = pygame.key.get_pressed()

player.update(pressed_keys)

screen.blit(player.surf, (400, 300))

pygame.display.flip()

现在,你应该能够通过方向键来控制矩形在屏幕上移动了!你可能会注意到,有时候你会把矩形移出屏幕,这可不是我们想要的。所以,让我们修改一下代码,使之能够检测出矩形超出了800 x 600 的窗口范围,如果超出了,就让它待在边框内。

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

在这段代码中,我们没有使用move方法,而是仅仅改变了上下左右的坐标。

(未完待续)

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

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