Python ignoring while loop with True condition - python-2.7

I'm writing a menu for a simple game, so I thought to use a while loop to let the user choose his wanted option by clicking on it. While my program works properly until this loop, it does not continue when reaching the line of the following loop:
pygame.mouse.set_visible(True) # This is the last line processed.
while True: # This line ist not processed.
(curx,cury)= pygame.mouse.get_pos()
screen.blit(cursor,(curx-17,cury-21))
pygame.display.flip()
# rating values of the cursor position and pressed mouse button below:
(b1,b2,b3) = pygame.mouse.get_pressed() #getting states of mouse buttons
if (b1 == True or b2 == True or b3 == True): # "if one mouse button is pressed"
(cx,cy) = pygame.mouse.get_pos()
if (px <= curx <= px+spx and py <= cury <= py+spy):
return (screen,0)
elif (ox <= curx <= ox+sox and oy <= cury <= oy+soy):
return (screen,1)
elif (cx <= curx <= cx+scx and cy <= cury <= cy+scy):
return (screen,2)
else:
return (screen,3)
time.sleep(0.05)
I have already checked such things like wrong indentation.
BTW my interpreter (python.exe, Python 2.7.11) always does not respond after reaching this line of the
while True:
Because the question was asked in a deleted answer:
I had a print("") between every above shown line to find the problematic line.
As I wrote 4 lines above: The interpreter (and with it the debugger and bug report) has crashed without any further response.
The whole code of this function is:
# MAIN MENU
def smenu (screen,res,menuimg,cursor):
#preset:
x,y = res
click = False
print("preset") # TEST PART
# Fontimports, needed because of non-standard font in use
menu = pygame.image.load("menu.png")
playGame = pygame.image.load("play.png")
options = pygame.image.load("options.png")
crdts = pygame.image.load("credits.png")
print("Fontimport") # TEST PART
#SIZETRANSFORMATIONS
# setting of sizes
smx,smy = int((y/7)*2.889),int(y/7)
spx,spy = int((y/11)*6.5),int(y/11)
sox,soy = int((y/11)*5.056),int(y/11)
scx,scy = int((y/11)*5.056),int(y/11)
print("setting of sizes") # TEST PART
# setting real size of text 'n' stuff
menu = pygame.transform.scale(menu,(smx,smy))
playGame = pygame.transform.scale(playGame,(spx,spy))
options = pygame.transform.scale(options, (sox,soy))
crdts = pygame.transform.scale(crdts, (scx,scy))
cursor = pygame.transform.scale(cursor,(41,33))
print("actual size transformation") # TEST PART
#DISPLAY OF MENU
# fixing positions
mx, my = int((x/2)-((y/7)/2)*2.889),10 # position: 1. centered (x) 2. moved to the left for half of the text's length 3. positioned to the top(y), 10 pixels from edge
px, py = int((x/2)-((y/11)/2)*6.5),int(y/7+10+y/10) # position: x like above, y: upper edge -"menu"'s height, -10, - height/10
ox, oy = int((x/2)-((y/11)/2)*5.056),int(y/7+10+2*y/10+y/11)
cx, cy = int((x/2)-((y/11)/2)*5.056),int(y/7+10+3*y/10+2*y/11)
print("fixing positions") # TEST PART
# set to display
#screen.fill(0,0,0)
screen.blit(menuimg,(0,0))
screen.blit(menu,(mx,my))
screen.blit(playGame,(px,py))
screen.blit(options,(ox,oy))
screen.blit(crdts,(cx,cy))
pygame.display.flip()
print("set to display") # TEST PART
# request for input (choice of menu options)
pygame.mouse.set_visible(True)
print("mouse visible") # TEST PART last processed line
while (True):
print("While-loop") # TEST PART
curx,cury = pygame.mouse.get_pos()
screen.blit(cursor,(curx-17,cury-21))
pygame.display.flip()
# decision value below
(b1,b2,b3) = pygame.mouse.get_pressed() # getting mouse button's state
if (b1 == True or b2 == True or b3 == True): # condition true if a buton is pressed
(cx,cy) = pygame.mouse.get_pos()
if (px <= curx <= px+spx and py <= cury <= py+spy):
return (screen,0)
elif (ox <= curx <= ox+sox and oy <= cury <= oy+soy):
return (screen,1)
elif (cx <= curx <= cx+scx and cy <= cury <= cy+scy):
return (screen,2)
else:
return (screen,3)
time.sleep(0.05)
print("directly skipped")

