太空射击第15课: 道具(第1部分)

在本课中,我们将添加一些偶尔出现的道具。
本教程所需素材从这里可以下载

视频

您可以在此处观看本课程的视频

道具

我们的游戏已经走了很远,但我们仍然缺少的一件事是让玩家的飞船变得更强的一种方式。我们可以考虑添加多种道具,但现在我们将重点关注两种:

  • 护盾 - 恢复盾牌力量的物体
  • 枪 - 一种可以提高火力的物体

战斗力精灵

首先,我们需要定义另一个 Sprite,这次是用来表示我们的战斗力对象。

我们需要在组件加载部分中加载图像,以下是我们正在使用的图像(单击以下载):


使用字典来保存以战斗力类型为键的图像:

powerup_images = {}
powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert()
powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert()

为了简单起见,我们可以复制我们已经创建的Bullet()类,然后进行一些更改,因为行为将是相似的:从某个位置(刚刚被摧毁的流星的位置)开始向下移动,然后在精灵离开屏幕底部时将其杀死。对于它的图像,我们将在'gun''shield' 之间随机选择,这将是我们的两种道具。

class Pow(pygame.sprite.Sprite):def __init__(self, center):pygame.sprite.Sprite.__init__(self)self.type = random.choice(['shield', 'gun'])self.image = powerup_images[self.type]self.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.rect.center = centerself.speedy = 2def update(self):self.rect.y += self.speedy# kill if it moves off the bottom of the screenif self.rect.top > HEIGHT:self.kill()

生成道具

要生成它们,我们需要一个组来保存它们(用于碰撞):

powerups = pygame.sprite.Group()

然后,当子弹摧毁敌人时,我们想要一个(小的)随机概率,即道具会出现并下降:

# check to see if a bullet hit a mob
hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
for hit in hits:score += 50 - hit.radiusrandom.choice(expl_sounds).play()expl = Explosion(hit.rect.center, 'lg')all_sprites.add(expl)if random.random() > 0.9:pow = Pow(hit.rect.center)all_sprites.add(pow)powerups.add(pow)newmob()

在这里,random.random()选择一个介于0和1之间的随机十进制数,因此只有当该数字大于0.9时才生成意味着我们有10%的几率从被摧毁的流星产生道具。

与玩家碰撞

现在,我们需要另一次碰撞检查,这次是在玩家和道具组之间。把它添加到最后:

# check to see if player hit a powerup
hits = pygame.sprite.spritecollide(player, powerups, True)
for hit in hits:if hit.type == 'shield':player.shield += random.randrange(10, 30)if player.shield >= 100:player.shield = 100if hit.type == 'gun':pass

首先,我们处理护盾道具,这将为玩家提供随机数量的护盾。'gun'道具稍微复杂一,所以我们将在下一部分中处理这个问题。

下次,我们将完成枪支类型的通电代码。

此部分的完整代码


