天天看點

pygame 飛機大戰子彈的編寫(七)花樣年華

目标:實作子彈的花樣玩法,不同的子彈類型(image),不同的發射方式(speed,angle),不同的子彈數量。

前面幾篇文字,已經實作了子彈的不同特性,組合下就能開啟子彈的花樣年華。

想了兩個方案,一個方案是直接在bullet類中實作上述功能,設定參數來決定那種子彈類型;一個是bullet隻作為基本功能實作,另外建立一個類,繼承至bullet,然後擴充其他功能。感覺還是第二種好些,因為第一種方案不能實作多數量的子彈。

bullet.py 基本的子彈功能,代碼如下:

import pygame
import math
import random 

class Bullet(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/bullet0.png')
        self.rect = self.image.get_rect()
        self.x_speed = 0.00
        self.y_speed = 2.00
        self.angle = 0

    #會自動調用
    def update(self):
        self.rect.x += self.x_speed
        self.rect.y += self.y_speed
        # 可以用傳遞 scene來計算螢幕大小,示範用就簡單些吧。
        if (self.rect.x < 0 or self.rect.y < 0 or
            self.rect.x >480 or self.rect.y > 860):
            # print(self.rect.x)
            #超過螢幕自動删除
            self.kill()

    #為了和飛機的位置配合,需要設定初始位置
    def set_pos(self,x, y):
        self.rect.x = x
        self.rect.y = y 
    
    # 為了跟蹤彈用的
    def get_pos(self):
        return (self.rect.x,self.rect.y)

    def set_speed(self,speed, angle = 0):
        self.angle = math.pi * angle/180
        self.x_speed = speed * math.cos(self.angle)
        self.y_speed = speed * math.sin(self.angle)
           

建立BulletFactor類,來實作子彈的複雜功能 bulletfactor.py,代碼如下:

from bullet import *
class BulletFactor(Bullet):
    def __init__(self):
        Bullet.__init__(self)
        # pygame.sprite.Sprite.__init__(self)
        #下面兩條代碼不能少,sprite初始化需要
        self.image =  pygame.image.load('images/bullet0.png')
        self.rect = self.image.get_rect()
        
        self.motion_type = 0
        self.image_type = 0
        #多個子彈時需要用到Group
        #發現Group.add居然能添加Group,不需要逐個sprite添加。
        self.bullets = pygame.sprite.Group()
    
    #設定不同子彈圖檔,後期可以添加攻擊力等
    def set_image_type(self,type = 0):
        self.image_type = type
        if type == 0:
            self.image = pygame.image.load('images/bullet0.png')
        elif type == 1:
            self.image = pygame.image.load('images/bullet1.png')
        elif type == 2:
            self.image  = pygame.image.load('images/bullet2.png')
        elif type == 3:
            self.image = pygame.image.load('images/bullet3.png')
        else:
            pass
    
    #設定子彈的行動方式
    def set_motion(self, type = 0):
        self.motion_type = type
        # 向下直射
        if self.motion_type == 0:
            self.set_speed(2, 90)
        #向上直射
        elif self.motion_type == 1:
            self.set_speed(2, -90)
        #360度四周發散
        elif self.motion_type == 2:
            for angle in range(0, 360 , 10):
                bullet  = Bullet()
                bullet.image = self.image
                #位置可以調用時傳入
                bullet.set_pos(self.rect.x, self.rect.y)
                bullet.set_speed(3, angle)
                self.bullets.add(bullet)
                # print(self.bullets)
        else:
            pass
           

main.py裡測試

import pygame
from bullet import *
from sys import exit
import random
from pygame import Vector2
from bulletfactor import *
vect = pygame.math.Vector2

#定義螢幕類
class MainScene(object):
    #初始化
    def __init__(self):
        pygame.init()
        self.size = (480,860)
        self.scene = pygame.display.set_mode(self.size)
        pygame.display.set_caption("自學飛機大戰--V0.98")
        self.image = pygame.image.load('images/bg.png')
       
        self.bullet_sprite = pygame.sprite.Group()
        bullet_enemy = BulletFactor()
        bullet_enemy.set_image_type(1)
        self.bullet_sprite.add(bullet_enemy)

        bullet_hero = BulletFactor()
        bullet_hero.set_image_type(2)
        bullet_hero.set_pos(200,660)
        bullet_hero.set_motion(type = 1)
        self.bullet_sprite.add(bullet_hero)

        bullet_boss = BulletFactor()
        bullet_boss.set_image_type(0)
        bullet_boss.set_pos(200,600)
        bullet_boss.set_motion(2)
        self.bullet_sprite.add(bullet_boss.bullets)

    #繪制各個元素
    def drawElements(self):
        self.scene.blit(self.image,(0,0))
        self.bullet_sprite.draw(self.scene)

    #處理鍵盤和滑鼠相應
    #隻是編寫了子彈子產品,那麼跟蹤彈在這裡處理算了,
    def handleEvent(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            if event.type == pygame.MOUSEMOTION:
                 # 獲得滑鼠點選三個按鈕的點選情況(1,0,0)
                # 如果第一個參數為1,表示左鍵被按下
                # 如果第二個參數為1,表示滾輪被按下
                # 如果第三個參數為1,表示右鍵被按下
                buttons = pygame.mouse.get_pressed()
                # 我們隻處理左鍵被按下的情況
                if buttons[0]:
                    pass
                    # 注釋的代碼為跟蹤彈的實作方式
                    # 獲得拖動滑鼠的拖動位置
                    # pos_mouse = pygame.mouse.get_pos()
                    # pos1 = vect(pos_mouse[0], pos_mouse[1])
                    # for bullet in self.bullet_sprite.sprites():
                    #     pos_bullet = bullet.get_pos()
                    #     pos2 = vect(pos_bullet[0],pos_bullet[1])
                    #     pos0 = vect(0,0)
                    #     pos = pos1 - pos2
                    #     angle = pos0.angle_to(pos)
                    #     圖像轉不好# bulleted = pygame.transform.rotate(self.image ,angle)
                    #     bullet.set_speed(5,angle)

    #運作主程式
    def runScene(self):
        while True:
            self.drawElements()
            self.handleEvent()
            self.bullet_sprite.update()
            pygame.display.update()
            # pygame.time.delay(100)



if __name__ == '__main__':
    mainScene = MainScene()
    mainScene.runScene()
           

效果如下:

pygame 飛機大戰子彈的編寫(七)花樣年華

繼續閱讀