繁体   English   中英

pygame —跳墙

[英]pygame — wall jumping

好的,这样我的代码就会启动并运行,现在,当玩家握住左右手时,玩家与墙壁碰撞时,如果玩家释放方向(向左或向右),玩家将缓慢地滑下墙壁。正常下降。

我想要做的就是使它在玩家击打墙壁时“粘在”墙壁上,这意味着他仍然会向下滑动并向下滑动直到他撞到地面(用户不必保持方向)或用户可以跳下墙。 (对于那些曾经玩过游戏或看过游戏玩法或超人的人,请考虑超级肉男孩)。 谁能建议一种解决此问题的好方法?

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()

给玩家类一个在他们接触或停止接触墙壁时设置的布尔值可能与您需要的一样复杂。 只是要注意使布尔值与游戏世界中实际发生的变化保持同步的典型问题:您应该在每个更新周期(最有可能在角色移动之后,并且没有其他地方)检查是否在同一位置更改此值。 此外,如果墙壁或地形本身可以移动,则必须考虑到这一点。

根据我编写的一些代码,这只是一个粗略的想法。

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM