pygame screen not refreshing - python

So i am new to python, and im working on a code that draws a spirograph and moves it. When I ran the code, all I got was a black screen with no circles on it. Im sure that im drawing circles and the screen is refreshing because i printed out its coordinates. However, the screen is still black. Any help?
import pygame
import math
import sys
import time
#setting colors
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
ORANGE = (255, 127, 0)
YELLOW = (255, 255, 0)
PURPLE = (160, 32, 240)
#setting what order the colors go in
listCircleColor = (RED, BLUE, GREEN, ORANGE, YELLOW, PURPLE, WHITE)
#how many circles per color
intGroup = 5
#the space between each circle
turnangle = 360/35
#width of screen
width = 600
#height of screen
height = 600
#radius of circles
radius = 100
#making the screen
screen = pygame.display.set_mode((width, height))
#if the code is running, then continue
running = True
##.draw.circle(screen, BLUE, (0, 0), radius, width=2)
circles = []
#draw
alpha = turnangle
for i in range(intGroup):
for cl in listCircleColor:
surfacetemp = pygame.Surface((width, height))
##circlerect = pygame.rect
if alpha > 0 and alpha < 90:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 + radius *
math.cos(math.radians(alpha)), 300 + radius * math.sin(math.radians(alpha))), radius, width=2)
# second quarter of circles
if alpha > 90 and alpha < 180:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 - radius *
math.cos(math.radians(180 - alpha)), 300 + radius * math.sin(math.radians(180 - alpha))), radius, width=2)
# third quarter of circles
if alpha > 180 and alpha < 270:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 - radius *
math.cos(math.radians(270 - alpha)), 300 - radius * math.sin(math.radians(270 - alpha))), radius, width=2)
# last quarter of circles
if alpha > 270 and alpha < 360:
circlerect = pygame.draw.circle(surfacetemp, cl, (300 + radius *
math.cos(math.radians(360 - alpha)), 300 - radius * math.sin(math.radians(360 - alpha))), radius, width=2)
alpha = alpha + turnangle
##circles.append(circlerect)
circles.append(surfacetemp)
#move"
#exit only when user clicks on exit button
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
for crect in circles:
ret = crect.get_rect()
ret.right += 5
ret.left += 5
screen.blit(screen, ret)
##screen.blit(crect,crect)
pygame.time.Clock().tick(20)
pygame.display.update()
##for center, color in circles:
## pygame.draw.circle(screen, color, center, radius, 2)
##pygame.display.flip()

You blit on correct screen but you blit wrong objects.
You should use crect instead of screen as first argument
screen.blit(crect, ret)
but you have
screen.blit(screen, ret)
so you blit black screen on black screen
Surface as default uses 24bit colors R,G,B and it has black background so your code shows only one circle because other circles are behind black backgrounds of other surfaces.
To make transparent background you have to convert surfaces to 32bit colors R,G,B,Alpha
surfacetemp = surfacetemp.convert_alpha()
and fill background with transparent color - last value (alpha) has to be 0, other values don't matter (if you don't need semi-transparent color)
surfacetemp.fill((0,0,0,0))
And now you can see all circles.
There is also other problem.
Surface can keep image but not position. surface.get_rect() gives always only (0, 0, width, height). If you want to animate then you need another list to keep positions - you can use pygame.Rect() for this.
At start I create circles_rect with all get_rect() and later I use this list to change position and blit it.
Animation need also to clear screen in every loop to remove circles in old positions. I use screen.fill((0,0,0)) to draw black background.
If you change rec.right += 5 then you don't have to change rec.left because it is changed automatically (the same with rec.centerx)
Running
rec.right += 5
rec.left += 5
gives the same result as
rec.right += 10
EDIT:
You don't have to make different calculations for different quarters.
import pygame
import math
# setting colors
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 255, 0)
RED = (255, 0, 0)
ORANGE = (255, 127, 0)
YELLOW = (255, 255, 0)
PURPLE = (160, 32, 240)
# setting what order the colors go in
listCircleColor = (RED, BLUE, GREEN, ORANGE, YELLOW, PURPLE, WHITE)
# how many circles per color
intGroup = 5
# the space between each circle
turnangle = 360/35
# width of screen
width = 600
# height of screen
height = 600
# radius of circles
radius = 100
# making the screen
screen = pygame.display.set_mode((width, height))
# .draw.circle(screen, BLUE, (0, 0), radius, width=2)
circles = []
circles_rect = []
# draw
alpha = turnangle
for i in range(intGroup):
for cl in listCircleColor:
surfacetemp = pygame.Surface((width, height))
surfacetemp = surfacetemp.convert_alpha()
surfacetemp.fill((0,0,0,0))
x = 300 + radius * math.cos(math.radians(alpha))
y = 300 + radius * math.sin(math.radians(alpha))
circlerect = pygame.draw.circle(surfacetemp, cl, (x, y), radius, width=2)
alpha = alpha + turnangle
circles.append(surfacetemp)
circles_rect.append(surfacetemp.get_rect())
# move
# exit only when user clicks on exit button
# if the code is running, then continue
running = True
clock = pygame.time.Clock()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
#running = False
screen.fill((0,0,0)) # remove previous circles
for crect, ret in zip(circles, circles_rect):
ret.right += 5
#ret.left += 5
screen.blit(crect, ret)
result = clock.tick(25)
fps = clock.get_fps()
text = f'FRAME TIME: {result:.02f} ms | FPS: {fps:.02f}'
pygame.display.set_caption(text)
#print(text)
#pygame.display.update()
pygame.display.flip()

