1

我的问题:

在我的游戏中,我想添加一些功能,如二段跳、墙跳等。
但是我的碰撞检测遇到了问题,我似乎无法解决它。
问题是当我的角色与地面发生碰撞时,它会发生碰撞。
然而,即使我在地上,它也不再记录碰撞。
这会在检测我是否与墙壁碰撞或我当前是否与地面碰撞等方面产生问题。
这会产生更多问题,因为当它未检测到碰撞时,我的 y 速度将不断降低。
所以,我的玩家有一个恒定的 y 速度,它在增加,而不是在地面上时它只是 0。

例子:

正如您在左手角看到的那样,我的 y 速度在这样的数字中跳跃:

0  
0  
0.3  
0.6  
0.9

然后重新开始。
我真正需要的是,当我在地面上时,它始终为 0,并且代码能够识别我在地面上。
但事实并非如此,我不知道为什么,有人可以帮忙吗?

代码:

import pygame
from pygame import *

WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)

DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30

def main():
    pygame.init()
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
    #pygame.display.set_caption("Use arrows to move!")
    timer = pygame.time.Clock()

    up = down = left = right = space = False
    bg = Surface((32,32))
    bg.convert()
    bg.fill(Color("#0094FF"))
    entities = pygame.sprite.Group()
    player = Player(32, 32)
    platforms = []
    plants = []

    space_num = 0

    x = 0
    y = 0
    level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                           PPPP     PPPPPPP",
        "P                                       PPPP",
        "P                                       PPPP",
        "P                                       PPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPP           PPPPPPPPPPPPPPPPPP",]
    # build the level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = ExitBlock(x, y)
                platforms.append(e)
                entities.add(e)
            if col == "p":
                p = Plant(x, y)
                plants.append(p)
                entities.add(p)
            x += 32
        y += 32
        x = 0

    total_level_width = len(level[0]) * 32
    total_level_height = len(level) * 32
    camera = Camera(complex_camera, total_level_width, total_level_height)
    entities.add(player)

    while 1:
        timer.tick(60)

        for e in pygame.event.get():
            if e.type == QUIT: raise SystemExit, "QUIT"
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                raise SystemExit, "ESCAPE"
            if e.type == KEYDOWN and e.key == K_UP:
                up = True
            if e.type == KEYDOWN and e.key == K_DOWN:
                down = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right = True
            if e.type == KEYDOWN and e.key == K_SPACE:
                if space_num < 6:
                    space = True
                    space_num += 1

            if e.type == KEYUP and e.key == K_UP:
                up = False
            if e.type == KEYUP and e.key == K_DOWN:
                down = False
            if e.type == KEYUP and e.key == K_LEFT:
                left = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False
            if e.type == KEYUP and e.key == K_SPACE:
                space = False

        # draw background
        for y in range(20):
            for x in range(25):
                screen.blit(bg, (x * 32, y * 32))

        camera.update(player)

        # update player, draw everything else
        player.update(up, down, left, right, platforms, space)
        for e in entities:
            screen.blit(e.image, camera.apply(e))
        pygame.display.update()

class Camera(object):
    def __init__(self, camera_func, width, height):
        self.camera_func = camera_func
        self.state = Rect(0, 0, width, height)

    def apply(self, target):
        return target.rect.move(self.state.topleft)

    def update(self, target):
        self.state = self.camera_func(self.state, target.rect)

#def simple_camera(camera, target_rect):
#    l, t, _, _ = target_rect
#    _, _, w, h = camera
#    return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)

def complex_camera(camera, target_rect):
    l, t, _, _ = target_rect
    _, _, w, h = camera
    l, t, _, _ = -l + HALF_WIDTH, -t+HALF_HEIGHT, w, h

    l = min(0, l)                           # stop scrolling left
    l = max(-(camera.width-WIN_WIDTH), l)   # stop scrolling right
    t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling bottom

    return Rect(l, t, w, h)

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Player(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = Surface((32,32))
        self.image.fill(Color("#0000FF"))
        self.image.convert()
        self.rect = Rect(400, 400, 32, 32)

    def update(self, up, down, left, right, platforms, space):
        if space:
            if not self.onGround:
                self.yvel = -12
            if self.onGround:
                self.yvel = 0
        else:
            if up:
                if self.onGround: self.yvel -= 10 # only jump if on the ground
            if down:
                pass
            if left:
                self.xvel = -8
            if right:
                self.xvel = 8
            if not self.onGround:
                self.yvel += 0.3 # only accelerate with gravity if in the air
                if self.yvel > 40: self.yvel = 40 # max falling speed
            if not(left or right):
                self.xvel = 0

            self.rect.left += self.xvel # increment in x direction
            self.collide(self.xvel, 0, platforms) # do x-axis collisions
            self.rect.top += self.yvel # increment in y direction
            self.onGround = False; # assuming we're in the air
            self.collide(0, self.yvel, platforms) # do y-axis collisions

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if isinstance(p, ExitBlock):
                    pygame.event.post(pygame.event.Event(QUIT))
                if xvel > 0: self.rect.right = p.rect.left
                if xvel < 0: self.rect.left = p.rect.right
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = 0
                if yvel < 0: self.rect.top = p.rect.bottom


class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((32, 32))
        self.image.convert()
        self.image.fill(Color("#DDDDDD"))
        self.rect = Rect(x, y, 32, 32)

    def update(self):
        pass

class ExitBlock(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image = pygame.image.load("bush.png")

class Decoration(Entity):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Plant(Decoration):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((64, 64))
        self.image.convert()
        #self.image = pygame.image.load("bush.png")
        self.rect = Rect(x, y, 64, 64)




if __name__ == "__main__":
    main()
4

1 回答 1

1

看起来只要不按住空间,更新代码就会让你在空中:

def update(self, up, down, left, right, platforms, space):
    if space:
    else:
        self.onGround = False; # assuming we're in the air
        self.collide(0, self.yvel, platforms) # do y-axis collisions

如果角色没有移动单个像素以与平台重叠,那么pygame的碰撞代码可能不会检测到碰撞,而是就它而言正好在它上面?在这种情况下,你会经历一个着陆循环,将 yvel 设置为 0。好吧,我们正在下降,0.3,下降,0.6,下降,0.9,下降......好吧,我们移动了 1 个像素并且我们重叠了,我们降落,将 yvel 设置为 0。然后在开始时重复。

于 2013-01-22T00:37:13.223 回答