Would comment but can't because of low rep.
The problem might be, that you're returning a value to a while loop outside a function.
Although it's a bit weird that your interpreter/IDE isn't giving you the correct Error message for it.

I think that the problem is in the following line of your code:
if (b1 == True or b2 == True or b3 == True):
This condition never becomes true so you are stuck into the while loop without your function returning anything.

Related

Mouse selection of images with Psychopy

I have created two stimuli(red and green rectangles) as stimuli in Psychopy. Also, I have enabled mouse movements to four directions. Using the function[mouse.getPressed()] in Psychopy for selecting the stimuli, I am facing some issues.
Basically, I want the mouse to move in four directions, and when the mouse reaches red/green rectangle stimuli, I need to select that stimuli and change its color to blue.
Can anyone look into the issue and help me to resolve the same?
Here is my code:
from psychopy import visual, core, event
import numpy as np
# Create a window.
# For configuring and debugging the code turn off full screen.
fullscr = False
win = visual.Window(
[1200,1000],
monitor="testMonitor",
units="deg",
fullscr=fullscr
)
#cursor = visual.Circle(win, radius=0.2)
#cursor = visual.CustomMouse(win,
# leftLimit=-10, topLimit=10, rightLimit=10, bottomLimit=-10,
# showLimitBox=True, clickOnUp=True)
pos_zero = (0, 0)
cursor = visual.Rect(
win=win,
size=400,
pos=pos_zero,
opacity=0
)
mouse = event.Mouse(visible=True)
# Sinusoidal control version.
freq_one = 0.5
freq_two = 1.5
# Colors of the rectangles.
#color_zero='black'
color_one = 'red'
color_two = 'green'
# Positions of the rectanges.
pos_one = (-10, 0)
pos_two = (10, 0)
start = core.getTime()
cnt = 0
cursor.pos = mouse.getPos()
print cursor.pos
while cnt<600:
second = core.getTime() - start
sin_val_one = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_one))
sin_val_two = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_two))
#while not mouse.getPressed()[0]:
# Do something if mouse moved
for key in event.getKeys():
if key == 'escape':
core.quit()
elif key == "right":
cursor.pos = cursor.pos + (2,0)
elif key =="left":
cursor.pos = cursor.pos - (2,0)
elif key =="up":
cursor.pos = cursor.pos + (0,2)
elif key =="down":
cursor.pos = cursor.pos - (0,2)
#if cursor.pos == pos_one:
# mouse.getpressed(rect_one)
#elif cursor.pos == pos_two:
# mouse.getpressed(rect_two)
mouse.setPos(cursor.pos)
mouse.lastPos = cursor.pos
rect_one = visual.Rect(
win=win,
fillColor=color_one,
lineColor=color_one,
size=15,
pos=pos_one,
opacity=sin_val_one
)
rect_two = visual.Rect(
win=win,
fillColor=color_two,
lineColor=color_two,
size=15,
pos=pos_two,
opacity=sin_val_two
)
#images = [rect_one, rect_two]
#for image in images:
# if mouse.isPressedIn(image):
# pressed_shape = shape
#
# pressed_image.fillColor = 'blue'
# pressed_image.draw()
# print pressed_image.name
rect_one.draw()
rect_two.draw()
cursor.draw()
win.flip()
cnt += 1
win.close()
Any help is greatly appreciated. Thanks!
I made several changes and post the updated code below. It's significantly shorter and simpler.
Removed everything using mouse. Since you just want something visual to move on key presses, there's no need to invoke the mouse - especially when you actually don't want subjects to use the mouse...
Create the colored shapes once, then updating the color during runtime. This is significantly faster, i.e. avoids dropping frames.
Changed the cursor size. It was 400 degrees!
Removed the line around the rectangles so that only fillColor needs to be changed on overlap.
A few other simplifications.
Here is the code:
from psychopy import visual, core, event
import numpy as np
# Settings
fullscr = False
directions = {'left': (-2,0), 'right': (2,0), 'up': (0, 2), 'down': (0, -2)}
freq_one = 0.5 # # Sinusoidal control
freq_two = 1.5
# Create a window.
win = visual.Window([1200,1000], monitor="testMonitor", units="deg", fullscr=fullscr)
# The two rectangles
rect_one = visual.Rect(win=win, fillColor='red', lineColor=None, size=15, pos=(-10, 0))
rect_two = visual.Rect(win=win, fillColor='green', lineColor=None, size=15, pos=(10, 0))
# Cursor
cursor = visual.Circle(win, fillColor='white', radius=0.2)
# Run five trials
for trial in range(5):
# Set to initial condition
rect_one.fillColor = 'red'
rect_two.fillColor = 'green'
cursor.pos = (0, 0)
# Start task
start = core.getTime()
for frame in range(600):
# Set rectangle opacities
second = core.getTime() - start
rect_one.opacity = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_one))
rect_two.opacity = 0.5+0.5*np.sin(2 * np.pi * second * float(freq_two))
# Show it
rect_one.draw()
rect_two.draw()
cursor.draw()
win.flip()
# Get keyboard responses and change color if there is overlap
for key in event.getKeys():
if key == 'escape':
core.quit()
elif key in directions.keys(): # if this is a key corresponding to a direction
cursor.pos += directions[key] # Lookup the pos change in "directions" and add it to current position
if cursor.overlaps(rect_one):
rect_one.fillColor = 'blue'
if cursor.overlaps(rect_two):
rect_two.fillColor = 'blue'

