Skip to main content
GameDev.net gamedev.net
🔒 Locked

Pygame Image Loading

Started by Robomaniac Jul 7, 2005 at 8:12 AM 8 replies 2.7k views
Original Post
Robomaniac
Robomaniac
Alright, this has been bugging me for a couple of hours now. If i try to load an image in my main python file, it loads fine, and i can display it. However, if I try to load it from my Tile class, the image fails to load. I've tried repositioning the file to any other directory, and it just doesn't work : Is there any know problem with pygame and loading images from a class? the main.py file and the Tile.py file are in the same directory, and the image is in a data subdir. Thanks for any help load_image function

def load_image(name, colorkey=None) :
    fullname = name
    
    try:
	image = pygame.image.load(fullname)
	    
    except pygame.error, message:
        print "Cannot load image: ", name
        raise SystemExit, message

    image = image.convert()
    
    if colorkey is not None:
       if colorkey is -1:
           colorkey = image.get_at((0, 0))

    image.set_colorkey(colorkey, RLEACCEL)

    return image, image.get_rect()
Tile class

class Tile :
	#position is in matrix location, i.e. 1 4
	def __init__(self, name, x, y):
		print "Loading Tile:" , name
		fullname = os.path.join("data/tiles", name);
		fullname = fullname + ".tile"
		
		file = open(fullname, "r")
		
		self.properties = {}
		
		for line in file.readlines():
			key, value = line.split("=")
			self.properties[key] = value
			print key, value
		
		self.image, self.rect = loaders.load_image("data/" + self.properties["image"])
		
		self.rect.top = y * 16
		self.rect.left = x * 16
		
	def draw(self, screen):
		screen.blit(self.image, self.rect)
_____________________________Stephen EckenrodeProject Head / Lead Programmer
Fruny
Fruny
Can you provide a test script that demonstrate the error, so that I can try to reproduce it here?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
SiCrane
SiCrane
Also which pygame version are you using?
Robomaniac
Robomaniac
Here's a test script:
import sys, osimport pygamefrom pygame.locals import *import Roomimport loaderspygame.init()screen = pygame.display.set_mode((640, 480))room = Room.Room("test", "standard")while 1:	for event in pygame.event.get():		if event.type == pygame.QUIT: sys.exit()		screen.fill((0, 0, 0))	#room.draw()	pygame.display.flip()


I am using pygame version 1.6.2 and python 2.3
_____________________________Stephen EckenrodeProject Head / Lead Programmer
Fruny
Fruny
Ok, looking at your code and the sample script, I can see we are missing a lot of things here. When I asked you for a script I could run, I meant a script I could run with only the two bits of code you'd given me (one in 'main.py', the other in 'Tile.py') - that doesn't appear to be the case.

No 'Room.py', no 'loaders.py'.
And I don't have a tile file I can parse either...

If you want us to be able to help you, please do give us enough to actually run a test.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Robomaniac
Robomaniac
sorry... here you go

.py files are in $ROOT$
.bmp files are in $ROOT$/data
.tile file are in $ROOT$/data/tiles

--------------------------------------------------------------------------------
loaders.py
import os, sysimport pygamefrom pygame.locals import *if not pygame.font: print "Warning, fonts disabled"if not pygame.mixer: print "Warning, sound disabled"def load_image(name, colorkey=None) :    fullname = name        try:	image = pygame.image.load(fullname)	        except pygame.error, message:        print "Cannot load image: ", name        raise SystemExit, message    image = image.convert()        if colorkey is not None:       if colorkey is -1:           colorkey = image.get_at((0, 0))    image.set_colorkey(colorkey, RLEACCEL)    return image, image.get_rect()def load_sound(name) :    class NoneSound :        def play(self): pass    if not pygame.mixer:        return NoneSound()    fullname = os.path.join("data", name)    try:        sound = pygame.mixer.Sound(fullname)    except pygame.error, message:        print "Cannot load sound: ", name        raise SystemExit, message    return sound


--------------------------------------------------------------------------------
Tile.py
import sys, osimport pygamefrom pygame.locals import *import loadersclass Tile :	#position is in matrix location, i.e. 1 4	def __init__(self, name, x, y):		print "Loading Tile:" , name		fullname = os.path.join("data/tiles", name);		fullname = fullname + ".tile"				file = open(fullname, "r")				self.properties = {}				for line in file.readlines():			key, value = line.split("=")			self.properties[key] = value			print key, value				self.image, self.rect = loaders.load_image("data/" + self.properties["image"])				self.rect.top = y * 16		self.rect.left = x * 16			def draw(self, screen):		screen.blit(self.image, self.rect)


--------------------------------------------------------------------------------
main.py
import sys, osimport pygamefrom pygame.locals import *import Tileimport loaderspygame.init()screen = pygame.display.set_mode((640, 480))img = pygame.image.load("data/floor.bmp")rect = img.get_rect()print "Image Loaded"tile = Tile.Tile("floor", 0, 0)while 1:	for event in pygame.event.get():		if event.type == pygame.QUIT: sys.exit()				screen.fill((0, 0, 0))	tile.draw()	pygame.display.flip()


