天天看點

pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇

前言:

BOSS系列寫完了,還可以增加些BOSS子彈的發射方式,例如螺旋線,就是把射擊的間隔縮短,每顆子彈按照時間間隔發射,每次的發射角度在前次上遞增。看起來就是螺旋線發射了。

我的代碼發射的子彈和發射的方式有點亂,隻是為了展示效果,真正要好玩,還得細化,把子彈和發射方式控制一下,有簡單到難。代碼有些地方備援,可以簡化,這些工作,等有空在慢慢調試。

接下來寫點英雄系列的日志吧。

在BOSS系列裡,英雄出師未捷身先死,一點英雄氣概也沒看到,完全是個我躲,我躲,我躲的閃客。

那就給英雄寫點吧。

還得從選擇界面進入英雄系列。

本來想用文字的,網上的成熟的代碼很多,功能很強大,可是還是想自己碼一個。簡單的,不抽象的。

實作要求如下:

1、在啟動主程式前,期待選擇界面,裡面有四架英雄飛機可以選擇(因為我隻有四架飛機的素材),可以通過左右按鍵(a,d)來選。

2、選擇過程中,能看到所選英雄飛機的基本資訊,動态圖像。

3、選擇完成後,出現主界面,飛機角色為所選角色。

遊戲界面選擇架構如下:selectmenu.py

1、初始化四家飛機

2、初始化選擇框

3、初始化動态顯示框

4、初始化預設飛機基本資訊

因為界面退出後,沒有什麼用了,重置self.kill()

建立一個循環,用于處理選擇的步驟  。

選擇完成,在main.py裡儲存飛機資訊

selectmenu裡的所有精靈self.kill()自毀

先建立一個類SelectMenu。用來設定飛機圖像和選擇框,選擇框也是一個圖像,比飛機圖像開框大些,飛機位置透明。

pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇
pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇
pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇
pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇
pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇

中心對齊後看起來就像是套在上面。

class SelectMenu(pygame.sprite.Sprite):
    def __init__(self, imagename):
        self._layer = 3
        self.groups = selectgroup
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.image = pygame.image.load(imagename)
        self.rect = self.image.get_rect()

    def update(self):
        pass

    def move(self, direction, distant=100):
        if direction == 'LEFT':
            self.rect.x -= distant
        elif direction == 'RIGHT':
            self.rect.x += distant

    def set_pos(self, x, y):
        self.rect.x = x
        self.rect.y = y
           

飛機圖像不動,選擇是,框移動。

class SelectHero(pygame.sprite.Sprite):
    def __init__(self, scene):
        self._layer = 3
        self.groups = selectgroup
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.main_scene = scene
        self.image = pygame.image.load('images/bg/select.jpeg')
        self.rect = self.image.get_rect()
        self.hero_index = 0
        self.first_index = 0
        self.last_index = 3
        self.selected = False
        pos_x = SCENEWIDTH // 4 - 50
        pos_y = SCENEHEIGHT * 3 // 4
        step = 100
        hero0 = SelectMenu('images/hero/plane0_sel.png')
        hero0.set_pos(pos_x, pos_y)
        pos_x += step
        hero1 = SelectMenu('images/hero/plane1_sel.png')
        hero1.set_pos(pos_x, pos_y)
        pos_x += step
        hero2 = SelectMenu('images/hero/plane2_sel.png')
        hero2.set_pos(pos_x, pos_y)
        pos_x += step
        hero3 = SelectMenu('images/hero/plane3_sel.png')
        hero3.set_pos(pos_x, pos_y)
        self.select_frame = SelectMenu("images/hero/plane_sel.png")
        self.select_frame.rect.center = hero0.rect.center



    def kill(self):
        selectgroup.empty()

    def run(self):
        while not self.selected:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_j:
                        pass
                    elif event.key == pygame.K_a:
                        if self.hero_index == self.first_index:
                            break
                        self.select_frame.move('LEFT')
                        self.hero_index -= 1
                        
                    elif event.key == pygame.K_d:
                        if self.hero_index == self.last_index:
                            break
                        self.hero_index += 1
                        self.select_frame.move('RIGHT')
                       
                    elif event.key == pygame.K_RETURN:  #語句中的retur居然也會觸發這個,隻好改用break
                        self.selected = True
                    #ESC 退出
                    elif event.key == pygame.K_ESCAPE or event.key == pygame.K_F4:
                        pygame.quit()
                        exit()
            selectgroup.update()
            selectgroup.draw(self.main_scene)
            pygame.display.update()
           

建立了一個selectgroup的精靈組,在退出選擇界面後 self.kill,清理所有精靈

在main.py架構類的初始裡,添加

#載入選擇地圖
        b = SelectHero(self.scene)
        b.run()
        hero_index = b.hero_index
        b.kill()
           

運作效果如下

pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇

 加入一些文字說明,加入資訊提示。完整代碼如下:

from setting import *
from animation import *


class Text(pygame.sprite.Sprite):
    """a pygame Sprite displaying text"""

    def __init__(self,
                 msg="ok",
                 color=(0, 0, 0),
                 topleft=(0, 0)):
        self.groups = selectgroup
        self.topleft = topleft
        self._layer = 99
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.newmsg(msg, color)

    def update(self):
        pass  

    def newmsg(self, msg, color=(0, 0, 0)):
        self.image = self.write(msg, color)
        self.rect = self.image.get_rect()
        self.rect.topleft = self.topleft

    def write(self, msg="ok", color=(0, 0, 0)):
        """write text into pygame surfaces"""
        myfont = pygame.font.SysFont("None", 32)
        mytext = myfont.render(msg, True, color)
        mytext = mytext.convert_alpha()
        return mytext

    def set_pos(self, x, y):
        self.rect.x = x
        self.rect.y = y


