【问题标题】:How do I make the character drag the camera when it hits the edges in pygame?如何让角色在 pygame 中碰到边缘时拖动相机?
【发布时间】:2021-11-16 19:38:52
【问题描述】:

第一次发帖,我不知道如何让游戏中的角色在镜头碰到屏幕边缘时拖动镜头。使用夹子只会阻止我的角色在击中某个点(而不是在我想要的位置)时移动。任何帮助将不胜感激。

    
import pygame, os
pygame.init()

        
SPEED = 10


SCREEN_W, SCREEN_H = 800, 600
MAP_W, MAP_H = SCREEN_W*3, SCREEN_H*3

WIN = pygame.display.set_mode((SCREEN_W, SCREEN_H))
FPS = 60
clock = pygame.time.Clock()
back = pygame.image.load("my_image")
BACKGROUND = pygame.transform.scale(back, (MAP_W, MAP_H))

CAMERA_X1, CAMERA_Y1, CAMERA_X2, CAMERA_Y2 = 0, 0, SCREEN_W, SCREEN_H

def draw_screen(player):
    WIN.fill((255,255,255))
    WIN.blit(BACKGROUND, (CAMERA_X1, CAMERA_Y1))
    pygame.draw.rect(WIN, (0,0,0), (player.x, player.y, 50, 50))
    pygame.display.update()


def handle_movement(pressed, player):
    global CAMERA_X1, CAMERA_Y1, CAMERA_X2, CAMERA_Y2
    if pressed[pygame.K_a]: #left
        if player.x+50 < CAMERA_X1:
            CAMERA_X1 -= SPEED*2
        else:
            player.x -= SPEED
    if pressed[pygame.K_d]: #right
        if player.x-50 > CAMERA_X2:
            CAMERA_X2 += SPEED*2
        else:
            player.x += SPEED
    if pressed[pygame.K_w]: #up
        if player.y+50 < CAMERA_Y1:
            CAMERA_Y1 -= SPEED*2
        else:
            player.y -= SPEED
    if pressed[pygame.K_s]: #down
        if player.y-50 > CAMERA_Y2:
            CAMERA_Y2 += SPEED*2
        else:
            player.y += SPEED


def main(): #Main game loop
    player = pygame.Rect(0, 0, 50, 50)
    running = True
    while running:
        clock.tick(FPS)
        draw_screen(player)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        keys_pressed = pygame.key.get_pressed()
        handle_movement(keys_pressed, player)

    
    pygame.quit()



if __name__ == "__main__":
    main()

我对 pygame 比较陌生,所以请尽量解释清楚:)

【问题讨论】:

标签: python pygame


【解决方案1】:

因此,相机基本上只是添加到场景中所有内容的偏移量。这里有一个 场景只有一个可控矩形和一个背景,没有摄像头。

import pygame, os
pygame.init()
   
SPEED = 10

SCREEN_W, SCREEN_H = 800, 600
MAP_W, MAP_H = SCREEN_W*3, SCREEN_H*3
WIN = pygame.display.set_mode((SCREEN_W, SCREEN_H))
FPS = 60
clock = pygame.time.Clock()
BACKGROUND = pygame.Surface((MAP_W, MAP_H)).convert()

sq = pygame.Surface((50, 50)).convert()
sq.fill((255, 255, 0))
for x in range(27):
    for y in range(18):
        BACKGROUND.blit(sq, (x * 100, y * 100))
    
cameraOffset = [0 ,0]    
def draw_screen(player):
    WIN.fill((255,255,255))
    WIN.blit(BACKGROUND, (0, 0))
    playerPos = (player.x, player.y)
    pygame.draw.rect(WIN, (100, 10, 255), (*playerPos, player.width, player.height))
    pygame.display.update()


def handle_movement(pressed, player):
    global cameraOffset, playerScreenPos
    player.x += (pressed[pygame.K_d] - pressed[pygame.K_a]) * SPEED
    player.y += (pressed[pygame.K_s] - pressed[pygame.K_w]) * SPEED

