Sign in to follow this  

Terrain Parsing/Draw

Recommended Posts

I recently changed how my game's terrain is drawn (it now parses it from a file of characters which are 1's, 2's and 3's to dictate grass, mountain and water) and it still runs. The problem, like most times, is it does not do what I want it to. :D When I run it, it displays all water, when the text file dictates all grass with a few mountains. I have a feeling that the terrainIdentifier is off, but when I error tested it with a print command, it printed 1's which should mean that grass will be drawn. Is it because of the last image I am loading that it goes screwy?
# MAIN.PY: Matt Gallivan, 2007, Terra Pugna
import pygame, sys, os
from pygame.locals import *

# -- Define DRAW functions --
def terrainDraw(terrainList):
    terrainType = pygame.image.load("mountain.png")
    terrainIdentifier = 0
    xCoordinate = 0
    yCoordinate = 0
    displayX = 768
    displayY = 1024
    n = 0
    for x in range(0, displayX, 32):
        for y in range(0, displayY, 32):
            terrainIdentifier = terrainList[n]
            if terrainIdentifier == 1:
                terrainType = pygame.image.load("grass.png")
            elif terrainIdentifier == 2:
                terrainType = pygame.image.load("mountain.png")
                terrainType = pygame.image.load("river.png")
            screen.blit(terrainType, (xCoordinate,yCoordinate))
            xCoordinate += 32
            n += 1
        yCoordinate += 32
        xCoordinate = 0
def windowDraw():
    window = pygame.display.set_mode((1024,768))
# -- Define LOAD functions --
def loadImageFile( fileName, useColorKey = False ):
        image = pygame.image.load( fileName )
    except pygame.error, message:
        print "Cannot load image:", fileName
        raise SystemExit, message

    image = image.convert()

    if useColorKey is True:
        colorkey = image.get_at( (0,0) )
        image.set_colorkey( colorkey, RLEACCEL )
    return image

# -- Define PARSER functions --
def mapParser(terrainList):
    increment = 1
    while increment <= 768:
        f = open('C:/Documents and Settings/Matt/Desktop/RPJ/terrain.txt', 'r+')
        increment += 1
    return terrainList

# -- Initialise pyGame and set up the window --
terrainList = []
screen = pygame.display.get_surface()
background = screen.copy()

# -- Load images and set the surfaces --
loadImageFile("hero-n.gif", True)
loadImageFile("hero-w.gif", True)
loadImageFile("hero-e.gif", True)
loadImageFile("hero-s.gif", True)
loadImageFile("grass.png", True)
loadImageFile("mountain.png", True)
loadImageFile("river.png", True)
backgroundimage = pygame.image.load("river.png")
hero_surface_n = pygame.image.load("hero-n.gif")
hero_surface_w = pygame.image.load("hero-w.gif")
hero_surface_e = pygame.image.load("hero-e.gif")
hero_surface_s = pygame.image.load("hero-s.gif")
heroimage = hero_surface_s

# -- Set user input values --
keys = {pygame.K_LEFT : False, pygame.K_RIGHT : False, pygame.K_UP : False, pygame.K_DOWN : False}
heroX = 50
heroY = 50

while True: 
    for event in pygame.event.get(): 
       if event.type == QUIT: 
       elif event.type == pygame.KEYDOWN:
          keys[event.key] = True
       elif event.type == pygame.KEYUP:
          keys[event.key] = False
    if keys[pygame.K_LEFT]:
        heroX -= 1
        heroimage = hero_surface_w
    if keys[pygame.K_RIGHT]:
        heroX += 1
        heroimage = hero_surface_e
    if keys[pygame.K_UP]:
        heroY -= 1
        heroimage = hero_surface_n
    if keys[pygame.K_DOWN]:
        heroY += 1
        heroimage = hero_surface_s
    screen.blit(background, (0,0))
    screen.blit(heroimage, (heroX,heroY))

EDIT: Changed source code since I revised the blitting in the while loop. [Edited by - Gallivan on August 12, 2007 3:01:44 PM]

Share this post

Link to post
Share on other sites
I didn't see where you stored the map...since I'm not a Python developer, I might have missed it completely. But shouldn't you have an array like

int[,] map[6, 6] {
{1, 1, 2, 1, 3, 1},
{1, 2, 2, 1, 3, 3},
{1, 2, 1, 1, 1, 1},
{1, 2, 1, 1, 1, 1},
{2, 2, 2, 2, 2, 2},
{2, 2, 2, 2, 2, 2}

Share this post

Link to post
Share on other sites
In map parser (where I think the problem is) it reads a .txt file which looks like:


And is supposed to take each of those values and place it in a list which is then read and drawn.

Share this post

Link to post
Share on other sites
I commented out the map parser and went back to using a stored list of values. While it's not the prettiest thing I've seen I think I would rather code a map editor than edit .txt files by hand anyways.

Thanks for your help crayon. :D (Nice name)

Share this post

Link to post
Share on other sites
Well that's what I was attempting to do, but the problem (which I just discovered) was that through my means of parsing it was filling the list with 'None' values.

Share this post

Link to post
Share on other sites
This appears to be more of a python scripting issue rather than some actual problem with your terrain engine.

I don't advocate cross posting but why don't you try asking in the scripting forum? I know that Kylotan the forum moderator knows a fair amount of python (rather unsurprisingly!) and someone there will actually know how to go about formatting your input file and reading the values in reliably.

Good luck


Share this post

Link to post
Share on other sites
You're making a common mistake. For every tile in the map data, you're loading it's corresponding image. Now read that sentence again. If your map is 20x20 tiles, you're loading 400 images into memory - whether there's only 3 distinct images or 10. Obviously, that's a waste of memory. Just load every needed tile image once, and draw that image multiple times, once for every occurence in the map data.

Oh... it's even worse! Every time you draw the scene, you're loading these images again! Load them once, store them in some variabeles and use them throughout your program for as long as you need them. Get the idea? :)

As for your map parser, there's various things wrong or flawed in it. First, what does that magical number, 768, mean? I assume it's the size of your map-date. Don't do that! You won't remember it after a while, and you'll then wonder why your program breaks when you load in a larger map file. Also, you're opening your map file every loop cycle! Open it once, read your data from it, then close it. And another thing: you're reading characters from it, so don't check if a tile value is 0, but check if it's '0' instead.

Here's a revised version for you (and before you copy'n'paste, note that I'm using tabs, not spaces ;)):

# By passing the filename, this function becomes reusable:
# you can now load different map files without changing this code
def ParseMapData(filename):
# Open the file, just once
file = open(filename)
# Create an empy array to hold our terrain data
terrain = []

# For every character that we can read from the file, do some stuff
# (the loop will stop when we reach the end of the file, so we don't
# need magical numbers here)
for char in
# A little check: lines contain an end-of-line character, and we
# don't want to store those!
if(char != '\n'):
# We're done now, so close the file and return the terrain data array
return terrain

I hope that helps you somewhat. Good luck! :)

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this