在arcade游戏编程中的碰撞精灵消失问题,敌人子弹打中角色后,如有多个子弹,坦克的消失问题分析,动画爆炸效果的实现及过程中注意事项及错误试验分析
失败代码:
if self.enemy_reset:# 重置坦克及子弹# for dr in self.scene[LAYER_tanks]:# dr.remove_from_sprite_lists()# for zd in self.scene[LAYER_bullet]:# zd.remove_from_sprite_lists()## if len(self.scene[LAYER_tanks])>0:# print('重清空坦克')# for dr in self.scene[LAYER_tanks]:# dr.remove_from_sprite_lists()## if len(self.scene[LAYER_bullet])>0:# print('重清空')# for zd in self.scene[LAYER_bullet]:# zd.remove_from_sprite_lists()
在update,draw中都会出现此问题,通过查看scene原码
发现其有个remove_sprite_list_by_name函数,得以解决
def remove_sprite_list_by_name(
self,
name: str,
) -> None:
“”"
Remove a SpriteList by it’s name.
This function serves to completely remove the SpriteList from the Scene.:param str name: The name of the SpriteList to remove."""sprite_list = self.name_mapping[name]self.sprite_lists.remove(sprite_list)del self.name_mapping[name]
if self.enemy_reset:# 重置坦克及子弹# for dr in self.scene[LAYER_tanks]:# dr.remove_from_sprite_lists()# for zd in self.scene[LAYER_bullet]:# zd.remove_from_sprite_lists()## if len(self.scene[LAYER_tanks])>0:# print('重清空坦克')# for dr in self.scene[LAYER_tanks]:# dr.remove_from_sprite_lists()## if len(self.scene[LAYER_bullet])>0:# print('重清空')# for zd in self.scene[LAYER_bullet]:# zd.remove_from_sprite_lists()self.scene.remove_sprite_list_by_name(LAYER_bullet)self.scene.remove_sprite_list_by_name(LAYER_tanks)self.scene.add_sprite_list_after(LAYER_bullet, 'wj')self.scene.add_sprite_list_after(LAYER_tanks, 'wj')print('清空后',len(self.scene[LAYER_bullet]))print('清空后坦克',len(self.scene[LAYER_tanks]))self.setup_enemy()self.enemy_reset = Falsereturnelse:self.scene.draw() # 摄相机与scence的顺序不能放错,否则不会移动for aa in self.scene[LAYER_tanks]:aa.draw_word(aa.left, aa.top + 20)
def on_draw(self):self.clear()self.camera.use() # 摄象机# if self.enemy_reset:# # 重置坦克及子弹# self.scene.remove_sprite_list_by_name(LAYER_bullet)# self.scene.remove_sprite_list_by_name(LAYER_tanks)# self.scene.add_sprite_list_after(LAYER_bullet, 'wj')# self.scene.add_sprite_list_after(LAYER_tanks, 'wj')# self.setup_enemy()# self.enemy_reset = False# else:self.scene.draw() # 摄相机与scence的顺序不能放错,否则不会移动for aa in self.scene[LAYER_tanks]:aa.draw_word(aa.left, aa.top + 20)
def on_update(self, delta_time: float):self.physics_engine.update() # 运用引擎移动角色self.collision_all()self.update_remind()self.scene['wj'].update()if self.enemy_reset:# 重置坦克及子弹self.scene.remove_sprite_list_by_name(LAYER_bullet)self.scene.remove_sprite_list_by_name(LAYER_tanks)self.scene.add_sprite_list_after(LAYER_bullet, 'wj')self.scene.add_sprite_list_after(LAYER_tanks, 'wj')self.setup_enemy()self.enemy_reset = Falseself.scene[LAYER_bullet].update()self.scene[LAYER_explosions].update()
最终先确定放在碰撞中吧
# 碰撞检测def collision_all(self):self.collision_bullet_enemy()self.collision_bullet_player()if self.enemy_reset:# 重置坦克及子弹self.scene.remove_sprite_list_by_name(LAYER_bullet)self.scene.remove_sprite_list_by_name(LAYER_tanks)self.scene.add_sprite_list_after(LAYER_bullet, 'wj')self.scene.add_sprite_list_after(LAYER_tanks, 'wj')self.setup_enemy()self.enemy_reset = False
# 爆炸动画
class Explosion(arcade.Sprite):""" 爆炸动画 """def __init__(self, texture_list):super().__init__()#开始的第一幁self.current_texture = 0self.textures = texture_listdef update(self):# 更新到动画的下一帧。如果我们到了终点,然后删除这个精灵。self.current_texture += 1if self.current_texture < len(self.textures):self.set_texture(self.current_texture)else:self.remove_from_sprite_lists()
# 爆炸self.setup_explosion_piclist()self.explosions_list = arcade.SpriteList()同时在ondraw中增加self.explosions_list.draw()
# 爆炸(动画效果)def baozha(self,hit_list):# 制造爆炸explosion = Explosion(self.explosion_texture_list)# 位置explosion.center_x = hit_list[0].center_xexplosion.center_y = hit_list[0].center_y# 更新爆炸explosion.update()# 添加列表self.explosions_list.append(explosion)for cc in hit_list:if (self.scene[LAYER_tanks] in cc.sprite_lists):# 磁撞的是敌人 根据子弹伤害及敌人生命值确定争分数及消失cc.remove_from_sprite_lists()# 声音arcade.play_sound(self.hit_sound1)# 爆炸效果self.baozha(hit_list)
增加# 调用更新
self.scene[LAYER_bullet_player].update()
self.explosions_list.update()
这句很关健
def collision_bullet_player(self):# 调用更新***self.scene[LAYER_bullet_player].update()self.explosions_list.update()***# 子弹的碰撞检测for bullet in self.scene[LAYER_bullet_player]:hit_list = arcade.check_for_collision_with_lists(bullet,[self.scene[LAYER_tanks],# self.scene[LAYER_tree],self.scene['建筑物'],],)if hit_list:bullet.remove_from_sprite_lists()for cc in hit_list:if (self.scene[LAYER_tanks] in cc.sprite_lists):# 磁撞的是敌人 根据子弹伤害及敌人生命值确定争分数及消失cc.remove_from_sprite_lists()# 声音arcade.play_sound(self.hit_sound1)# 爆炸效果self.baozha(hit_list)if cc.hz == self.key:self.score += 100self.wanjia.bullets +=5self.enemy_reset = Trueelse:self.wanjia.life -= 2print('打错了')if (self.scene['建筑物'] in cc.sprite_lists):# 磁撞的是建筑物, 制造爆炸for i in range(20):particle = Particle(self.scene[LAYER_explosions])particle.position = cc.position # 粒子位置,也即敌人位置self.scene[LAYER_explosions].append(particle)smoke = Smoke(30)smoke.position = cc.position # 烟雾位置self.scene[LAYER_explosions].append(smoke)cc.remove_from_sprite_lists()# 爆炸声音arcade.sound.play_sound(self.hit_sound2)return# 如过子弹超过屏幕则删掉.if (bullet.right < 0) or (bullet.bottom > SCREEN_height) or (bullet.left > (self.tile_map.width * self.tile_map.tile_width) * TILE_Scaling) :bullet.remove_from_sprite_lists()
可关注博主后,私聊博主免费获取
需要技术指导,育娃新思考,企业软件合作等更多服务请联系博主
今天是以此模板持续更新此育儿专栏的第 29/50次。
可以关注我,点赞我、评论我、收藏我啦。