Pygame:运行两次函数时运动停止

时间:2016-04-28 09:21:12

标签: python-2.7 pygame collision

我目前正在开展一个小项目。我期待创建一个基本的RPG来习惯Python 2.7.1中的类。我正在使用Pygame。我目前编写了一个基于点击的移动系统,并以玩家精灵为中心(固定在显示屏的中心)。希望模仿暗黑破坏神II系统。

可以在此WeTransfer链接中找到运行该程序的所有文件: Program Files

运动基础知识: 在主循环的每次迭代中,我运行下面的get_offset(字符,事件)函数,如果检测到MOUSEBUTTONDOWN事件,那么只有这样才能为我提供ax和y偏移量以及达到该函数所需的一些“步骤”。 destination(点击时鼠标位置下的地图区域)。

在每个循环中重复x和y偏移,直到玩家再次点击或“步数”下降到0,在这种情况下,偏移设置为0(玩家停止)。

get_offset函数如下:

def get_offset(character,event):
    if event.type == MOUSEBUTTONDOWN:
        print 'reset'
        m_pos = pygame.mouse.get_pos() #mouse position tracker
        variables.player_dest_pos = m_pos
        speed = character.speed #player's speed

        xp = (variables.screenWIDTH/2)
        yp = (variables.screenHEIGHT/2)
        #print xp,yp
        xm = m_pos[0]-10 #adds offset to center player
        ym = m_pos[1]-5

        dx= xm-xp
        dy= float(ym-yp) 

        dist = (dx**2+dy**2)**0.5 #get lenght to travel

        #sets number of steps/loops needed to reach destination
        steps = dist/speed #float
        steps = int(dist)/speed #int        

        #calculates angle and sets quadrant
        if dx == 0 or dy == 0:
            angle_rad = 0
            if dx == 0 and ym > yp:
                xoffset = 0
                yoffset = -speed
            elif dx == 0 and ym < yp:
                xoffset = 0
                yoffset = speed
            elif dy == 0 and xm > xp:
                xoffset = 0
                yoffset = -speed
            elif dy == 0 and xm < xp:
                xoffset = 0
                yoffset = speed
            else:
                xoffset, yoffset = 0,0
        elif xm > xp and ym > yp:
            angle_rad = np.arctan((abs(dy)/abs(dx)))
            xoffset = -np.cos(angle_rad)*speed
            yoffset = -np.sin(angle_rad)*speed
        elif xm < xp and ym > yp:
            angle_rad = np.arctan((abs(dx)/abs(dy)))
            xoffset = -np.cos(angle_rad)*speed
            yoffset = -np.sin(angle_rad)*speed
        elif xm < xp and ym < yp:
            angle_rad = np.arctan((abs(dy)/abs(dx)))
            xoffset = np.cos(angle_rad)*speed
            yoffset = np.sin(angle_rad)*speed
        else:# xm > xp and ym < yp:
            angle_rad = np.arctan((abs(dx)/abs(dy)))
            xoffset = -np.sin(angle_rad)*speed
            yoffset =  np.cos(angle_rad)*speed

        #sets the values to global accessible in the 'variables' module       
        variables.xoffset = xoffset
        variables.yoffset = yoffset

        variables.offset_time = steps

然后我创建了一个具有以下移动方法的敌人精灵:

 def move(self,event):#,mouse_pos, screen, background
    if event.type == MOUSEBUTTONDOWN:
        self.dest = (random.randint(0,600),random.randint(0,480))
    if self.dest[0] > self.rect[0]:
        variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg 
        variables.move_speed = self.speed
        self.move_EW() #moves player
        variables.screen.blit(self.image, self.rect) #draws player
    if self.dest[0] < self.rect[0]:
        variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg 
        variables.move_speed = -self.speed
        self.move_EW() #moves player
        variables.screen.blit(self.image, self.rect) #draws player  
    if self.dest[1] < self.rect[1]:
        variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg 
        variables.move_speed = -self.speed
        self.move_NS() #moves player
        variables.screen.blit(self.image, self.rect) #draws player
    if self.dest[1] > self.rect[1]:
        variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg 
        variables.move_speed = self.speed
        self.move_NS() #moves player
        variables.screen.blit(self.image, self.rect) #draws player 