import pygame
import random
from os import pathimg_dir = path.join(path.dirname(__file__), 'img')
snd_dir = path.join(path.dirname(__file__), 'snd')WIDTH = 480
HEIGHT = 600
FPS = 60# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Shmup!")
clock = pygame.time.Clock()font_name = pygame.font.match_font('arial')
def draw_text(surf, text, size, x, y):font = pygame.font.Font(font_name, size)text_surface = font.render(text, True, WHITE)text_rect = text_surface.get_rect()text_rect.midtop = (x, y)surf.blit(text_surface, text_rect)def newmob():m = Mob()all_sprites.add(m)mobs.add(m)def draw_shield_bar(surf, x, y, pct):if pct < 0:pct = 0BAR_LENGTH = 100BAR_HEIGHT = 10fill = (pct / 100) * BAR_LENGTHoutline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)pygame.draw.rect(surf, GREEN, fill_rect)pygame.draw.rect(surf, WHITE, outline_rect, 2)def draw_lives(surf, x, y, lives, img):for i in range(lives):img_rect = img.get_rect()img_rect.x = x + 30 * iimg_rect.y = ysurf.blit(img, img_rect)class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.transform.scale(player_img, (50, 38))self.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.radius = 20# pygame.draw.circle(self.image, RED, self.rect.center, self.radius)self.rect.centerx = WIDTH / 2self.rect.bottom = HEIGHT - 10self.speedx = 0self.shield = 100self.shoot_delay = 250self.last_shot = pygame.time.get_ticks()self.lives = 3self.hidden = Falseself.hide_timer = pygame.time.get_ticks()def update(self):# unhide if hiddenif self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:self.hidden = Falseself.rect.centerx = WIDTH / 2self.rect.bottom = HEIGHT - 10self.speedx = 0keystate = pygame.key.get_pressed()if keystate[pygame.K_LEFT]:self.speedx = -8if keystate[pygame.K_RIGHT]:self.speedx = 8if keystate[pygame.K_SPACE]:self.shoot()self.rect.x += self.speedxif self.rect.right > WIDTH:self.rect.right = WIDTHif self.rect.left < 0:self.rect.left = 0def shoot(self):now = pygame.time.get_ticks()if now - self.last_shot > self.shoot_delay:self.last_shot = nowbullet = Bullet(self.rect.centerx, self.rect.top)all_sprites.add(bullet)bullets.add(bullet)shoot_sound.play()def hide(self):# hide the player temporarilyself.hidden = Trueself.hide_timer = pygame.time.get_ticks()self.rect.center = (WIDTH / 2, HEIGHT + 200)class Mob(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image_orig = random.choice(meteor_images)self.image_orig.set_colorkey(BLACK)self.image = self.image_orig.copy()self.rect = self.image.get_rect()self.radius = int(self.rect.width * .85 / 2)# pygame.draw.circle(self.image, RED, self.rect.center, self.radius)self.rect.x = random.randrange(WIDTH - self.rect.width)self.rect.bottom = random.randrange(-80, -20)self.speedy = random.randrange(1, 8)self.speedx = random.randrange(-3, 3)self.rot = 0self.rot_speed = random.randrange(-8, 8)self.last_update = pygame.time.get_ticks()def rotate(self):now = pygame.time.get_ticks()if now - self.last_update > 50:self.last_update = nowself.rot = (self.rot + self.rot_speed) % 360new_image = pygame.transform.rotate(self.image_orig, self.rot)old_center = self.rect.centerself.image = new_imageself.rect = self.image.get_rect()self.rect.center = old_centerdef update(self):self.rotate()self.rect.x += self.speedxself.rect.y += self.speedyif self.rect.top > HEIGHT + 10 or self.rect.left < -100 or self.rect.right > WIDTH + 100:self.rect.x = random.randrange(WIDTH - self.rect.width)self.rect.y = random.randrange(-100, -40)self.speedy = random.randrange(1, 8)class Bullet(pygame.sprite.Sprite):def __init__(self, x, y):pygame.sprite.Sprite.__init__(self)self.image = bullet_imgself.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.rect.bottom = yself.rect.centerx = xself.speedy = -10def update(self):self.rect.y += self.speedy# kill if it moves off the top of the screenif self.rect.bottom < 0:self.kill()class Pow(pygame.sprite.Sprite):def __init__(self, center):pygame.sprite.Sprite.__init__(self)self.type = random.choice(['shield', 'gun'])self.image = powerup_images[self.type]self.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.rect.center = centerself.speedy = 2def update(self):self.rect.y += self.speedy# kill if it moves off the top of the screenif self.rect.top > HEIGHT:self.kill()class Explosion(pygame.sprite.Sprite):def __init__(self, center, size):pygame.sprite.Sprite.__init__(self)self.size = sizeself.image = explosion_anim[self.size][0]self.rect = self.image.get_rect()self.rect.center = centerself.frame = 0self.last_update = pygame.time.get_ticks()self.frame_rate = 75def update(self):now = pygame.time.get_ticks()if now - self.last_update > self.frame_rate:self.last_update = nowself.frame += 1if self.frame == len(explosion_anim[self.size]):self.kill()else:center = self.rect.centerself.image = explosion_anim[self.size][self.frame]self.rect = self.image.get_rect()self.rect.center = center# Load all game graphics
background = pygame.image.load(path.join(img_dir, "starfield.png")).convert()
background_rect = background.get_rect()
player_img = pygame.image.load(path.join(img_dir, "playerShip1_orange.png")).convert()
player_mini_img = pygame.transform.scale(player_img, (25, 19))
player_mini_img.set_colorkey(BLACK)
bullet_img = pygame.image.load(path.join(img_dir, "laserRed16.png")).convert()
meteor_images = []
meteor_list = ['meteorBrown_big1.png', 'meteorBrown_med1.png', 'meteorBrown_med1.png','meteorBrown_med3.png', 'meteorBrown_small1.png', 'meteorBrown_small2.png','meteorBrown_tiny1.png']
for img in meteor_list:meteor_images.append(pygame.image.load(path.join(img_dir, img)).convert())
explosion_anim = {}
explosion_anim['lg'] = []
explosion_anim['sm'] = []
explosion_anim['player'] = []
for i in range(9):filename = 'regularExplosion0{}.png'.format(i)img = pygame.image.load(path.join(img_dir, filename)).convert()img.set_colorkey(BLACK)img_lg = pygame.transform.scale(img, (75, 75))explosion_anim['lg'].append(img_lg)img_sm = pygame.transform.scale(img, (32, 32))explosion_anim['sm'].append(img_sm)filename = 'sonicExplosion0{}.png'.format(i)img = pygame.image.load(path.join(img_dir, filename)).convert()img.set_colorkey(BLACK)explosion_anim['player'].append(img)
powerup_images = {}
powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert()
powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert()# Load all game sounds
shoot_sound = pygame.mixer.Sound(path.join(snd_dir, 'pew.wav'))
expl_sounds = []
for snd in ['expl3.wav', 'expl6.wav']:expl_sounds.append(pygame.mixer.Sound(path.join(snd_dir, snd)))
player_die_sound = pygame.mixer.Sound(path.join(snd_dir, 'rumble1.ogg'))
pygame.mixer.music.load(path.join(snd_dir, 'tgfcoder-FrozenJam-SeamlessLoop.ogg'))
pygame.mixer.music.set_volume(0.4)all_sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):newmob()score = 0
pygame.mixer.music.play(loops=-1)
# Game loop
running = True
while running:# keep loop running at the right speedclock.tick(FPS)# Process input (events)for event in pygame.event.get():# check for closing windowif event.type == pygame.QUIT:running = False# Updateall_sprites.update()# check to see if a bullet hit a mobhits = pygame.sprite.groupcollide(mobs, bullets, True, True)for hit in hits:score += 50 - hit.radiusrandom.choice(expl_sounds).play()expl = Explosion(hit.rect.center, 'lg')all_sprites.add(expl)if random.random() > 0.9:pow = Pow(hit.rect.center)all_sprites.add(pow)powerups.add(pow)newmob()# check to see if a mob hit the playerhits = pygame.sprite.spritecollide(player, mobs, True, pygame.sprite.collide_circle)for hit in hits:player.shield -= hit.radius * 2expl = Explosion(hit.rect.center, 'sm')all_sprites.add(expl)newmob()if player.shield <= 0:player_die_sound.play()death_explosion = Explosion(player.rect.center, 'player')all_sprites.add(death_explosion)player.hide()player.lives -= 1player.shield = 100# check to see if player hit a poweruphits = pygame.sprite.spritecollide(player, powerups, True)for hit in hits:if hit.type == 'shield':player.shield += random.randrange(10, 30)if player.shield >= 100:player.shield = 100if hit.type == 'gun':pass# if the player died and the explosion has finished playingif player.lives == 0 and not death_explosion.alive():running = False# Draw / renderscreen.fill(BLACK)screen.blit(background, background_rect)all_sprites.draw(screen)draw_text(screen, str(score), 18, WIDTH / 2, 10)draw_shield_bar(screen, 5, 5, player.shield)draw_lives(screen, WIDTH - 100, 5, player.lives, player_mini_img)# *after* drawing everything, flip the displaypygame.display.flip()pygame.quit()

