2

わかりましたので、コードを実行しています。現在、ユーザーが右または左を保持しているときにプレーヤーが壁に衝突すると、プレーヤーは壁をゆっくりと滑り落ち、プレーヤーが方向 (左または右) を放すと、プレーヤーは続行します。普通に落ちる。

私がやりたいことは、プレイヤーが壁にぶつかったときに壁に「くっつく」ようにすることです。つまり、彼はまだ滑り落ち、地面にぶつかるまで滑り落ちます (ユーザーは方向を保持する必要はありません)ユーザーは壁から飛び降りることができます。(それをプレイしたり、ゲームプレイやロックマンを見たりした人にとっては、スーパーミートボーイだと思います)。誰かがこれにアプローチする良い方法を提案できますか?

import pygame, time
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

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("#000000"))
    entities = pygame.sprite.Group()
    player = Player(32, 32)
    platforms = []

    space_num = 0

    x = y = 0
    level = [
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                              E           P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                           PPPPPP         P",
        "P                                          P",
        "P                                          P",
        "PPPPP                                      P",
        "P                                          P",
        "P         PPPPPPP                          P",
        "P                                          P",
        "P                     PPPPPP               P",
        "P                                          P",
        "P   PPPPPPPPPPP                            P",
        "P                                          P",
        "P                 PPPPPPPPPPP              P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "P                                          P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]
    # 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)
            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.onWall = 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 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
        self.rect.top += self.yvel # increment in y direction
        self.onGround = False; # assuming we're in the air
        self.onWall = False
        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
                    self.onWall = True

                if xvel < 0:
                    self.rect.left = p.rect.right
                    self.onWall = True

                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.onWall = False
                    self.yvel = 0
                if yvel < 0: self.rect.top = p.rect.bottom

                if self.onWall:
                    self.yvel = 3


class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((32, 32))
        self.image.convert()
        self.image.fill(Color("#F0FFFF"))
        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.fill(Color("#00ff00"))

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

2 に答える 2

1

プレーヤー クラスに、壁に触れたとき、または触れなくなったときに設定されるブール値を与えることは、おそらく必要なほど複雑です。そのブール値をゲームの世界で実際に起こっていることと同期させる際の典型的な問題に気をつけてください。更新サイクルごとに同じ場所でこの値を変更することを確認する必要があります。おそらくキャラクターの移動後、それ以外の場所ではありません. さらに、壁や地形自体が移動できる場合は、それを考慮する必要があります。

于 2013-01-17T01:24:40.743 に答える
0

これは、私が書いたいくつかのコードに基づいた大まかなアイデアです。

onCollision(wall, player):
  player.stuck = true
  player.wall_jump = true

onCollision(floor, player):
  player.stuck = false
  player.wall_jump = false # If you slide to the bottom of the floor, you can't walljump

onInput():

  player = getPlayer()
  if jump_key.state and player.wall_jump: # assuming you set jump_key.state to true, when jump key is pressed
    # set player direction to opposite
    # set player's horizontal and vertical velocity
    player.stuck = false;
于 2013-01-17T00:37:37.317 に答える