皮格姆的摄像机不动了

2024-06-01 09:34:08 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我正在尝试创建一个跟踪pygame中玩家的移动相机,我读了一些指南,也就是流行的关于堆栈溢出的指南(参考:this one),但仍然无法正常工作。你知道吗

基本上我的问题是,游戏只是“冻结”我不能移动玩家和重力不起作用,虽然我仍然可以按键盘上的一个按钮,退出游戏,也尝试了一些打印在一些行和程序没有卡住确定。你知道吗

这是我的密码:

import pygame
pygame.init()
# global constants
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 640
RESOLUTION = (SCREEN_WIDTH, SCREEN_HEIGHT)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)


class Player(pygame.sprite.Sprite):

    def __init__(self, x, y):
        # get sprite class attributes
        super(Player, self).__init__()
        # create the player image and hit box
        self.image = pygame.Surface([32, 32])
        self.image.fill(BLACK)
        self.rect = self.image.get_rect()
        # the player pos
        self.rect.x = x
        self.rect.y = y
        self.facing = "left"
        # player movement vectors
        self.change_x = 0
        self.change_y = 0
        self.walls = None
        # current level the player is in
        self.level = None

    # change the movement vectors
    def change_speed(self, x, y):
        self.change_x += x
        self.change_y += y

    def update(self):
        # move the player
        # calc the gravity effect
        self.calc_gravity()

        # move left/right
        self.rect.x += self.change_x

        # see if we hit anything
        block_hit_list = pygame.sprite.spritecollide(self, self.level.block_list, False)
        for block in block_hit_list:
            # if we are moving right,
            # set our right side to the left side of the item we hit
            if self.change_x > 0:
                self.rect.right = block.rect.left
            elif self.change_x < 0:
                # otherwise if we are moving left, do the opposite
                self.rect.left = block.rect.right

        # move up/down
        self.rect.y += self.change_y

        # check and see if we hit anything
        block_hit_list = pygame.sprite.spritecollide(self, self.level.block_list, False)
        for block in block_hit_list:

            # reset our position based on the top/bottom of the object
            if self.change_y > 0:
                self.rect.bottom = block.rect.top
            elif self.change_y < 0:
                self.rect.top = block.rect.bottom

            # stop our vertical movement
            self.change_y = 0

    def calc_gravity(self):
        # calculate effect of gravity
        if self.change_y == 0:
            self.change_y = 1
        else:
            # maximum downward velocity
            if self.change_y < 10:
                # gravity
                self.change_y += 0.45
            else:
                pass

    # the player's jump
    def jump(self):
        # move down a bit and see if there is a platform below us
        # move down 2 pixels because it doesn't work well if we only move down
        # 1 when working with a platform moving down
        self.rect.y += 2
        block_hit_list = pygame.sprite.spritecollide(self, self.level.block_list, False)
        self.rect.y -= 2

        # If it is ok to jump, set our speed upwards
        if len(block_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
            self.change_y = -7

    # player-controlled movement
    def go_left(self):
        self.change_x = -5
        self.facing = "left"

    def go_right(self):
        self.change_x = 5
        self.facing = "right"

    def stop(self):
        self.change_x = 0


# blocks the player can stand on or to limit his movement in the map
class Blocks(pygame.sprite.Sprite):

    # create the block
    def __init__(self, width, height):
        super(Blocks, self).__init__()
        self.image = pygame.Surface([width, height])
        self.image.fill(BLUE)
        self.rect = self.image.get_rect()


# super class for levels, each level will be a sub class of Level and have a different layout
class Level(object):

    def __init__(self, player):
        self.block_list = pygame.sprite.Group()
        self.player = player

    # updates the level
    def update(self):
        self.block_list.update()

    # draw all the level objects
    def draw(self, screen):
        # the background
        screen.fill(WHITE)
        self.block_list.draw(screen)


# level one sub class
class LevelOne(Level):

    def __init__(self, player):
        super(LevelOne, self).__init__(player)
        self.level_width = 2500
        self.level_height = 1400
        # level one blocks
        blocks_loc = [[0, 0, 10, 800], [10, 790, 2500, 10], [2500, 0, 10, 800]]
        for x in blocks_loc:
            block = Blocks(x[2], x[3])
            block.rect.x = x[0]
            block.rect.y = x[1]
            self.block_list.add(block)


# camera class that follows the player around the screen
class Camera(object):

    def __init__(self, width, height):
        self.camera = pygame.Rect(0, 0, width, height)
        self.width = width
        self.height = height

    def apply(self, entity):
        return entity.rect.move(self.camera.topleft)

    def update(self, target):
        x = -target.rect.x + int(SCREEN_WIDTH/2)
        y = -target.rect.y + int(SCREEN_HEIGHT/2)
        self.camera = pygame.Rect(x, y, self.width, self.height)


# create the game screen
screen = pygame.display.set_mode(RESOLUTION)
# window title
pygame.display.set_caption("test")
# create the player object
player = Player(600, 50)
# create the levels
levels_list = []
levels_list.append(LevelOne(player))
active_sprite_list = pygame.sprite.Group()
current_level_num = 0
current_level = levels_list[current_level_num]
player.level = current_level
active_sprite_list.add(player)
camera = Camera(current_level.level_width, current_level.level_height)
# the clock will be used for the frame rate of the game
clock = pygame.time.Clock()
# flag to know when the game is done
done = False
while not done:
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            done = True

        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_LEFT:
                player.go_left()

            if event.key == pygame.K_RIGHT:
                player.go_right()

            if event.key == pygame.K_UP:
                player.jump()

            if event.key == pygame.K_ESCAPE:
                done = True

        if event.type == pygame.KEYUP:

            if event.key == pygame.K_LEFT and player.change_x < 0:
                player.stop()

            if event.key == pygame.K_RIGHT and player.change_x > 0:
                player.stop()

    # update part
    current_level.update()
    active_sprite_list.update()
    camera.update(player)
    # draw part
    current_level.draw(screen)
    for sprite in active_sprite_list:
        screen.blit(sprite.image, camera.apply(sprite))
    # refresh part
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tags: therectselfeventifdefchangeblock
1条回答
网友
1楼 · 发布于 2024-06-01 09:34:08

还必须将摄影机偏移应用于标高中的块精灵。一个简单的解决方案是将摄影机传递给level实例的draw方法:

def draw(self, screen, camera):
    screen.fill(WHITE)
    for block in current_level.block_list:
        screen.blit(block.image, camera.apply(block))

您还可以将级别中的块添加到active_sprite_list。你知道吗

相关问题 更多 >