Related

rotating a rectangle in pygame

I'm trying to make a white rectangle rotate like a the hands of a clock in pygame using this code,
import random, pygame, math, sys
from pygame.locals import *
Blue = (0,0,255)
Black = (0, 0, 0)
Green = (0,255,0)
White = (255,255,255)
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Sailing!')
FPS = 30
fpsClock = pygame.time.Clock()
Sail = pygame.Surface([100,10])
Sail.set_colorkey (Black)
Sail.fill(White)
degrees = 0
hyp = 100
x = 200
y = 150
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
adj = 10 * math.cos(degrees)
opp = 10 * math.sin(degrees)
dx = adj + 200
dy = opp + 150
rotatedSail = pygame.transform.rotate(Sail, degrees)
Sail_rect = Sail.get_rect(topleft = (dx, dy))
DISPLAYSURF.fill(Blue)
DISPLAYSURF.blit(rotatedSail, Sail_rect)
pygame.display.flip()
fpsClock.tick(FPS)
degrees += 1
but the rectangle rotates in a weird way. I would appreciate it if you could keep the suggestion as simple and as close to my code as possible, because I'm just starting to learn. Plus i know it's easier to do it using an image of a rectangle, but I'm trying to use a surface.
can anyone help?
You need to get the bounding rectangle of the rotated rectangle and set the center of the rectangle by (x, y) (see also How do I rotate an image around its center using PyGame?):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
rotatedSail = pygame.transform.rotate(Sail, degrees)
rotatedSail_rect = rotatedSail.get_rect(center = (x, y))
DISPLAYSURF.fill(Blue)
DISPLAYSURF.blit(rotatedSail, rotatedSail_rect)
pygame.display.flip()
fpsClock.tick(FPS)
degrees += 1
To rotate the object around another point than the center point is much more complicate. A general solution is described in the answer to How can you rotate an image around an off center pivot in PyGame.
Complete Example:
import pygame, math, sys
from pygame.locals import *
Blue = (0,0,255)
Black = (0, 0, 0)
Green = (0,255,0)
White = (255,255,255)
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Sailing!')
FPS = 30
fpsClock = pygame.time.Clock()
Sail = pygame.Surface([100,10])
Sail.set_colorkey (Black)
Sail.fill(White)
degrees = 0
hyp = 100
x = 200
y = 150
def blitRotate(surf, image, pos, originPos, angle):
# calcaulate the axis aligned bounding box of the rotated image
w, h = image.get_size()
sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle))
min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])
# calculate the translation of the pivot
pivot = pygame.math.Vector2(originPos[0], -originPos[1])
pivot_rotate = pivot.rotate(angle)
pivot_move = pivot_rotate - pivot
# calculate the upper left origin of the rotated image
origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])
# get a rotated image
rotated_image = pygame.transform.rotate(image, angle)
# rotate and blit the image
surf.blit(rotated_image, origin)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
DISPLAYSURF.fill(Blue)
blitRotate(DISPLAYSURF, Sail, (x, y), (0, 5), degrees)
pygame.display.flip()
fpsClock.tick(FPS)
degrees += 1

Pygame BLEND Fullscreen Bug [duplicate]

