球员不会倒下

时间:2013-04-14 18:13:16

标签: python pygame collision gravity

问题:

所以我正在制作这个2D平台游戏并遇到了一个问题。当玩家跳到一个平台上时,重力并不会影响它,直到你再次按下跳跃键它才会掉下来,就像它认为它一直在地上,直到你更新他为止。我已经将问题缩小到重力或碰撞,但无法找到问题。有人可以帮忙吗?我已附上以下代码。

代码:

import pygame, sys, time, random, math
from pygame.locals import *

BACKGROUNDCOLOR = (255, 255, 255)

WINDOWW = 800 
WINDOWH = 600
PLAYERW = 66
PLAYERH = 22
FPS = 60
MOVESPEED = 3
YACCEL = 0.13
GRAVITY = 2
BLOCKSIZE = 30

pygame.init()
screen = pygame.display.set_mode((WINDOWW, WINDOWH), 0, 32)
mainClock = pygame.time.Clock()

testLevel = [
            (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,),
            (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,)]

def createblock(length, height, color):
    tmpblock = pygame.Surface((length, height))
    tmpblock.fill(color)
    tmpblock.convert()
    return tmpblock

def terminate(): # Used to shut down the software
    pygame.quit()
    sys.exit()

def add_level(lvl, bSize): # Creates the level based on a map (lvl) and the size of blocks
    bList = [] # List of every block
    bListDisp = [] # List of every block to display    
    bTypeList = [] # List with corresponding type of block(wall, air, etc.)

    for y in range(len(lvl)): 
        for x in range(len(lvl[0])):

            if lvl[y][x] == 0: # If the block type on lvl[y][x] is '0', write "air" down in the type list
                bTypeList.append("air")
            elif lvl[y][x] == 1: # If the block type on lvl[y][x] is '1', write "wall" down in the type list
                bTypeList.append("solid")

            bList.append(pygame.Rect((bSize * x), (bSize * y), bSize, bSize)) #Append every block that is registered
            bListDisp.append(pygame.Rect((bSize * x), (bSize * y), bSize, bSize)) #Append every block to display that is registered

    return bList, bListDisp, bTypeList

player = pygame.Rect((WINDOWW/2), (WINDOWH - BLOCKSIZE*3), PLAYERW, PLAYERH)
wallblock = createblock(BLOCKSIZE, BLOCKSIZE,(20,0,50))

lastTime = pygame.time.get_ticks()
isGrounded = False

vx = 0
vy = 0

allLevels = [testLevel] # A list containing all lvls(only one for now)
maxLevel = len(allLevels) # Checks which level is the last
currLevel = allLevels[0] # Current level(start with the first lvl)
blockList, blockListDisp, blockTypeList = add_level(currLevel, BLOCKSIZE) # A list with every block and another list with the blocks types

thrusters = True
jumping = False
falling = True
while True:
    """COLLISION"""
    for i in range(len(blockTypeList)): # Go through every block...
        if blockTypeList[i] == "solid": # ...and check what kind of block it is
            if player.colliderect(blockList[i]): #Apply necessary influences from the block(e.g. a solid block prevents the player from moving into it)
                if vx > 0 and not falling:
                    player.right = blockListDisp[i].left
                    print 'Collide Right'
                if vx < 0 and not falling:
                    player.left = blockListDisp[i].right
                    print 'Collide Left'
                if vy > 0:
                    player.bottom = blockListDisp[i].top
                    isGrounded = True
                    falling = False
                    vy = 0
                    print 'Collide Bottom'
                if vy < 0:
                    player.top = blockListDisp[i].bottom
                    print 'Collide Top'
    # Input
    pressedKeys = pygame.key.get_pressed() # Checks which keys are being pressed
    timeDiff = pygame.time.get_ticks() - lastTime # Calculates time difference 
    lastTime +=  timeDiff # Last time checked reset to current time

    # Shut-down if the ESC-key is pressed or the window is "crossed down"
    for event in pygame.event.get():
        if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
            terminate()    

    """X-axis control"""
    if pressedKeys[ord('a')]:
        vx = -MOVESPEED
    if pressedKeys[ord('d')]:
        vx = MOVESPEED
    if not pressedKeys[ord('d')] and not pressedKeys[ord('a')]:
        vx = 0

    """Y-axis control"""
    # Controls for jumping
    if pressedKeys[ord('w')] and thrusters == True:
            vy -= YACCEL * timeDiff; # Accelerate along the y-xis when "jumping", but not above/below max speed
            if vy <= -4:
                vy = -4
            isGrounded = False # You are airborne
            jumping = True # You are jumping

    if event.type == KEYUP: # If you let go of the "jump"-button, stop jumping
        if event.key == ord('w') and vy < 0 and not isGrounded:
            jumping = False
            falling = True

    player.x += vx
    player.y += vy

    # Gravity
    if not isGrounded or falling:
        vy += 0.3
        if vy > 80:
            vy = 80

    screen.fill(BACKGROUNDCOLOR)

    for i in range(len(blockTypeList)):
        if blockTypeList[i] == "solid":
            screen.blit(wallblock, (blockListDisp[i].x, blockListDisp[i].y)) #blit the wall-block graphics

    pygame.draw.rect(screen, (0, 0, 0), player)

    pygame.display.update()
    mainClock.tick(FPS)

1 个答案:

答案 0 :(得分:0)

可以帮助您的清单。

创建self.min_height:

  • min_height初始化为最低可能级别(例如,楼层)
  • 如果玩家没有碰到任何东西,那么min_height仍然是地板
  • 如果玩家与平台发生碰撞,那么他的min_height就会变成平台
  • 播放器CAN JUMP如果distance_between(min_height,current_y)接近JUMP_SENSITIVITY(您可能需要一种方法来判断他是否会很快发生碰撞,但稍后将其留下)
  • 只要尚未达到min_height,玩家将继续堕落。

编辑:这可以帮助你摆脱跳跃/下降的旗帜