I tried to create a camera for my platformer using this tutorial and I can't get it work. It's probably (hopefully) something really easy to fix because I'm new to programming.
This is what it should do.
Instead it's just acting as if there is no camera implemented at all. The player sprite moves around the screen that's visible.
This is my code, if you want the entire thing so you can run it, I'd be happy to provide it:
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, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
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 Rect(l, t, w, h)
return Rect(l, t, w, h)
class Sprite(pygame.sprite.Sprite):
def __init__(self,img):
pygame.sprite.Sprite.__init__(self)
class Player(Sprite):
def __init__(self,x,y,width,height):
self.dx = 0
self.dy = 0
self.onGround = False
self.image = pygame.image.load('robotStanding_sprite.png')
self.rect = pygame.Rect(x,y,width,height)
def update(self):
self.rect.x += self.dx
self.collide(self.dx,0,terrain_list)
self.rect.y += self.dy
self.collide(0,self.dy,terrain_list)
if moving_right: self.dx = SPEED
if moving_left: self.dx = -SPEED
if not(moving_left or moving_right): self.dx = 0
if moving_up:
self.dy = -SPEED
self.onGround = False
elif not moving_up: self.dy = SPEED
if self.rect.y >= LOWER_BOUNDARY-GROUND_LEVEL_HEIGHT-ROBOT_HEIGHT:
self.rect.y = LOWER_BOUNDARY-GROUND_LEVEL_HEIGHT-ROBOT_HEIGHT
self.onGround = True
def collide(self,xvel,yvel,blocks):
for block in blocks:
if pygame.sprite.collide_rect(player,block):
if xvel > 0: self.rect.right = block.rect.left
if xvel < 0: self.rect.left = block.rect.right
if yvel > 0:
self.rect.bottom = block.rect.top
self.onGround = True
class Terrain(Sprite):
def __init__(self,img,x,y,width,height):
self.image = pygame.image.load(img)
self.rect = pygame.Rect(x,y,width,height)
def addBlock(img,x,y,width,height):
block = Terrain(img,x,y,width,height)
terrain_list.append(block)
pygame.init()
size = [700,500]
screen = pygame.display.set_mode(size)
LEFT_BOUNDARY = 0
RIGHT_BOUNDARY = size[0]
UPPER_BOUNDARY = 0
LOWER_BOUNDARY = size[1]
HALF_WIDTH = size[0] / 2
HALF_HEIGHT = size[1] / 2
TILE_SIZE = 20
ROBOT_HEIGHT = 2*TILE_SIZE
ROBOT_WIDTH = 25
GROUND_HEIGHT = 100
GROUND_LEVEL_HEIGHT = 4*TILE_SIZE
GROUND_WIDTH = 3000
BLOCK_HEIGHT = 500
BLOCK_WIDTH = 160
SCREEN_WIDTH = 24*TILE_SIZE
SCREEN_HEIGHT = 35*TILE_SIZE
terrain_list = []
player = Player(17*TILE_SIZE,19*TILE_SIZE,ROBOT_WIDTH,ROBOT_HEIGHT)
Terrain.addBlock('ground.fw.png',
0*TILE_SIZE,21*TILE_SIZE,GROUND_WIDTH,GROUND_HEIGHT)
Terrain.addBlock('block1.fw.png',
-5*TILE_SIZE,0*TILE_SIZE,BLOCK_WIDTH,BLOCK_HEIGHT) # LEFT WALL
Terrain.addBlock('block1.fw.png',
24*TILE_SIZE,16*TILE_SIZE,BLOCK_WIDTH,BLOCK_HEIGHT)
Terrain.addBlock('block1.fw.png',
32*TILE_SIZE,20*TILE_SIZE,BLOCK_WIDTH,BLOCK_HEIGHT)
Terrain.addBlock('block1.fw.png',
40*TILE_SIZE,12*TILE_SIZE,BLOCK_WIDTH,BLOCK_HEIGHT)
# CREATE CAMERA -----------------------------------------------------------
camera = Camera(complex_camera, 24*TILE_SIZE, 3000)
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_d: moving_right = True
if event.key == pygame.K_a: moving_left = True
if event.key == pygame.K_w:
if player.onGround:
moving_up = True
if event.key == pygame.K_DOWN: moving_down = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_d: moving_right = False
if event.key == pygame.K_a: moving_left = False
if event.key == pygame.K_w: moving_up = False
screen.fill(SKY_BLUE)
camera.update(player)
player.update()
screen.blit(player.image,player.rect)
for block in terrain_list:
screen.blit(block.image,camera.apply(block))
# DRAW TILE LINES -----------------------------------------------------
if draw_tiles:
x = 0
y = 0
for i in range(RIGHT_BOUNDARY // 2):
pygame.draw.line(screen,BLACK,
[x,UPPER_BOUNDARY],[x,LOWER_BOUNDARY])
pygame.draw.line(screen,BLACK,
[LEFT_BOUNDARY,y],[RIGHT_BOUNDARY,y])
x += TILE_SIZE
y += TILE_SIZE
# tile test
pygame.draw.rect(screen,BLACK,
(34*TILE_SIZE,24*TILE_SIZE,TILE_SIZE,TILE_SIZE))
pygame.display.flip()
clock.tick(60)
pygame.quit()