def main(): #Main game loop
    player = pygame.Rect(0, 0, 50, 50)
    running = True
    while running:
        clock.tick(FPS)
        draw_screen(player)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        keys_pressed = pygame.key.get_pressed()
        handle_movement(keys_pressed, player)

    
    pygame.quit()

if __name__ == "__main__":
    main() 

现在,如何让相机跟随那个矩形?很简单,只需为场景中的所有内容添加一个偏移值即可。我们在场景中只有一个背景和一个矩形,所以上面的代码会相应地改变:

#WIN.blit(BACKGROUND, (0, 0))
WIN.blit(BACKGROUND, (0 - cameraOffset[0], 0 - cameraOffset[1]))
#playerPos = (player.x, player.y)
playerPos = (player.x - cameraOffset[0], player.y - cameraOffset[1])

所有这一切都是将对象移动偏移量。现在唯一需要弄清楚的是偏移值需要是什么。偏移值应该是玩家位置 - 屏幕大小的一半。这会导致矩形始终位于中心。

cameraOffset[0] += player.x - cameraOffset[0] - (SCREEN_W * 0.5)
cameraOffset[1] += player.y - cameraOffset[1] - (SCREEN_H * 0.5)

注意玩家位置是以向量的形式写出来的。这允许我们添加 通过将向量除以某物来减小向量的大小,从而产生延迟跟踪效果。

delay = 10
cameraOffset[0] += (player.x - cameraOffset[0] - (SCREEN_W * 0.5)) / delay
cameraOffset[1] += (player.y - cameraOffset[1] - (SCREEN_H * 0.5)) / delay

然后,根据您的需要,您可以限制相机偏移量,使其平移不会超出 一定的限度。

cameraOffset[0] = max(0, min(cameraOffset[0], MAP_W - SCREEN_W))
cameraOffset[1] = max(0, min(cameraOffset[1], MAP_H - SCREEN_H))

这是添加相机后的代码。如您所见,变化不大。

import pygame, os
pygame.init()
   
SPEED = 10

SCREEN_W, SCREEN_H = 800, 600
MAP_W, MAP_H = SCREEN_W*3, SCREEN_H*3
WIN = pygame.display.set_mode((SCREEN_W, SCREEN_H))
FPS = 60
clock = pygame.time.Clock()
BACKGROUND = pygame.Surface((MAP_W, MAP_H)).convert()

sq = pygame.Surface((50, 50)).convert()
sq.fill((255, 255, 0))
for x in range(27):
    for y in range(18):
        BACKGROUND.blit(sq, (x * 100, y * 100))

delay = 10
cameraOffset = [0 ,0]    
def draw_screen(player):
    WIN.fill((255,255,255))
    WIN.blit(BACKGROUND, (0 - cameraOffset[0], 0 - cameraOffset[1]))
    playerPos = (player.x - cameraOffset[0], player.y - cameraOffset[1])
    pygame.draw.rect(WIN, (100, 10, 255), (*playerPos, player.width, player.height))
    pygame.display.update()


def handle_movement(pressed, player):
    global cameraOffset, playerScreenPos
    player.x += (pressed[pygame.K_d] - pressed[pygame.K_a]) * SPEED
    player.y += (pressed[pygame.K_s] - pressed[pygame.K_w]) * SPEED

    cameraOffset[0] += (player.x - cameraOffset[0] - (SCREEN_W * 0.5)) / delay
    cameraOffset[1] += (player.y - cameraOffset[1] - (SCREEN_H * 0.5)) / delay

    cameraOffset[0] = max(0, min(cameraOffset[0], MAP_W - SCREEN_W))
    cameraOffset[1] = max(0, min(cameraOffset[1], MAP_H - SCREEN_H))

def main(): #Main game loop
    player = pygame.Rect(0, 0, 50, 50)
    running = True
    while running:
        clock.tick(FPS)
        draw_screen(player)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        keys_pressed = pygame.key.get_pressed()
        handle_movement(keys_pressed, player)

    
    pygame.quit()

if __name__ == "__main__":
    main()

【讨论】:

  • 谢谢,这真的很有帮助:D
  • @dan_stan_man 欢迎您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
相关资源
最近更新 更多