I am creating an RPG like game, however, I have absolutely no idea how to scroll through the map so the player is in the centre. Any other suggestions you may have would be greatly appreciated too! Thanks for all your help! Here's my code:
import pygame
from pytmx import load_pygame
pygame.init()
transparent = (0,0,0,0)
black = (0,0,0)
white = (255,255,255)
x,y = 0,0
moveSpeed = 5
#create window
screenSize = (800,600)
screen = pygame.display.set_mode(screenSize)
pygame.display.set_caption("Frozen")
gameMap = load_pygame("Frozen.tmx")
def getMap(layer):
#creates list of single tiles
images = []
for y in range(50):
for x in range(50):
image = gameMap.get_tile_image(x,y,layer)
images.append(image)
#displays tiles in locations
i = 0
for y in range(50):
for x in range(50):
screen.blit(images[i],(x*32,y*32))
i += 1
def getProperties():
#gets properties of tiles in map
properties = []
for y in range(50):
for x in range(50):
tileProperties = gameMap.get_tile_properties(x,y,3)
properties.append(tileProperties)
return properties
def createBoxes():
#creates collision rectangles for unpassable tiles
noWalkLocs = []
rects = []
i = 0
testSurf = pygame.Surface(screenSize).convert_alpha()
testSurf.fill(transparent)
for y in range(50):
for x in range(50):
tileProperties = properties[i]
walkable = tileProperties.get("walkable")
if walkable == "False":
rect = pygame.draw.rect(testSurf,(0,0,0, 0),(x*32,y*32,32,32))
rects.append(rect)
i += 1
return rects
def getCollisions():
global x
global y
collisionLoc = player.rect.collidelist(rects)
collision = rects[collisionLoc]
if player.rect.collidepoint(collision.bottomleft):
if x > 0 and y < 0:
player.rect.topright = collision.bottomleft
x,y = 0, 0
elif x > 0:
player.rect.right = collision.left
x =0
elif y < 0:
player.rect.top = collision.bottom
y = 0
elif player.rect.collidepoint(collision.topleft):
if x > 0 and y > 0:
player.rect.bottomright = collision.topleft
x,y = 0, 0
elif x > 0:
player.rect.right = collision.left
x =0
elif y > 0:
player.rect.bottom = collision.top
y = 0
elif player.rect.collidepoint(collision.bottomright):
if x < 0 and y <0:
player.rect.topleft = collision.bottomright
x,y = 0, 0
elif x < 0:
player.rect.left = collision.right
x =0
elif y < 0:
player.rect.top = collision.bottom
y = 0
elif player.rect.collidepoint(collision.topright):
if x < 0 and y > 0:
player.rect.bottomleft = collision.topright
x,y = 0, 0
elif x < 0:
player.rect.left = collision.right
x =0
elif y > 0:
player.rect.bottom = collision.top
y = 0
elif player.rect.collidepoint(collision.midbottom):
player.rect.top = collision.bottom
y = 0
elif player.rect.collidepoint(collision.midtop):
player.rect.bottom = collision.top
y = 0
elif player.rect.collidepoint(collision.midright):
player.rect.left = collision.right
x = 0
elif player.rect.collidepoint(collision.midleft):
player.rect.right = collision.left
x = 0
return player.rect.x, player.rect.y, x, y
class sprite(pygame.sprite.Sprite):
def __init__(self,x,y):
pygame.sprite.Sprite.__init__(self)
self.x,self.y = x,y
self.image = standFront
self.rect = self.image.get_rect()
self.frontImages = [standFront,walkFront1,walkFront2,walkFront3]
self.backImages = [standBack,walkBack1,walkBack2,walkBack3]
self.leftImages = [standLeft,walkLeft1,walkLeft2,walkLeft3]
self.rightImages = [standRight,walkRight1,walkRight2,walkRight3]
self.index = 0
def walkFront(self):
self.index += 1
if self.index >= len(self.frontImages):
self.index=0
self.image = self.frontImages[self.index]
def walkBack(self):
self.index += 1
if self.index >= len(self.backImages):
self.index=0
self.image = self.backImages[self.index]
def walkLeft(self):
self.index += 1
if self.index >= len(self.leftImages):
self.index=0
self.image = self.leftImages[self.index]
def walkRight(self):
self.index += 1
if self.index >= len(self.rightImages):
self.index=0
self.image = self.rightImages[self.index]
def render(self):
screen.blit(self.image,(self.x,self.y))
self.rect.x, self.rect.y = self.x, self.y
#loads images
standFront = pygame.image.load("Images/Elsa Sprite/WalkFront/StandFront.png").convert_alpha()
walkFront1 = pygame.image.load("Images/Elsa Sprite/WalkFront/WalkFront1.png").convert_alpha()
walkFront2 = pygame.image.load("Images/Elsa Sprite/WalkFront/WalkFront2.png").convert_alpha()
walkFront3 = pygame.image.load("Images/Elsa Sprite/WalkFront/WalkFront3.png").convert_alpha()
standBack = pygame.image.load("Images/Elsa Sprite/WalkBack/StandBack.png").convert_alpha()
walkBack1 = pygame.image.load("Images/Elsa Sprite/WalkBack/WalkBack1.png").convert_alpha()
walkBack2 = pygame.image.load("Images/Elsa Sprite/WalkBack/WalkBack2.png").convert_alpha()
walkBack3 = pygame.image.load("Images/Elsa Sprite/WalkBack/WalkBack3.png").convert_alpha()
standLeft = pygame.image.load("Images/Elsa Sprite/WalkLeft/StandLeft.png").convert_alpha()
walkLeft1 = pygame.image.load("Images/Elsa Sprite/WalkLeft/WalkLeft1.png").convert_alpha()
walkLeft2 = pygame.image.load("Images/Elsa Sprite/WalkLeft/WalkLeft2.png").convert_alpha()
walkLeft3 = pygame.image.load("Images/Elsa Sprite/WalkLeft/WalkLeft3.png").convert_alpha()
standRight = pygame.image.load("Images/Elsa Sprite/WalkRight/StandRight.png").convert_alpha()
walkRight1 = pygame.image.load("Images/Elsa Sprite/WalkRight/WalkRight1.png").convert_alpha()
walkRight2 = pygame.image.load("Images/Elsa Sprite/WalkRight/WalkRight2.png").convert_alpha()
walkRight3 = pygame.image.load("Images/Elsa Sprite/WalkRight/WalkRight3.png").convert_alpha()
#creates tick
clock = pygame.time.Clock()
#creates player
player = sprite(250, 300)
properties = getProperties()
rects = createBoxes()
#main loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#gets keypresses
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x, y = 0, 0
x -= moveSpeed
elif event.key == pygame.K_RIGHT:
x, y = 0, 0
x += moveSpeed
elif event.key == pygame.K_UP:
x, y = 0, 0
y -= moveSpeed
elif event.key == pygame.K_DOWN:
x, y = 0, 0
y += moveSpeed
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x = 0
player.image = player.leftImages[0]
elif event.key == pygame.K_RIGHT:
x = 0
player.image = player.rightImages[0]
elif event.key == pygame.K_UP:
y = 0
player.image = player.backImages[0]
elif event.key == pygame.K_DOWN:
y = 0
player.image = player.frontImages[0]
player.x += x
player.y += y
if y > 0:
player.walkFront()
if y < 0:
player.walkBack()
if x > 0:
player.walkRight()
if x < 0:
player.walkLeft()
getMap(0)
getMap(1)
getMap(2)
player.render()
pygame.display.flip()
player.rect.x, player.rect.y, x, y = getCollisions()
player.x, player.y = player.rect.x, player.rect.y
clock.tick(10)
pygame.quit()
You could use Pygame's .scroll()
method. Instead of changing the x
and y
coordinates of your player
, call tieldMap.scroll()
function and pass to it the new x
and y
(i.e. mx
and my
) values.
To do this you need two surfaces, the main screen
surface (you already have), and another which you can "scroll" (e.g. tieldMap
).
Add these lines somewhere after the pygame.init()
function call:
mapSize = (120,120) #change this values
tieldMap = pygame.Surface(mapSize)
mx, my = 0, 0
and change the code in your getMap()
function (where you blit the tiles onto the main screen
) to:
#displays tiles in locations
i = 0
for y in range(50):
for x in range(50):
tieldMap.blit(images[i],(x*32,y*32))
i += 1
Now you can "scroll" the tieldMap
surface in the main game loop:
Change these lines
player.x += x
player.y += y
to
mx += x
my += y
Add this two lines to create a copy called _tieldMap
of your tieldMap
surface (.copy
) and call the .scroll
function.
_tieldMap = tieldMap.copy()
_tieldMap.scroll(xm, ym)
Finally blit in your main game loop the tieldMap
surface onto the screen
at (0,0)
and update it:
screen.blit(_tieldMap,(0,0))
pygame.display.flip()
Important: You must check if xm
or ym
are smaller or greater than the image height or width!
I hope this helps! :)