我问的问题是因为我需要一个滚动相机。我已经在相机上尝试了一些方法,但它们都没有用。或者他们说有一个全局名称错误。这是我使用的具有全局名称错误的代码
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
screen_width = 700
screen_height = 400
half_width = int(screen_width / 2)
half_height = int(screen_height / 2)
def main():
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("RPG")
global cameraX, cameraY
pygame.init()
player = pygame.image.load("Textures(Final)\Whoo_For_Testing.bmp").convert()
playerect = player.get_rect()
player.set_colorkey(WHITE)
grasstile = pygame.image.load("Textures(Final)\Grass_Tile.bmp").convert()
watertile = pygame.image.load("Textures(Final)\Water_Tile.bmp").convert()
waterbeach = pygame.image.load("Textures(Final)\Water_Beach.bmp").convert()
grassrect = grasstile.get_rect()
waterrect = watertile.get_rect()
waterb = waterbeach.get_rect()
TILE_WIDTH = 32
TILE_HEIGHT = 32
tilemap = [
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile]
]
total_level_width = len(tilemap[0]) * 32
total_level_height = len(tilemap)*32
camera = Camera(simple_camera ,total_level_width, total_level_height)
map_surface = pygame.Surface(( len(tilemap[0])*TILE_WIDTH, len(tilemap)*TILE_HEIGHT))
for y,row in enumerate(tilemap):
for x,tile_surface in enumerate(row):
map_surface.blit(tile_surface,(x*TILE_WIDTH,y*TILE_HEIGHT))
map_surface = pygame.transform.scale(map_surface, (1200, 800))
player = pygame.transform.scale(player, (50, 100))
done = False
clock = pygame.time.Clock()
move_speed = 5
x, y = 100, 100
entities = pygame.sprite.Group()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
y -= move_speed
elif keys[pygame.K_DOWN]:
y += move_speed
elif keys[pygame.K_LEFT]:
x -= move_speed
elif keys[pygame.K_RIGHT]:
x += move_speed
screen.fill(BLACK)
screen.blit(map_surface, grassrect)
screen.blit(player, (x,y))
camera.update(player)
clock.tick(20)
pygame.display.flip()
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 at the left edge
l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return Rect(l, t, w, h)
if __name__ == "__main__":
main()
pygame.quit()
基本上我要问的是如何解决这个问题。对不起,不太擅长解释东西。谢谢!
答案 0 :(得分:0)
这里有几件事需要解决。首先是关于NameErrors,因为Rect是来自导入的pygame包,你必须专门导入Rect:from pygame import Rect
或写pygame.Rect
。 (还要注意全局变量中的大写字母!)。现在,至于实际的相机问题,你遇到的主要问题是你传递给你的相机功能的玩家的矩形是不一个移动的矩形,它只是使用了直接的pygame存储表面的大小(因此topleft将始终为(0,0))。当你真正画出它们时,你也没有将相机应用到表面的部分。这是我开始工作的代码:
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
SCREEN_WIDTH = 700
SCREEN_HEIGHT = 400
HALF_WIDTH = int(SCREEN_WIDTH / 2)
HALF_HEIGHT = int(SCREEN_HEIGHT / 2)
def main():
screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
pygame.display.set_caption("RPG")
global cameraX, cameraY
pygame.init()
#player = pygame.image.load("Textures(Final)\Whoo_For_Testing.bmp").convert()
player = pygame.Surface((40,40))
player.fill((255,0,0))
playerrect = player.get_rect()
player.set_colorkey(WHITE)
#grasstile = pygame.image.load("Textures(Final)\Grass_Tile.bmp").convert()
#watertile = pygame.image.load("Textures(Final)\Water_Tile.bmp").convert()
#waterbeach = pygame.image.load("Textures(Final)\Water_Beach.bmp").convert()
grasstile = pygame.Surface((40,40))
watertile = pygame.Surface((40,40))
waterbeach = pygame.Surface((40,40))
grasstile.fill((0,200,0))
watertile.fill((0,0,200))
waterbeach.fill((200,200,250))
grassrect = grasstile.get_rect()
waterrect = watertile.get_rect()
waterb = waterbeach.get_rect()
TILE_WIDTH = 32
TILE_HEIGHT = 32
tilemap = [
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile],
[grasstile, grasstile, grasstile, grasstile, waterbeach, watertile, watertile, watertile, watertile]
]
total_level_width = len(tilemap[0]) * 32
total_level_height = len(tilemap)*32
camera = Camera(simple_camera ,total_level_width, total_level_height)
map_surface = pygame.Surface(( len(tilemap[0])*TILE_WIDTH, len(tilemap)*TILE_HEIGHT))
for y,row in enumerate(tilemap):
for x,tile_surface in enumerate(row):
map_surface.blit(tile_surface,(x*TILE_WIDTH,y*TILE_HEIGHT))
map_surface = pygame.transform.scale(map_surface, (1200, 800))
player = pygame.transform.scale(player, (50, 100))
done = False
clock = pygame.time.Clock()
move_speed = 5
x, y = 100, 100
entities = pygame.sprite.Group()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
y -= move_speed
elif keys[pygame.K_DOWN]:
y += move_speed
elif keys[pygame.K_LEFT]:
x -= move_speed
elif keys[pygame.K_RIGHT]:
x += move_speed
screen.fill(BLACK)
screen.blit(map_surface, camera.apply(grassrect))
screen.blit(player, camera.apply(pygame.Rect(x,y,50,100)))
camera.update(player.get_rect().move((x,y)))
clock.tick(20)
pygame.display.flip()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = pygame.Rect(0, 0, width, height)
def apply(self, rect):
return rect.move(self.state.topleft)
def update(self, target_rect):
self.state = self.camera_func(self.state, target_rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return pygame.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 at the left edge
l = max(-(camera.width-SCREEN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-SCREEN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return pygame.Rect(l, t, w, h)
if __name__ == "__main__":
main()
pygame.quit()
这适用于您的simple_camera方法,但不适用于complex_camera方法,我将留给您尝试修复。