前言:
BOSS系列寫完了,還可以增加些BOSS子彈的發射方式,例如螺旋線,就是把射擊的間隔縮短,每顆子彈按照時間間隔發射,每次的發射角度在前次上遞增。看起來就是螺旋線發射了。
我的代碼發射的子彈和發射的方式有點亂,隻是為了展示效果,真正要好玩,還得細化,把子彈和發射方式控制一下,有簡單到難。代碼有些地方備援,可以簡化,這些工作,等有空在慢慢調試。
接下來寫點英雄系列的日志吧。
在BOSS系列裡,英雄出師未捷身先死,一點英雄氣概也沒看到,完全是個我躲,我躲,我躲的閃客。
那就給英雄寫點吧。
還得從選擇界面進入英雄系列。
本來想用文字的,網上的成熟的代碼很多,功能很強大,可是還是想自己碼一個。簡單的,不抽象的。
實作要求如下:
1、在啟動主程式前,期待選擇界面,裡面有四架英雄飛機可以選擇(因為我隻有四架飛機的素材),可以通過左右按鍵(a,d)來選。
2、選擇過程中,能看到所選英雄飛機的基本資訊,動态圖像。
3、選擇完成後,出現主界面,飛機角色為所選角色。
遊戲界面選擇架構如下:selectmenu.py
1、初始化四家飛機
2、初始化選擇框
3、初始化動态顯示框
4、初始化預設飛機基本資訊
因為界面退出後,沒有什麼用了,重置self.kill()
建立一個循環,用于處理選擇的步驟 。
選擇完成,在main.py裡儲存飛機資訊
selectmenu裡的所有精靈self.kill()自毀
先建立一個類SelectMenu。用來設定飛機圖像和選擇框,選擇框也是一個圖像,比飛機圖像開框大些,飛機位置透明。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL4QDOzQDO0AjM1ADNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
中心對齊後看起來就像是套在上面。
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()
運作效果如下
加入一些文字說明,加入資訊提示。完整代碼如下:
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()
運作效果如下:
libpng warning:icpp……這個錯誤提示,用ImageMagick Display這個軟體,轉換一下圖像就可以解決問題了。
附上下載下傳連結
https://gitee.com/hailler/hero/tree/master