NameError: not defined (python)

Trying to build a simple game using turtle graphics and Python.
I created enemies and put them in the while loop so that whenever they touch the boundaries on either sides they move down by 40 units. I put the value of y co-ordinate in a variable u. But when I run the code it says:
nameError: 'u' not defined
Help!!
#!/usr/bin/python
import turtle
import os
#screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("spaceinvaders")
#boarder
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300,-300)
border_pen.pendown()
border_pen.pensize(3)
for side in range(4):
border_pen.fd(600)
border_pen.lt(90)
border_pen.hideturtle()
#player
player = turtle.Turtle()
player.color("blue")
player.shape("triangle")
player.penup()
player.speed(0)
player.setposition(0,-250)
player.setheading(90)
playerspeed = 15
#enemy
enemy = turtle.Turtle()
enemy.color("red")
enemy.shape("circle")
enemy.penup()
enemy.speed(0)
enemy.setposition(-200,250)
enemyspeed = 2
#move
def move_left():
x = player.xcor()
x -= playerspeed
if x < -280:
x = - 280
player.setx(x)
def move_right():
x = player.xcor()
x += playerspeed
if x > 280:
x = +280
player.setx(x)
#key bindings
turtle.listen()
turtle.onkey(move_left,"Left")
turtle.onkey(move_right,"Right")
#mainloop
while True:
#enemy moves
x = enemy.xcor()
x += enemyspeed
enemy.setx(x)
if enemy.xcor() < -280:
u = enemy.ycor()
u -= 40
enemyspeed *= -1
enemy.sety(u)
if enemy.xcor() > 280:
u = enemy.ycor()
u -= 40
enemyspeed *= -1
enemy.sety(u)
delay = raw_input("press enter to finish")
Even with the incorrect loop indentation that #downshift noted, you shouldn't have gotten the error you quoted as u is set immediately before being used.
The main problem I see with your code design is your use of while True: which should not occur in an event driven program. Rather, the enemy's motion should be handled via a timer event and program control turned over to mainloop() so that other events can fire correctly. I've reworked your program along those lines below and made some style and optimizaion tweaks:
import turtle
# player motion event handlers
def move_left():
turtle.onkey(None, 'Left') # avoid overlapping events
player.setx(max(-280, player.xcor() - playerspeed))
turtle.onkey(move_left, 'Left')
def move_right():
turtle.onkey(None, 'Right')
player.setx(min(280, player.xcor() + playerspeed))
turtle.onkey(move_right, 'Right')
# enemy motion timer event handler
def move_enemy():
global enemyspeed
# enemy moves
enemy.forward(enemyspeed)
x = enemy.xcor()
if x < -280 or x > 280:
enemy.sety(enemy.ycor() - 40)
enemyspeed *= -1
wn.ontimer(move_enemy, 10)
# screen
wn = turtle.Screen()
wn.bgcolor('black')
wn.title('spaceinvaders')
# border
STAMP_SIZE = 20
border_pen = turtle.Turtle('square', visible=False)
border_pen.shapesize(600 / STAMP_SIZE, 600 / STAMP_SIZE, 3)
border_pen.pencolor('white')
border_pen.stamp()
# player
player = turtle.Turtle('triangle', visible=False)
player.color('blue')
player.speed('fastest')
player.penup()
player.setheading(90)
player.setposition(0, -250)
player.showturtle()
playerspeed = 15
# enemy
enemy = turtle.Turtle('circle', visible=False)
enemy.color('red')
enemy.speed('fastest')
enemy.penup()
enemy.setposition(-200, 250)
enemy.showturtle()
enemyspeed = 2
# key bindings
turtle.onkey(move_left, 'Left')
turtle.onkey(move_right, 'Right')
turtle.listen()
wn.ontimer(move_enemy, 100)
turtle.mainloop() # for Python 3 use wn.mainloop()
This should hopefully smooth your path to adding more functionality to your game.

