Reputation: 491
I am trying to put the stars on screen and give them random x,y coordinates
but when the screen refresh the previous stars still on the screen and it overlap with the next stars
I put the setting.screen.fill((255,0,0))
why this background not refresh the previous stars?
what cause it????
here's the codes:
#!/usr/bin/python
import sys
import pygame as p
from random import randint
#13-1
class Setting():
def __init__(self,width,height):
self.w=width
self.h=height
self.screen=p.display.set_mode((self.w,self.h),p.RESIZABLE,0)
p.display.set_caption("EXE 13-1")
class Star(p.sprite.Sprite):
def __init__(self):
super().__init__()
pic=p.image.load("../image/star.jpg").convert_alpha()
self.image=p.transform.smoothscale(pic,(100,100))
self.rect=self.image.get_rect()
self.rect.x=(self.rect.width)/2
def create(self,setting,stars):
spacex=setting.w-2*self.rect.x
numbers=int(spacex/(2*self.rect.x))
rows=int(setting.h/(2*self.rect.height))
for row in range(rows):
for number in range(numbers):
star=Star()
star.rect.x=randint(-10,10)+2*self.rect.width*number
star.rect.y=randint(-10,10)+2*self.rect.height*row
stars.add(star)
def blit(self,setting,stars):
stars.draw(setting.screen)
# for star in stars.sprites():
# setting.screen.blit(star.image,star.rect)
def game():
p.init()
setting=Setting(1200,800)
star=Star()
stars=p.sprite.Group()
while True:
for event in p.event.get():
if event.type == p.QUIT:
sys.exit()
elif event.type == p.KEYDOWN:
if event.key == p.K_ESCAPE:
sys.exit()
setting.screen.fill((255,0,0))
star.create(setting,stars)
star.blit(setting,stars)
p.display.flip()
game()
Upvotes: 1
Views: 410
Reputation: 210889
The issue is caused, because the entire stars a recreated in each frame and append to the pygame.sprite.Group
stars
. But the group is never emptied and grows continuously:
while True: # [...] star.create(setting,stars) # <-- adds new objects to Group "stars" in every frame
The easiest solution would be to empty() the Group
in every frame
def game():
# [...]
while True:
# [...]
# remove all stars from the group
stars.empty()
# create new stars
star.create(setting,stars)
But the much better solution would be to keep the stars in the Group
and to randomize their positions. Note, recreating the stars in every frame will gain a performance impact.
Create the stars one before the mein application loop and set a new random position to each star in the main application loop:
class Star(p.sprite.Sprite):
# [...]
def create(self,setting,stars):
spacex=setting.w-2*self.rect.x
numbers=int(spacex/(2*self.rect.x))
rows=int(setting.h/(2*self.rect.height))
for row in range(rows):
for number in range(numbers):
star=Star()
# store row and colume of the stare
star.col = number
star.row = row
star.randomize()
stars.add(star)
# calculate random position
def randomize(self):
self.rect.x=randint(-10,10)+2*self.rect.width*self.col
self.rect.y=randint(-10,10)+2*self.rect.height*self.row
def game():
p.init()
setting=Setting(1200,800)
star=Star()
stars=p.sprite.Group()
star.create(setting,stars)
while True:
for event in p.event.get():
if event.type == p.QUIT:
sys.exit()
elif event.type == p.KEYDOWN:
if event.key == p.K_ESCAPE:
sys.exit()
# randomize positions of stars
for star in stars:
star.randomize()
setting.screen.fill((255,0,0))
star.blit(setting,stars)
p.display.flip()
Finally I recommend to remove the self
parameter from the class methods create
and blit
. It is sufficient to lad the image of the star once:
class Star(p.sprite.Sprite):
def __init__(self, col, row, image):
super().__init__()
self.image = image
self.rect = self.image.get_rect()
self.col, self.row = col, row
self.randomize()
def randomize(self):
self.rect.x=randint(-10,10)+2*self.rect.width*self.col
self.rect.y=randint(-10,10)+2*self.rect.height*self.row
def create(setting,stars):
pic = p.image.load("../image/star.jpg").convert_alpha()
pic = p.transform.smoothscale(pic,(100,100))
numbers, rows = setting.w // 100, setting.h // 100
for row in range(rows):
for number in range(numbers):
star=Star(number, row, pic)
stars.add(star)
def randomizeStars(stars):
for star in stars:
star.randomize()
def blit(setting,stars):
stars.draw(setting.screen)
def game():
p.init()
setting=Setting(1200,800)
stars=p.sprite.Group()
Star.create(setting,stars)
while True:
for event in p.event.get():
if event.type == p.QUIT:
sys.exit()
elif event.type == p.KEYDOWN:
if event.key == p.K_ESCAPE:
sys.exit()
Star.randomizeStars(stars)
setting.screen.fill((255,0,0))
Star.blit(setting,stars)
p.display.flip()
Upvotes: 1