太空射击第15课: 道具相关推荐

  1. 太空射击第16课: 道具(Part 2)

    太空射击第16课: 道具(Part 2) 在本课中,我们将添加增加对子弹道具的处理. 视频 您可以在此处观看本课程的视频: 武器道具 上一次,我们创建了一个道具精灵,当流星被摧毁时,它会从流星中随机掉 ...

  2. 太空射击第14课: 玩家生命

    太空射击第14课: 玩家生命 在本课中,我们将为玩家添加多个生命值,并在玩家死亡时添加一个漂亮的爆炸. 本教程所有素材包从这里下载 视频 您可以在此处观看本课程的视频: 玩家爆炸 我们将使用不同的爆炸 ...

  3. 太空射击第17课: Game Over (結束)

    太空射击第17课: Game Over (結束) 在本课中,我们将通过添加"游戏结束"屏幕和再次玩游戏的功能来完成游戏. 视频 您可以在此处观看本课程的视频: 游戏结束 现在,当我 ...

  4. 太空射击 第07课: 添加图形

    太空射击 第07课: 添加图形 在本课中,我们将讨论如何在游戏中使用预先绘制的图形. 视频 在这里可以观看本教程的视频 选择图形 我们谈到了 Opengameart.org,这是免费游戏艺术的重要来源 ...

  5. 太空射击第13课: 爆炸效果

    太空射击第13课: 爆炸效果 在本课中,我们将在玩家射击流星时进行一些动画爆炸. 视频 您可以在此处观看本课程的视频: 自动开火 首先,让我们对玩家的射击方式进行一些小的改变.现在,我们必须为每次射击 ...

  6. 太空射击第08课: 改进的碰撞

    太空射击第08课: 改进的碰撞 在本课中,我们将讨论如何更改 Pygame 处理精灵之间冲突的方式. 视频 可以在这里找到本教程的视频 碰撞是怎么回事? 在上一次教程中,我们添加了图形,将精灵从普通矩 ...

  7. 太空射击第10课: Score (繪畫和文字)

    太空射击第10课: Score (繪畫和文字) 在本课中,我们将开始显示分数,并学习如何在屏幕上显示文本.将使用pygame.freetype模块来完成文本的渲染,模块的详细说明在这里. 视频 观看视 ...

  8. 太空射击第09课:精灵动画

    太空射击第09课:精灵动画 在本课中,我们将通过添加一些精灵动画来使我们的流星更有趣.本次课用到的图像可以点击这里下载 视频 观看视频 流星动画 pygame 中的transform模块 我们所有的流 ...

  9. 太空射击 第05课: 敌人精灵

    视频 观看视频 太空射击 : 敌人精灵 这是我们"Shmup"项目的第2部分!在本课中,我们将添加一些敌人的精灵供玩家躲避.在本系列课程中,我们将使用Python和Pygame构建 ...

