ゼロ戦の武器は機関銃と思うのが当たり前ですが、当たり前でつまらない。UFOを相手にするのだからもっと強力なもの。
そうだ<かめかめ波>にしよう! 動画はこれ。
今までは描画した画像は非表示になることはありませんでした。今回からかめはめ波に当たったUFOは爆発して消えます。
また、かめはめ波もUFOに当たったら非表示になります。
ソース
import pygame
from pygame import image
import pygame.sprite
import sys
SCREEN = pygame.Rect(0, 0, 640, 480)
#UFOのクラス
class ufo(pygame.sprite.Sprite):
def __init__(self, x,y, vx, vy, angle=0):
pygame.sprite.Sprite.__init__(self)
self.vx = vx
self.vy = vy
self.angle = angle
self.image = pygame.image.load('ufo.png').convert_alpha()
if angle != 0:
self.image = pygame.transform.rotate(self.image, angle)
w = self.image.get_width()
h = self.image.get_height()
self.rect = pygame.Rect(x, y, w, h)
self.attacked = False
self.attackCnt = 4
def update(self):
self.rect.move_ip(self.vx, self.vy)
self.rect = self.rect.clamp(SCREEN)
#かめはめ波のクラス
class kamehame(pygame.sprite.Sprite):
def __init__(self, x, y , vy):
pygame.sprite.Sprite.__init__(self)
self.vy = vy
self.image = pygame.image.load('kame.png').convert_alpha()
w = self.image.get_width()
h = self.image.get_height()
self.rect = pygame.Rect(x, y, w, h)
self.attacking = True
def update(self):
self.rect.move_ip(0, self.vy)
def main():
pygame.init()
pygame.display.set_caption("Pygame インベーダー ゼロ戦がかめはめ波")
screen = pygame.display.set_mode(SCREEN.size)
img_zero = pygame.image.load('zerosen.png')
img_kame = pygame.image.load('kame.png')
clock = pygame.time.Clock()
#スプライトグループの作成
group = pygame.sprite.RenderUpdates()
# スプライトの追加
#横8列、縦4行
x = 16
y = 16
x_jet = 0
y_jet = SCREEN.height - img_zero.get_height()
for i in range(4):
for j in range(8):
ufo1= ufo(x,y, 2, 0, 0)
group.add(ufo1)
x += 64
y +=50
x = 16
#かめはめ波グループ
groupKame = pygame.sprite.RenderUpdates()
while True:
keyName =''
for event in pygame.event.get():
if event.type == pygame.QUIT:
# 終了ボタンで終了
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
keyName = pygame.key.name(event.key)
#キーの取得
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] == True:
x_jet -= 4
elif key[pygame.K_RIGHT] == True:
x_jet += 4
if x_jet >= SCREEN.right - img_zero.get_width():
x_jet = SCREEN.right - img_zero.get_width()
elif x_jet < SCREEN.left:
x_jet = SCREEN.left
# かめかめ波発射
if keyName == 'space':
if len(groupKame) <= 4:
beam1 = kamehame(x_jet + img_zero.get_width() / 2 - img_kame.get_width() / 2,
y_jet - img_kame.get_height(), -10)
groupKame.add(beam1)
#かめはめ波の処理
for km in groupKame:
if km.rect.bottom < 0:
km.remove(groupKame)
continue
for uf in group:
headX = km.rect.left + (km.rect.right - km.rect.left) / 2
if km.rect.top <= uf.rect.bottom and \
headX >= uf.rect.left and headX < uf.rect.right:
uf.attacked = True
uf.image = pygame.image.load('explode.png').convert_alpha()
km.remove(groupKame)
break
for uf in group:
if uf.attacked == True:
uf.attackCnt -= 1
if uf.attackCnt == 0:
uf.remove(group)
screen.fill((128, 128, 255)) # 画面の背景色
# スプライトグループを更新
dir = 0
for u in group:
if u.vx + u.rect.right >= SCREEN.width:
dir = 1
break
elif u.rect.left + u.vx < SCREEN.left:
dir = -1
break
for u in group:
if dir == 1:
u.vx = -abs(u.vx)
elif dir == -1:
u.vx = abs(u.vx)
group.update()
groupKame.update()
# スプライトを描画
group.draw(screen)
groupKame.draw(screen)
screen.blit(img_zero, [x_jet,y_jet])
pygame.display.update()
clock.tick(50)
if __name__ == '__main__':
main()
だいぶ長めのソースになりました。このバージョンではゼロ戦からUFOの攻撃はできますが、UFOからの攻撃はありません。
かめはめ波のクラス
#かめはめ波のクラス
class kamehame(pygame.sprite.Sprite):
def __init__(self, x, y , vy):
pygame.sprite.Sprite.__init__(self)
self.vy = vy
self.image = pygame.image.load('kame.png').convert_alpha()
w = self.image.get_width()
h = self.image.get_height()
self.rect = pygame.Rect(x, y, w, h)
self.attacking = True
def update(self):
self.rect.move_ip(0, self.vy)
ufoクラスに比べて縦方向に移動するだけなので簡単です。
インスタンスの作成 このクラスはスペースキーを押したときにインスタンスが作られます。
if keyName == 'space':
if len(groupKame) <= 4:
beam1 = kamehame(x_jet + img_zero.get_width() / 2 - img_kame.get_width() / 2,
y_jet - img_kame.get_height(), -10)
groupKame.add(beam1)
x座標はゼロ戦の中央になるように計算します。 y座標はゼロ戦のy座標からかめかめ波の高さを引きます。 作成したインスタンスをかめはめ波グループに追加します。
UFOに命中しなかった時の処理
for km in groupKame:
if km.rect.bottom < 0:
km.remove(groupKame)
continue
かめはめ波の下の位置が0より小さくなったら命中しなかったことになります。
そしてこのオブジェクトをかめはめ波グループから取り除くことにより、このオブジェクトは無効にあります。
かめはめ波がUFOに命中
for uf in group:
headX = km.rect.left + (km.rect.right - km.rect.left) / 2
if km.rect.top <= uf.rect.bottom and \
headX >= uf.rect.left and headX < uf.rect.right:
uf.attacked = True
uf.image = pygame.image.load('explode.png').convert_alpha()
km.remove(groupKame)
break
headXはかめはめ波の中央の座標です。これがUFOの下座標より大きくかつ左右座標にあれば命中にします。 攻撃されたフラグをオンにします。
画像を爆発に変更します。 かめはめ波をグループから取り除きます。 これで爆発の画像が表示されます。
for uf in group:
if uf.attacked == True:
uf.attackCnt -= 1
if uf.attackCnt == 0:
uf.remove(group)
攻撃されたフラグがオンのとき、カウンターを減じて0になったらufoをグループから取り除きます。これで爆発の表示から無表示になります。
画像のダウンロード
|