1

私の問題:

私がゲームにいる時点で、ダブル ジャンプ、ウォール ジャンプなどの機能をいくつか追加したいと考えて
います。
問題は、キャラクターが地面に衝突すると、衝突が記録されることです。
ただし、次のティックでは、地面にいても衝突を記録していません。
これにより、壁に衝突したかどうか、または現在地面などに衝突しているかどうかを
検出する際に問題が発生します。衝突を検出しないと、y 速度が常に減少するため、さらに問題が発生します。
したがって、私のプレーヤーは、地面にいるときに 0 になるのではなく、増加する一定の y 速度を持っています。

例:

左側のコーナーでわかるように、私の 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

おそらく、キャラクターがプラットフォームと重なるように1ピクセル移動しない場合、pygameの衝突コードは衝突を検出せず、代わりに、関係する限り正確に衝突を検出しますか?このような場合は、着陸のループを通過し、yvelを0に設定します。OK、落下、0.3、落下、0.6、落下、0.9、落下... OK、1ピクセル移動して、オーバーラップしました。着陸し、yvelを0に設定します。最初から繰り返します。

于 2013-01-22T00:37:13.223 に答える