I'm trying to make a simple Pygame application where some colors are blended with colors under them. Here is my code:
code-listing 1:
import pygame, sys, time
from pygame.locals import *
#define constants
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 600
FPS = 60
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), 0, 32)
alpha = 0
increasing = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#fill screen with red
screen.fill(pygame.Color(247, 25, 0,255))
alpha_surface = pygame.Surface((screen.get_rect().width, screen.get_rect().height))
alpha_surface = alpha_surface.convert_alpha()
surfaceRect = alpha_surface.get_rect()
#fill surface with orange
pygame.draw.rect(alpha_surface, (247, 137, 0, 255), (0, 0, 480, 480))
#fill surface with translucent yellow
pygame.draw.rect(alpha_surface, (220, 247, 0, alpha), (120, 120, 360, 360))
#fill surface with green
pygame.draw.rect(alpha_surface, (0, 247, 4), (240, 240, 240, 240))
#fill surface with translucent blue
pygame.draw.rect(alpha_surface, (0, 78, 247, alpha), (360, 360, 120, 120))
screen.blit(alpha_surface, (120,120))
pygame.display.update()
clock.tick(FPS)
if increasing:
alpha += 1
if alpha > 255:
alpha = 255
increasing = False
else:
alpha -= 1
if alpha < 0:
alpha = 0
increasing = True
the code is supposed to make it so the yellow rectangle blends with the orange rectangle and the blue rectangle with the green rectangle. Instead I am getting something that goes from this:
figure 1: original state with yellow and blue opacity set to 0%
to this:
figure 2: final state with yellow and blue opacity set to 100%
As you can see the yellow and blue rectangles not only blend with the red rectangle (screen surface) but they also make a hole to the orange and green rectangle so that we can see the red rectangle through them.
If you want to blend different layers, then you have to create different pygame.Surfaces or images. A Surface can be genrated by loading an image (pygame.image) or by constructing a pygame.Surface object.
Create a surface completely transparent Surface with per pixel alpha. Use pygame.Surface.convert_alpha to change the pixel format of an image including per pixel alphas. Fill the Surface with a transparent color (e.g pygame.Color(0, 0, 0, 0)):
Minimal example:
import pygame
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((600, 600), 0, 32)
def transparentSurface(size):
surface = pygame.Surface(size).convert_alpha()
surface.fill((0, 0, 0, 0))
return surface
alpha, increase = 0, 1
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill(pygame.Color(247, 25, 0,255))
alpha_surface1 = transparentSurface(screen.get_size())
pygame.draw.rect(alpha_surface1, (247, 137, 0, 255), (120, 120, 480, 480))
alpha_surface2 = transparentSurface(screen.get_size())
pygame.draw.rect(alpha_surface2, (220, 247, 0, alpha), (240, 240, 360, 360))
alpha_surface3 = transparentSurface(screen.get_size())
pygame.draw.rect(alpha_surface3, (0, 247, 4), (360, 360, 240, 240) )
alpha_surface4 = transparentSurface(screen.get_size())
pygame.draw.rect(alpha_surface4, (0, 78, 247, alpha), (480, 480, 120, 120) )
screen.blit(alpha_surface1, (0,0))
screen.blit(alpha_surface2, (0,0))
screen.blit(alpha_surface3, (0,0))
screen.blit(alpha_surface4, (0,0))
pygame.display.update()
alpha += increase
if alpha < 0 or alpha > 255:
increase *= -1
alpha = max(0, min(255, alpha))
pygame.quit()

inconsistent motion with pygame

