Rect location problem


monkeyelf

Still Fresh
Joined
Dec 8, 2011
Messages
2
I'll start of by saying I'm very new to python/pygame and even before that I don't have a lot of programming experience. My problem is that I have a rectangle called platform, and when I use platform.surf.get_rect the rect appears at 0,0 instead of 200,300 the location of platform. My code is below


if self.keymap[3]:


for dot in self.dot_list:


for platform in self.platform_list:


dot.dir = 3


future_dot = dot.rect.move(10, 0)


if platform.surf.get_rect().colliderect(future_dot):


dot.rect.right = 200


elif self.screen.get_rect().contains(future_dot):


dot.rect = future_dot


else:


dot.rect.right = 800
 
Wrap in code tags so indentation doesn't get removed. I assume this is what you meant:



Code:
if self.keymap[3]:

    for dot in self.dot_list:

        for platform in self.platform_list:

            dot.dir = 3

            future_dot = dot.rect.move(10, 0)

            if platform.surf.get_rect().colliderect(future_dot):

                dot.rect.right = 200

            elif self.screen.get_rect().contains(future_dot):

                dot.rect = future_dot

            else:

                dot.rect.right = 800

But I don't think I can help just from this snippet of code. If there's a problem with a value returned from "platform", you'll have to tell us more about platform. This code only shows what happens to dot; what code creates and modifies platform?
 
Code:
import pygame, random

import math, sys

class Dot(object):

	"""Dot object"""

	def __init__(self):

    	self.surf = pygame.image.load("arrow.png").convert_alpha()

    	self.rect = pygame.Rect(0,0,50,50)

    	self.frame = 0

    	self.dir = 0 # 0 = up, 1 = down, 2 = left, 3 = right

    	self.start_time = pygame.time.get_ticks()

	def update(self, keymap):

    	"""updates the sprite"""

    	if keymap[0] or keymap[1] or keymap[2] or keymap[3]:

        	if pygame.time.get_ticks() - self.start_time > 250:

            	self.frame += 1

            	if self.frame > 3:

                	self.frame = 0

            	self.start_time = pygame.time.get_ticks()

    	else:

        	self.frame = 0

        	self.start_time = pygame.time.get_ticks()

class Platform(object):

	"""Platform Object"""

	def __init__(self):

    	self.surf = pygame.Surface((100, 25))

    	self.surf.fill((0, 0, 0))

    	self.rect = self.surf.get_rect()

    	#self.rect = pygame.Rect(200,300,100,25)