def move_NS(self):
    self.rect = self.rect.move(0, variables.move_speed)
    if self.rect.top < 0:
        self.rect.bottom = 480
    if self.rect.bottom > 480:
        self.rect.top = 0
    # Check for Collisions
    for obstacle in variables.building_list:
        if pygame.sprite.collide_rect(self, obstacle):
            #print 'collide'
            self.rect = self.rect.move(0, -(variables.move_speed))


def move_EW(self):
    self.rect = self.rect.move(variables.move_speed , 0)
    if self.rect.right > 600:
        self.rect.left = 0
    if self.rect.left < 0:
        self.rect.left = 600
    # Check for Collisions
    for obstacle in variables.building_list:
        if pygame.sprite.collide_rect(self, obstacle):
            #print 'collide'
            self.rect = self.rect.move(-(variables.move_speed) , 0)

此精灵的移动基本上与其他任何东西无关。

然后我在group_offset(组,字符)函数中编码,该函数能够将get_offset偏移量添加到组中的任何精灵中,以使游戏中的任何精灵相对于玩家“移动”(因此适用)对于静态对象。)它还检查组中的任何元素是否使用局部变量test_rect与播放器冲突,如果发生冲突,则偏移量在两个方向上都设置为0。如果没有发生碰撞,则精灵移动偏移值。

def group_offset(group,character):
    for sprite in group: #checks if sprite collide with character using test_rect
        test_rect = Rect(sprite.rect)
        if variables.offset_time  > 0:
            test_rect = test_rect.move(variables.xoffset,variables.yoffset)
            if test_rect.colliderect(character.rect):
                variables.xoffset, variables.yoffset = 0,0
    #if no collision occurs moves the sprites in the group            
    if variables.xoffset != 0 and variables.yoffset != 0:
        for sprite in group:
            if variables.offset_time  > 0:
                sprite.rect = sprite.rect.move(variables.xoffset,variables.yoffset)

当我使用组偏移功能两次,一次用于我的建筑物,一次用于我的敌人时,我的问题就出现了。当我这样做时,我的英雄在看起来只有一个“步骤”之后停止移动。

第一次通话结束后一切正常,英雄一直移动到达目的地。

当我再次使用group_offset(variables.ennemi_list,hero)调用它时。 然后我的播放器在一步后停止。

我最初认为我的敌人精灵在检查与我的建筑物碰撞而不是我的玩家,但是正如你可以看到呼叫是与玩家(英雄)进行的,因此它应该只检测到碰撞并在我的时候停止运动玩家击中一个建筑物(从第一次通话开始)或敌人......

任何帮助都会有所帮助,因为我真的不知道为什么会发生这个错误。我试过评论很多东西,看起来问题似乎来自这行代码:group_offset(variables.ennemi_list,hero)。

这是我的带有游戏循环的main.py脚本:

导入pygame,sys,变量 来自pygame.locals import * 从类导入* 来自实例导入* 来自函数import *

#game loop    
while True:
    variables.screen.fill((0,0,0)) #make background black for map edges
    for event in pygame.event.get(): #setting up quit
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    get_offset(hero,event) # sets the movement offset for the iteration

    for o in variables.char_list: 
        if isinstance(o, Character): #moves characters
            o.move(event)
        if isinstance(o, Ennemi): #performs attack when enemmi is clicked and in contact
            if pygame.sprite.collide_rect(o,hero) == True:
                hero.attack(sword,o)

    group_offset(variables.building_list,hero) #new building position using offset
    scroll_map.offset() #offsets grass background map

    variables.screen.blit(scroll_map.image, scroll_map.rect) # blits the grass map to new pos
    variables.building_list.draw(variables.screen) #blits the buildings to new pos
    variables.screen.blit(hero.image, hero.rect) #blits hero to screen center

    #group_offset(variables.ennemi_list,hero)
    for o in variables.ennemi_list:
        variables.screen.blit(o.image, o.rect)
    pygame.display.update()
    pygame.time.delay(10)
    variables.offset_time -= 1 #removes on step from the offset counter to keep track of when
    #offset needs to be reset to 0, i.e. position is reached

0 个答案:

没有答案