I am having a problem where i am trying to get a circle to go to the same spot every time i execute the program. But each time I run the code, the dot doesn't always line up. I have a test circle in the same place to compare run to run. The Red circle should cover the white circle perfectly but it changes every time i run the program. I am reseting the kernal as i am using pygame.time.get_ticks() to time everything.
import sys, pygame, math
from pygame.locals import *
# set up a bunch of constants
BLUE = ( 0, 0, 255)
WHITE = (255, 255, 255)
ORANGE = (255, 165, 0)
PINK = (255, 20, 147)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
LIMEGREEN = ( 50, 205, 50)
YELLOW = (255, 255, 0)
PURPLE = (160, 32, 240)
BLACK = ( 0, 0, 0)
#Background Colour
BGCOLOR = BLACK
#Setting Window Size and finding window x and y centre
WINDOWWIDTH = 1918# width of the program's window, in pixels 960x540
WINDOWHEIGHT = 1078# height in pixels
WIN_CENTERX = int(WINDOWWIDTH / 2) # the midpoint for the width of the window
WIN_CENTERY = int(WINDOWHEIGHT / 2) # the midpoint for the height of the window
# frames per second to run at
FPS = 60
#intializing Variables
AMPLITUDE = 450
colourArray=[BLUE,WHITE,YELLOW,GREEN,RED,PINK,PURPLE,LIMEGREEN,ORANGE]
i=0
xPos = 0
step = 0
small_step =0
stop_step=step=0
xPos=0
yPos=0
c=RED
timestep=0
# standard pygame setup code
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT),pygame.FULLSCREEN)
pygame.display.set_caption('Task1')
fontObj = pygame.font.Font('freesansbold.ttf', 16)
# main application loop
while True:
# event handling loop for quit events
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
#setup for label and time
tempTime=pygame.time.get_ticks()/1000
time_string=str(tempTime)
instructionsSurf = fontObj.render(time_string, True, WHITE, BGCOLOR)
instructionsRect = instructionsSurf.get_rect()
instructionsRect.left = 10
instructionsRect.bottom = WINDOWHEIGHT - 10
# fill the screen to draw from a blank state
DISPLAYSURF.fill(BGCOLOR)
DISPLAYSURF.blit(instructionsSurf, instructionsRect)
tempTime=pygame.time.get_ticks()/1000
#Color change loop
c=RED
if (0<=(tempTime)<3):
c=RED
if (3<=(tempTime)<5):
c=BLUE
if (5<=(tempTime)<7):
c=GREEN
if (7<=(tempTime)<9):
c=YELLOW
if (9<=(tempTime)<11):
c=WHITE
if (11<=(tempTime)<17):
c=RED
if (17<=(tempTime)<42):
c=RED
if (42<=(tempTime)<46):
c=RED
if (46<=(tempTime)<120):
c=colourArray[i]
#Setting position of x and y coordinates
if (0<=(tempTime)<14):
xPos = 0
yPos = 0
if (14<(tempTime)<17):
small_step += 5.111
xPos = small_step
yPos = 0
if (17<(tempTime)<43):
step += 0.05001
step %= 2 * math.pi
xPos = math.cos(step) * AMPLITUDE
yPos = math.sin(step) * AMPLITUDE
if (43<(tempTime)<46):
stop_step=step
xPos = math.cos(stop_step) * AMPLITUDE
yPos = math.sin(stop_step) * AMPLITUDE
if (46<(tempTime)<120):
step += 0.05001
step %= 2 * math.pi
xPos = math.cos(step) * AMPLITUDE
yPos = math.sin(step) * AMPLITUDE
#test dot
pygame.draw.circle(DISPLAYSURF, WHITE, (WIN_CENTERX+AMPLITUDE, 0+WIN_CENTERY),12,0)
# draw dot1
dot1=pygame.draw.circle(DISPLAYSURF, c, (int(xPos)+ WIN_CENTERX, int(yPos) + WIN_CENTERY), 12,0)
# draw dot2
dot2=pygame.draw.circle(DISPLAYSURF, BLACK, (int(xPos) + WIN_CENTERX, int(yPos) + WIN_CENTERY), 6,0)
#refresh
pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)
pygame.display.update()
FPSCLOCK.tick(FPS)
I've only scanned your code but I would guess your inconsistency is due to a high frame rate (60). FPSCLOCK.tick(FPS) will make sure you go up to 60, but does not mean you will go 60 fps. So if your computer can not handle 60 frames per second, it will go below 60 frames.
Cristph Terasa's recommendation of using busy_loop should do the job for ya, but I personally have no experience for it and want to share a method of normalizing game speed across different FPSs.
Rather than reinventing a wheel, here's a link to a question that explains it. I recommend the second answer, written by pmoleri.
In Pygame, normalizing game-speed across different fps values
This solution should help your game run at the same speed no matter the frame rate.

PyGame/Python: Placing a circle onto an ellipse

