[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Problem accessing pygame.Rect() members



I wrote a custom pygame.sprite.RenderPlain() class. It modifies
.draw() to include a source rect of the sprite. Now I need to modify
the dest rect, converting its world() coordinates to screen()
coordinates.

I wrote: Map().coord_to_screen( world ) and Map().coord_to_world(
screen ) and they are working. But I can't access the member
spr.rect.left or spr.rect.top of the sprite's Rect() to modify it. I
get an AttributeError.

The classes I'm using in this sprite group are:

class Unit(pygame.sprite.Sprite):

Which derives .Sprite(), adding movement. It works fine until I try
accessing the .rect in RenderSrcRect().draw(): to blit with global
coordinates converted to screen coordinates.

(1) The documentation says that these aren't members( .top, .left,
etc...), but are virtual attributes. What is a virtual attribute?

(2) What's wrong with my code?

The first code snippet is my working class, that just uses spr.rect as
the dest rect. The second code snippet is my failed attempts to modify
to convert the .rect world() coords to screen() coords.

# code: original class, before screen() coords. This class *does* work.
# file: RenderSrcRect.py
# Author: jake bolton [created: 2007/11/14]
# About: RenderSrcRect
	# child of RenderPlain, adds source rect support
	
import pygame

class RenderSrcRect(pygame.sprite.RenderPlain):
	"""custom sprite group rendering class. Uses src Rect()s of sprite.
	
	the inheritance is: RenderPlain() == Group() which derives
AbstractGroup()
		
	members used from the sprites to blit:
		.image = the sprite's surface
		.rect = the blit dest rect
		.rect_source = the blit source rect
	"""
	
	def __init__(self):
		"""initialize Unit()"""
		pygame.sprite.RenderPlain.__init__(self)
	
	def draw(self, surface):
		"""draw(surface). Draw all sprites onto the surface
		
		same as .RenderPlain.draw() except spr.rect_source is used to blit"""
		sprites = self.sprites()
		surface_blit = surface.blit
		for spr in sprites:
			# blit with src rect
			self.spritedict[spr] = surface_blit(spr.image, spr.rect,
spr.rect_source)
		self.lostsprites = []
	

# modified class, uses screen() coords. This class has AttributeError:
# the error:

AttributeError: 'tuple' object has no attribute 'left' on line:
	spr.rect.left = 40

If you comment out the whole (try 1) block, (try 2) will still fail.

# code:
# file: RenderSrcRect.py
# Author: jake bolton [created: 2007/11/14]
# About: RenderSrcRect
	# child of RenderPlain, adds source rect support, and uses screen() coords
	
from euclid import Vector2
import pygame
from pygame.locals import * # needed for Rect() ?

class RenderSrcRect(pygame.sprite.RenderPlain):
	"""custom sprite group rendering class. Uses src rects of sprite.
	
	the inheritance is: RenderPlain() == Group() which derives
AbstractGroup()
		
	members used from the sprites to blit:
		.image = the sprite's surface
		.rect = the blit dest rect
		.rect_source = the blit source rect
	"""
	
	def __init__(self, game):
		"""initialize Unit()"""
		pygame.sprite.RenderPlain.__init__(self)
		# reference to the Map() class, for the later .coord_to_screen() call
		self.game = game
		self.map = self.game.map
	
	def draw(self, surface):
		"""draw(surface). Draw all sprites onto the surface
		
		same as .RenderPlain.draw() except spr.rect_source is used to blit"""
		sprites = self.sprites()
		surface_blit = surface.blit
		
		for spr in sprites:									
			# use screen coords for dest rect
			# == (try 1): I want to do something like this: but it fails: ==
			# note: self.map.coord_to_screen() returns a euclid.Vector2()
			dest_rect = pygame.Rect(
				self.map.coord_to_screen( spr.rect.topleft ).x,
				self.map.coord_to_screen( spr.rect.topleft ).y,
				spr.rect.x,
				spr.rect.y,
				0, 0 ) # dest rect ignores w,h values
			
			# (try 2): try 1 didn't work, so I test just Rect() member access: fails
			spr.rect.left = 40 # this line gives an attribute error
			
			self.spritedict[spr] = surface_blit(spr.image, dest_rect, spr.rect_source)
		self.lostsprites = []

thanks,
-- 
Jake