Skip to main content
 首页 » 编程设计

python之pygame——跳墙

2025年05月04日9me-sa

好的,我已经启动并运行了我的代码,现在当玩家在用户按住右侧或左侧时与墙壁碰撞时,如果玩家释放方向(左侧或右侧),播放器将慢慢滑下墙壁玩家继续正常下落。

我想做的是,当玩家撞到墙上时,他会“粘”在墙上,这意味着他仍然会向下滑动,并且会向下滑动直到他撞到地面(用户不必按住方向) 或者用户可以跳下墙。 (对于那些玩过或看过游戏玩法或洛克人的人来说,想想 super 肉男孩)。谁能提出解决此问题的好方法?

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

请您参考如下方法:

为玩家类提供一个 bool 值,当他们触摸或停止触摸墙壁时设置它可能和您需要的一样复杂。只需注意使 bool 值与游戏世界中实际发生的事情保持同步的典型问题:您应该在每个更新周期检查是否在同一位置更改此值,很可能是在角色移动之后,而不是在其他任何地方.此外,如果墙壁或地形本身可以移动,您必须考虑到这一点。