I am trying to place multiple circles onto an eclipse and be able to move that circle around the eclipse. From looking into PyGames examples I have seen that you can rotate a line around an eclipse however cannot figure out how to do with with a circle.
This is the error message I recieve upon trying:
Traceback (most recent call last):
File "C:/Python32/Attempts/simple_graphics_demo.py", line 66, in <module>
pygame.draw.circle(screen, BLUE, [x, y], 15, 3)
TypeError: integer argument expected, got float
.
import pygame
import math
# Initialize the game engine
pygame.init()
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
PI = 3.141592653
# Set the height and width of the screen
size = [400, 400]
screen = pygame.display.set_mode(size)
my_clock = pygame.time.Clock()
# Loop until the user clicks the close button.
done = False
angle = 0
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Set the screen background
screen.fill(WHITE)
# Dimensions of radar sweep
# Start with the top left at 20,20
# Width/height of 250
box_dimensions = [20, 20, 250, 250]
# Draw the outline of a circle to 'sweep' the line around
pygame.draw.ellipse(screen, GREEN, box_dimensions, 2)
# Draw a black box around the circle
pygame.draw.rect(screen, BLACK, box_dimensions, 2)
# Calculate the x,y for the end point of our 'sweep' based on
# the current angle
x = 125 * math.sin(angle) + 145
y = 125 * math.cos(angle) + 145
# Draw the line from the center at 145, 145 to the calculated
# end spot
pygame.draw.line(screen, GREEN, [145, 145], [x, y], 2)
# Attempt to draw a circle on the radar
pygame.draw.circle(screen, BLUE, [x, y], 15, 3)
# Increase the angle by 0.03 radians
angle = angle + .03
# If we have done a full sweep, reset the angle to 0
if angle > 2 * PI:
angle = angle - 2 * PI
# Flip the display, wait out the clock tick
pygame.display.flip()
my_clock.tick(60)
# on exit.
pygame.quit()
The math.sin and math.cos functions return floats, and the pos keyword argument to pygame.draw.circle expects integer positions, so you'll want to actually cast your coordinates. You have a few options for doing this:
[int(x), int(y)]
[math.floor(x), math.floor(y)]
[math.ceil(x), math.ceil(y)]
Each comes with slightly different behaviours so you might want to figure out which fits your program best. (specifically: int and floor work differently for negative numbers -- int rounds towards 0 and floor rounds down, as expected)
It is not answer for your main question - because you already got answer.
To put more circles use list with angles and for loop to get angle from list (one-by-one) and draw circle.
import pygame
import math
# === CONSTANTS ===
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
SIZE = (400, 400)
TWO_PI = 2 * math.pi # you don't have to calculate it in loop
# === MAIN ===
# --- init ---
pygame.init()
screen = pygame.display.set_mode(SIZE)
# --- objects ---
angles = [0, 1, math.pi] # angles for many circles
box_dimensions = [20, 20, 250, 250] # create only once
# --- mainloop ---
clock = pygame.time.Clock()
done = False
while not done:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
# --- draws (without updates) ---
screen.fill(WHITE)
pygame.draw.ellipse(screen, GREEN, box_dimensions, 2)
pygame.draw.rect(screen, BLACK, box_dimensions, 2)
# draw many circles
for a in angles:
x = int(125 * math.sin(a)) + 145
y = int(125 * math.cos(a)) + 145
pygame.draw.line(screen, GREEN, [145, 145], [x, y], 2)
pygame.draw.circle(screen, BLUE, [x, y], 15, 3)
pygame.display.flip()
clock.tick(60)
# --- updates (without draws) ---
# new values for many angles
for i, a in enumerate(angles):
a += .03
if a > TWO_PI:
a -= TWO_PI
angles[i] = a
# --- the end ---
pygame.quit()

Adding gradient to moving objects in pygame

