1
votes

Unimportant Preamble:

Hello, I'm using Python and Pygame to create a game. This is for the purpose of improving my programming skills rather than a serious attempt at game creation. I've taken a break from Python lately for Objective C, but I'm now returning to it. This is a problem that I was having before I took a brief break, and I've returned to a question that was originally puzzling me. I've spent quite a while researching it, and I have a suspicion I've come across the solution and merely failed to understand it. I apologize for some of the bad naming conventions/lack of comments. I'm working on improving that.

Substance of Question:

Anyway, I've attached the four images I'm using. The program uses a simple function to position various Tiles on the screen. The mouse cursor is a sword. It is the entire image, but I'll be changing that later. I've made the program type "blue" in the shell whenever the cursor collides with a Tile. My goal is to have this happen when it collides with "ANY" tile of that color.

Long-term, I want to be able to modify the properties of these tile sprites. Various game-pieces would interact, and I would need to save the state of each sprite. I'd also be setting interactions for the other sprites.

Right now the sprites are all generating images, but my collision rectangle for the Tile is simply moving after each image is generated. I suppose that makes sense given the code, but I need a way to multiple sprites, each with a rectangle for collision.

Thanks

EDIT: I was unable to add images due to a new-user restriction. They are available enter link description here I think I read somewhere that people can (and do) edit posts here. So if anyone who the ability to move the images into this thread is welcome to do so.

import random,math,sys,os
import pygame
from pygame.locals import *

pygame.init() #Initializing Pygame

#Colors
black=(0,0,0)

#Screen
screen=pygame.display.set_mode((1200,800),0,0)
pygame.display.set_caption("Nero's Sandbox")
pygame.mouse.set_visible(False)
clock=pygame.time.Clock()
fps=40

#Game Functions:

def terminate():
    pygame.quit()
    sys.exit()

def numgen(x,y):
    return random.randint(x,y)

#Loop Variables
tri=2

#Groups:

allsprites = pygame.sprite.Group()
alltiles = pygame.sprite.Group()
allmice = pygame.sprite.Group()

#Mouse Classes

class Pointy(pygame.sprite.DirtySprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load('redsword.png').convert() #31x32 image
        self.image.set_colorkey(black)
        self.rect=self.image.get_rect()
        self.set=pygame.sprite.Group()
        self.add(allmice, allsprites, self.set)
        pygame.sprite.RenderPlain((self.set,allmice,allsprites))

    def update(self):
        screen.fill(black)
        alltiles.draw(screen)
        if event.type == pygame.MOUSEMOTION:
            pos = pygame.mouse.get_pos()
            self.rect.topright = pos
            self.set.draw(screen)

#Tile Sprites - only one rect is being recognized.

class Tile(pygame.sprite.Sprite):
    def __init__(self, graphic):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(graphic).convert()
        self.image = pygame.transform.scale((self.image),(50,50))
        self.rect=self.image.get_rect()
        self.add(alltiles, allsprites)
        self.set=pygame.sprite.RenderPlain((self))

    def update(self, x, y):
        pos = (x,y)
        self.rect.topleft = pos

#Micers
pointy1=Pointy()

#Game Loops

while True:  #Ensures all loops within program are constantly called when conditions are met.  
    screen.fill(black)
    while tri==2:                                   
        for event in pygame.event.get():
            if event.type == QUIT:
                terminate()
        pygame.display.flip()
        x = 0
        y = 50
        w = 0
        while  x!=600:
               x=x+50
               w = w+1
               if w%2==0:
                    purpletile1=Tile('purplesquare.png')
                    purpletile1.set.update(x,y)
                    purpletile1.set.draw(screen)
               else:
                   c=numgen(1,2)
                   if c==1:
                           bluetile1=Tile('lightbluesquare.png')
                           bluetile1.set.update(x,y)
                           bluetile1.set.draw(screen)
                   if c==2:
                           redtile1=Tile('redsquare.png')
                           redtile1.set.update(x,y)
                           redtile1.set.draw(screen)
               if x>=600 and y!=450:
                    if y<450:
                        x = 0
                        y = y+50
                        w=w-1
                    if y>=450:
                       tri=3

    while tri==3:
        for event in pygame.event.get():
           if event.type == QUIT:
               terminate()
           alltiles.draw(screen)
           pointy1.set.update()
           pointy1.set.draw(screen)
           pygame.display.flip()
           clock.tick(fps)
           if pygame.sprite.collide_rect(pointy1,bluetile1):
               print('blue')
1

1 Answers

1
votes

I had this same problem myself! I did some debugging, and it appeared that all instances of my class shared the same instance of pygame.Rect()

You may want to change the line:

pygame.sprite.Sprite.__init__(self)

to

super.__init__(self)

This way, pygame.sprite.Sprite's init will set attributes to your tile. I could be wrong, I'm not entirely familiar with python's inheritance syntax, but that is the way I do it.

I could also be the get_rect that is causing the same rectangle to be used for all classes, but that doesn't seem to be likely.

I hope that I was some help, and just remember that pygame.Rect is an object, so somehow you are instantiating only once.