Reputation: 13
The collisions between the creature class objects and plant class objects in my code will not register, if anyone has any ideas on how I can get each rectangle to check for collisions with a sprite group, delete that member of the sprite group it's colliding into, and effect a statistic in only the member of the creature class that collided with the secondary sprite group. Please help me out if you can, and thank you for your time.
class Creature(pg.sprite.Sprite):
def __init__(self, pos, game_area):
super().__init__()
self.image = pg.Surface((5, 5))
self.image.fill(pg.Color('Blue'))
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(2, 0).rotate(random.randrange(360))
self.pos = Vector2(pos)
self.game_area = game_area
self.energymax=10000
self.energy=10000
def update(self):
self.pos += self.vel
self.rect.center = self.pos
self.vel = Vector2(2, 0).rotate(random.randrange(360))
if not self.game_area.contains(self.rect):
self.kill()
self.energy=self.energy-10
if self.energy<=0:
self.kill()
pg.sprite.spritecollide(self,plant_sprites,True)
if pg.sprite.spritecollide(self,plant_sprites,True) and self.energy<self.energymax-1000:
self.energy=self.energy+1000
Plant.self.kill()
def main():
screen = pg.display.set_mode((640, 480))
game_area = pg.Rect(60, 60, 520, 360)
game_area_color = pg.Color('aquamarine2')
clock = pg.time.Clock()
all_sprites = pg.sprite.Group(Creature(game_area.center, game_area))
plant_sprites=pg.sprite.Group(Plant(game_area.center, game_area))
q_pressed = False
p_pressed = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_q:
q_pressed = True
if event.key == pg.K_p:
p_pressed = True
if event.type == pg.KEYUP:
if event.key == pg.K_q:
q_pressed = False
if event.key == pg.K_p:
p_pressed = False
mp=pg.mouse.get_pos()
if mp!=None and q_pressed==True:
all_sprites.add(Creature(mp, game_area))
all_sprites.update()
if mp!=None and p_pressed==True:
all_sprites.add(Plant(mp, game_area))
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.draw.rect(screen, game_area_color, game_area, 2)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Final code after problem was solved:
import pygame as pg
from pygame.math import Vector2
class Plant(pg.sprite.Sprite):
def __init__(self, pos, game_area):
super().__init__()
self.image = pg.Surface((2, 2))
self.image.fill(pg.Color('Green'))
self.rect = self.image.get_rect(center=pos)
self.game_area = game_area
def update(self):
if not self.game_area.contains(self.rect):
self.kill()
screen = pg.display.set_mode((640, 480))
game_area = pg.Rect(60, 60, 520, 360)
game_area_color = pg.Color('aquamarine2')
clock = pg.time.Clock()
plant_sprites=pg.sprite.Group(Plant(game_area.center, game_area))
q_pressed = False
p_pressed = False
class Creature(pg.sprite.Sprite):
def __init__(self, pos, game_area):
super().__init__()
self.image = pg.Surface((5, 5))
self.image.fill(pg.Color('Blue'))
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(2, 0).rotate(random.randrange(360))
self.pos = Vector2(pos)
self.game_area = game_area
self.energymax=10000
self.energy=10000
def update(self):
self.pos += self.vel
self.rect.center = self.pos
self.vel = Vector2(2, 0).rotate(random.randrange(360))
if not self.game_area.contains(self.rect):
self.kill()
self.energy=self.energy-10
if self.energy<=0:
self.kill()
if pg.sprite.spritecollide(self,plant_sprites,True):
if self.energy<self.energymax-2000:
self.energy=self.energy+2000
def main():
screen = pg.display.set_mode((640, 480))
game_area = pg.Rect(60, 60, 520, 360)
game_area_color = pg.Color('aquamarine2')
clock = pg.time.Clock()
global plant_sprites
all_sprites = pg.sprite.Group(Creature(game_area.center, game_area))
plant_sprites=pg.sprite.Group(Plant(game_area.center, game_area))
q_pressed = False
p_pressed = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_q:
q_pressed = True
if event.key == pg.K_p:
p_pressed = True
if event.type == pg.KEYUP:
if event.key == pg.K_q:
q_pressed = False
if event.key == pg.K_p:
p_pressed = False
mp=pg.mouse.get_pos()
if mp!=None and q_pressed==True:
all_sprites.add(Creature(mp, game_area))
all_sprites.update()
if mp!=None and p_pressed==True:
global new_plant
new_plant = Plant(mp, game_area)
plant_sprites.add(new_plant)
screen.fill((30, 30, 30))
all_sprites.draw(screen)
plant_sprites.draw(screen)
pg.draw.rect(screen, game_area_color, game_area, 2)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()```
Upvotes: 1
Views: 75
Reputation: 210928
See pygame.sprite.spritecollide
Return a list containing all Sprites in a Group that intersect with another Sprite. Intersection is determined by comparing the Sprite.rect attribute of each Sprite.
The dokill argument is a bool. If set to True, all Sprites that collide will be removed from the Group.
Therefore, if you call this function twice in one line with dokill set True
, the 2nd call does not detect collisions, as all colliding objects have been removed before.
Call pygame.sprite.spritecollide
just once:
class Creature(pg.sprite.Sprite):
# [...]
def update(self):
self.pos += self.vel
self.rect.center = self.pos
self.vel = Vector2(2, 0).rotate(random.randrange(360))
if not self.game_area.contains(self.rect):
self.kill()
self.energy=self.energy-10
if self.energy<=0:
self.kill()
# pg.sprite.spritecollide(self,plant_sprites,True) <--- DELETE
if pg.sprite.spritecollide(self,plant_sprites,True) and self.energy<self.energymax-1000:
self.energy=self.energy+1000
Plant.self.kill()
You must use the global
statement, if you want to set a variable in global namespace within a function:
def main():
global plant_sprites
# [...]
plant_sprites = pg.sprite.Group(Plant(game_area.center, game_area))
# [...]
You must add new Plants
to the plant_sprites
Group:
if mp!=None and p_pressed==True:
new_plant = Plant(mp, game_area)
plant_sprites.add(new_plant)
Upvotes: 1