I want to add gradient to the ball in this program & also possibly the waves drawn to fade into the colour of the background (as if glowing) instead of one colour fills.
I've looked at tons of tutorials however none of them are making much sense to my syntax, the general idea to me is confusing as I have moving objects that draw the space I want to add gradient to quite slowly. Can anyone give an insight into how I can do this?
code:
import sys, pygame, math
from pygame.locals import *
# set up of constants
WHITE = (255, 255, 255)
DARKRED = (128, 0, 0)
RED = (255, 0, 0)
BLACK = ( 0, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
BGCOLOR = WHITE
screen = pygame.display.set_mode()
WINDOWWIDTH = 800 # width of the program's window, in pixels
WINDOWHEIGHT = 800 # height in pixels
WIN_CENTERX = int(WINDOWWIDTH / 2) # the midpoint for the width of the window
WIN_CENTERY = int(WINDOWHEIGHT / 2) # the midpoint for the height of the window
screen = pygame.display.get_surface()
FPS = 160 # frames per second to run at
AMPLITUDE = 80 # how many pixels tall the waves with rise/fall.
# standard pygame setup code
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), pygame.RESIZABLE)
pygame.display.set_caption('Window title')
fontObj = pygame.font.Font('freesansbold.ttf', 16)
# variables that track visibility modes
showSine = True
showSquare = True
pause = False
xPos = 0
step = 0 # the current input f
posRecord = {'sin': [], 'square': []} # keeps track of the ball positions for drawing the waves
yPosSquare = AMPLITUDE # starting position
# main application loop
while True:
# event handling loop for quit events
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
# fill the screen to draw from a blank state
DISPLAYSURF.fill(BGCOLOR)
# sine wave
yPos = -1 * math.sin(step) * AMPLITUDE
posRecord['sin'].append((int(xPos), int(yPos) + WIN_CENTERY))
if showSine:
# draw the sine ball and label
pygame.draw.circle(DISPLAYSURF, RED, (int(xPos), int(yPos) + WIN_CENTERY), 10)
sinLabelRect.center = (int(xPos), int(yPos) + WIN_CENTERY + 20)
DISPLAYSURF.blit(sinLabelSurf, sinLabelRect)
# draw the waves from the previously recorded ball positions
if showSine:
for x, y in posRecord['sin']:
pygame.draw.circle(DISPLAYSURF, DARKRED, (x,y), 4)
#drawing horizontal lines
# square
posRecord['square'].append((int(xPos), int(yPosSquare) + WIN_CENTERY))
if showSquare:
# draw the sine ball and label
pygame.draw.circle(DISPLAYSURF, GREEN, (int(xPos), int(yPosSquare) + WIN_CENTERY), 10)
squareLabelRect.center = (int(xPos), int(yPosSquare) + WIN_CENTERY + 20)
DISPLAYSURF.blit(squareLabelSurf, squareLabelRect)
# draw the waves from the previously recorded ball positions
if showSquare:
for x, y in posRecord['square']:
pygame.draw.circle(DISPLAYSURF, BLUE, (x, y), 4)
# draw the border
pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)
pygame.display.update()
FPSCLOCK.tick(FPS)
if not pause:
xPos += 1
#wave movement
if xPos > WINDOWWIDTH:
#sine
xPos = 0
posRecord['sin'] = []
step = 0
# square
yPosSquare = AMPLITUDE
posRecord['square'] = []
else:
#sine
step += 0.008
#step %= 2 * math.pi
# square
# jump top and bottom every 100 pixels
if xPos % 100 == 0:
yPosSquare *= -1
# add vertical line
for x in range(-AMPLITUDE, AMPLITUDE):
posRecord['square'].append((int(xPos), int(x) + WIN_CENTERY))
Use SPACE to change background color.
First line use only transparency - and has no problem with different background color.
Second line changes only circles color - and depends on background color.
Third and fourth line (it is the same line with different starting color) change circles color and transparency - and depends on background color.
Second and last line look good on one color background and need more work to find good-looking fading.
import pygame
pygame.init()
screen = pygame.display.set_mode((600,200))
#--------------------------------------
# circles positions and transparency (x,y, alpha)
circles = []
for x in range(100):
circles.append( [100+x*3, 200, x*2] )
#--------------------------------------
white = True # background color
#--------------------------------------
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_SPACE:
white = not white
#--------------------------------------
if white:
screen.fill((255,255,255))
else:
screen.fill((0,0,0))
#--------------------------------------
# first
circle_img = pygame.Surface((20,20))
pygame.draw.circle(circle_img, (255,0,0), (10,10), 10)
circle_img.set_colorkey(0)
for x in circles:
circle_img.set_alpha(x[2])
screen.blit(circle_img, (x[0],40))
#--------------------------------------
# second
circle_img = pygame.Surface((20,20))
for x in circles:
pygame.draw.circle(circle_img, (255,255-x[2],255-x[2]), (10,10), 10)
circle_img.set_colorkey(0)
screen.blit(circle_img, (x[0],90))
#--------------------------------------
# last
circle_img = pygame.Surface((20,20))
for x in circles:
pygame.draw.circle(circle_img, (255,255-x[2],255-x[2]), (10,10), 10)
circle_img.set_colorkey(0)
circle_img.set_alpha(x[2])
screen.blit(circle_img, (x[0],140))
#--------------------------------------
pygame.display.flip()
pygame.quit()

Categories

Resources