pygame-通过平台的玩家

时间:2020-09-14 22:50:09

标签: python pygame collision platform

我正在使用pygame开发平台游戏。 因此,我有那些平台,而我想做的就是,当我按下向下箭头或S键时,玩家会跌倒平台。我只是想不通正确的方法。如果有人有任何示例,或者您可以帮助我,请在此处提供主要代码:

class Player:
def __init__(self, x, y):
    self.entity = e.entity(x, y, 14, 29, 'player')
    self.movingRight = False
    self.movingLeft = False
    self.momentum = 0
    self.airTimer = 0
    self.movement = [0,0]
    self.platformCollision = False
    self.onPlatform = False
    self.through = False
    self.levelOver = False

def events(self, event, dt):
    if event.type == KEYDOWN:
        if event.key == K_RIGHT:
            self.movingRight = True
        if event.key == K_d:
            self.movingRight = True
        if event.key == K_LEFT:
            self.movingLeft = True
        if event.key == K_a:
            self.movingLeft = True
        if event.key == K_UP:
            if self.airTimer == 0:
                self.momentum = -5
        if event.key == K_w:
            if self.airTimer == 0:
                self.momentum = -5
        if event.key == K_DOWN:
            self.through = not self.through
        if event.key == K_s:
            self.through = not self.through

    if event.type == KEYUP:
        if event.key == K_RIGHT:
            self.movingRight = False
        if event.key == K_d:
            self.movingRight = False
        if event.key == K_LEFT:
            self.movingLeft = False
        if event.key == K_a:
            self.movingLeft = False

def update(self, tile_rects, enemiesList, movingList, notCollisionable, screen, scroll, dt, distance):
    self.movement = [0,0]
    if self.movingRight == True:
        self.movement[0] += 300 * dt
    if self.movingLeft == True:
        self.movement[0] -= 300 * dt
    self.movement[1] += self.momentum*2.4
    self.momentum += 20 * dt
    if self.momentum > 5:
        self.momentum = 5

    if self.movement[0] == 0:
        self.entity.set_action('idle')
    elif self.movement[0] > 0:
        self.entity.set_flip(False)
        self.entity.set_action('run')
    elif self.movement[0] < 0:
        self.entity.set_flip(True)
        self.entity.set_action('run')

    collisionList = self.entity.move(self.movement, tile_rects, enemiesList, movingList, notCollisionable, self.airTimer)

    exitData = [False, False]

    for platform in collisionList['data']:
        if platform[1][3]:
            self.airTimer = 0
            self.momentum = 0
            self.platformCollision = False
        else:
            self.airTimer = 0
            self.platformCollision = False
        if platform[2] == 'horizontal':
            self.entity.obj.x += distance
        if platform[2] == "static":
            self.onPlatform = True
        if platform[2] == 'throughMiddle':
            if self.through:
                #HERE IS WHERE I DONT KNOW WHAT TO DO
                pass

        else:
            self.onPlatform = False
        if platform[2] == "spikeTop":
            exitData[0] = True
        if platform[2] == "endBall":
            self.levelOver = True
            exitData[1] = True

    if not collisionList['bottom']:
        self.airTimer += 1

    self.entity.changeFrame(1)
    self.entity.display(screen, scroll)
    return exitData

以下是处理实体类的引擎部分:

class entity(object):
global animation_database, animation_higher_database

def __init__(self,x,y,size_x,size_y,e_type): # x, y, size_x, size_y, type
    self.x = x
    self.y = y
    self.size_x = size_x
    self.size_y = size_y
    self.obj = physics_obj(x,y,size_x,size_y)
    self.animation = None
    self.image = None
    self.animation_frame = 0
    self.animation_tags = []
    self.flip = False
    self.offset = [0,0]
    self.rotation = 0
    self.type = e_type # used to determine animation set among other things
    self.action_timer = 0
    self.action = ''
    self.set_action('idle') # overall action for the entity
    self.entity_data = {}
    self.alpha = None