最新文章

  1. NameError: name xx is not defined
  2. 如何去使用Python爬虫来爬取B站的弹幕数据?
  3. python才能做爬虫,No,C#也可以!
  4. MATLAB-矩阵基本语法知识
  5. SQL Server中使用自定义指定顺序排序
  6. 最新版MySQL在MacOS上的实践!
  7. ArcGIS Engine开发之旅08--和查询相关的对象和接口
  8. txt.导入c语言,分求C语言问题解决——关于TXT文件导入(第二贴,能给出的这个100和另外的100一起拿走!)...
  9. Android NFC技术解析,附Demo源码
  10. GitHub快速上手指南
  11. SVLsimulator与apollo6.0联合仿真
  12. Mysql 分组查询top n(多种方法)
  13. 天气预报数据保存APP的制作
  14. 自动驾驶中的Scene, Situation和Scenario的定义与补充
  15. python计算绩效工资编程_Python实战精选:计算销售提成
  16. c++:十进制转化为二进制
  17. 万有引力不存在及爱因斯坦相对论中时空扭曲都是错误的
  18. opencv 学习笔记3.1 高斯双边滤波(EPF) 常用于美颜
  19. Lock锁与synchronized锁的区别
  20. java实现医嘱管理系统_java毕业设计_springboot框架的基于框架的医嘱管理系统

热门文章

  1. 猫眼电影爬虫和数据分析
  2. 猫眼api html,猫眼电影数据抓取
  3. 基于kali的一次无线渗透测试
  4. 测试成绩软件,软件部分测试成绩_精英 Z87H3-A3X_主板评测-中关村在线
  5. continue用法(continue用法总结)
  6. mysql和linux的题目_最强Linux和Mysql面试题套餐,让你的面试无懈可击!
  7. 初秋最时髦好看的搭配,竟是风衣里面套裙子!
  8. (跨平台UI)单片机用MTF HMI串口屏 UART通信易用兼容
  9. 最新 UltraEdit 24.20 注册成功经验分享
  10. -wl,-soname的作用