pygame constant movement with if statement

i am trying to make a simple game but movement doesn't work properly
i want it to constantly move while the buttons are pressed but respect the borders of the screen currently the buttons will work overall but it causes the rectangle to stutter, here is my code,
import pygame
pygame.init()
SD = pygame.display.set_mode((640,480))
x = 16
y = 16
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
if y > 0:
y -= 8
if keys[pygame.K_a]:
if x > 0:
x -= 8
if keys[pygame.K_s]:
if y < 448:
y += 8
if keys[pygame.K_d]:
if x < 608:
x += 8
SD.fill((255,255,255))
pygame.draw.rect(SD, (255,0,0), (x,y, 30, 30))
pygame.display.update()
pygame.event.get() will only return an event if a hardware event happened like pressing a key. So your if keys[...] won't be evaluated when nothing happens (a pressed key event won't get repeated)
Move your ifs one level up and it will work without stuttering but you'll have to slow down the movement of your box afterwards (a sleep(0.1) will do for the example but you probably want to move to something more advanced since you don't want to sleep in you drawing loop)
The way key presses are handled in pygame (and most other game engines) is that you only get an event when a key is pressed or released. The reason your character movement is looking so jumpy, is because the key press is being handled like holding a key down in a text editor. If you hold the key down, a letter will show up and after a short while you'll get lots of the letter repeating.
What you really want to do is to have a boolean for each key that you set to True when you get a key press event, and False when you get a key release event (take a very careful look at the process_events function).
I've modified your code to do just that (along with some other changes that I'll explain afterwards):
import pygame
class Game(object):
def __init__(self):
"""
Initialize our game.
"""
# The initial position.
self.x = 16
self.y = 16
# The keyboard state.
self.keys = {
pygame.K_w: False,
pygame.K_a: False,
pygame.K_s: False,
pygame.K_d: False,
}
# Create the screen.
self.SD = pygame.display.set_mode((640,480))
def move_character(self):
"""
Move the character according to the current keyboard state.
"""
# Process vertical movement.
if self.keys[pygame.K_w] and self.y > 0:
self.y -= 1
if self.keys[pygame.K_s] and self.y < 448:
self.y += 1
# Process horizontal movement.
if self.keys[pygame.K_a] and self.x > 0:
self.x -= 1
if self.keys[pygame.K_d] and self.x < 608:
self.x += 1
def process_events(self):
"""
Go through the pending events and process them.
"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
# If the event is a key press or release event, then register it
# with our keyboard state.
elif event.type == pygame.KEYDOWN:
self.keys[event.key] = True
elif event.type == pygame.KEYUP:
self.keys[event.key] = False
def draw(self):
"""
Draw the game character.
"""
self.SD.fill((255,255,255))
pygame.draw.rect(self.SD, (255,0,0), (self.x, self.y, 30, 30))
pygame.display.update()
def run(self):
while True:
self.process_events()
self.move_character()
self.draw()
def main():
pygame.init()
game = Game()
game.run()
# This just means that the main function is called when we call this file
# with python.
if __name__ == '__main__':
main()
The biggest change I've made is to move your game into a class to give you better access to variables from your functions. It also lets you partition your code into different functions that make it easier to read.

User controlled sprite stuck in box. Python 2.7.9 w/Pygame

Thanks for looking at my question and helping me out. I have a user controlled sprite that should cause the screen to shift around the sprite's position, kinda like an old Gameboy Pokemon game, yet that does not happen. Instead my sprite is stuck inside a box of coordinates that I used to help define parameters for background shift. This is the code I believe is causing this:
# Shift world left (-x)
if player.rect.right >= 510:
diff = player.rect.right - 510
player.rect.right = 510
current_level.shift_world_x(-diff)
# Shift world right (+x)
if player.rect.left <= 130:
diff = 130 - player.rect.left
player.rect.left = 130
current_level.shift_world_x(diff)
# Shift world up (-y)
if player.rect.top <= 100:
diff = 100 - player.rect.top
player.rect.top = 100
current_level.shift_world_y(diff)
# Shift world down (y)
if player.rect.bottom >= 380:
diff = player.rect.bottom - 380
player.rect.bottom = 380
current_level.shift_world_y(-diff)
If I put a # next to player.rect.right = 510, or any of the other three varients, my sprite can move freely, yet the screen will not shift.
Zip file with all assets is here:
https://www.dropbox.com/s/3g2w0mv1fuupetl/DoneGeon.zip?dl=0
The entirety of my code is as follows:
import pygame
"""---Global Constants---"""
# Colors
BLACK = (0, 0, 0)
# Screen Variables
screen_x = 720
screen_y = 480
# Background variables
back_x = 0
back_y = -243
back_x_change = 0
back_y_change = 0
class Player(pygame.sprite.Sprite):
"""---User Controled Character---"""
# Methods
def __init__(self):
"""---Contructor Function---"""
# Call parent's constructor
pygame.sprite.Sprite.__init__(self)
# Load player image
self.image = pygame.image.load("player.png").convert()
# Set referance to image "hit box"
self.rect = self.image.get_rect()
# Set speed of player
self.change_x = 0
self.change_y = 0
def update(self):
"""---Move the Player---"""
# Move left/right
self.rect.x += self.change_x
# Move up/down
self.rect.y += self.change_y
# User controlled movements
def go_left(self):
self.change_x = -3
def go_right(self):
self.change_x = 3
def go_up(self):
self.change_y = -3
def go_down(self):
self.change_y = 3
def stop_x(self):
self.change_x = 0
def stop_y(self):
self.change_y = 0
class Barrier(pygame.sprite.Sprite):
"""---Barriers that prevent player from passing---"""
def __init__(self,width,height):
""" Barrier constructor """
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width,height])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
class Level():
"""---All levels will spawn from this generic class---"""
def __init__(self,player):
""" Needed for when sprites collide with player """
self.barrier_list = pygame.sprite.Group()
self.enemy_list = pygame.sprite.Group()
self.player = player
# Distance world has been shifted left/right
self.world_shift_x = 0
# Background image
background_base = None
background_layera = None
# Distance world has been shifted up/down
self.world_shift_y = 0
def update(self):
""" Update everything on level """
self.barrier_list.update()
self.enemy_list.update()
def draw(self,screen):
""" Draw everything on level """
# Draw barriers
self.barrier_list.draw(screen)
# Draw the base layer
screen.blit(self.background_base,(back_x,back_y))
# Draw all sprites
self.enemy_list.draw(screen)
# Draw Layer A
screen.blit(self.background_layera,(back_x,back_y))
def shift_world_x(self,shift_x):
""" When character moves left/right, everything must follow """
# Track shift amount
self.world_shift_x += shift_x
# Go through all list and shift
for barrier in self.barrier_list:
barrier.rect.x += shift_x
for enemy in self.enemy_list:
enemy.rect.x += shift_x
def shift_world_y(self,shift_y):
""" When character moves up/down, everything must follow """
# Track shift amount
self.world_shift_y += shift_y
# Go through all list and shift
for barrier in self.barrier_list:
barrier.rect.y += shift_y
for enemy in self.enemy_list:
enemy.rect.y += shift_y
class Level_1(Level):
"""---Forest 1---"""
def __init__(self,player):
""" Create the level """
# Call parent constructor
Level.__init__(self,player)
self.level_limit_x = -1912
self.level_limit_y = 1080
# Make background
self.background_base = pygame.image.load("base1.png").convert()
self.background_layera = pygame.image.load("layera1.png").convert()
self.background_layera.set_colorkey(BLACK)
# List with w, h, x = 32, y = 32 of barriers
# Remove comment to activate-> level = []
# Go through the list above and add barriers
# Remove comment to activate-> for barriers in level:
def main():
"""---Main Program---"""
pygame.init()
# Set screen size and caption
size = (screen_x,screen_y)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("DoneGeon")
# Create Player
player = Player()
# Create all levels
level_list= []
level_list.append(Level_1(player))
# Set current level
current_level_no = 0
current_level = level_list[current_level_no]
# Add all sprites
active_sprite_list = pygame.sprite.Group()
# Add player
player.level = current_level
player.rect.x = 360
player.rect.y = 240
active_sprite_list.add(player)
# Loop until closed
done = False
# Screen update rate
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while not done:
"""---Main event loop---"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
"""---User Controls---"""
# Key Pressed
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.go_up()
if event.key == pygame.K_DOWN:
player.go_down()
# Key Released
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
player.stop_x()
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player.stop_y()
"""---Game Logic---"""
# Update Player
active_sprite_list.update()
# Update items in level
current_level.update()
# Shift world left (-x)
if player.rect.right >= 510:
diff = player.rect.right - 510
player.rect.right = 510
current_level.shift_world_x(-diff)
# Shift world right (+x)
if player.rect.left <= 130:
diff = 130 - player.rect.left
player.rect.left = 130
current_level.shift_world_x(diff)
# Shift world up (-y)
if player.rect.top <= 100:
diff = 100 - player.rect.top
player.rect.top = 100
current_level.shift_world_y(diff)
# Shift world down (y)
if player.rect.bottom >= 380:
diff = player.rect.bottom - 380
player.rect.bottom = 380
current_level.shift_world_y(-diff)
"""---Draw below here---"""
current_level.draw(screen)
active_sprite_list.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
if __name__ == "__main__":
main()
Thank you for any advice!
I think you'll find this easier to track down if you log the changes in player x and world x. Often with games small changes aren't visible so logging is the only way to monitor what's happening in the game loop.
I haven't tested this but my bet is that you've got a negative in the wrong place. This:
def shift_world_x(self,shift_x):
""" When character moves left/right, everything must follow """
suggests that if the player right edge moves past the world right edge the world right edge should extend to match the player but this code does the reverse:
if player.rect.right >= 510:
diff = player.rect.right - 510
player.rect.right = 510
current_level.shift_world_x(-diff)
If the player.right moves to 513 diff will be 3 so shift_world_x will be called with -3, moving the world box left to 507. Player right will then be set to 510 so the player right will still be outside the box the next loop. This suggests that the world image will drift to the left with the player sprite stuck at the right edge but it sounds like it's trapped against the right edge (I'm focussing on one edge because the logic is the same for all).
If you log player.rect.right and world.rect.right in the if shown above you should see the values as they change and get a better feel for what the game logic is doing.

