How can I blit a random image at a random coordinate everytime collision occurs? [duplicate] - python

This question already has answers here:
How can i controll collision from sprites?
(1 answer)
How can I show explosion image when collision happens?
(2 answers)
Adding a particle effect to my clicker game
(1 answer)
Closed 4 months ago.
with my code right now, whenever my sprite collides with a Pokemon, the pokemon blits at random locations 3 - 5 times then just doesn't let me collide with it anymore. Sometimes the pokemon that blits is random sometimes its not.
Here is my pokemon code and my collision code:
class Pokemon:
def __init__(self, parent_screen):
self.pokemon = [
pygame.image.load('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/pokemon/bulbasaur.png').convert(),
pygame.image.load('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/pokemon/caterpie.png').convert(),
pygame.image.load('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/pokemon/charmander.png').convert(),
pygame.image.load('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/pokemon/pidgey.png').convert(),
pygame.image.load('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/pokemon/squirtle.png').convert()
]
self.parent_screen = parent_screen
self.x = SIZE
self.y = SIZE
self.random_pokemon = random.choice(self.pokemon)
self.set_colorkey()
def set_colorkey(self):
for i in range(len(self.pokemon)):
image = self.pokemon[i]
image.set_colorkey((0, 0, 0))
self.pokemon[i] = pygame.transform.scale(image, (150, 150))
def move(self):
self.parent_screen.blit(random.choice(self.pokemon), (self.x, self.y))
self.x = random.randint(1,25)*SIZE
self.y = random.randint(1,25)*SIZE
def draw_pokemon(self):
self.parent_screen.blit(self.random_pokemon, (self.x, self.y))
#MY COLLISION CODE:
score = 0
class Game:
def __init__(self):
pygame.init()
pygame.display.set_caption('Pokemon Catcher')
pygame.mixer.init()
self.surface = pygame.display.set_mode((700, 677))
self.background_music()
self.snake = Snake(self.surface)
self.snake.draw()
self.random_pokemon = Pokemon(self.surface)
self.pokemon = Pokemon(self.surface)
self.pokemon.draw_pokemon()
def collide(self,x1,y1,x2,y2):
distance = math.sqrt((math.pow(x2 - x1,2)) + (math.pow(y2-y1,2)))
if distance < 40:
return True
else:
return False
def play(self):
global score
self.render_background()
self.snake.walk()
self.pokemon.draw_pokemon()
self.display_score()
pygame.display.flip()
if self.collide(self.snake.x, self.snake.y, self.random_pokemon.x, self.random_pokemon.y):
score += 1
self.pokemon.move()
sound = pygame.mixer.Sound('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/music/cartoon eat.wav')
pygame.mixer.Sound.play(sound)
pygame.display.flip()
# collide with boundary
if self.snake.x <= -40 or self.snake.y <= -40 or self.snake.x >= 650 or self.snake.y >= 600:
sound = pygame.mixer.Sound('/Users/gersh/PycharmProjects/snakeeo/venv/lib/resources/music/bump.wav')
pygame.mixer.Sound.play(sound)
raise 'Hit the boundry error'

Related

