I have a group of rects, they display in a row. I want them to change their colour when they have been clicked, until they are clicked again
I have this code so far to create the sprites:
class DrawableRect(pygame.sprite.Sprite):
def __init__(self,color,width,height,value=0):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.value = value
self.x = 0
self.y = 0
def change_value(self,color,value):
self.image.fill(color)
self.value=value
def DrawRects(start_x, start_y, rect_spacing, colour_list):
current_x_pos = start_x
for rect_num in range(0,8):
rect = DrawableRect(colour_list[rect_num], boxW, boxH)
rect.rect.x = current_x_pos
rect.rect.y = start_y
current_x_pos = current_x_pos + rect.rect.width + rect_spacing
rects.add(rect)
rects.draw(screen)
The idea of the app is for each rectangle to represent a bit, and when pressed it alternates between 0 and 1, the makeup of each bit displays the decimal equivalent somewhere.
I read that groups are unordered therefore indexing wouldn't work, is that true?
Here's an example I've modified to suit your purposes. I have a bunch of sprites (coloured rectangles) in a sprite group and I change* the colour of any sprite that collides with the mouse pointer when a mouse button is pressed.
Here's the code, you're probably most interested in the change_color() method and the MOUSEBUTTONUP event handling code.
import random
import pygame
screen_width, screen_height = 640, 480
def get_random_position():
"""return a random (x,y) position in the screen"""
return (random.randint(0, screen_width - 1), #randint includes both endpoints.
random.randint(0, screen_height - 1))
color_list = ["red", "orange", "yellow", "green", "cyan", "blue", "blueviolet"]
colors = [pygame.color.Color(c) for c in color_list]
class PowerUp(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
width, height = 64, 32
self.image = pygame.Surface([width, height])
self.clicked = False # track whether we've been clicked or not
# initialise color
self.color = random.choice(colors)
self.image.fill(self.color)
# Fetch the rectangle object that has the dimensions of the image
self.rect = self.image.get_rect()
# then move to a random position
self.update()
def update(self):
#move to a random position
self.rect.center = get_random_position()
def random_color(self):
# randomise color
self.clicked = not self.clicked
if self.clicked:
color = random.choice(colors)
else:
color = self.color
self.image.fill(color)
if __name__ == "__main__":
pygame.init()
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Sprite Color Switch Demo')
clock = pygame.time.Clock() #for limiting FPS
FPS = 60
exit_demo = False
pygame.key.set_repeat(300, 200)
#create a sprite group to track the power ups.
power_ups = pygame.sprite.Group()
for _ in range(10):
power_ups.add(PowerUp()) # create a new power up and add it to the group.
# main loop
while not exit_demo:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_demo = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
exit_demo = True
elif event.key == pygame.K_SPACE:
power_ups.update()
elif event.type == pygame.MOUSEBUTTONUP:
# check for collision
for p in power_ups:
if p.rect.collidepoint(event.pos): # maybe use event?
p.random_color()
screen.fill(pygame.Color("black")) # use black background
power_ups.draw(screen)
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
Let me know if you have any questions. Obviously this doesn't do row alignment of the sprites, I think you have a handle on that. I would suggest that you have all of your screen drawing operations in one place so your code can be clearer.
*The new colour is randomised from a short list, so there's a 14% chance it won't change from the starting colour.
Related
I'm making a CheckButton Widget to be able to use in game menus.
Wondering how I might be able to check if the mouse is colliding with the circle?
Using the self.surface.get_rect() method doesn't seem to work. is there a way to calculate where the circle is based on its location in its surface object? I was just going to just draw a smaller black circle inside the circle when self.active == True then back to its default color if its False. should I be using Sprites for this?
class CheckButton():
"""add label?"""
def __init__(self, screen, pos,size=(10,10),color=GREY):
self.screen = screen
self.pos = pos
self.size = size
self.color = color
self.active = False
self.surface = pygame.surface.Surface(self.size)
self.rect = self.surface.get_rect()
self.center = (5,5)
def check_for_click(self):
pos = pygame.mouse.get_pos()
mouseClicked = pygame.mouse.get_pressed()
if self.rect.collidepoint(pos) and mouseClicked == (1,0,0):
self.active = True
print(self.active)
def draw(self):
self.surface.fill(BG_COLOR)
pygame.draw.circle(self.surface,self.color, self.center,5, 0)
self.screen.blit(self.surface, self.pos)
When using pygame, don't give your objects attributes like pos or center (if you don't have to for whatever reasons). Just use the pygame's Sprite and Rect classes, which will handle all these things for you.
Here's a running example. Note the comments for further explanations:
import pygame
from math import hypot
pygame.init()
screen = pygame.display.set_mode((400, 400))
BG_COLOR=(55,0,200)
# note that pygame comes with a lot of colors already defined in THECOLORS
GREY=pygame.color.THECOLORS['grey']
# pygame's Group is great for sprite handling, but it does not offer a function for event handling
# so we create our own simple Group
class EventAwareGroup(pygame.sprite.Group):
def handle(self, event):
for spr in self.sprites():
if hasattr(spr, 'handle'):
spr.handle(event)
class CheckButton(pygame.sprite.Sprite):
def __init__(self, pos, size=(10,10), color=(255,100,200)):
super().__init__()
self.image = pygame.surface.Surface(size)
# we use a random color as colorkey, which means this color acts
# as a substitute for 'transparent'; so we don't have to care about the
# actual background
self.image.set_colorkey((99,32,127))
self.image.fill((99,32,127))
self.rect = self.image.get_rect()
# our image is a simple circle
# note how we can use the attributes of Rect to easily find the center of our Surface
pygame.draw.circle(self.image, color, self.rect.center, size[0]//2, 0)
# when the checkbox is active, we want to show another image, so let's create it here
# we want to do the drawing once, so we do it in the __init__ function
self.toggle_image = self.image.copy()
pygame.draw.circle(self.toggle_image, (0, 0, 0), self.rect.center, size[0]//3, 0)
# now let's position our checkbox at 'pos'
self.rect.center = pos
self.active = False
def handle(self, event):
# since we want to toggle the active state of the checkbox when a mouse click occurs,
# it's better to listen for the MOUSEBUTTONDOWN event
if event.type == pygame.MOUSEBUTTONDOWN:
# to check if the mouse click was actually in the circle, we simple calculate the distance
d = hypot(event.pos[0] - self.rect.center[0], event.pos[1] - self.rect.center[1])
if d <= self.rect.width/2 and event.button == 1:
# now let's toggle the active flag and the images
self.active = not self.active
self.image, self.toggle_image = self.toggle_image, self.image
c = CheckButton([150, 100], [100, 100])
g = EventAwareGroup(c)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
g.handle(event)
# note how simple and clean our main loop is
# when we need other sprites, just add them to the g Group
# no need to change the main loop for that
screen.fill(BG_COLOR)
g.update()
g.draw(screen)
pygame.display.update()
I am trying to have pygame create a new Bullet object every time the mouse is pressed. It works on the first bullet, but on the second Bullet I am getting a "'Bullet' object is not callable' error.
class Bullet(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((20,40))
self.image.fill(black)
self.rect = self.image.get_rect()
self.rect.x = player_1.rect.x
self.rect.y = player_1.rect.y
#self.image = pygame.image.load("C:/Users/Thomas/Desktop/rocket.png")
self.width = self.image.get_width()
self.height = self.image.get_height()
self.speed = 20
self.damage_radius = 0
self.damage = 0
self.angle = 0
def draw(self):
self.image.fill(black)
screen.blit(self.image, (self.rect.x, self.rect.y))
def delete(self):
pass
def fire(self, mouse):
"""Determine agnle of which rocket is fired"""
pass
def update(self):
self.rect.y -= self.speed
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill(intro_bg_color)
large_text = pygame.font.Font("C:/Users/Thomas/Desktop/Python Sketches/Fonts/Quesat Black Demo.OTF", 100)
player_1 = Player((100,100), 20, blue)
while True:
pygame.display.update()
clock.tick(FPS)
mouse = pygame.mouse.get_pos()
gameEvent = pygame.event.get()
"""Draw"""
"""This wil be for advancing bullets in playing field"""
screen.fill(bg_color)
player_1.draw(mouse)
for Bullet in bullet_list:
Bullet.update()
if Bullet.rect.y < 0:
bullet_list.remove(Bullet)
Bullet.draw()
for event in gameEvent:
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed()[0]:
mouse_is_pressed = True # Used to determine if the mouse is held or not
print("Mouse pressed")
"""Generate new bullet"""
bullet = Bullet()
all_sprites_list.add(bullet)
bullet_list.add(bullet)
bullet.rect.x = player_1.rect.x
bullet.rect.y = player_1.rect.y
elif event.type == pygame.MOUSEBUTTONUP and pygame.mouse.get_rel()[0]:
mouse_is_pressed = False
print("Mouse button released")
When mouse is pressed, generate new Bullet, add it to bullet_list. This is down how an example I looked at is done and I just can't solve the issues. Help is greatly appreciated!
I took this block of code:
for Bullet in bullet_list:
Bullet.update()
Bullet.draw()
and change the "Bullet" to "bullet" and the code finally started working.
for bullet in bullet_list:
bullet.update()
bullet.draw()
First of all ,I loaded a picture of the ship and initialized its location. thereafter I add bullet to my program. After that, I found that no matter how I debug it, it can't be in the right place.
# 1. - import library
import pygame,sys
from pygame.locals import *
from pygame.sprite import Sprite
class Player(Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load('image/pig.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
class Bullet(Sprite):
def __init__(self, player):
super().__init__()
self.rect = pygame.Rect(0, 0, bullet_width, bullet_height )
self.color = bullet_color
self.rect.center = player.rect.center
self.rect.left = player.rect.right
# 2. - Initialize the game
pygame.init()
width,height = 800,600
screen = pygame.display.set_mode((width,height))
keys = [False,False,False,False]
playerpos = [0,288]
bullet_width = 15
bullet_height = 6
bullet_color = (200, 200 , 0)
player = Player()
bullet = Bullet(player)
grass = pygame.image.load("image/bg.bmp")
# 4. - keep looping through
while True:
# 5. - clear the screen before drawing it again.
screen.fill(0)
# 6. - Draw the screen elements.
screen.blit(grass,(0,0))
screen.blit(player.image, playerpos)
pygame.draw.rect(screen, bullet.color, bullet.rect)
# 7. - update the screen
pygame.display.flip()
# 8. - loop through the events
for event in pygame.event.get():
# check if the event is the X button.
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
and why bullet appear in top-left
enter image description here
I hope bullet appear in ship's right side,but I can't do it if I don't use coordinate(x,y),how can I do it?
You are drawing the ship in a position unrelated to its rect's position, using playerpos. You need to make the link the ship's position linked to its rect, so that the bullet can access it:
# 1. - import library
import pygame,sys
from pygame.locals import *
from pygame.sprite import Sprite
class Player(Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load('image/pig.bmp')
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
class Bullet(Sprite):
def __init__(self, player):
super().__init__()
self.rect = pygame.Rect(0, 0, bullet_width, bullet_height )
self.color = bullet_color
self.rect.center = player.rect.center
self.rect.left = player.rect.right
# 2. - Initialize the game
pygame.init()
width,height = 800,600
screen = pygame.display.set_mode((width,height))
keys = [False,False,False,False]
bullet_width = 15
bullet_height = 6
bullet_color = (200, 200 , 0)
player = Player()
player.rect.topleft = [0,288]
bullet = Bullet(player)
grass = pygame.image.load("image/bg.bmp")
# 4. - keep looping through
while True:
# 5. - clear the screen before drawing it again.
screen.blit(grass, (0, 0))
# 6. - Draw the screen elements.
screen.blit(player.image, player.rect.topleft)
pygame.draw.rect(screen, bullet.color, bullet.rect)
# 7. - update the screen
pygame.display.flip()
# 8. - loop through the events
for event in pygame.event.get():
# check if the event is the X button.
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
This is because a surface's get_rect() method has no idea where the surface is going to be blitted on to another surface, so it just gives its position as (0, 0). get_rect() is only useful for obtaining a surface's dimensions.
I have a problem I'm stuck now for last two days. In file game_function in nested loop I'm creating aliens, when I added randint to create random numbers of aliens in a row I run in to problem. Not always (just re-run the game) but sometimes when I detect sprite edge as a method of Alien class Aliens/sprites won't change the direction, follow x axis to the right and constantly dropping down Aliens each pass of check edge. I don't know what the heck is that. Before when I haven't been using randit to generate random numbers of aliens in a row, everything was just fine.
settings.py
class Settings():
"""A class to store all settings for Alien Invasion"""
def __init__(self):
"""Initialize the game settings"""
#Screen settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230,230,230)
#ship settings
self.ship_speed_factor = 1.5
#Bullet settings
self.bullet_speed_factor = 1
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = (60, 60, 60)
self.bullets_allowed = 3
# Alien settings
self.alien_speed_factor = 1
self.fleet_drop_speed = 10
# fleet_direction of 1 represents right; -1 represents left.
self.fleet_direction = 1
ship.py
import pygame
class Ship():
def __init__(self,ai_settings, screen):
"""Initialize the ship and sets the starting position."""
self.screen = screen
self.ai_settings = ai_settings
#load the ship image and get its rect
self.image = pygame.image.load('images/ship.png')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# Start each new ship at the bottom center of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
self.center = float(self.rect.centerx)
#Movement Flag
self.moving_right = False
self.moving_left = False
def update(self):
"""Update the ship's position based on the movement Flag."""
#Update the ship's center value, not the rect
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
#update rect object from self.center
self.rect.centerx = self.center
def blitme(self):
"""Draw the ship at its current location"""
self.screen.blit(self.image, self.rect)
In a function create_fleet(ai_settings, screen, ship, aliens) is nested loop, when instead of generating random number between 3-9 and then placing new instance in row I've used constant calculation which always gives 9 aliens in row everything runned just fine. Aliens changed everytime directions and just one time dropped down until next check_edge event passed the condition. So from one wall to another. Now when the randint is in place, NOT ALWAYS, when check_edge method confirms true, then call to function change_fleet_direction() is made and there I see problem, it just sometimes doesn't change the direction. where for direction is used just simple +1 or -1 and in calling for update in Alien class it should either decrease x axis or increase until edge event.
game_functions.py
import sys
import pygame
from bullet import Bullet
from alien import Alien
from random import randint
def create_fleet(ai_settings, screen, ship, aliens):
"""Create a full fleet of aliens."""
#Create an Alien and find the number of aliens in a row
name= 'First unused'
alien = Alien(ai_settings, screen,name)
number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
number_rows = get_number_rows(ai_settings, ship.rect.height,
alien.rect.height)
# Create the fleet of aliens.
for row_number in range(number_rows):
random_num = randint(3, number_aliens_x)
for alien_number in range(0, random_num):
create_alien(ai_settings, screen, aliens, alien_number,
row_number)
def get_number_aliens_x(ai_settings, alien_width):
"""Determine the number of aliens that fit in a row."""
available_space_x = ai_settings.screen_width - 2 * alien_width
number_aliens_x = int(available_space_x / (2 * alien_width))
return number_aliens_x
def get_number_rows(ai_settings, ship_height, alien_height):
"""Determine the number of rows of aliens that fit on the screen."""
available_space_y = (ai_settings.screen_height -
(3 * alien_height) - ship_height)
number_rows = int(available_space_y / (2 * alien_height))
return number_rows
def create_alien(ai_settings, screen, aliens, alien_number, row_number):
"""Create alien and place it in the row"""
name = "Alien number " + str(alien_number) + " in row " + str(row_number)
alien = Alien(ai_settings, screen, name)
alien_width = alien.rect.width
alien.x = alien_width + 2 * alien_width * alien_number
alien.rect.x = alien.x
alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
aliens.add(alien)
def check_keydown_events(event, ai_settings, screen, ship, bullets):
"""Respond to key presses"""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, screen, ship, bullets)
elif event.key == pygame.K_q:
sys.exit()
def fire_bullet(ai_settings, screen, ship, bullets):
# Create a new bullet and add it to the bullets group.
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
def check_keyup_events(event,ship):
"""Respond to key releases"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ai_settings, screen, ship, bullets):
"""Respond to keypress and mouse events"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
def update_screen(ai_settings, screen, ship, aliens, bullets):
"""Update images on the screen and flip to the new screen."""
# Redraw the screen during each pass through the loop.
screen.fill(ai_settings.bg_color)
# Redraw all bullets behind ship and aliens.
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)
# Make the most recently drawn screen visible.
pygame.display.flip()
def update_bullets(bullets):
"""Update position of bullets and get rid of old bullets."""
# Update bullet positions.
bullets.update()
# Get rid of bullets that have disappeared.
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
def check_fleet_edges(ai_settings, aliens):
"""Respond appropriately if any aliens have reached an edge."""
for alien in aliens.sprites():
if alien.check_edges():
print(alien.name)
change_fleet_direction(ai_settings, aliens)
break
def change_fleet_direction(ai_settings, aliens):
"""Drop the entire fleet and change the fleet's direction."""
print("old direction " + str(ai_settings.fleet_direction))
for alien in aliens.sprites():
alien.rect.y += ai_settings.fleet_drop_speed
if ai_settings.fleet_direction == 1:
ai_settings.fleet_direction = -1
else:
ai_settings.fleet_direction = 1
print("new direction" + str(ai_settings.fleet_direction))
def update_aliens(ai_settings, aliens):
"""
Check if the fleet is at an edge,
and then update the positions of all aliens in the fleet.
"""
check_fleet_edges(ai_settings, aliens)
aliens.update()
Main file alien_invasion.py
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
# Initialize game and create a screen object.
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
ship = Ship(ai_settings,screen)
#Make a group to store bullets in
bullets = Group()
aliens = Group()
#Create the fleet of aliens
gf.create_fleet(ai_settings, screen, ship, aliens)
# Start the main loop for the game.
while True:
gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
bullets.update()
gf.update_bullets(bullets)
gf.update_aliens(ai_settings, aliens)
gf.update_screen(ai_settings, screen, ship, aliens, bullets)
run_game()
bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""A class to manage bullets fired from the ship"""
def __init__(self, ai_settings, screen, ship):
"""create a bullet object at the ship's current position"""
super().__init__()
self.screen = screen
#Create a bullet rect at (0, 0) and then set correct position
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
ai_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
#Store the bullet position as a decimal value.
self.y = float(self.rect.y)
self.color = ai_settings.bullet_color
self.speed_factor = ai_settings.bullet_speed_factor
def update(self):
"""Move bullet up the scereen"""
#Update the decimal position of the bullet
self.y -= self.speed_factor
#Update the rect position
self.rect.y = self.y
def draw_bullet(self):
"""Draw the bullet to the screen"""
pygame.draw.rect(self.screen, self.color, self.rect)
alien.py
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
"""A class to represent a single alien in the fleet"""
def __init__(self, ai_settings, screen, name):
"""Initialize the alien and set its starting position"""
super().__init__()
self.screen = screen
self.ai_settings = ai_settings
#Load the alien image and set its rect attribute.
self.image = pygame.image.load('images/alien.bmp')
self.rect = self.image.get_rect()
#Start each alien near the top left of the screen
self.rect.x = self.rect.width
self.rect.y = self.rect.height
#Store the alien's exact position
self.x = float(self.rect.x)
self.name = name
# def blitme(self):
# """Draw the alien at its current location."""
# self.screen.blit(self.image, self.rect)
#
def check_edges(self):
"""Return True if alien is at edge of screen."""
screen_rect = self.screen.get_rect()
if self.rect.right >= screen_rect.right:
print("Right >= right screen" +' direction is' + str(self.ai_settings.fleet_direction))
return True
elif self.rect.left <= 0:
print("Left <= left")
return True
def update(self):
"""Move the alien right or left."""
self.x += (self.ai_settings.alien_speed_factor *
self.ai_settings.fleet_direction)
self.rect.x = self.x
I'm new to pygame and sprites, I don't understand it why randit has such impact. I've placed in the code when crucial changes are about to be made print statements to debug it from console (but I dunno if it is logic problem). Anyone who can shed a light to it I would appreciate so much. Lost 2 days of learning and programming already. Running python 3.4 from Eclipse Neon on win 10 Thanks very much.
Found the mistake, indentation in func change_fleet_direction(), if block: cannot be in for loop.
i am working on something like Space Invaders since i just started to learn programing i try to keep it simple, what i want is enemy ships coming from top of the screen and then settling in one line.I managed to make them coming from top at some speed but i dont know how to make them stop at a line,for example at y = 40.The code is below:
# Sprites vjezba.py
import pygame
# Define colors
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,0,255)
# Define screen size
SCREEN_WIDTH = 420
SCREEN_HEIGHT = 400
# Classes
class Square(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20,20])
self.image.fill(red)
self.rect = self.image.get_rect()
def update(self):
pos = pygame.mouse.get_pos()
self.rect.x = pos[0]
self.rect.y = pos[1]
class Enemies(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([20,20])
self.image.fill(black)
self.rect = self.image.get_rect()
def update(self):
speed_y = 1
self.rect.y += speed_y
# Initialize pygame
pygame.init()
# Initialize screen
screen = pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])
# Set the clock
clock = pygame.time.Clock()
# Create sprites lists
square_list = pygame.sprite.Group()
enemies_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
# Create sprites
#--- Enemies sprites
diff_x = 0
diff_y = 0
for i in range(10):
enemies = Enemies()
enemies.rect.x = 20 + diff_x
diff_x += 40
enemies.rect.y = 20 - diff_y
diff_y += 20
enemies_list.add(enemies)
all_sprites_list.add(enemies)
# --- Square sprite
square = Square()
square.rect.x = 200
square.rect.y = 370
square_list.add(square)
all_sprites_list.add(square)
# -------Main Loop----------
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
all_sprites_list.update()
screen.fill(white)
all_sprites_list.draw(screen)
pygame.display.flip()
clock.tick(40)
pygame.quit()
At the moment, your update() for the Enemies looks like this:
def update(self):
speed_y = 1
self.rect.y += speed_y
This has two obvious flaws:
The speed is set locally, then discarded again at the end of the method; and
It doesn't know anything about position.
To fix this, I suggest making speed_y an instance attribute:
def __init__(self):
...
self.speed_y = 1
Allowing the setting of a target position
def set_target(y_pos):
self.y_target = y_pos
And using this information in update, for example:
def update(self):
self.rect.y += self.speed_y
if self.rect.y >= self.y_target:
self.speed_y = 0
This is a very basic example that just stops at the target y (and only works in one dimension), but hopefully gives you an idea of how to control the movement of your Enemies.