--------------------------------------------------------------------------------
floor.tile (in $ROOT$/data/tiles)
name=Floorimage=floor.bmppassable=1visible=1


just put any image in floor.bmp (in $ROOT$/data)
_____________________________Stephen EckenrodeProject Head / Lead Programmer
Fruny
Fruny
Anyway, modified thusly, it works for me:

main.py
import pygamedef load_image(name, colorkey=None) :    fullname = name        try:	image = pygame.image.load(fullname)	        except pygame.error, message:        print "Cannot load image: ", name        raise SystemExit, message    image = image.convert()        if colorkey is not None:       if colorkey is -1:           colorkey = image.get_at((0, 0))    image.set_colorkey(colorkey, pygame.RLEACCEL)    return image, image.get_rect()


Tile.py
import pygamedef load_image(name, colorkey=None) :    fullname = name        try:	image = pygame.image.load(fullname)	        except pygame.error, message:        print "Cannot load image: ", name        raise SystemExit, message    image = image.convert()        if colorkey is not None:       if colorkey is -1:           colorkey = image.get_at((0, 0))    image.set_colorkey(colorkey, pygame.RLEACCEL)    return image, image.get_rect()


data/foo.png - An image

data/tile/foo.tile
image=foo.png


Be careful that with your code as it is, you cannot have spaces around the '=' sign. Use str.trim(). Also, make sure to call os.path.join("data","tile",name) instead of os.path.join("data/tile",name).

Interactive:
import pygameimport Tilepygame.init()scr = pygame.display.set_mode((256,256))t = Tile.Tile("foo",0,0)
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Robomaniac
Robomaniac
(you seem to have posted the code to the load_image function twice in the main.py box and the Tile.py box, afaict)
_____________________________Stephen EckenrodeProject Head / Lead Programmer
Fruny
Fruny
Ok, going over your new example, the problem is that in the tile file, when you read the line, the string you get back does include the newline character. So the name of the file it is trying to load is "...\floor.bmp\n".

printing the key/value pair with print "'%s'='%s'" % (key, value) demonstrates this.

The solution:
key = key.strip()value = value.strip()


(and not 'trim' as I said before)

Tile.py
import sys, osimport pygamefrom pygame.locals import *import loadersclass Tile :	#position is in matrix location, i.e. 1 4	def __init__(self, name, x, y):		print "Loading Tile:" , name        	fullname = os.path.join("data","tiles", name);		fullname = fullname + ".tile"		                try:                    file = open(fullname, "r")                except:                    print "Cannot open tile file", os.path.realpath(fullname)                    raise				self.properties = {}				for line in file.readlines():			key, value = line.split("=")			key = key.strip()			value = value.strip()			self.properties[key] = value			print "'%s'='%s'" % (key, value)                imagename = os.path.join("data", self.properties["image"] )				self.image, self.rect = loaders.load_image(imagename)				self.rect.top = y * 16		self.rect.left = x * 16			def draw(self, screen):		screen.blit(self.image, self.rect)


main.py
import sys, osimport pygamefrom pygame.locals import *import Tileimport loadersdef main():    screen = pygame.display.set_mode((640, 480))##    img = pygame.image.load(r"data\floor.png")##    rect = img.get_rect()####    print "Image Loaded"    tile = Tile.Tile("floor", 0, 0)    while 1:            for event in pygame.event.get():                    if event.type == pygame.QUIT: sys.exit()                                        screen.fill((0, 0, 0))            tile.draw(screen)            pygame.display.flip()if __name__ == "__main__":    pygame.init()    try:        main()    finally:        pygame.quit()


loader.py
import os, sysimport pygamefrom pygame.locals import *if not pygame.font: print "Warning, fonts disabled"if not pygame.mixer: print "Warning, sound disabled"def load_image(name, colorkey=None) :    fullname = name        try:	image = pygame.image.load(fullname)	        except pygame.error, message:        print "Cannot load image: ", name, " = ", os.path.realpath(fullname)        raise SystemExit, message    image = image.convert()        if colorkey is not None:       if colorkey is -1:           colorkey = image.get_at((0, 0))    image.set_colorkey(colorkey, RLEACCEL)    return image, image.get_rect()def load_sound(name) :    class NoneSound :        def play(self): pass    if not pygame.mixer:        return NoneSound()    fullname = os.path.join("data", name)    try:        sound = pygame.mixer.Sound(fullname)    except pygame.error, message:        print "Cannot load sound: ", name        raise SystemExit, message    return sound


And make sure to always use os.path.join instead of just adding "/"
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Robomaniac
Robomaniac
thanks, works like a beaut :)

http://img73.imageshack.us/img73/3562/screen1tilemap9kf.gif
_____________________________Stephen EckenrodeProject Head / Lead Programmer

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.