当前位置: 首页 > 科技观察

如何将敌人

时间:2023-03-15 23:16:44 科技观察

添加到您的Python游戏中在本系列的第五部分中,学习如何添加一个坏人来对抗您的好人。在本系列的前几篇文章中(见***部分、第二部分、第三部分和第四部分),您已经学习了如何使用Pygame和Python生成一个可玩的角色。但是,如果没有恶棍,英雄会怎样呢?如果你没有敌人,这将是一个非常无聊的游戏。因此,在本文中,您将向游戏中添加一个敌人并构建一个用于创建关卡的框架。在玩家精灵上实现完整功能之前实现敌人似乎很奇怪。但是你学到了很多东西,创造反派与创造玩家地精非常相似。所以放轻松,用你已经知道的,看看你能激起什么样的麻烦。对于本练习,您可以从OpenGameArt下载一些预制资产。以下是我使用的一些资产:Incatiles(LCTT译注:游戏中使用的Tiletextures)一些入侵者sprite、角色、对象和效果来创建敌人sprite是的,你已经知道了,不管你是否意识到如何成就敌人。该过程与创建玩家精灵非常相似:创建一个用于生成敌人的类创建一个更新方法以使敌人能够检测到碰撞创建一个移动方法以使敌人能够四处游荡从该类开始。从概念上讲,它与您的Player类非常相似。您设置一张图片或一组图片,然后设置小妖精的初始位置。在继续下一步之前,确保你有敌人的图像,即使它只是一个临时图像。将图像放在游戏项目的图像目录中(与放置玩家图像的目录相同)。如果所有生物都有动画,游戏看起来会好得多。为敌方精灵设置动画与为玩家精灵设置动画的方式相同。但是现在,为了简单起见,我们使用没有动画的精灵。在代码的对象部分的顶部,使用以下代码创建一个名为Enemy的类:classEnemy(pygame.sprite.Sprite):'''Spawnanenemy'''def__init__(self,x,y,img):pygame.sprite.Sprite.__init__(self)self.image=pygame.image.load(os.path.join('images',img))self.image.convert_alpha()self.image.set_colorkey(ALPHA)self.rect=self.image.get_rect()self.rect.x=xself.rect.y=y如果你想让你的敌人动起来,使用和你的玩家动起来一样的方法。产生一个敌人你可以通过告诉班级小妖精应该使用哪个图像以及它应该出现在世界的什么地方来产生多个敌人。这意味着您可以使用相同的敌人类别在游戏世界的任何地方生成任意数量的敌人精灵。您需要做的就是调用此类并告诉它要使用哪个图像以及要生成的点的X和Y坐标。同样,这在原则上类似于生成玩家精灵。在脚本的设置部分添加以下代码:enemy=Enemy(20,200,'yeti.png')#生成敌人enemy_list=pygame.sprite.Group()#创建敌人组enemy_list.add(enemy)#添加敌人到敌人组在示例代码中,X坐标为20,Y坐标为200。您可能需要根据敌人精灵的大小调整这些数字,但尽量在玩家精灵可以触及的区域生成。Yeti.png是用于敌人的图像。接下来,在屏幕上画出敌群的所有敌人。现在,你只有一个敌人,如果你想要更多,你可以稍后添加。一旦你将一个敌人添加到敌人组中,它就会在主循环中被绘制到屏幕上。中间一行是你需要添加的新行:选择X和Y坐标。一级您的游戏仍处于起步阶段,但您可能想为其添加另一个级别。为你的程序的未来做计划很重要,因为随着你学习更多的编程技能,你的程序也会随之成长。即使您还没有一个完整的关卡,您也应该假设会有很多关卡。想想什么是“水平”。你怎么知道你在游戏中处于特定级别?您可以将关卡视为项目的集合。就像您刚刚创建的平台一样,一个关卡由平台的特定排列、敌人放置、战利品等组成。您可以创建一个类来围绕您的玩家创建关卡。最终,当您创建多个关卡时,您可以使用此类在玩家达到特定目标时生成下一个关卡。将您为生成敌人及其组而编写的代码移动到一个新函数中,每次生成新关卡时都会调用该函数。您需要进行一些更改,以便每次创建新关卡时都能创建一些敌人。classLevel():defbad(lvl,eloc):iflvl==1:enemy=Enemy(eloc[0],eloc[1],'yeti.png')#生成敌人enemy_list=pygame.sprite.Group()#生成敌人列表enemy_list.add(enemy)#添加敌人到敌人列表iflvl==2:print("Level"+str(lvl))returnenemy_listreturn语句确保当你调用Level.bad方法时,你会得到一个enemy_list变量,其中包含你定义的所有敌人。由于您现在将在每个关卡中创建敌人,因此您的设置部分也需要进行一些更改。您不必创建敌人,而是必须定义敌人产生的位置以及敌人所属的级别。eloc=[]eloc=[200,20]enemy_list=Level.bad(1,eloc)再次运行游戏以确保正确生成关卡。像往常一样,您应该可以看到您的玩家,并且能够看到您在本章中添加的敌人。痛击敌人如果敌人对玩家没有影响,那么它就不是真正的敌人。当玩家与敌人发生碰撞时,他们通常会对玩家造成伤害。由于您可能想要跟踪玩家的健康状况,因此碰撞检测发生在Player类中,而不是Enemy类中。当然,如果你愿意,你也可以追踪敌人的健康状况。它们之间的逻辑和代码大多相似,目前,我们只需要跟踪玩家的健康状况。为了跟踪玩家的健康状况,您必须为其定义一个变量。代码示例中的第一行是上下文提示,因此将第二行代码添加到您的Player类中:self.frame=0self.health=10在您的Player类的更新方法中,添加以下代码块:hit_list=pygame.sprite.spritecollide(self,enemy_list,False)forenemyinhit_list:self.health-=1print(self.health)此代码使用Pygame的sprite.spritecollide方法创建一个名为Makeenemy_hit的碰撞检测器。每当其父精灵(生成检测器的玩家精灵)的碰撞区域触及enemy_list中任何精灵的碰撞区域时,碰撞检测器都会发出信号。收到此信号后,将触发for循环并扣除玩家的生命值。一旦此代码位于您的Player类的更新方法中,并且在您的主循环中调用了更新方法,Pygame将在每个时钟滴答声中检测到碰撞。移动的敌人如果您愿意,静止的敌人也很有用,例如可以伤害玩家的尖刺和陷阱。但如果敌人可以四处游荡,游戏就会更具挑战性。与玩家地精不同,敌方地精不受玩家控制,因此必须自动移动。最终,您的游戏世界将会滚动。那么,如何让游戏世界中的敌人在游戏世界本身滚动的同时来回移动呢?例如,你告诉你的敌人地精向右移动10步,向左移动10步。但是敌人的哥布林不算,所以你需要创建一个变量来跟踪你的敌人移动了多少步,并根据计数变量的值向左或向右移动你的敌人。首先,在Enemy类中创建计数变量。添加以下代码示例中的最后一行代码:self.rect=self.image.get_rect()self.rect.x=xself.rect.y=yself.counter=0#countvariable然后,在您的CreateEnemy类中的移动方法。使用if-else循环创建一个所谓的无限循环:如果计数在0到100之间,则向右移动;否则向右移动。如果计数在100到200之间,则向左移动;如果计数大于200,则将计数清零。无限循环是没有尽头的,因为循环判断条件永远为真,所以会一直循环下去。在这种情况下,计数器始终介于0和100或100和200之间,因此敌人总是从左向右移动,然后从右向左移动。敌人在每个方向移动多远所使用的确切值取决于屏幕的大小,更准确地说,是敌人移动的平台的大小。从较小的值开始,并在您习惯后逐渐增加该值。首先尝试以下操作:defmove(self):'''Enemymoves'''distance=80speed=8ifself.counter>=0andself.counter<=distance:self.rect.x+=speedelifself.counter>=distanceandself.counter<=distance*2:self.rect.x-=speedelse:self.counter=0self.counter+=1您可以根据需要调整距离和速度。当您现在开始游戏时,此代码是否有效?当然不是,你应该知道为什么。您必须在主循环中调用move方法。下面示例代码中的第一行是一个上下文提示,所以添加前两行代码:发生在敌人身上。您可能需要调整地精生成的位置,以便您的玩家和敌人发生碰撞。当它们发生碰撞时,查看IDLE或Ninja-IDE的控制台,您可以看到正在扣除健康。您应该已经注意到,当您的玩家与敌人接触时,会不时扣除生命值。这是一个问题,但在使用Python进行更多练习后,您将解决它。现在,尝试添加更多敌人。请记住将每个敌人添加到enemy_list。作为练习,看看你是否能想到如何改变不同敌方地精的移动距离。