def set_pos(self,x,y):
    self.x = x
    self.y = y
    self.obj.x = x
    self.obj.y = y
    self.obj.rect.x = x
    self.obj.rect.y = y

def move(self,momentum,platforms,ramps=[], platRects=[], vertRects=[], airTimer=0):
    collisions = self.obj.move(momentum,platforms,ramps, platRects, vertRects, airTimer)
    self.x = self.obj.x
    self.y = self.obj.y
    return collisions

def rect(self):
    return pygame.Rect(self.x,self.y,self.size_x,self.size_y)

def set_flip(self,boolean):
    self.flip = boolean

def set_animation_tags(self,tags):
    self.animation_tags = tags

def set_animation(self,sequence):
    self.animation = sequence
    self.animation_frame = 0

def set_action(self,action_id,force=False):
    if (self.action == action_id) and (force == False):
        pass
    else:
        self.action = action_id
        anim = animation_higher_database[self.type][action_id]
        self.animation = anim[0]
        self.set_animation_tags(anim[1])
        self.animation_frame = 0

def get_entity_angle(entity_2):
    x1 = self.x+int(self.size_x/2)
    y1 = self.y+int(self.size_y/2)
    x2 = entity_2.x+int(entity_2.size_x/2)
    y2 = entity_2.y+int(entity_2.size_y/2)
    angle = math.atan((y2-y1)/(x2-x1))
    if x2 < x1:
        angle += math.pi
    return angle

def get_center(self):
    x = self.x+int(self.size_x/2)
    y = self.y+int(self.size_y/2)
    return [x,y]

def clear_animation(self):
    self.animation = None

def set_image(self,image):
    self.image = image

def set_offset(self,offset):
    self.offset = offset

def set_frame(self,amount):
    self.animation_frame = amount

def handle(self):
    self.action_timer += 1
    self.change_frame(1)

def changeFrame(self,amount):
    self.animation_frame += amount
    if self.animation != None:
        while self.animation_frame < 0:
            if 'loop' in self.animation_tags:
                self.animation_frame += len(self.animation)
            else:
                self.animation = 0
        while self.animation_frame >= len(self.animation):
            if 'loop' in self.animation_tags:
                self.animation_frame -= len(self.animation)
            else:
                self.animation_frame = len(self.animation)-1

def get_current_img(self):
    if self.animation == None:
        if self.image != None:
            return flip(self.image,self.flip)
        else:
            return None
    else:
        return flip(animation_database[self.animation[self.animation_frame]],self.flip)

def get_drawn_img(self):
    image_to_render = None
    if self.animation == None:
        if self.image != None:
            image_to_render = flip(self.image,self.flip).copy()
    else:
        image_to_render = flip(animation_database[self.animation[self.animation_frame]],self.flip).copy()
    if image_to_render != None:
        center_x = image_to_render.get_width()/2
        center_y = image_to_render.get_height()/2
        image_to_render = pygame.transform.rotate(image_to_render,self.rotation)
        if self.alpha != None:
            image_to_render.set_alpha(self.alpha)
        return image_to_render, center_x, center_y

def display(self,surface,scroll):
    image_to_render = None
    if self.animation == None:
        if self.image != None:
            image_to_render = flip(self.image,self.flip).copy()
    else:
        image_to_render = flip(animation_database[self.animation[self.animation_frame]],self.flip).copy()
    if image_to_render != None:
        center_x = image_to_render.get_width()/2
        center_y = image_to_render.get_height()/2
        image_to_render = pygame.transform.rotate(image_to_render,self.rotation)
        if self.alpha != None:
            image_to_render.set_alpha(self.alpha)
        blit_center(surface,image_to_render,(int(self.x)-scroll[0]+self.offset[0]+center_x,int(self.y)-scroll[1]+self.offset[1]+center_y))

