Pygame sprite collision random movement - pygame

I'm trying to create a game (pygame) where there is a sprite, which when, collided into by the player randomnly moves to another place on the surface, i am not sure how i would do this, as i have very basic knowledge, one guess i had would be to assign random.randint to the sprite, but where would i go from there? Thanks a lot, i'd appreciate the help. Code is below :)
import pygame, sys
from pygame.locals import *
import random
pygame.init()
game=0
width=450
height=613
blue=(100,149,237)
white=(255,255,255)
purple =(128,0,128)
Level=pygame.image.load("level.jpg")
background=pygame.image.load("background.jpg")
startscreen=pygame.image.load("ocean.jpg")
gamescreen=pygame.image.load("screengame.jpg")
Display=pygame.display.set_mode((width,height))
pygame.display.set_caption("Ocean")
movex = 100
movey = 100
DirectX = 0
DirectY = 0
game = 0
MoveEnemy1X = 150
MoveEnemy1Y = 50
rectDirectX = 10
rectDirectY = 9
MoveEnemy2X = 300
MoveEnemy2Y = 100
rectDirect2X = 30
rectDirect2Y = 10
MoveEnemy3X = 400
MoveEnemy3Y = 200
rectDirect3X = 12
rectDirect3Y = 10
clock = pygame.time.Clock()
gameScore = 0
scorefont = pygame.font.SysFont("Arial",30)
score = scorefont.render("Score: " +str(gameScore),True,white)
##pygame.mixer.music.load('ocean.mp3')
##pygame.mixer.music.play(-1,0.0)
direc1 = 5
direc2 = 5
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderPlayer(self):
pygame.draw.rect(Display,blue,(self.x,self.y,self.width,self.height))
self.rect = pygame.Rect(self.x,self.y,self.width,self.height)
class EnemySprite(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy(self):
pygame.draw.rect(Display,white,(MoveEnemy1X,MoveEnemy1Y,30,30))
self.rect = pygame.Rect(MoveEnemy1X,MoveEnemy1Y,self.width,self.height)
class EnemySprite2(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy2(self):
pygame.draw.rect(Display,white,(MoveEnemy2X,MoveEnemy2Y,40,10))
self.rect = pygame.Rect(MoveEnemy2X,MoveEnemy2Y, self.width,self.height)
class EnemySprite3(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderEnemy3(self):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
class GoodSprite(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.rect = pygame.Rect(x,y,width,height)
def RenderGoodSprite(self):
pygame.draw.rect(Display,purple,(100,100,10,10))
self.rect = pygame.Rect(100,100,self.width,self.height)
Player1=Player(100,100,20,20)
Enemy1=EnemySprite(200,200,30,30)
Enemy2=EnemySprite2(300,200,40,10)
Enemy3=EnemySprite3(240,190,30,20)
Good=GoodSprite(150,400,10,10)
TheGameLoop = True
while TheGameLoop:
for event in pygame.event.get():
if (event.type==pygame.QUIT):
TheGameLoop=False
if (event.type==pygame.KEYDOWN):
if (event.key==pygame.K_LEFT):
direc1 = -4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_RIGHT):
direc1 = 4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_DOWN):
direc2 = 4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.key==pygame.K_UP):
direc2 = -4
gameScore+=1
score = scorefont.render("Score: " +str(gameScore),True,white)
if (event.type==pygame.KEYUP):
if (event.key==pygame.K_LEFT):
direc1 = 0
if (event.key==pygame.K_RIGHT):
direc1 = 0
if (event.key==pygame.K_UP):
direc2 = 0
if (event.key==pygame.K_DOWN):
direc2 = 0
if MoveEnemy1X > 430:
MoveEnemy1X = 425
rectDirectX = -5
elif MoveEnemy1X < 0:
MoveEnemy1X = 10
rectDirectX = 5
elif MoveEnemy1Y > 613:
MoveEnemy1Y = 600
rectDirectY = -9
elif MoveEnemy1Y < 0:
MoveEnemy1Y = 0
rectDirectY = 11
if MoveEnemy2X > 430:
MoveEnemy2X = 425
rectDirect2X = -5
elif MoveEnemy2X < 0:
MoveEnemy2X = 11
rectDirect2X = 6
elif MoveEnemy2Y > 613:
MoveEnemy2Y = 600
rectDirect2Y = -12
elif MoveEnemy2Y < 0:
MoveEnemy2Y = 0
rectDirect2Y = 8
if MoveEnemy3X > 430:
MoveEnemy3X = 422
rectDirect3X = -7
elif MoveEnemy3X < 0:
MoveEnemy3X = 11
rectDirect3X = 8
elif MoveEnemy3Y > 613:
MoveEnemy3Y = 600
rectDirect3X = -12
elif MoveEnemy3Y < 0:
MoveEnemy3Y = 0
rectDirect3Y = 5
if direc1 > 430:
Display.blit(Level,(0,0))
pygame.display.update()
if game==0:
Display.blit(startscreen,(0,0))
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_SPACE:
game=1
Display.blit(gamescreen,(0,0))
elif event.key==pygame.K_ESCAPE:
pygame.quit()
pygame.display.update()
if game==1:
Display.blit(gamescreen,(0,0))
Display.blit(score,(220,10))
Player1.RenderPlayer()
Enemy1.RenderEnemy()
Enemy2.RenderEnemy2()
Enemy3.RenderEnemy3()
Good.RenderGoodSprite()
Player1.x +=direc1
Player1.y +=direc2
MoveEnemy1X +=rectDirectX
MoveEnemy1Y +=rectDirectY
MoveEnemy2X +=rectDirect2X
MoveEnemy2Y +=rectDirect2Y
MoveEnemy3X + rectDirect3X
MoveEnemy3Y += rectDirectY
## pygame.mixer.music.load("ocean.mp3")
## pygame.mixer.music.play(-1,0.0)
pygame.display.update()
if pygame.sprite.collide_rect(Player1,Enemy1):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
if pygame.sprite.collide_rect(Player1,Enemy2):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
if pygame.sprite.collide_rect(Player1,Good):
gameScore+=1
Good.x=random.randint(0,500)
Good.y=random.randint(0,600)
pygame.display.update()
if game==2:
Display.blit(background,(0,0))
Display.blit(score,(200,20))
gameScore=0
pygame.display.update()
pygame.mixer.music.stop()
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_SPACE:
game=1
pygame.display.update()
clock.tick(50)

Focusing on this section of your code:
if pygame.sprite.collide_rect(Player1,Enemy1):
game=2
Display.blit(background,(0,0))
pygame.mixer.music.load("untitled.mp3")
pygame.mixer.music.play(1,0.0)
I usually use pygame.sprite.spritecollide().
I am not sure if "collide_rect" can do this too, but here's the trick:
pygame.sprite.spritecollide() returns a list of collisions. This is super helpful.
(Also, I would put all your sprites you want to behave this way in a list.)
--So if I were to use all this in your situation:
for each_enemy in enemy_list:
# see if player hit an enemy;
# the 'False' flag means DON'T delete anything in the event of a collision
enemy_touched_list = pygame.sprite.spritecollide(each_enemy, Player1, False)
# good, now each enemy that was touching a player is in this list
# now we will iterate through this list and find a random place for the enemy.
for enemy_touched in enemy_touched_list:
enemy_touched.render(random.randint(0,width), random.randint(0,height))
Ok, so that code will go through each enemy in your list of enemies, check to see if it is touching a player, and if it is the enemy's position will be reset with your Enemy classes .render() method.
For that last line to work, we need to tweak you class a bit.\
CLASSES:
It looks like you understand the syntax of setting up a class, but you are missing out on their power.
There is no reason you should Have 4 enemy classes! They are all almost identical. The only difference is a few values! That sounds like an object to me!
You should have ONE enemysprite class and then make as many objects from that class as your heart desires. That is why classes are the best. Any slight customization you want between sprites, set up your class so you can pass those in when creating an object.
--let me know if you need more help changing the class stuff.--
--maybe you're new to OOP and these classes are from a tutorial, if that's the case, I can give more info--
and like I said earlier, for my version of your code to work, we need to change your (soon to be single) enemy class's .render() method:
The original:
def RenderEnemy3(self):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,10,10))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
MODIFIED:
def RenderEnemy3(self,xpos,ypos):
pygame.draw.rect(Display, white,(MoveEnemy3X,MoveEnemy3Y,xpos,ypos))
self.rect = pygame.Rect(MoveEnemy3X,MoveEnemy3Y, self.width,self.height)
If you want, I can edit this answer to include the whole "EnemySprite" class modified to communicate well with itself and need only ONE class.
Hope this helps. Just comment if you need clarification on anything. Pygame is way fun.

