Reputation: 2161
I'm having a bit of trouble rendering an isometric 2D tile-based world using Python and Pygame with the following code:
'''
Map Rendering Demo
rendermap.py
By James Walker (trading as Ilmiont Software).
Copyright (C)Ilmiont Software 2013. All rights reserved.
This is a simple program demonstrating rendering a 2D map in Python with Pygame from a list of map data.
Support for isometric or flat view is included.
'''
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480), DOUBLEBUF) #set the display mode, window title and FPS clock
pygame.display.set_caption('Map Rendering Demo')
FPSCLOCK = pygame.time.Clock()
map_data = [
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]
] #the data for the map expressed as [row[tile]].
wall = pygame.image.load('wall.png').convert() #load images
grass = pygame.image.load('grass.png').convert()
tileWidth = 64 #holds the tile width and height
tileHeight = 64
currentRow = 0 #holds the current map row we are working on (y)
currentTile = 0 #holds the current tile we are working on (x)
for row in map_data: #for every row of the map...
for tile in row:
tileImage = wall
cartx = currentTile * 64 #x is the index of the currentTile * the tile width
print(cartx)
carty = currentRow * 64 #y is the index of the currentRow * the tile height
print(carty)
x = cartx - carty
print(x)
y = (cartx + carty) / 2
print(y)
print('\n\n')
currentTile += 1 #increase the currentTile holder so we know that we are starting rendering a new tile in a moment
DISPLAYSURF.blit(tileImage, (x, y)) #display the actual tile
currentTile = 0 #reset the current working tile to 0 (we're starting a new row remember so we need to render the first tile of that row at index 0)
currentRow += 1 #increment the current working row so we know we're starting a new row (used for calculating the y coord for the tile)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYUP:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
pygame.display.flip()
FPSCLOCK.tick(30)
The tile size used is 64x64; the above code when run generates the following output:
The tiles all have transparent edges and only the 'wall' tile is featured in this example but obviously something is going wrong as the tiles are all too far apart.
I have tried reading some tutorials online but I can't seem to find one actually written in Python so please advise me as to where I am going wrong.
Thanks in advance, Ilmiont
Upvotes: 3
Views: 8915
Reputation: 955
You can get rid of the black triangles by setting the colorkey to black, I copied your example and was able to fix it by changing:
for row in map_data: #for every row of the map...
for tile in row:
tileImage = wall
to
for row in map:
for tile in row:
tileImage = wall
tileImage.set_colorkey((0,0,0))
Found from: https://www.pygame.org/docs/ref/surface.html#pygame.Surface.set_colorkey
There is probably a better way to set the colorkey for all, but I tried this and it seems to work. I see the comment about about alpha, I'm sure that works better too.
In regards to positioning, You would just need to start rendering from the middle of the screen. I was able to do this with your code by simple changing:
x = cartx - carty
print(x)
y = (cartx + carty) / 2
to
x = 320 + ((cartx - carty) / 2)
y = ((cartx+carty) / 4 * 3)
I hope this helps any newcomers to this thread!
Upvotes: 2
Reputation: 1025
Try this:
print(carty)
x = (cartx - carty) / 2
print(x)
y = (cartx + carty)/4*3
And, after test, modify convert() to convert_alpha(), because optimisation kill alpha on convert()
I also modify y ( /4*3 ), to take in account your image. It's work for me.
Upvotes: 2