以及处理碰撞的功能:

class physics_obj(object):

def __init__(self,x,y,x_size,y_size):
    self.width = x_size
    self.height = y_size
    self.rect = pygame.Rect(x,y,self.width,self.height)
    self.x = x
    self.y = y
    self.prevX = 0

def move(self, movement, tiles, enemiesList=[], movingList=[], notCollisionable=[], airTimer=0):
    #tile_rects, enemiesList, movingList, notCollisionable
    self.x += movement[0]
    self.rect.x = int(self.x)

    collision_types = {'top':False,'bottom':False,'right':False,'left':False,'slant_bottom':False,'data':[]}
    # added collision data to "collision_types". ignore the poorly chosen variable name
    #====================================================================
    block_hit_list = collision_test(self.rect, tiles)
    for block in block_hit_list:
        type = "tile"
        markers = [False,False,False,False]
        if movement[0] > 0:
            self.rect.right = block.left
            collision_types['right'] = True
            markers[0] = True
        elif movement[0] < 0:
            self.rect.left = block.right
            collision_types['left'] = True
            markers[1] = True
        collision_types['data'].append([block,markers, type])
        self.x = self.rect.x
    self.y += movement[1]
    self.rect.y = int(self.y)
    block_hit_list = collision_test(self.rect,tiles)
    for block in block_hit_list:
        type = "tile"
        markers = [False,False,False,False]
        if movement[1] > 0:
            self.rect.bottom = block.top
            collision_types['bottom'] = True
            markers[2] = True
        elif movement[1] < 0:
            self.rect.top = block.bottom
            collision_types['top'] = True
            markers[3] = True
        collision_types['data'].append([block,markers, type])
        self.change_y = 0
        self.y = self.rect.y
    #====================================================================
    block_hit_list = movingCollision(self.rect, movingList)
    for block in block_hit_list:
        type = block.type
        markers = [False,False,False,False]
        tol = abs(self.rect.bottom - block.entity.obj.rect.top)
        if movement[1] > 0 and tol < 16:
            self.rect.bottom = block.entity.obj.rect.top
            collision_types['bottom'] = True
            markers[2] = True
        collision_types['data'].append([block.entity.obj.rect,markers, type])
        self.change_y = 0
        self.y = self.rect.y
    #====================================================================
    block_hit_list = movingCollision(self.rect, enemiesList)
    for block in block_hit_list:
        type = block.type
        markers = [False,False,False,False]
        if movement[0] > 0:
            self.rect.right = block.entity.obj.rect.left
            collision_types['right'] = True
            markers[0] = True
        elif movement[0] < 0:
            #self.rect.left = block.entity.obj.rect.right
            collision_types['left'] = True
            markers[1] = True
        elif movement[1] > 0:
            #self.rect.bottom = block.entity.obj.rect.top
            collision_types['bottom'] = True
            markers[2] = True
        elif movement[1] < 0:
            #self.rect.top = block.entity.obj.rect.bottom
            collision_types['top'] = True
            markers[3] = True
        collision_types['data'].append([block.entity.obj.rect,markers, type])
    #====================================================================
    block_hit_list = movingCollision(self.rect, notCollisionable)
    for block in block_hit_list:
        type = block.type
        markers = [False,False,False,False]
        if movement[0] > 0:
            collision_types['right'] = True
            markers[0] = True
        elif movement[0] < 0:
            #self.rect.left = block.entity.obj.rect.right
            collision_types['left'] = True
            markers[1] = True
        elif movement[1] > 0:
            #self.rect.bottom = block.entity.obj.rect.top
            collision_types['bottom'] = True
            markers[2] = True
        elif movement[1] < 0:
            #self.rect.top = block.entity.obj.rect.bottom
            collision_types['top'] = True
            markers[3] = True
        collision_types['data'].append([block.entity.obj.rect,markers, type])
    return collision_types

0 个答案:

没有答案