Related

How to make enemies move to the centre of screen? [duplicate]

i'm learning python by myself, and started with a simple game with pygame.
The game consists, so far, in a ball that's been chased by other balls, i have created a loop that avoid the chasing balls to overlap.
The way the loop works its by a nested loop that moves thru a list that includes all the chasing balls, then measures the distance between them, if the distance is less than the ball radius, it is moved away.
It seems to work most of the time, but sometimes a ball overlaps. I dont know why, if anyone can take a look at my code and give me a hint i would apreciate it, i think the error happens when there are more than 3 balls and at the moment when the player's ball (pelota) collides.
import pygame, random, math
pygame.init()
ancho , alto = 800 , 600
negro = (0,0,0)
blanco=(255,255,255)
FPS = 60
velocidad = 7
velocidadnalguis = velocidad - 2
contadordecolisiones = 1
perseguidores = []
pantalla=pygame.display.set_mode((ancho,alto))
pygame.display.set_caption("un jueguito")
reloj=pygame.time.Clock()
class Pelota(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("pelota.png").convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.image.set_colorkey(negro)
self.rect = self.image.get_rect()
self.rect.center = (ancho/2,alto/2)
self.speed = 0
def update(self):
self.speedx = 0
self.speedy = 0
tecla = pygame.key.get_pressed()
if tecla[pygame.K_LEFT]:
self.speedx = -velocidad
if tecla[pygame.K_RIGHT]:
self.speedx = velocidad
if tecla[pygame.K_UP]:
self.speedy = -velocidad
if tecla[pygame.K_DOWN]:
self.speedy = velocidad
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.right > ancho:
self.rect.right = ancho
if self.rect.bottom > alto:
self.rect.bottom = alto
if self.rect.left < 0:
self.rect.left = 0
if self.rect.top < 0:
self.rect.top = 0
pelota = Pelota()
class Perseguidor(pygame.sprite.Sprite):
def __init__(self,):
super().__init__()
self.image = pygame.image.load('nalguis.png').convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.image.set_colorkey(negro)
self.rect = self.image.get_rect()
self.velocidad = velocidadnalguis
self.radius = self.rect.width/2
self.center = self.rect.center
self.contadordecolisiones = 1
self.enerandom = random.randint(0,4)
if self.enerandom == 0:
self.rect.center = (random.randrange(-130,-30),random.randrange(-130,alto+130))
if self.enerandom == 1:
self.rect.center = (random.randrange(-130,ancho+130),random.randrange(-130,-30))
if self.enerandom == 2:
self.rect.center = (random.randrange(ancho+30,ancho+130),random.randrange(-130,alto+130))
if self.enerandom == 3:
self.rect.center = (random.randrange(-130,ancho+130),random.randrange(alto+30,alto+130))
def update(self):
self.pely = pelota.rect.y
self.pelx = pelota.rect.x
self.perx = self.rect.x
self.pery = self.rect.y
self.dist = math.sqrt(((self.pely-self.pery)**2) + ((self.pelx-self.perx)**2))/velocidadnalguis
self.angulo = math.atan2(self.pely-self.pery,self.pelx-self.perx)
self.speedx = 0
self.speedy = 0
self.speedx = math.cos(self.angulo)
self.speedy = math.sin(self.angulo)
if self.dist>=1:
self.rect.x += velocidadnalguis * self.speedx
self.rect.y += velocidadnalguis * self.speedy
all_sprites = pygame.sprite.Group()
perseguidor_grupo = pygame.sprite.Group()
all_sprites.add(pelota)
terminar=False
while not terminar:
reloj.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminar=True
if len(perseguidor_grupo)<1:
perseguidor=Perseguidor()
perseguidor_grupo.add(perseguidor)
all_sprites.add(perseguidor)
hit = pygame.sprite.spritecollide(pelota, perseguidor_grupo, True, pygame.sprite.collide_circle)
if hit:
if len(perseguidor_grupo)<25:
perseguidor = Perseguidor()
perseguidor1 = Perseguidor()
all_sprites.add(perseguidor, perseguidor1)
perseguidor_grupo.add(perseguidor, perseguidor1)
perseguidores.append(perseguidor1)
perseguidores.append(perseguidor)
else :
perseguidor = Perseguidor()
all_sprites.add(perseguidor)
perseguidor_grupo.add(perseguidor)
perseguidores.append(perseguidor)
dist=1
for i in range (len(perseguidores)):
for j in range(i+1,len(perseguidores)):
perseguidoresxy = [perseguidores[i].rect.centerx,perseguidores[i].rect.centery]
dist=math.hypot(perseguidores[i].rect.centerx - perseguidores[j].rect.centerx , perseguidores[i].rect.centery - perseguidores[j].rect.centery)
if dist <= perseguidor.radius*2:
if perseguidores[i].rect.centerx < perseguidores[j].rect.centerx:
perseguidores[i].rect.centerx -= 3
if perseguidores[i].rect.centery < perseguidores[j].rect.centery:
perseguidores[i].rect.centery -= 3
if perseguidores[i].rect.centerx > perseguidores[j].rect.centerx:
perseguidores[i].rect.centerx += 3
if perseguidores[i].rect.centery > perseguidores[j].rect.centery:
perseguidores[i].rect.centery -= 3
if len(perseguidores)> len(perseguidor_grupo):
del perseguidores [0]
all_sprites.update()
pantalla .fill(negro)
all_sprites.draw(pantalla)
pygame.display.flip()
pygame.quit()
quit()
[...] then measures the distance between them, if the distance is less than the ball radius, it is moved away. It seems to work most of the time, but sometimes a ball overlaps. [...]
Of course.You only consider 2 balls when moving a ball away.
This means that if you move a ball away from one ball, it can happen that you move it straight onto another ball.
You need to check that there is no other ball in the position where you are moving the ball.
Make sure the balls don't overlap as they spawn:
requested_balls = 1
while not terminar:
# [...]
hit = pygame.sprite.spritecollide(pelota, perseguidor_grupo, True, pygame.sprite.collide_circle)
if hit:
requested_balls = min(25, requested_balls+1)
if len(perseguidor_grupo) < requested_balls:
perseguidor = Perseguidor()
if not pygame.sprite.spritecollide(perseguidor, perseguidor_grupo, True, pygame.sprite.collide_circle):
all_sprites.add(perseguidor)
perseguidor_grupo.add(perseguidor)
perseguidores.append(perseguidor)
Only move a ball if the new position of the ball is not yet occupied by a ball:
class Perseguidor(pygame.sprite.Sprite):
# [...]
def update(self):
# [...]
old_rect = self.rect.copy()
if self.dist>=1:
self.rect.x += velocidadnalguis * self.speedx
self.rect.y += velocidadnalguis * self.speedy
hit = pygame.sprite.spritecollide(self, perseguidor_grupo, False, pygame.sprite.collide_circle)
if len(hit) > 1: # at last 1, because the ball hits itself
if random.randrange(2) == 0:
self.rect.x = old_rect.x
else:
self.rect.y = old_rect.y
hit = pygame.sprite.spritecollide(self, perseguidor_grupo, False, pygame.sprite.collide_circle)
if len(hit) > 1:
self.rect = old_rect
Complete example:
import pygame, random, math
pygame.init()
ancho , alto = 800 , 600
negro = (0,0,0)
blanco=(255,255,255)
FPS = 60
velocidad = 7
velocidadnalguis = velocidad - 2
contadordecolisiones = 1
perseguidores = []
pantalla=pygame.display.set_mode((ancho,alto))
pygame.display.set_caption("un jueguito")
reloj=pygame.time.Clock()
class Pelota(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("pelota.png").convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.image.set_colorkey(negro)
self.rect = self.image.get_rect()
self.rect.center = (ancho/2,alto/2)
self.speed = 0
def update(self):
self.speedx = 0
self.speedy = 0
tecla = pygame.key.get_pressed()
if tecla[pygame.K_LEFT]:
self.speedx = -velocidad
if tecla[pygame.K_RIGHT]:
self.speedx = velocidad
if tecla[pygame.K_UP]:
self.speedy = -velocidad
if tecla[pygame.K_DOWN]:
self.speedy = velocidad
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.right > ancho:
self.rect.right = ancho
if self.rect.bottom > alto:
self.rect.bottom = alto
if self.rect.left < 0:
self.rect.left = 0
if self.rect.top < 0:
self.rect.top = 0
pelota = Pelota()
class Perseguidor(pygame.sprite.Sprite):
def __init__(self,):
super().__init__()
self.image = pygame.image.load('nalguis.png').convert()
self.image = pygame.transform.scale(self.image, (30, 30))
self.image.set_colorkey(negro)
self.rect = self.image.get_rect()
self.velocidad = velocidadnalguis
self.radius = self.rect.width/2
self.center = self.rect.center
self.contadordecolisiones = 1
self.enerandom = random.randint(0,4)
if self.enerandom == 0:
self.rect.center = (random.randrange(-130,-30),random.randrange(-130,alto+130))
if self.enerandom == 1:
self.rect.center = (random.randrange(-130,ancho+130),random.randrange(-130,-30))
if self.enerandom == 2:
self.rect.center = (random.randrange(ancho+30,ancho+130),random.randrange(-130,alto+130))
if self.enerandom == 3:
self.rect.center = (random.randrange(-130,ancho+130),random.randrange(alto+30,alto+130))
def update(self):
self.pely = pelota.rect.y
self.pelx = pelota.rect.x
self.perx = self.rect.x
self.pery = self.rect.y
self.dist = math.sqrt(((self.pely-self.pery)**2) + ((self.pelx-self.perx)**2))/velocidadnalguis
self.angulo = math.atan2(self.pely-self.pery,self.pelx-self.perx)
self.speedx = 0
self.speedy = 0
self.speedx = math.cos(self.angulo)
self.speedy = math.sin(self.angulo)
old_rect = self.rect.copy()
if self.dist>=1:
self.rect.x += velocidadnalguis * self.speedx
self.rect.y += velocidadnalguis * self.speedy
hit = pygame.sprite.spritecollide(self, perseguidor_grupo, False, pygame.sprite.collide_circle)
if len(hit) > 1: # at last 1, because the ball hits itself
if random.randrange(2) == 0:
self.rect.x = old_rect.x
else:
self.rect.y = old_rect.y
hit = pygame.sprite.spritecollide(self, perseguidor_grupo, False, pygame.sprite.collide_circle)
if len(hit) > 1:
self.rect = old_rect
all_sprites = pygame.sprite.Group()
perseguidor_grupo = pygame.sprite.Group()
all_sprites.add(pelota)
terminar=False
requested_balls = 1
while not terminar:
reloj.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminar=True
if len(perseguidor_grupo)<1:
perseguidor=Perseguidor()
perseguidor_grupo.add(perseguidor)
all_sprites.add(perseguidor)
hit = pygame.sprite.spritecollide(pelota, perseguidor_grupo, True, pygame.sprite.collide_circle)
if hit:
requested_balls = min(25, requested_balls+1)
if len(perseguidor_grupo) < requested_balls:
perseguidor = Perseguidor()
if not pygame.sprite.spritecollide(perseguidor, perseguidor_grupo, True, pygame.sprite.collide_circle):
all_sprites.add(perseguidor)
perseguidor_grupo.add(perseguidor)
perseguidores.append(perseguidor)
dist=1
if len(perseguidores)> len(perseguidor_grupo):
del perseguidores [0]
all_sprites.update()
pantalla .fill(negro)
all_sprites.draw(pantalla)
pygame.display.flip()
pygame.quit()
quit()

How to check if a button is clicked in pygame [duplicate]

This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 1 year ago.
I am making a spaceship game where you fire bullets at enemy spaceships and collect coins. When you click the start button, the game is supposed to start. However, when I try clicking the start button, the game doesn't start! Is something wrong with my if statement to identify if the start button is clicked?
This is my current code:
import pygame
from pygame.locals import *
from random import randint, choice
from tools import *
pygame.init()
pygame.font.init()
SCREEN_X = 800
SCREEN_Y = 500
CENTER_POS = (400, 225)
screen = pygame.display.set_mode((SCREEN_X, SCREEN_Y))
class Spaceship(pygame.sprite.Sprite):
"""A spaceship object. Used for the player."""
def __init__(self, s, x, y):
pygame.sprite.Sprite.__init__(self)
self.screen = s
self.x, self.y = x, y
self.image = pygame.image.load("spaceship.png")
self.image = pygame.transform.scale(self.image, (175, 175))
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
def update(self):
"""Updates the spaceship rect"""
self.rect.center = (self.x, self.y)
class Bullet(pygame.sprite.Sprite):
"""A bullet object. Appears when the player clicks."""
def __init__(self, s, x, y):
pygame.sprite.Sprite.__init__(self)
self.screen = s
self.x, self.y = x, y
self.image = pygame.image.load("bullet.png")
self.image = pygame.transform.scale(self.image, (100, 100))
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
def update(self):
"""Let's the bullet move upward."""
self.y -= 5
self.rect.center = (self.x, self.y)
if self.y < 0:
self.kill()
class Enemy(pygame.sprite.Sprite):
"""An enemy object. The player's job is to destroy enemies."""
def __init__(self, s, x, y, t):
pygame.sprite.Sprite.__init__(self)
self.type = t
self.screen, self.x, self.y = s, x, y
self.image = pygame.image.load(get_enemy_image()[self.type])
# There is an if statement because the
# N1 Galaxy Fighter and M7 Comet Glider need different sizes
if self.type == "N1 Galaxy Fighter":
self.image = pygame.transform.scale(self.image, (235, 215))
elif self.type == "M7 Comet Glider":
self.image = pygame.transform.scale(self.image, (155, 215))
self.rect = self.image.get_rect()
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
self.score_given = get_enemy_given_score()[self.type]
def update(self):
if self.y < 0:
self.kill()
self.y += 3
self.rect.center = (self.x, self.y)
class GameOverBackground(pygame.sprite.Sprite):
"""The game over background object."""
def __init__(self, s, x, y, size=(100, 100)):
pygame.sprite.Sprite.__init__(self)
self.screen, self.x, self.y = s, x, y
self.size = size
self.image = pygame.image.load("Game_Over.jpg")
self.image = pygame.transform.scale(self.image, self.size)
self.rect = self.image.get_rect()
def blitme(self):
"""Blits the game over image on the screen"""
self.screen.blit(self.image, self.rect)
class Coin(pygame.sprite.Sprite):
"""A coin object."""
def __init__(self, pos=(0, 0), size=(100, 100)):
pygame.sprite.Sprite.__init__(self)
self.x, self.y = pos[0], pos[1]
self.size = size
self.image = pygame.image.load("coin.png")
self.image = pygame.transform.scale(self.image, self.size)
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
def update(self):
"""Updates the coin rect"""
self.rect.center = (self.x, self.y)
class StartButton(pygame.sprite.Sprite):
def __init__(self, s, x, y, size=None):
pygame.sprite.Sprite.__init__(self)
self.screen = s
self.x = x
self.y = y
self.image = pygame.image.load("start_button.png")
if size is not None:
self.image = pygame.transform.scale(self.image, size)
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
def blitme(self):
self.screen.blit(self.image, self.rect)
bg = GameOverBackground(screen, 0, 0, size=(800, 500))
spaceship = Spaceship(screen, 400, 400)
start_button = StartButton(screen, CENTER_POS[0], CENTER_POS[1], size=(300, 195))
game_started = False
bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()
coins = pygame.sprite.Group()
clock = pygame.time.Clock()
enemy_interval = 2000
enemy_event = pygame.USEREVENT + 1
pygame.time.set_timer(enemy_event, enemy_interval)
coin_interval = 3500
coin_event = pygame.USEREVENT + 1
pygame.time.set_timer(coin_event, coin_interval)
score = 0
lives = 3
with open("high_score.txt", "r") as file:
highscore = file.read()
font = pygame.font.SysFont("Arial", 30)
score_text_surface = font.render("Score: {:,}".format(score), True, (0, 0, 0))
lives_text_surface = font.render("HP: %s" % lives, True, (0, 0, 0))
high_score_text_surface = font.render("High score: %s" % highscore, True, (0, 0, 0))
spaceship_collided = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if game_started and event.type == MOUSEBUTTONDOWN:
bullet = Bullet(screen, spaceship.x, spaceship.y - 20)
bullets.add(bullet)
if game_started and event.type == enemy_event and not lives <= 0:
enemy = Enemy(screen, randint(-100, 725), 0, choice(["N1 Galaxy Fighter", "M7 Comet Glider"]))
enemies.add(enemy)
if game_started and event.type == coin_event and not lives <= 0:
if len(coins) < 100:
coins.add(Coin((randint(-125, 750), randint(-200, 400))))
screen.fill((255, 255, 255)) # DO NOT DRAW ANYTHING IN FRONT OF THIS LINE, I'M WARNING YOU
if not game_started:
start_button.blitme()
mouse_pos = pygame.mouse.get_pos()
if CENTER_POS[0] < mouse_pos[0] < CENTER_POS[0]+250 and CENTER_POS[1] > mouse_pos[1] > CENTER_POS[1] + 460:
game_started = True
else:
bullets.update()
key = pygame.key.get_pressed()
amount = 5
if key[pygame.K_a]:
spaceship.x -= amount
elif key[pygame.K_d]:
spaceship.x += amount
elif key[pygame.K_w]:
spaceship.y -= amount
elif key[pygame.K_s]:
spaceship.y += amount
spaceship.update()
if not lives <= 0:
screen.blit(spaceship.image, spaceship.rect)
if not lives <= 0:
bullets.draw(screen)
enemies.draw(screen)
coins.update()
coins.draw(screen)
for i in enemies:
i.update()
if pygame.sprite.spritecollide(i, bullets, True):
score += i.score_given
i.kill()
if spaceship_collided and lives <= 0:
bg.blitme()
if score > int(highscore):
with open("high_score.txt", "w") as file:
file.write(str(score))
if score >= 99999:
score = 99999
if not lives <= 0:
score_text_surface = font.render("Score: {:,}".format(score), True, (0, 0, 0))
screen.blit(score_text_surface, (590, 0))
lives_text_surface = font.render("HP: %s" % lives, True, (0, 0, 0))
screen.blit(lives_text_surface, (260, 0))
high_score_text_surface = font.render("High score: %s" % highscore, True, (0, 0, 0))
screen.blit(high_score_text_surface, (360, 0))
if pygame.sprite.spritecollide(spaceship, enemies, dokill=True):
lives -= 1
spaceship_collided = True
if pygame.sprite.spritecollide(spaceship, coins, dokill=True):
score += 10
pygame.display.update()
clock.tick(60)
Use a pygame.Rect object and the method collidepoint:
button_rect = start_button.image.get_rect(topleft = (start_button.x, start_button.y))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == MOUSEBUTTONDOWN:
if not game_started:
if button_rect.collidepoint(event.pos):
game_started = True
else:
bullet = Bullet(screen, spaceship.x, spaceship.y - 20)
bullets.add(bullet)
See Pygame mouse clicking detection

I want to add a bomb into my flappy bird game, but it won't detect the collision. here is the code

I want to add a bomb into my flappy bird game, but it won't detect the collision.
I cannot get the bird to be detected if it made contact with the bomb
The bomb shows up, but I can't make it detect the collision with the bird, here is the code I have so far.Also,i did not class a new object for the bomb, I put it in with the pipes.
I think there is a problem with the colliderect
If you need the images please tell me.
Can someone help me?
I would be really grateful.
Thanks in advance.
import pygame
from pygame.locals import * # noqa
import sys
import random
class FlappyBird:
def __init__(self):
self.screen = pygame.display.set_mode((400, 708))
self.bird = pygame.Rect(65, 50, 50, 50)
self.background = pygame.image.load("background.png")
self.birdSprites = [pygame.image.load("1.png"),
pygame.image.load("2.png"),
pygame.image.load("dead.png")]
self.wallUp = pygame.image.load("bottom.png")
self.wallDown = pygame.image.load("top.png")
self.bomb = pygame.image.load("bomb.png")
self.bombx = 600
self.gap = 130
self.wallx = 400
self.birdY = 350
self.jump = 0
self.jumpSpeed = 10
self.gravity = 5
self.dead = False
self.sprite = 0
self.counter = 0
self.offset = random.randint(-110, 110)
def updateWalls(self):
self.wallx -= 2
if self.wallx < -80:
self.wallx = 400
self.counter += 1
self.offset = random.randint(-110, 110)
self.bombx -= 2
if self.bombx < -80:
self.bombx = 600
self.counter += 1
self.offset = random.randint(-110, 110)
def birdUpdate(self):
if self.jump:
self.jumpSpeed -= 1
self.birdY -= self.jumpSpeed
self.jump -= 1
else:
self.birdY += self.gravity
self.gravity += 0.2
self.bird[1] = self.birdY
upRect = pygame.Rect(self.wallx,
360 + self.gap - self.offset + 10,
self.wallUp.get_width() - 10,
self.wallUp.get_height())
downRect = pygame.Rect(self.wallx,
0 - self.gap - self.offset - 10,
self.wallDown.get_width() - 10,
self.wallDown.get_height())
bombRect = pygame.Rect(self.bombx,
0 - self.gap - self.offset - 10,
self.bomb.get_width() - 10,
self.bomb.get_height()
)
if upRect.colliderect(self.bird):
self.dead = True
if downRect.colliderect(self.bird):
self.dead = True
if bombRect.colliderect(self.bird):
self.bomb = pygame.image.load("bombexplode")
self.dead = True
if not 0 < self.bird[1] < 720:
self.bird[1] = 50
self.birdY = 50
self.dead = False
self.counter = 0
self.wallx = 400
self.offset = random.randint(-110, 110)
self.gravity = 5
def run(self):
clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont("Arial", 50)
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not self.dead:
self.jump = 17
self.gravity = 5
self.jumpSpeed = 10
self.screen.fill((255, 255, 255))
self.screen.blit(self.background, (0, 0))
self.screen.blit(self.wallUp,
(self.wallx, 360 + self.gap - self.offset))
self.screen.blit(self.wallDown,
(self.wallx, 0 - self.gap - self.offset))
self.screen.blit(self.bomb,
(self.bombx, 0 - self.gap - self.offset))
self.screen.blit(font.render(str(self.counter),
-1,
(255, 255, 255)),
(200, 50))
if self.dead:
self.sprite = 2
elif self.jump:
self.sprite = 1
self.screen.blit(self.birdSprites[self.sprite], (70, self.birdY))
if not self.dead:
self.sprite = 0
self.updateWalls()
self.birdUpdate()
pygame.display.update()
if __name__ == "__main__":
FlappyBird().run()
I don't know much about using sprites, but if you can get the position and size of each object, you can give them rectangular hitboxes and check if their corners are inside each other:
Another way is to use circular hitboxes if those fit better. For these, find the distace between the centers and check if it is smaller than their radius' combined.
Edit :
You can use
self.bird = pygame.Rect(65, 50, 50, 50)
# creating bomb hitbox
self.rect_bomb = pygame.Rect(100, 100, 200, 200)
if self.bird.colliderect(self.rect_bomb):
# end up your code

Enemy Sprite is hit and disappears but is not fixed later if it was hit on the sides

I have a code solved for this issue Image does not remain on screen after executing for loop in pygame. So I decided to put some platforms as a result of what I learned from pygame. I also decided to make the cowboy move to the right and left and go down to the bottom of the screen.
But when a collision occurs on the right or left side of the cowboy as shown in the Diagram, the class PlayerShip is not executed as expected in the main loop through the def draw_reaction () function because I do not see the image of the cowboy represented by player_sprite fixed in position (60, 48). It only works correctly if the cowboy is hit from below.
Assets
missile.png
cowboy.png
police.png
Diagram:
|missile| <--<-- (is touched its right side by the missile)|cowboy| <--<-- direction
^
|
^
|
(fire missile direction vertical)
^
|
d
i
r
e
c
t
i
o
n
My MWE coding:
import pygame
import random
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
GRAY = (128,128,128)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
class PlayerShip( pygame.sprite.Sprite ):
def __init__(self):
super().__init__()
self.image = pygame.image.load( "cowboy.png" )
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.topleft = ( 60, 48 )
player_sprite = PlayerShip()
class Platform(pygame.sprite.Sprite):
def __init__(self, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(GREEN)
self.rect = self.image.get_rect()
class MovingPlatform(Platform):
change_x = 0
change_y = 0
boundary_top = 0
boundary_bottom = 0
boundary_left = 0
boundary_right = 0
player = None
level = None
def update(self):
self.rect.x += self.change_x
hit = pygame.sprite.collide_rect(self, self.player)
if hit:
if self.change_x < 0:
self.player.rect.right = self.rect.left
else:
self.player.rect.left = self.rect.right
self.rect.y += self.change_y
hit = pygame.sprite.collide_rect(self, self.player)
if hit:
if self.change_y < 0:
self.player.rect.bottom = self.rect.top
else:
self.player.rect.top = self.rect.bottom
if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
self.change_y *= -1
cur_pos = self.rect.x - self.level.world_shift
if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
self.change_x *= -1
class Level(object):
def __init__(self, player):
self.platform_list = pygame.sprite.Group()
self.enemy_list = pygame.sprite.Group()
self.player = player
self.background = None
self.world_shift = 0
self.level_limit = -1000
def update(self):
self.platform_list.update()
self.enemy_list.update()
def draw(self, screen):
screen.fill(GRAY)
self.platform_list.draw(screen)
self.enemy_list.draw(screen)
def shift_world(self, shift_x):
self.world_shift += shift_x
for platform in self.platform_list:
platform.rect.x += shift_x
for enemy in self.enemy_list:
enemy.rect.x += shift_x
class Room(object):
wall_list = None
enemy_sprites = None
def __init__(self):
self.wall_list = pygame.sprite.Group()
self.enemy_sprites = pygame.sprite.Group()
class Level_01(Level):
def __init__(self, player):
Level.__init__(self, player)
self.level_limit = -1500
level = [[210, 70, 500, 500],
[210, 70, 800, 400],
[210, 70, 1000, 500],
[210, 70, 1120, 280],
[210, 70, -120, 500],
]
for platform in level:
block = Platform(platform[0], platform[1])
block.rect.x = platform[2]
block.rect.y = platform[3]
block.player = self.player
self.platform_list.add(block)
block = MovingPlatform(70, 40)
block.rect.x = 1350
block.rect.y = 280
block.boundary_left = 1350
block.boundary_right = 1600
block.change_x = 10
block.player = self.player
block.level = self
self.platform_list.add(block)
class Level_02(Level):
def __init__(self, player):
Level.__init__(self, player)
self.level_limit = -1000
level = [[210, 70, 500, 550],
[210, 70, 800, 400],
[210, 70, 1000, 500],
[210, 70, 1120, 280],
]
for platform in level:
block = Platform(platform[0], platform[1])
block.rect.x = platform[2]
block.rect.y = platform[3]
block.player = self.player
self.platform_list.add(block)
block = MovingPlatform(70, 70)
block.rect.x = 1500
block.rect.y = 300
block.boundary_top = 100
block.boundary_bottom = 550
block.change_y = -1
block.player = self.player
block.level = self
self.platform_list.add(block)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
width = 40
height = 60
self.image = pygame.image.load("police.png").convert()
self.rect = self.image.get_rect()
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.change_x = 0
self.change_y = 0
self.level = None
def update(self):
self.calc_grav()
self.rect.x += self.change_x
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
elif self.change_x < 0:
self.rect.left = block.rect.right
self.change_y += 0
self.rect.y += self.change_y
block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.bottom = block.rect.top
elif self.change_y < 0:
self.rect.top = block.rect.bottom
self.change_y = 0
if isinstance(block, MovingPlatform):
self.rect.x += block.change_x
def calc_grav(self):
if self.change_y == 0:
self.change_y = 1
else:
self.change_y += .35
if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.change_y >= 0:
self.change_y = 0
self.rect.y = SCREEN_HEIGHT - self.rect.height
def jump(self):
self.rect.y += 2
platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
self.rect.y -= 2
if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
self.change_y = -10
def go_left(self):
self.change_x = -6
def go_right(self):
self.change_x = 6
def stop(self):
self.change_x = 0
class Cowboy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("cowboy.png").convert()
self.rect = self.image.get_rect()
self.image.set_colorkey(BLACK)
class Missile(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("missile.png").convert()
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
def update(self):
self.rect.y += -3
def main():
pygame.init()
size = [SCREEN_WIDTH, SCREEN_HEIGHT]
screen = pygame.display.set_mode(size)
block_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
pygame.display.set_caption("Platformer with moving platforms")
apple = pygame.image.load("missile.png").convert()
block = Cowboy()
player_image = pygame.image.load("cowboy.png").convert()
player = Player()
level_list = []
level_list.append(Level_01(player))
level_list.append(Level_02(player))
current_level_no = 0
current_level = level_list[current_level_no]
block_list.add(block)
all_sprites_list.add(block)
all_sprites_list.add(player)
active_sprite_list = pygame.sprite.Group()
player.level = current_level
player.rect.x = 340
player.rect.y = SCREEN_HEIGHT - player.rect.height
active_sprite_list.add(player)
done = False
clock = pygame.time.Clock()
x_speed = 0
y_speed = 0
rect_x = 50
rect_y = 50
rect_change_x = 1
rect_change_y = 90
x = rect_x
y = rect_y
player.rect.y = rect_x
player.rect.y = 480
score = 0
size = (1366, 768)
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
while not done:
x += x_speed
y += y_speed
rect_x += rect_change_x
if rect_x > 280:
rect_change_x *= -1
rect_x += rect_change_x
rect_y += rect_change_y
if rect_x < 0:
rect_change_x *= -1
rect_x += rect_change_x
rect_y += rect_change_y
block.rect.x = rect_x
block.rect.y = rect_y
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
bullet = Missile()
bullet.rect.x = player.rect.x
bullet.rect.y = player.rect.y
all_sprites_list.add(bullet)
bullet_list.add(bullet)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.go_left()
if event.key == pygame.K_RIGHT:
player.go_right()
if event.key == pygame.K_UP:
player.jump()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and player.change_x < 0:
player.stop()
if event.key == pygame.K_RIGHT and player.change_x > 0:
player.stop()
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
score += 1
print(score)
screen.blit(player_image, [60, 48])
if bullet.rect.y < -10:
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
def draw_reaction():
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
all_sprites_list.add( player_sprite )
break
all_sprites_list.update()
active_sprite_list.update()
current_level.update()
if player.rect.right >= 1500:
diff = player.rect.right - 500
player.rect.right = 500
current_level.shift_world(-diff)
if player.rect.left <= 120:
diff = 120 - player.rect.left
player.rect.left = 120
current_level.shift_world(diff)
current_position = player.rect.x + current_level.world_shift
if current_position < current_level.level_limit:
if current_level_no < len(level_list)-1:
player.rect.x = 120
current_level_no += 1
current_level = level_list[current_level_no]
player.level = current_level
else:
done = True
current_level.draw(screen)
active_sprite_list.draw(screen)
x += x_speed
y += y_speed
all_sprites_list.draw(screen)
draw_reaction()
clock.tick(60)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()
UPDATE EDIT: If current_level.draw(screen) is not used in the main loop then the code works as expected. But I still don't know what causes it.
I simply added all_sprites_list.add (player_sprite) to the for block in block_hit_list:. In my view this would be necessary to track self.image.get_rect (). Then:
Before:
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
score += 1
print(score)
screen.blit(player_image, [60, 48])
if bullet.rect.y < -10:
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
Later:
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
all_sprites_list.add(player_sprite)
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
score += 1
print(score)
screen.blit(player_image, [60, 48])
if bullet.rect.y < -10:
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
But I would like someone to explain to me how it really happened behind the code by making more experienced references to the documentation or the style of the code itself. Thankful if anyone can make that explanation.

pygame creating multiple sprites

I am very new to pygame, and was trying to make a basic tower defence game. I have looked around, but cannot grasp how to create multiple sprites (towers) from the image I am using. Here is my code for the TD game. But I do not know how to create more then one sprite(tower).
import pygame
import time
import sys
import os
pygame.init()
WINDOWWIDTH = 1800
WINDOWHEIGHT = 1800
os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (0,30)
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
background_colour = (63,200,70)
GAMETITLE = "Tower Defence"
font = pygame.font.SysFont(None, 100)
def balanceText(balance):
screen_text = font.render(str(balance), True, (255,255,255))
screen.blit(screen_text, [1640,0])
def main():
balance = 100
pygame.display.set_caption(GAMETITLE)
clock = pygame.time.Clock()
spritegroup =pygame.sprite.Group()
sprite =pygame.sprite.Sprite()
tower = sprite.image = pygame.image.load("tower.png")
sprite.image = tower
sprite.rect = sprite.image.get_rect()
drawTower = False
towerPlaced = False
bulletX = 250
sprite.add(spritegroup)
while True:
screen.fill(background_colour)
pygame.draw.rect(screen, (255,255,255), ((0, 100), (1100, 90)))
pygame.draw.rect(screen, (255, 255,255), ((1010, 100), (100, 600)))
pygame.draw.rect(screen, (255,255,255), ((1010, 700), (2400, 90)))
pygame.draw.rect(screen, (139,69,19), ((1600, 0), (2400, 18000)))
pygame.draw.rect(screen, (128, 128,128), (( 300,250), (140,140)))
pygame.draw.rect(screen, (128, 128,128), (( 600,250), (140,140)))
pygame.draw.rect(screen, (128, 128,128), (( 800,700), (140,140)))
pygame.draw.rect(screen, (128, 128,128), (( 1150,500), (140,140)))
balanceText(balance)
if drawTower:
spritegroup.draw(screen)
pygame.display.update()
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pressed()[0] and towerPlaced == False:
mousePos = pygame.mouse.get_pos()
if mousePos[0] > 300 and mousePos[0] < 450 and mousePos[1] > 250 and mousePos[1] < 400:
drawTower = True
sprite.rect.center = (370, 320)
towerPlaced = True
balance -= 50
elif mousePos[0] > 600 and mousePos[0] < 750 and mousePos[1] > 250 and mousePos[1] < 400:
drawTower = True
sprite.rect.center = (670, 320)
towerPlaced = True
balance-= 50
elif mousePos[0] > 800 and mousePos[0] < 950 and mousePos[1] > 700 and mousePos[1] < 850:
drawTower = True
sprite.rect.center = (870, 770)
towerPlaced = True
balance-= 50
elif mousePos[0] > 1150 and mousePos[0] < 1300 and mousePos[1] > 500 and mousePos[1] < 650:
drawTower = True
sprite.rect.center = (1220, 570)
towerPlaced = True
balance-= 50
elif event.type == pygame.QUIT:
pygame.display.quit()
main()
Thanks for looking! I know the code is a bit messy right now.
You need to use the Sprite class properly. To do this, you have to define your sprite as a subclass of pygame.sprite.Sprite, like this:
class Tower(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = tower_img
self.rect = self.image.get_rect()
self.rect.center = (x, y)
Then you can spawn a tower any time you like by creating another instance and adding it to the group:
new_tower = Tower(370, 320)
spritegroup.add(new_tower)
I highly recommend looking at the Sprite documentation:
http://www.pygame.org/docs/ref/sprite.html - there's lots of good info in there. There are also many good tutorials out there that go into how you use sprites in Pygame. Here is a link to one that I wrote:
http://kidscancode.org/blog/2016/08/pygame_1-2_working-with-sprites/