class IntroduceVideo(pygame.sprite.Sprite):
    def __init__(self, index):
        self.groups = selectgroup
        self._layer = 99
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.animation = Animation()
        self.images = self.animation.load_image(
            'images/hero/plane' + str(index) + '.png', 226, 85, 1, 4)
        original = self.images[0]
        self.image = pygame.transform.scale2x(original)
        self.rect = self.image.get_rect()
        self.index = 0
        self.heor_info = {
            0: ['speed 4', 'damage 4', 'HP 100'],
            1: ['speed 3', 'damage 5', 'HP 100'],
            2: ['speed 5', 'damage 3', 'HP 100'],
            3: ['speed 5', 'damage 5', 'HP 50']
        }
        self.set_animation(0)
        plane_info = self.heor_info[index]
        self.screentext0 = Text("plane information", (152, 0, 255), (400, 200))
        self.screentext1 = Text(plane_info[0], (255, 0, 255), (400, 250))
        self.screentext2 = Text(plane_info[1], (255, 0, 0), (400, 300))
        self.screentext3 = Text(plane_info[2], (0, 255, 0), (400, 350))

    def update(self):
        original = self.animation.get_current_image()
        self.image = pygame.transform.scale2x(original)
        plane_info = self.heor_info[self.index]
        self.screentext1.newmsg(plane_info[0], (255, 0, 255))
        self.screentext2.newmsg(plane_info[1], (255, 0, 0))
        self.screentext3.newmsg(plane_info[2], (0, 255, 0))

    def set_pos(self, x, y):
        self.rect.x = x
        self.rect.y = y

    def set_animation(self, index):
        original_center = self.rect.center
        self.images = self.animation.load_image(
            'images/hero/plane' + str(index) + '.png', 226, 85, 1, 4)
        original = self.images[0]
        self.image = pygame.transform.scale2x(original)
        self.rect.center = original_center
        self.index = index


class SelectMenu(pygame.sprite.Sprite):
    def __init__(self, imagename):
        self._layer = 3
        self.groups = selectgroup
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.image = pygame.image.load(imagename)
        self.rect = self.image.get_rect()

    def update(self):
        pass

    def move(self, direction, distant=100):
        if direction == 'LEFT':
            self.rect.x -= distant
        elif direction == 'RIGHT':
            self.rect.x += distant

    def set_pos(self, x, y):
        self.rect.x = x
        self.rect.y = y


class SelectHero(pygame.sprite.Sprite):
    def __init__(self, scene):
        self._layer = 3
        self.groups = selectgroup
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.main_scene = scene
        self.image = pygame.image.load('images/bg/select.jpeg')
        self.rect = self.image.get_rect()
        self.hero_index = 0
        self.first_index = 0
        self.last_index = 3
        self.selected = False
        pos_x = SCENEWIDTH // 4 - 50
        pos_y = SCENEHEIGHT * 3 // 4
        step = 100
        hero0 = SelectMenu('images/hero/plane0_sel.png')
        hero0.set_pos(pos_x, pos_y)
        pos_x += step
        hero1 = SelectMenu('images/hero/plane1_sel.png')
        hero1.set_pos(pos_x, pos_y)
        pos_x += step
        hero2 = SelectMenu('images/hero/plane2_sel.png')
        hero2.set_pos(pos_x, pos_y)
        pos_x += step
        hero3 = SelectMenu('images/hero/plane3_sel.png')
        hero3.set_pos(pos_x, pos_y)
        self.select_frame = SelectMenu("images/hero/plane_sel.png")
        self.select_frame.rect.center = hero0.rect.center

        Text("PRESS ENTER TO CONFIRM", (182, 192, 192), (SCENEWIDTH // 4, 100))
        Text('PRESS A OR D TO SELECT', (182, 182, 182), (SCENEWIDTH // 4, 130))

        self.intro_fram = IntroduceVideo(0)
        self.intro_fram.set_pos(200, 200)

    def kill(self):
        selectgroup.empty()

    def run(self):
        while not self.selected:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_j:
                        pass
                    elif event.key == pygame.K_a:
                        if self.hero_index == self.first_index:
                            break
                        self.select_frame.move('LEFT')
                        self.hero_index -= 1
                        self.intro_fram.set_animation(self.hero_index)
                    elif event.key == pygame.K_d:
                        if self.hero_index == self.last_index:
                            break
                        self.hero_index += 1
                        self.select_frame.move('RIGHT')
                        self.intro_fram.set_animation(self.hero_index)
                    elif event.key == pygame.K_RETURN:  #語句中的retur居然也會觸發這個,隻好改用break
                        self.selected = True
                    #ESC 退出
                    elif event.key == pygame.K_ESCAPE or event.key == pygame.K_F4:
                        pygame.quit()
                        exit()
            selectgroup.update()
            selectgroup.draw(self.main_scene)
            pygame.display.update()
           

運作效果如下:

pygame飛機大戰用精靈組層編寫英雄系列(一)英雄也問出處,界面的菜單選擇

libpng warning:icpp……這個錯誤提示,用ImageMagick Display這個軟體,轉換一下圖像就可以解決問題了。

附上下載下傳連結

https://gitee.com/hailler/hero/tree/master

繼續閱讀