class Game(object):

	def __init__(self):

    	self.screen = pygame.display.set_mode((800, 600))

    	self.screen.fill((0, 255, 255))

    	self.game_over = False

    	self.clock = pygame.time.Clock()

    	self.dot_list = [Dot() for x in range(1)]

    	self.keymap = [False, False, False, False] #up, down, left, right key pressed? Really should use a dictionary

    	for dot in self.dot_list:

        	dot.rect.topleft = (775*random.random(), 575*random.random())

    	self.platform_list = [Platform() for x in range(1)]

    	for platform in self.platform_list:

        	platform.rect.topleft = (200, 300)



	def process_input(self):

    	for event in pygame.event.get():

        	if event.type == pygame.KEYDOWN:

            	if event.key == pygame.K_ESCAPE:

                	self.game_over = True

            	if event.key == pygame.K_d:

                	self.keymap[3] = True

            	if event.key == pygame.K_a:

                	self.keymap[2] = True

            	if event.key == pygame.K_w:

                	self.keymap[0] = True

            	if event.key == pygame.K_s:

                	self.keymap[1] = True

        	if event.type == pygame.KEYUP:

            	if event.key == pygame.K_d:

                	self.keymap[3] = False

            	if event.key == pygame.K_a:

                	self.keymap[2] = False

            	if event.key == pygame.K_w:

                	self.keymap[0] = False

            	if event.key == pygame.K_s:

                	self.keymap[1] = False


	def update(self):

    	if self.keymap[3]:

        	for dot in self.dot_list:

            	for platform in self.platform_list:

                	dot.dir = 3

                	future_dot = dot.rect.move(10, 0)

                	if platform.surf.get_rect().colliderect(future_dot):

                    	dot.rect.right = 200

                	elif self.screen.get_rect().contains(future_dot):

                    	dot.rect = future_dot

                	else:

                    	dot.rect.right = 800

    	if self.keymap[2]:

        	for dot in self.dot_list:

            	for platform in self.platform_list:

                	dot.dir = 2

                	future_rect = dot.rect.move(-10,0)

                	if platform.surf.get_rect().colliderect(future_rect):

                    	dot.rect.left = 300

                	elif self.screen.get_rect().contains(future_rect):

                    	dot.rect = future_rect

                	else:

                    	dot.rect.left = 0

    	if self.keymap[0]:

        	for dot in self.dot_list:

            	for platform in self.platform_list:

                	dot.dir = 0

                	future_rect = dot.rect.move(0,-10)

                	if platform.surf.get_rect().colliderect(future_rect):

                    	dot.rect.top = 325

                	elif self.screen.get_rect().contains(future_rect):

                    	dot.rect = future_rect

                	else:

                    	dot.rect.top = 0

    	if self.keymap[1]:

        	for dot in self.dot_list:

            	for platform in self.platform_list:

                	dot.dir = 1

                	future_rect = dot.rect.move(0,10)

                	if platform.surf.get_rect().colliderect(future_rect):

                    	dot.rect.bottom = 300

                	elif self.screen.get_rect().contains(future_rect):

                    	dot.rect = future_rect

                	else:

                    	dot.rect.bottom = 600

    	for dot in self.dot_list:

        	dot.update(self.keymap)


	def draw(self):

    	self.screen.fill((0, 255, 255))

    	for dot in self.dot_list:

        	self.screen.blit(dot.surf, dot.rect, pygame.Rect(dot.frame*50, dot.dir*50, 50, 50))

    	for platform in self.platform_list:

        	self.screen.blit(platform.surf, platform.rect)


pygame.init()

g = Game()

while not g.game_over:

	g.clock.tick(30)

	g.process_input()

	g.update()

	g.draw()

	pygame.display.flip()

sys.exit()

That's all the code
 
Ah, got it. I had to fix the indentation in your code (I assume it works for you and got messed up in the copy-paste, otherwise it wouldn't work at all).


The problem is that you're using platform.surf.get_rect(), when instead you should just use platform.rect. See, each call to Surface.get_rect() returns a new Rect object. You could call get_rect() on one surface over and over, but each returned Rect would have no idea if you modified any of the other Rects. So your code creates platform.rect from platform.surf, then moves platform.rect to a new position, but platform.surf remains unaware of the move. The fix, therefore, is to go to lines 73, 84, 95, and 106, and replace "surf.get_rect()" with "rect". Now the Dot collides with the Platform.


I do have another issue where the Dot object is only shown after I press the up key. Pressing any of the other directions makes it disappear, but its location is still tracked properly. I don't know if this is a problem for you, or just an issue with indentation, so I haven't investigated it.


Also, you don't need to end with sys.exit(). Once the program reaches the end, it should exit automatically.


Ah, and you may want to look at pygame's sprite stuff; it looks like your Dot and Platform classes could just be Sprites, and Game could make use of Groups.
 
Last edited by a moderator:
Surface.get_rect() just returns a rect at (0,0) by default. It's to create a new rect from an image (e.g. something you would pass on to the rect attribute of a sprite).


I can see you're trying to do WAY too much by hand, almost like you're coming from C/SDL. Pygame has a lot of useful stuff (e.g. Sprites) and ignoring them can only result in your game being slower.


Do look at this:


http://www.pygame.org/docs/tut/newbieguide.html


Finally, this isn't really a great place to ask general questions about Python (though it seems it worked out this time, which is great); Python-forum.org is a much better place. This place is really mostly useful if you're having a problem specific to the Pandora.
 
Back
Top