前言:
BOSS系列写完了,还可以增加些BOSS子弹的发射方式,例如螺旋线,就是把射击的间隔缩短,每颗子弹按照时间间隔发射,每次的发射角度在前次上递增。看起来就是螺旋线发射了。
我的代码发射的子弹和发射的方式有点乱,只是为了展示效果,真正要好玩,还得细化,把子弹和发射方式控制一下,有简单到难。代码有些地方冗余,可以简化,这些工作,等有空在慢慢调试。
接下来写点英雄系列的日志吧。
在BOSS系列里,英雄出师未捷身先死,一点英雄气概也没看到,完全是个我躲,我躲,我躲的闪客。
那就给英雄写点吧。
还得从选择界面进入英雄系列。
本来想用文字的,网上的成熟的代码很多,功能很强大,可是还是想自己码一个。简单的,不抽象的。
实现要求如下:
1、在启动主程序前,期待选择界面,里面有四架英雄飞机可以选择(因为我只有四架飞机的素材),可以通过左右按键(a,d)来选。
2、选择过程中,能看到所选英雄飞机的基本信息,动态图像。
3、选择完成后,出现主界面,飞机角色为所选角色。
游戏界面选择框架如下:selectmenu.py
1、初始化四家飞机
2、初始化选择框
3、初始化动态显示框
4、初始化默认飞机基本信息
因为界面退出后,没有什么用了,重置self.kill()
建立一个循环,用于处理选择的步骤 。
选择完成,在main.py里保存飞机信息
selectmenu里的所有精灵self.kill()自毁
先新建一个类SelectMenu。用来设置飞机图像和选择框,选择框也是一个图像,比飞机图像开框大些,飞机位置透明。
中心对齐后看起来就像是套在上面。
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这个软件,转换一下图像就可以解决问题了。
附上下载链接