Pygame independent moving images on the screen

I am new to Python and Pygame. I want to have a screen in pygame with multiple copies of the same images moving around independently. I have tried to write it as a class and then call instances of it inside the while loop, but it doesn't work. Could someone show how can i basically do such a thing using a class?
I've tried to keep everything simple
Example:
import pygame
pygame.init()
WHITE = (255,255,255)
BLUE = (0,0,255)
window_size = (400,400)
screen = pygame.display.set_mode(window_size)
clock = pygame.time.Clock()
class Image():
def __init__(self,x,y,xd,yd):
self.image = pygame.Surface((40,40))
self.image.fill(BLUE)
self.x = x
self.y = y
self.x_delta = xd
self.y_delta = yd
def update(self):
if 0 <= self.x + self.x_delta <= 360:
self.x += self.x_delta
else:
self.x_delta *= -1
if 0 <= self.y + self.y_delta <= 360:
self.y += self.y_delta
else:
self.y_delta *= -1
screen.blit(self.image,(self.x,self.y))
list_of_images = []
list_of_images.append(Image(40,80,2,0))
list_of_images.append(Image(160,240,0,-2))
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(WHITE)
for image in list_of_images:
image.update()
pygame.display.update()
clock.tick(30)
pygame.quit()
Each image can be called individually from the list and moved by simply changing Image.x/y to whatever you want