Syntax error in the pygame collision detection function python3 [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
Closed 1 year ago.
so I try to program a 2d game platform like space invaders, but the problem is in the collision, when I try to define the collision, which I use in her characteristics, the characteristics of the classes (enemy coordinates and the bullet coordinates), the code won't start. And this is the result : `
def isc (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
^
SyntaxError: invalid syntax
this is the code if you need it :
############# LIBRARIES ####################
import pygame, sys, random
import math
from pygame.constants import SYSTEM_CURSOR_WAITARROW
from pygame import mixer
pygame.init()
############ WINDOW OPTIONS ################
Swidth = 800
Sheight =600
screen = pygame.display.set_mode((Swidth, Sheight))
pygame.display.set_caption("Space Invader By Mal4D")
icon = pygame.image.load('places/favicon.png')
pygame.display.set_icon(icon)
############# COLORS #######################
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255 , 255 , 0)
########### VARIANTS ######################
isJumping= False
LevelJump = 0.25
rocket = pygame.image.load("rocket/rocket.png")
space = pygame.image.load("places/bg.png")
bullet = pygame.image.load("rocket/bullet.png")
Sound = pygame.mixer.music.load("Sounds/laser.mp3")
Bgsound= pygame.mixer.music.load("Sounds/bg.mp3")
enemy = pygame.image.load("Enemy/enemy.png")
ax=random.randint(0,700)
by=random.randint(20,120)
Bgsound1 = mixer.Sound("Sounds/bg.mp3")
BullletSound = mixer.Sound("Sounds/laser.mp3")
############## Class Players ##########################
class Player():
def __init__(self,x,y,width,height):
self.x=x
self.y=y
self.width=width
self.height=height
self.step=10
self.speed=10
self.isJumping= False
def drawplayer (self,screen):
screen.blit(rocket, (rockeet.x, rockeet.y))
def drawscreen (self,screen):
screen.blit(space, (0,0))
rockeet = Player(350,500,50,50)
########### Bullet #####################
class Bullet():
def __init__(self, x, y , y_change, x_change, state):
self.x=x
self.y= y
self.y_change=y_change
self.x_change= x_change
self.state= state
def fire(x,y):
Bulllet.state = "fire"
screen.blit(bullet,(x+16, y+10))
Bulllet=Bullet(350,500,20,0,"ready")
**def isCollision (ax1, by1, cx, dy):
distance = math.sqrt(math.pow(ax1 - cx, 2) + (math.pow(by1- dy, 2)))
if distance <27:
return True
else:
return False**
################## Enemy ########################
class Enemy():
def __init__(self, x ,y, stepx,stepy):
self.x = x
self.y=y
self.stepx=stepx
self.stepy=stepy
def drawenemy(screen):
screen.blit(enemy,(ax,by))
eneemy = Enemy(random.randint(0,700),random.randint(20,120),3,35)
################# Clussion#########################
score = 0
def isc (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
distance = math.sqrt(math.pow(eneemy.x - Bulllet.x, 2) + (math.pow(eneemy.y- Bulllet.y, 2)))
if distance <27:
return True
else:
return False
################### Game Loop #####################################
#Bgsound1.play(180)
while 1:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
keys=pygame.key.get_pressed()
rockeet.drawscreen(screen)
Enemy.drawenemy(screen)
if keys[pygame.K_SPACE]:
if Bulllet.state == "ready":
BullletSound.play()
Bulllet.x=rockeet.x
Bulllet.y=rockeet.y
Bullet.fire(Bulllet.x, Bulllet.y)
if keys[pygame.K_LEFT] and rockeet.x - rockeet.step >= 0:
rockeet.x =rockeet.x-rockeet.step
if keys[pygame.K_RIGHT] and rockeet.x + rockeet.width +rockeet.step <= Swidth :
rockeet.x =rockeet.x+rockeet.step
if Bulllet.y <= 0:
Bulllet.y= 500
Bulllet.state = "ready"
if Bulllet.state == "fire":
Bullet.fire(Bulllet.x, Bulllet.y)
Bulllet.y -= Bulllet.y_change
########### Enemy Mouvement #########################################
collision = isCollision( eneemy.x, eneemy.y, Bulllet.x, Bulllet.y)
ax+= eneemy.stepx
if ax<= 0:
eneemy.stepx=3
by+= eneemy.stepy
elif ax >= 750:
eneemy.stepx=-3
by+= eneemy.stepy
if collision:
Bulllet.y= 500
Bulllet.state="ready"
eneemy.x= random.randint(0,700)
eneemy.y=random.randint(20,)
################## Collision ######################
################## OUTRO #######################################
rockeet.drawplayer(screen)
pygame.display.update()
the result:
def isCollision (eneemy.x, eneemy.y, Bulllet.x, Bulllet.y ):
^
SyntaxError: invalid syntax
The formal parameters of a function cannot be structure elements like eneemy.x. Either Change the names of the parameters:
def isc (enemy_x, enemy_y, bullet_x, bullet_y):
distance = math.sqrt(math.pow(enemy_x - bullet_x, 2) + (math.pow(enemy_y- bullet_y, 2)))
if distance <27:
return True
else:
return False
Or pass the objects to the function:
def isc (enemy, bullet):
distance = math.sqrt(math.pow(enemy.x - bullet.x, 2) + (math.pow(enemy.y- bullet.y, 2)))
if distance <27:
return True
else:
return False
collision = isCollision( eneemy.x, eneemy.y, Bulllet.x, Bulllet.y)
collision = isCollision(eneemy, Bulllet)
Note, that you can use math.hypot instead of math.sqrt and math.pow:
distance = math.sqrt(math.pow(enemy_x - bullet_x, 2) + (math.pow(enemy_y- bullet_y, 2)))
distance = math.hypot(enemy_x - bullet_x, enemy_y - bullet_y)

Pygame rotation sprite pivot on moving displayed surface [duplicate]

This question already has answers here:
How can you rotate an image around an off center pivot in Pygame
(1 answer)
Still Having Problems With Rotating Cannon's Properly Towards The Player Pygame
(1 answer)
How do I make image rotate with mouse python [duplicate]
(1 answer)
Closed 1 year ago.
so I tried to add the weapon to my game and rotate it on a pivot point looking to the mouse, I achieved to do it but I have an issue I can't resolve, when I walk with my player, after I walk down around the middle of the map the rotate angle looks to become wrong.
I link you a gif for a better understanding.
Here is some part of the working rotation code :
import pygame, os, math
from weapon_constants import *
from level_constants import *
from pygame.math import Vector2
class Weapon(pygame.sprite.Sprite):
def __init__(self, game, name, label, x, y):
self._layer = WEAPON_LAYER
self.groups = game.all_sprites, game.weapons
pygame.sprite.Sprite.__init__(self, self.groups)
self.options = WEAPONS[name]
self.label = label
self.game = game
self.file = os.path.join(os.getcwd(), DEFAULT_WEAPON_IMAGE_PATH, self.get_option('image'))
self.image = pygame.transform.scale(pygame.image.load(self.file).convert_alpha(), DEFAULT_WEAPON_SIZE)
self.original_image = self.image
self.rect = self.image.get_rect(center=(x, y))
self.offset = Vector2(25, 0)
self.pos = Vector2(self.rect.x, self.rect.y)
self.angle = 0
def get_option(self, option):
if option in self.options:
return self.options[option]
return False
def update(self):
self.pos = Vector2(self.game.player.rect.center)
rel_x, rel_y = pygame.mouse.get_pos() - self.pos
self.angle = (180 / math.pi) * math.atan2(rel_y, rel_x)
if self.pos.y > pygame.display.get_surface().get_width() // 2:
print('bad rotation happen \n pos_y : {}, \n angle : {}, \n mouse_pos : {}'.format(self.pos.y, self.angle, pygame.mouse.get_pos()))
pass
self.rotate()
def rotate(self):
self.image = pygame.transform.rotozoom(self.original_image, -self.angle, 1)
rotated_offset = self.offset.rotate(self.angle)
self.rect = self.image.get_rect(center= self.pos + rotated_offset)
Here is the first output (I saw it was around half width of the map) :
bad rotation happen
pos_y : 452.0,
angle : 23.962488974578186,
mouse_pos : (450, 468)

I attempted to make a function that allows my sprites to re-produce but it create an infinite amount [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I made a class function that will allow the animals to reproduce once they have eaten enough of a group, from there it would create a new sprite on that location, and then it should lower the energy Val of that sprite, instead it does not do this and instead causes an infinite amount of sprites to be created causing the program to slow down and crash.
this is the functions I made for it to work
def checkEnergy(self):
EnergyVal=self.energy
return EnergyVal
def reproduce(self,energy,Xpos,Ypos):
if energy==10:
prey = Prey(prey_image,Xpos,Ypos )
all_sprites.add(prey)
Rabbit_group.add(prey)
self.energy-=4
here is where I implemented it:
if len(carrots) > 0:
for rabbit in Rabbit_group:
movementx, movementy = Track(rabbit.x, carrots[0].x, rabbit.y, carrots[0].y)#how the prey move
rabbit.move(movementx, movementy)
energyval=prey.checkEnergy()
rabbit.reproduce(energyval,600,700)
full code:
#simulates interactions of wild life
import math
import random
import pygame,sys
import random
import pdb
from pygame.locals import *
#classes--------------
class Animal(pygame.sprite.Sprite):#main class
def __init__(self, image, x, y):
super().__init__()
self.x = x
self.y = y
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.Energy=10
def move(self, mx, my):#moves the sprite
self.x += mx
self.y += my
self.rect = self.image.get_rect(center = (self.x, self.y))#sets the image to the position
def is_collided_with(self, sprite):#is the eat function
return self.rect.colliderect(sprite.rect)
def checkEnergy(self):
EnergyVal=self.energy
return EnergyVal
def reproduce(self,energy,Xpos,Ypos):
if energy==10:
prey = Prey(prey_image,Xpos,Ypos )
all_sprites.add(prey)
Rabbit_group.add(prey)
self.energy-=4
class Predator(Animal):#class for predators
def __init__(self):
image = pygame.image.load('Icon.png')
self.energy=10
super().__init__(image, 600, 700)
class Prey(Animal):
"""prey class"""
def __init__(self, image, x, y):
super().__init__(image, x, y)
self.energy=10
#self.rect = self.image.get_rect(center = (self.x, self.y))
class Carrot(pygame.sprite.Sprite):#food for prey class
def __init__(self):
super().__init__()
self.x = 100
self.y = 100
self.image = pygame.image.load('carrot.png')
self.rect = self.image.get_rect(center = (self.x, self.y))
# Functions-----------
def Track(AgressorX,DefenderX,AgressorY,DefenderY):#finds comapres X and Y, tells sprite how to move
if AgressorX > DefenderX:
XMovement=-1
elif AgressorX< DefenderX:
XMovement=1
else:
XMovement=0
if AgressorY > DefenderY:
YMovement=-1
elif AgressorY < DefenderY:
YMovement=1
else:
YMovement=0
return XMovement, YMovement
def leavingWindow(Xpos, Ypos):#boundry, keeps sprites in the window
if Xpos<=0:
return True
elif Xpos>=950:
return True
if Ypos<=0:
return True
elif Ypos>=750:
return True
def Boundry(Xpos, Ypos):
if Xpos<=0:
Xmovement=0
elif Xpos>=950:
Xmovement=950
else:
Xmovement=+0
if Ypos<=0:
ymovement=0
elif Ypos>=750:
ymovement=60
else:
ymovement=+0
return Xmovement, ymovement
pygame.init()#setsup pygame
screen = pygame.display.set_mode((1000,800))#setsup screen
clock = pygame.time.Clock()#tells program how fast to update
timmer = 1#how long program has gone on for
#setsup the classes
predator = Predator()
predator2=Predator()
#prey = Prey()
carrot = Carrot()
all_sprites = pygame.sprite.Group()
prey_image = pygame.image.load('Prey.png')
carrot_group = pygame.sprite.Group()
carrot_group.add(Carrot())
Wolf_group= pygame.sprite.Group()
Wolf_group.add(Predator())
Rabbit_group= pygame.sprite.Group()
for i in range(0, 2):
prey = Prey(prey_image, 100 * i, 700)
all_sprites.add(prey)
Rabbit_group.add(prey)
#setsup the classes as sprites
all_sprites.add(carrot_group)
all_sprites.add(Wolf_group)
all_sprites.add(Rabbit_group)
#start of program
running=True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
carrots = carrot_group.sprites()
preys = Rabbit_group.sprites()
predators = Wolf_group.sprites()
if len(preys) > 0:
for wolf in Wolf_group:
movementx, movementy = Track(wolf.x, preys[0].x, wolf.y, preys[0].y)#how the predators move
wolf.move(0,1)#movementx, #movementy)
Leaving=leavingWindow(wolf.x,wolf.y)#keeps sprites in window
if Leaving == True:
movementx,movementy=Boundry(wolf.x,wolf.y)
wolf.x=movementx
wolf.y=movementy
if len(carrots) > 0:
for rabbit in Rabbit_group:
movementx, movementy = Track(rabbit.x, carrots[0].x, rabbit.y, carrots[0].y)#how the prey move
rabbit.move(movementx, movementy)
energyval=prey.checkEnergy()
rabbit.reproduce(energyval,600,700)
screen.fill((0,128,0))#background
all_sprites.draw(screen)#makes the sprites
pygame.display.update()#updates screen
timmer=timmer+1
for carrot in carrots:#removes the carrots if they contact a rabbit
for rabbit in Rabbit_group:
if rabbit.is_collided_with(carrot):
print('works')
carrot.kill()
for wolf in Wolf_group:
for rabbit in Rabbit_group:
if rabbit.is_collided_with(wolf):
print("works 2")
rabbit.kill()
pygame.quit()
exit()
MRE Here:
import pygame,sys
import random
import pdb
from pygame.locals import *
class Animal(pygame.sprite.Sprite):#main class
def __init__(self, image, x, y):
super().__init__()
self.x = x
self.y = y
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.Energy=10
def move(self, mx, my):#moves the sprite
self.x += mx
self.y += my
self.rect = self.image.get_rect(center = (self.x, self.y))#sets the image to the position
def checkEnergy(self):
EnergyVal=self.energy
return EnergyVal
def reproduce(self,energy,Xpos,Ypos):
if energy==10:
prey = Prey(prey_image,Xpos,Ypos )
all_sprites.add(prey)
Rabbit_group.add(prey)
self.energy-=4
class Prey(Animal):
"""prey class"""
def __init__(self, image, x, y):
super().__init__(image, x, y)
self.energy=10
#self.rect = self.image.get_rect(center = (self.x, self.y))
pygame.init()#setsup pygame
screen = pygame.display.set_mode((1000,800))#setsup screen
clock = pygame.time.Clock()#tells program how fast to update
timmer = 1#how long program has gone on for
prey_image = pygame.image.load('Prey.png')
Rabbit_group= pygame.sprite.Group()
all_sprites=pygame.sprite.Group()
for i in range(0, 2):
prey = Prey(prey_image, 100 * i, 700)
all_sprites.add(prey)
Rabbit_group.add(prey)
#setsup the classes as sprites
all_sprites.add(Rabbit_group)
#start of program
running=True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
preys = Rabbit_group.sprites()
for rabbit in Rabbit_group:
rabbit.move(0, -1)
energyval=prey.checkEnergy()
rabbit.reproduce(energyval,600,700)
screen.fill((0,128,0))#background
all_sprites.draw(screen)#makes the sprites
pygame.display.update()#updates screen
timmer=timmer+1
pygame.quit()
exit()
I'm pretty sure the issue is self.energy-=4 I don't think its working properly but I am unsure on how to fix it.
I made a class function that will allow the animals to reproduce once they have eaten enough of a group [...]
You do the evaluation at the wrong place.
if len(carrots) > 0:
for rabbit in Rabbit_group:
movementx, movementy = Track(rabbit.x, carrots[0].x, rabbit.y, carrots[0].y)#how the prey move
rabbit.move(movementx, movementy)
# energyval=prey.checkEnergy() <--- DELETE
# rabbit.reproduce(energyval,600,700) <--- DELETE
Increment the energy when the rabbit eats a carrot. And reproduce the rabbit if the energy reaches the threshold:
class Animal(pygame.sprite.Sprite):#main class
# [...]
def reproduce(self):
if self.energy >= 10:
prey = Prey(self.image, self.x, self.y)
all_sprites.add(prey)
Rabbit_group.add(prey)
self.energy -= 4
while running:
# [...]
for carrot in carrots:#removes the carrots if they contact a rabbit
for rabbit in Rabbit_group:
if rabbit.is_collided_with(carrot):
print('works')
carrot.kill()
rabbit.energy += 1
rabbit.reproduce()

I am making snake in pygame and python is giving me an error that one of my objects is actually a string, but its not meant to be

The error that shows up in python right now is
Traceback (most recent call last):
File "C:\Users\Eduardo.Graglia\AppData\Local\Programs\Python\Python37\Start.py", line 66, in <module>
snake = snake(self) # create an instance
File "C:\Users\Eduardo.Graglia\AppData\Local\Programs\Python\Python37\Start.py", line 17, in __init__
food.image = pygame.image.load("food.png")
AttributeError: 'str' object has no attribute 'image'
I am very new to python and pygame, so most of the code I've been using is stuff I've taken and adapted from stack overflow
What I was trying to do with the food object was make it so that it was all in one player class because I am confused on how to call methods from other classes and use objects from other classes in one class. If anyone has any alternatives to what I've done please tell me.
import pygame
import os
import time
import math
import random
length = 650
width = 400
headx = 0
heady = 0
class snake(object):
def __init__(self, food):
self.image = pygame.image.load("head.png")
self.x = 0
self.y = 0
food.image = pygame.image.load("food.png")
food.x = 0
food.y = 0
def handle_keys(self):
""" Handles Keys """
key = pygame.key.get_pressed()
dist = 25 # distance moved in 1 frame, try changing it to 5
if key[pygame.K_DOWN]: # down key
self.y += dist # move down
heady = heady - dist
elif key[pygame.K_UP]: # up key
self.y -= dist # move up
heady = heady - dist
if key[pygame.K_RIGHT]: # right key
self.x += dist # move right
headx = headx - dist
elif key[pygame.K_LEFT]: # left key
self.x -= dist # move left
headx = headx - dist
def fooddrop(food, surface):
newfoodx = 1
newfoody = 1
while newfoodx % 25 != 0 or newfoodx !=0:
newfoodx = random.randint(0,650)
while newfoody % 25 != 0 or newfoody !=0:
newfoody = random.randint(0,400)
food.x = newfoodx
food.y = newfoody
surface.blit(food.image,(food.x,food.y))
def draw(self, surface):
""" Draw on surface """
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
self = 'null'
food = 'null'
pygame.init()
screen = pygame.display.set_mode((length, width))
snake = snake(self) # create an instance
food = snake(food)
running = True
while running:
# handle every event since the last frame.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # quit the screen
running = False
if snake.y > width or snake.y < 0 or snake.x > length or snake.x < 0: #Border Created
pygame.quit() # quit the screen
running = False
time.sleep(0.125)
snake.handle_keys() # handle the keys
screen.fill((0,0,0)) # fill the screen with white
snake.draw(screen) # draw the snake to the screen
snake.fooddrop(screen)
pygame.display.update() # update the screen
clock.tick(40)
Feel free to completely destroy my code because I am new and need to learn.
Thanks in advance!
You have to distinguish between Classes and instances of classes (objects).
Create a class Snake (or whatever name). Please use a leading capital letter for the name of the class to avoid confusions (see Style Guide for Python Code - Class Names).
The constructor of the class has 1 parameter (beside self), the name of the image:
class Snake(object):
def __init__(self, imagename):
self.image = pygame.image.load(imagename)
self.x = 0
self.y = 0
Create 2 instances of the class:
snake = Snake("head.png")
food = Snake("food.png")

Software Design and Development Major: Pygame Smudge Trails

First off, i have searched online and this website for solutions and the ones i have tried are not working so i decided to post my individual question and code. This program was created using Python 3.2.2 and the corresponding compatible version of pygame. I also realize a more efficient method would be to use sprites, sprite groups and 'dirty rect' updating but i unable to convert the program and so i will continue without the added benefits of such functions.
Problem: Smudge trails where the 'asteroids' are moving are left behind.
Hypothesis: Background is blitted onto the screen however the asteroids are blitted onto the Background.
Please Reply - btw i'm a highschooler from AUS :D
import pygame
import random
import math
pygame.init()
height = 550
width = 750
screen = pygame.display.set_mode((width, height))
background = pygame.image.load("Planet.jpg")
Clock = pygame.time.Clock()
class asteroid(pygame.sprite.Sprite):
def __init__(self, x, y, size):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.size = 15
self.speed = 0.0
self.angle = 0
self.colour = (171, 130, 255)
self.thickness = 0
def display(self):
pygame.draw.circle(background, self.colour, (int(self.x),int(self.y)), self.size, self.thickness)
pygame.draw.circle(background, (255, 255, 255), (int(self.x),int(self.y)), self.size, 1)
def move(self):
self.x += math.sin(self.angle) * self.speed
self.y -= math.cos(self.angle) * self.speed
def boundaries(self):
if self.x > width - self.size:
self.x = 0 + self.size
elif self.x < self.size:
self.x = width - self.size
if self.y > height - self.size:
self.y = 0 + self.size
elif self.y <self.size:
self.y = height - self.size
num_target = 5
my_particles = []
num_particles = len(my_particles)
while num_particles < 5:
for n in range(num_target):
size = 20
x = random.randint(size, height - size)
y = random.randint(size, width - size)
target = asteroid(x, y, size)
target.speed = random.uniform(1.0, 1.0)
target.angle = random.uniform(0, math.pi*2)
my_particles.append(target)
num_particles = num_particles + 1
def main():
pygame.display.set_caption("Anyu's Game")
screen.blit(background, (0,0))
pygame.display.update()
score = (pygame.time.get_ticks()/1000)
print (score)
while True:
pygame.display.update()
screen.blit(background, (0,0))
MouseP = pygame.mouse.get_pos()
frames = Clock.get_fps
pygame.mouse.set_visible
score = (pygame.time.get_ticks()/1000)
print (score)
print (MouseP)
for target in my_particles:
target.move()
target.boundaries()
target.display()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit();
if __name__=='__main__':
main()
Basically, you are right! The circles are drawn directly onto the background, and everytime new circles are drawn, the old circles remain. Resulting in the smudges/trails.
You can just change background to screen in your draw method. This will fix it.
But it is really worth using the Sprite classes as intended. I've made a few changes to your code to switch it over for you. With these changes it runs without trails :)
Here are the changes and explainations:
Add this near the top:
#Create a new `pygame.Surface`, and draw a circle on it, then set transparency:
circle = pygame.Surface((30,30))
circle = circle.convert()
pygame.draw.circle(circle, (171, 130, 255), (int(15),int(15)), 15, 0)
circle.set_colorkey(circle.get_at((0, 0)), pygame.RLEACCEL)
Add this to the asteroid, __init__ method:
#Sets the asteroid image, and then the asteroids co-ords (these are in `rect`)
self.image = circle
self.rect = self.image.get_rect()
Add this to the end of def move(self):
self.rect[0] = self.x
self.rect[1] = self.y
change:
my_particles = []
to:
#This is a special pygame container class, it has a draw() method that tracks changed areas of the screen.
my_particles = pygame.sprite.RenderUpdates()
change:
my_particles.append(target)
to:
my_particles.add(target)
change:
while True:
pygame.display.update()
screen.blit(background, (0,0))
MouseP = pygame.mouse.get_pos()
frames = Clock.get_fps
pygame.mouse.set_visible
score = (pygame.time.get_ticks()/1000)
print (score)
print (MouseP)
for target in my_particles:
target.move()
target.boundaries()
target.display()
pygame.display.update()
to:
#initial screen draw:
screen.blit(background, (0,0))
pygame.display.update()
while True:
#remove previous drawn sprites and replaces with background:
my_particles.clear(screen, background)
MouseP = pygame.mouse.get_pos()
frames = Clock.get_fps
pygame.mouse.set_visible
score = (pygame.time.get_ticks()/1000)
print (score)
print (MouseP)
for target in my_particles:
target.move()
target.boundaries()
#draws changed sprites to the screen:
pygame.display.update(my_particles.draw(screen))
Remove the display method as it is no longer needed.
This will also run a lot faster than the your earlier code, as the time taken to draw something is proportional to the size of the drawing area, and previously it was drawing the whole background everytime - now it only draws the sprites and changes to the background!
Hope this helps :)
This already has an answer but this can be useful instead of other methods.
Make sure when you blit the images onto the screen, flip the display after blitting everything.
I would consider making a draw() function
Like this:
def draw(self):
# Blit images
self.screen.blit(image)
# Flip display
pygame.display.flip()
This will flip the display every frame and then draw the next frame without a trail.
Also quick notes, remember to do image = pygame.image.load(image).convert or .convert_alpha() else after adding more images the game will slow down.
Also, if you do import pygame as pg you don't have to type out pygame each time, instead you can just type pg.

Categories