I have tried to implement a camera function in my 2d game made with pygame but the only I obtain is my player set in the middle of the window. I see how its x and y cordenates changes but the player does not move.I know I must use the camera's apply method to the map but I don't know how to do it since is my first approach to pygame. Here is my code:
import pygame, sys
from pygame.locals import *
import random
"""
dirt 0
grass 1
water 2
coal 3
"""
DIRT = 0
GRASS = 1
WATER = 2
COAL = 3
DIAMOND = 4
CLOUD = 5
cloudx = -200
cloudy = 0
WHITE = (255, 255, 255)
BLACK = (0, 0, 0 )
BROWN = (153, 76, 0 )
GREEN = (0, 255, 0 )
BLUE = (0, 0, 255)
TILESIZE = 40
MAPWIDTH = 140
MAPHEIGHT = 120
WIN_WIDTH = 800
WIN_HEIGHT = 600
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
fpsClock = pygame.time.Clock()
colours = {
DIRT: BROWN,
GRASS: GREEN,
WATER: BLUE,
COAL: BLACK
}
"""tilemap = [
[GRASS, COAL, DIRT ],
[WATER, WATER, GRASS],
[COAL, WATER, GRASS],
[DIRT, WATER, COAL ],
[GRASS, WATER, DIRT]
]"""
resources = [WATER, GRASS, COAL, DIRT, DIAMOND]
tilemap = [[random.choice(resources) for w in range(MAPWIDTH)] for h in range(MAPHEIGHT)]
textures = {
DIRT: pygame.image.load("dirt.gif"),
GRASS: pygame.image.load("grass.gif"),
COAL: pygame.image.load("coal.gif"),
WATER: pygame.image.load("water.gif"),
DIAMOND: pygame.image.load("diamond.gif"),
CLOUD: pygame.image.load("nube.gif")
}
inventory = {
DIRT :0,
WATER :0,
GRASS :0,
COAL :0,
DIAMOND :0
}
playerPos = [50,50]
move = 0
vel_x = 0
vel_y = 0
speed = 1
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)
global cameraX, cameraY
total_level_width = len(tilemap[0]) * TILESIZE
total_level_height = len(tilemap)*TILESIZE
camera = Camera(simple_camera ,total_level_width, total_level_height)
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
pygame.display.set_caption("My first game :)")
pygame.display.set_icon(pygame.image.load("player.gif"))
PLAYER = pygame.image.load("player.gif")
playerrect = PLAYER.get_rect()
for rw in range(MAPHEIGHT):
for cl in range(MAPWIDTH):
randomNumber = random.randint(0,50)
if randomNumber <= 10:
tile = COAL
elif randomNumber > 11 and randomNumber <= 20:
tile = WATER
elif randomNumber > 21 and randomNumber <= 45:
tile = GRASS
elif randomNumber > 46 and randomNumber <= 49:
tile = DIRT
else:
tile = DIAMOND
tilemap[rw][cl] = tile
INVFONT = pygame.font.Font("freeSansBold.ttf", 18)
while True:
for event in pygame.event.get():
if event.type == QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
#movement
if event.key == K_RIGHT and playerPos[0] < MAPWIDTH - 1:
playerPos[0] += move
elif event.key == K_LEFT and playerPos[0] > 1/TILESIZE:
playerPos[0] -= move
elif event.key == K_DOWN and playerPos[1] < MAPHEIGHT - 1:
playerPos[1] += move
elif event.key == K_UP and playerPos[1] > 1/TILESIZE:
playerPos[1] -= move
#pick up resource
elif event.key == K_SPACE:
currentTile = tilemap[playerPos[1]][playerPos[0]]
inventory[currentTile] += 1
tilemap[playerPos[1]][playerPos[0]] = DIRT
#place resources
elif event.key == K_1:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[WATER] > 0:
inventory[WATER] -= 1
tilemap[playerPos[1]][playerPos[0]] = WATER
inventory[currentTile] += 1
elif event.key == K_2:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[GRASS] > 0:
inventory[GRASS] -= 1
tilemap[playerPos[1]][playerPos[0]] = GRASS
inventory[currentTile] += 1
elif event.key == K_3:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[COAL] > 0:
inventory[COAL] -= 1
tilemap[playerPos[1]][playerPos[0]] = COAL
inventory[currentTile] += 1
elif event.key == K_4:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[DIRT] > 0:
inventory[DIRT] -= 1
tilemap[playerPos[1]][playerPos[0]] = DIRT
inventory[currentTile] += 1
elif event.key == K_5:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[DIAMOND] > 0:
inventory[DIAMOND] -= 1
tilemap[playerPos[1]][playerPos[0]] = DIAMOND
inventory[currentTile] += 1
keys = pygame.key.get_pressed()
if keys[K_LEFT] and playerPos[0] > 1/TILESIZE:
playerPos[0] -= speed
if keys[K_RIGHT] and playerPos[0] < MAPWIDTH - 1:
playerPos[0] += speed
if keys[K_UP] and playerPos[1] > 1/TILESIZE:
playerPos[1] -= speed
if keys[K_DOWN] and playerPos[1] < MAPHEIGHT - 1:
playerPos[1] += speed
for row in range(MAPHEIGHT):
for column in range(MAPWIDTH):
DISPLAYSURF.blit(textures[tilemap[row][column]], (column*TILESIZE, row*TILESIZE))
#DISPLAYSURF.blit(PLAYER, (playerPos[0]*TILESIZE, playerPos[1]*TILESIZE))
DISPLAYSURF.blit(PLAYER, camera.apply(pygame.Rect(playerPos[0],playerPos[1],42,42)))
camera.update(PLAYER.get_rect().move((playerPos[0],playerPos[1])))
pygame.display.update()
fpsClock.tick(10)
print playerPos