I am trying to animate two characters in my game. I want the animation to play without any key being held down. Every tutorial I have seen requires the player to press a key for an animation to play. How would you get the dolphin to be animated, but still work with the existing code I have? Currently I have the dolphin set to frame[0] so it is visible when you run it. Any help is appreciated!
Images and Sound FX download: https://mega.nz/#F!7O5zRQDK!YQhrs_zavCvdSdAMwEXEIQ
Game I am basing off of: https://www.youtube.com/watch?v=9jjy9PjbeiA&t=3s
import pygame
import random
import time
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d, %d" %(0, 20)
pygame.init()
SIZE = W, H = 400, 700
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
# colours
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BACKGROUND = (94, 194, 222)
STRIPE = (60, 160, 190)
LANELINE = (255, 255, 255)
x1 = 30
x2 = 330
lane1 = 30
lane2 = 130
lane3 = 230
lane4 = 330
y = 530
width = 40
height = 64
toggle1 = 0
toggle2 = 0
target_x1 = 30
target_x2 = 330
vel_x = 10
def drawScene():
screen.fill(BACKGROUND)
pygame.draw.polygon(screen, STRIPE, ((200, 700), (300, 700), (400, 600), (400, 500)))
pygame.draw.polygon(screen, STRIPE, ((0, 700), (100, 700), (400, 400), (400, 300)))
pygame.draw.polygon(screen, STRIPE, ((0, 500), (0, 600), (400, 200), (400, 100)))
pygame.draw.polygon(screen, STRIPE, ((0, 300), (0, 400), (400, 0), (300, 0)))
pygame.draw.polygon(screen, STRIPE, ((0, 100), (0, 200), (200, 0), (100, 0)))
pygame.draw.line(screen, LANELINE, (100, 0), (100, 700), 2)
pygame.draw.line(screen, LANELINE, (200, 0), (200, 700), 4)
pygame.draw.line(screen, LANELINE, (300, 0), (300, 700), 2)
dolphinSheet = pygame.image.load("dolphinSheet.png").convert()
cells = []
for n in range(6):
dolphinW, dolphinH, = (31, 74)
rect = pygame.Rect(n * dolphinW, 0, dolphinW, dolphinH)
image = pygame.Surface(rect.size).convert()
image.blit(dolphinSheet, (0, 0), rect)
alpha = image.get_at((0, 0))
image.set_colorkey(alpha)
cells.append(image)
playerImg = cells[0]
# main loop
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
pygame.mixer.music.load('percussiveHit.mp3')
pygame.mixer.music.play()
toggle1 += 1
if toggle1 % 2 == 1:
target_x1 += 100
else:
target_x1 -= 100
elif event.key == pygame.K_d:
pygame.mixer.music.load('percussiveHit.mp3')
pygame.mixer.music.play()
toggle2 += 1
if toggle2 % 2 == 1:
target_x2 -= 100
else:
target_x2 += 100
if x1 < target_x1:
x1 = min(x1 + vel_x, target_x1)
else:
x1 = max(x1 - vel_x, target_x1)
if x2 < target_x2:
x2 = min(x2 + vel_x, target_x2)
else:
x2 = max(x2 - vel_x, target_x2)
pygame.draw.rect(screen, RED, (x1, y, width, height))
pygame.draw.rect(screen, RED, (x2, y, width, height))
drawScene()
# players
screen.blit(playerImg, (x1 + 4, y - 5))
screen.blit(playerImg, (x2 + 4, y - 5))
pygame.display.update()
pygame.quit()
Update the image based on a real-time millisecond value using pygame.time.get_ticks() which returns the number of milliseconds since pygame.init().
The idea is the code remembers the time the frame was changed, and then waits until X seconds have elapsed (playerImg_show_for below), before switching to the next image in the set.
...
playerImg = cells[0]
playerImg_cell = -1 # start at first cell
playerImg_shown_at = 0 # time when this frame (cell) was shown
playerImg_show_for = 200 # milliseconds
# main loop
run = True
while run:
clock.tick(60)
ms_now = pygame.time.get_ticks() # milliseconds since start
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# ... handle keys, etc. removed for the sake of brevity
pygame.draw.rect(screen, RED, (x1, y, width, height))
pygame.draw.rect(screen, RED, (x2, y, width, height))
drawScene()
# players
# If this frame of animation has been shown for long enough, then
# switch to the next frame
if ( ms_now - playerImg_shown_at > playerImg_show_for ):
playerImg_cell += 1 # find the next cell, with wrap-around
if ( playerImg_cell >= len( cells ) ):
playerImg_cell = 0
playerImg_shown_at = ms_now # use new start time
playerImg = cells[playerImg_cell] # use new animation cell
screen.blit(playerImg, (x1 + 4, y - 5))
screen.blit(playerImg, (x2 + 4, y - 5))
pygame.display.update()
pygame.quit()
Of course this would be better suited to being a PyGame sprite object, and all handled in the sprite's update() function.
Related
import pygame
import random
import time
pygame.init()
backX = 1000
backY = 600
screen = pygame.display.set_mode((backX, backY))
score = 0
white = (255, 255, 255)
green = (0, 255, 0)
blue = (0, 0, 128)
timespent = 0
pygame.display.set_caption('Monkey Simulator') # game name
pygame.font.init() # you have to call this at the start,
# if you want to use this module.
myfont = pygame.font.SysFont('Comic Sans MS', 30)
textsurface = myfont.render('Score: ' + str(score), False, (255, 255, 255))
pygame.mixer.init()
# music
sound = pygame.mixer.Sound('background1.mp3')
collection = pygame.mixer.Sound('collection.mp3')
gameover1 = pygame.mixer.Sound('gameover.mp3')
sound.play(-1)
# score indicator
text = myfont.render('Score: ' + str(score), True, white, blue)
textRect = text.get_rect() # getting the rectangle for the text object
textRect.center = (400 // 2, 400 // 2)
pre_background = pygame.image.load('background.jpeg')
background = pygame.transform.scale(pre_background, (backX, backY))
clock = pygame.time.Clock()
FPS = 60
vel = 6.5
BLACK = (0, 0, 0)
monkeyimg = pygame.image.load('monkey.png')
playerX = 410
playerY = 435
bananavelocity = 4
monkey = pygame.transform.scale(monkeyimg, (100, 120))
prebanana = pygame.image.load('banana.png')
bananaXList = []
def change():
if score>=5:
monkey = pygame.transform.scale(pre_shark, (100, 100))
banana = pygame.transform.scale(pre_meat, (50, 50))
background = pygame.transform.scale(underwater, (backX, backY))
for i in range(50):
value = random.randint(10, 980)
bananaXList.append(value)
valuenumber = random.randint(1, 30)
bananaX = bananaXList[valuenumber - 1]
bananaY = 0
banana = pygame.transform.scale(prebanana, (50, 50))
underwater = pygame.image.load('underwater.jpg')
pre_shark = pygame.image.load('shark.png')
pre_meat = pygame.image.load('meat.png')
banana_rect = banana.get_rect(topleft=(bananaX, bananaY))
monkey_rect = monkey.get_rect(topleft=(playerX, playerY))
run = True
black = (0, 0, 0)
# start screen
screen.blit(background, (0, 0))
myfont = pygame.font.SysFont("Britannic Bold", 50)
end_it = False
while not end_it:
myfont1 = pygame.font.SysFont("Britannic Bold", 35)
nlabel = myfont.render("Monkey Simulator", 1, (255, 255, 255))
info = myfont1.render("Use your right and left arrow keys to move the character.", 1, (255, 255, 255))
info2 = myfont1.render("Try to catch as many bananas as you can while the game speeds up!", 1, (255, 255, 255))
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
end_it = True
screen.blit(nlabel, (400, 150))
screen.blit(info, (100, 300))
screen.blit(info2, (100, 350))
pygame.display.flip()
while run:
clock.tick(FPS)
screen.fill(BLACK)
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
# banana animation
bananaY = bananaY + bananavelocity
timespent = int(pygame.time.get_ticks() / 1000)
bananavelocity = 4 + (timespent * 0.055)
vel = 6.5 + (timespent * 0.07)
# end game sequence
change()
if bananaY > 510:
bananaX = -50
bananaY = -50
banana
velocity = 0
gameover = pygame.image.load("gameover.jpg")
background = pygame.transform.scale(gameover, (backX, backY))
pygame.mixer.Sound.stop(sound)
gameover1.play()
# collecting coins sequence
if banana_rect.colliderect(monkey_rect):
collection.play()
valuenumber = random.randint(1, 30)
bananaX = bananaXList[valuenumber - 1]
bananaY = -25
score += 1
# moving character
if keys[pygame.K_LEFT] and playerX > 0:
playerX = playerX - vel
if keys[pygame.K_RIGHT] and playerX < 930:
playerX = playerX + vel
# adding the sprites to the screen
screen.blit(monkey, (playerX, playerY))
screen.blit(banana, (bananaX, bananaY))
banana_rect = banana.get_rect(topleft=(bananaX, bananaY))
monkey_rect = monkey.get_rect(topleft=(playerX, playerY))
pygame.draw.rect(screen, (150, 75, 0), pygame.Rect(0, 534, 1000, 20))
screen.blit(textsurface, (30, 0))
textsurface = myfont.render('Score: ' + str(score), False, (255, 255, 255))
pygame.display.update()
Right now I'm making a collection game. I want to use a function for replacing all the images once you hit a certain score. It doesn't work, though, no matter how high of a score you get. I don't understand the issue because I tested both the function and the if statement by putting print statements.
You have to use the global statement when you want to change a variable in the global namespace within a function:
def change():
global monkey, banana, background
if score>=5:
monkey = pygame.transform.scale(pre_shark, (100, 100))
banana = pygame.transform.scale(pre_meat, (50, 50))
background = pygame.transform.scale(underwater, (backX, backY))
If you don't use the global statement, the values are assigned to local variables in the scope of the function.
Another option is to return the new values from the function:
def change():
if score>=5:
return (
pygame.transform.scale(pre_shark, (100, 100)),
pygame.transform.scale(pre_meat, (50, 50)),
pygame.transform.scale(underwater, (backX, backY)) )
return monkey, banana, background
while True:
# [...]
monkey, banana, background = change()
I'm trying to create this program in pygame to study code/math, but i don't know how to lock the mouse position around a circle in pygame, any help?
import pygame
pygame.init()
x = 250
y = 250
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption("around circle")
#line to be created
def Lin(xref, yref):
lin = pygame.draw.line(window, (250, 250, 0), (x, y), (xref, yref), 1)
window_open = True
while window_open:
pygame.display.update()
window.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
window_open = False
mousepos = pygame.mouse.get_pos()
xref = mousepos[0]
yref = mousepos[1]
# 2 circles to get only the border
cir0 = pygame.draw.circle(window, (250, 250, 250), (x, y), 100, 1)
cir1 = pygame.draw.circle(window, (250, 250, 250), (x, y), 99, 1)
Lin(xref, yref)
pygame.quit()
I would do something similar to Mike67 answer, but would take advantage of the features of pygame's Vector's (see docs here).
import pygame
pygame.init()
x = 250
y = 250
radius = 100
center = pygame.Vector2(x, y)
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption("around circle")
#line to be created
def Lin(start_point, vector):
pygame.draw.line(window, (250, 250, 0), start_point, start_point+vector, 1)
window_open = True
while window_open:
pygame.display.update()
window.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
window_open = False
mousepos = pygame.mouse.get_pos()
line_vector = pygame.Vector2(mousepos) - center
if line_vector.length() > radius:
line_vector.scale_to_length(radius)
# 2 circles to get only the border
cir0 = pygame.draw.circle(window, (250, 250, 250), (x, y), radius, 1)
cir1 = pygame.draw.circle(window, (250, 250, 250), (x, y), radius-1, 1)
Lin(center, line_vector)
pygame.quit()
I modified the Lin() function as well.
EDIT:
From your comment you indicated that you want it to always scale to the side of the circle. In that case just skip the test if line_vector.length() > radius and always scale it. You might be tempted to only scale it if length != radius, but when comparing floating point calculated numbers they are very unlikely to actually be the same (because of the decimal places involved) and you could see if the difference is less than a threshold and call them equal, but it really isn't worth the complication.
import pygame
pygame.init()
x = 250
y = 250
radius = 100
center = pygame.Vector2(x, y)
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption("around circle")
#line to be created
def Lin(start_point, vector):
pygame.draw.line(window, (250, 250, 0), start_point, start_point+vector, 1)
window_open = True
while window_open:
pygame.display.update()
window.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
window_open = False
mousepos = pygame.mouse.get_pos()
line_vector = pygame.Vector2(mousepos) - center
line_vector.scale_to_length(radius)
# 2 circles to get only the border
cir0 = pygame.draw.circle(window, (250, 250, 250), (x, y), radius, 1)
cir1 = pygame.draw.circle(window, (250, 250, 250), (x, y), radius-1, 1)
Lin(center, line_vector)
pygame.quit()
To keep the line in the circle, just adjust the mouse x/y coordinates relative to the mouse distance from the center.
Here is the updated code:
import pygame
import math
pygame.init()
x = 250
y = 250
window = pygame.display.set_mode((500, 500))
pygame.display.set_caption("around circle")
#line to be created
def Lin(xref, yref):
lin = pygame.draw.line(window, (250, 250, 0), (x, y), (xref, yref), 1)
window_open = True
while window_open:
pygame.display.update()
window.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
window_open = False
mousepos = pygame.mouse.get_pos()
xref = mousepos[0]
yref = mousepos[1]
# get mouse distance from center
dist = math.sqrt((xref-x)**2 + (yref-y)**2)
if (dist > 100): # if mouse outside circle, adjust x/y proportionally
xref = x + (xref - x) * (100/dist)
yref = y + (yref - y) * (100/dist)
# 2 circles to get only the border
cir0 = pygame.draw.circle(window, (250, 250, 250), (x, y), 100, 1)
cir1 = pygame.draw.circle(window, (250, 250, 250), (x, y), 99, 1)
Lin(xref, yref)
pygame.quit()
I am a python beginner. I want to recreate chrome dino game. the random rectangle won't stop and the loop runs forever...please help me to stop the loop and make rectangles move.
Code:
import pygame
import random
pygame.init()
win = pygame.display.set_mode((500, 500))
#red rectangle(dino)
x = 20
y = 400
width = 30
height = 42
gravity = 5
vel = 18
black = (0, 0, 0)
#ground
start_pos = [0, 470]
end_pos = [500, 470]
#cactus
x1 = 20
y1 = 30
white = (2, 200, 200)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(30)
pygame.time.delay(10)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#random rectangle generation
for i in range(1):
width2 = random.randint(25, 25)
height2 = random.randint(60, 60)
top = random.randint(412, 412)
left = random.randint(300, 800)
rect = pygame.draw.rect(win, white, (left, top, width2,height2))
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
y = y - vel
else:
y = min(428, y + gravity)
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win, white, start_pos, end_pos, 2)
pygame.display.update()
pygame.display.flip()
pygame.quit()
pygame.draw.rect() des not "generate" a rectangle, it draws a rectangle on a surface.
pygame.Rect is a rectangle object. Create an instance of pygame.Rect before the main application loop:
obstracle = pygame.Rect(500, random.randint(0, 412), 25, 60)
Change the position of the rectangle:
obstracle.x -= 3
if obstracle.right <= 0:
obstracle.y = random.randint(0, 412)
And draw the rectangle to the window surface:
pygame.draw.rect(win, white, obstracle)
Example:
import pygame
import random
pygame.init()
win = pygame.display.set_mode((500, 500))
start_pos = [0, 470]
end_pos = [500, 470]
gravity = 5
vel = 18
black = (0, 0, 0)
white = (2, 200, 200)
hit = 0
dino = pygame.Rect(20, 400, 30, 40)
obstracles = []
number = 5
for i in range(number):
ox = 500 + i * 500 // number
oy = random.randint(0, 412)
obstracles.append(pygame.Rect(ox, oy, 25, 60))
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
dino.y -= vel
else:
dino.y = min(428, dino.y + gravity)
for obstracle in obstracles:
obstracle.x -= 3
if obstracle.right <= 0:
obstracle.x = 500
obstracle.y = random.randint(0, 412)
if dino.colliderect(obstracle):
hit += 1
win.fill(black)
color = (min(hit, 255), max(255-hit, 0), 0)
pygame.draw.rect(win, color, dino)
for obstracle in obstracles:
pygame.draw.rect(win, white, obstracle)
pygame.draw.line(win, white, start_pos, end_pos, 2)
pygame.display.update()
pygame.quit()
Im trying to make the game Towers of hanoi with pygame.
My biggest struggle is now that i have to move the disks, this is my code so far, but it is not moving the disks and i dont know why. I think it is also registering only the first mouseclick and not the second. but it isnt removing the disc either.
import pygame, sys
from pygame.locals import*
pygame.init()
screen = pygame.display.set_mode((500, 300))
pygame.display.set_caption("Towers of Hanoi")
# Colours
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
SILVER = (192, 192, 192)
AQUA = (0, 255, 255)
PURPLE = (128, 0, 128)
# Background
background = screen.fill(WHITE)
# Platform
pygame.draw.rect(screen, BLUE,(50, 250, 400, 20))
# Towers
tower_left = pygame.draw.line(screen, SILVER,(125, 100), (125, 249), 20)
tower_middle = pygame.draw.line(screen, SILVER,(250, 100), (250, 249), 20)
tower_right = pygame.draw.line(screen, SILVER,(375, 100), (375, 249), 20)
# Discs
big = pygame.draw.ellipse(screen, RED,(70, 235, 115, 15))
middle = pygame.draw.ellipse(screen, GREEN,(75, 220, 105, 15))
small = pygame.draw.ellipse(screen, BLACK,(85, 205, 85, 15))
# List of towers (3 being the biggest)
left_tower = [big, middle, small]
middle_tower = []
right_tower = []
count = 0
# Click locations
clicks = []
for c in range(0, 1):
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
clicks.append([x, y])
# Main game loop
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.quit()
# Getting the mouseposition and moving the disc
elif event.type == MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
first_click = x, y
# Remove the disc if it is in the range of the first tower
if (x > 100) and (x < 140) and (y > 150) and (y < 250):
if len(left_tower) == 0:
print "That's not valid"
elif len(left_tower) in (big, middle, small):
upper_disc = left_tower[-1]
left_tower.remove(upper_disc)
if event.type == MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
second_click = x, y
# Add the upper disc to the tower where the second click was
if (x > 140) and (x < 220) and (y > 150) and (y < 250):
middle_tower.append(upper_disc)
elif (x > 350) and (x < 450) and (y > 150) and (y < 250):
right_tower.append(upper_disc)
else:
left_tower.append(upper_disc)
pygame.display.update()
pygame.time.wait(10)
A couple things I see. There appears to be some indentation issues with your code. When I fix this how I believe it should be fixed it never falls into the last elif so elif len(left_tower) in (big, middle, small): is never returning True.
Just out of curiosity, why does a game lag when I load an image as well as display pygame shapes for example rectangles, circles and ellipses. I have this code where you shoot the ghosts that fall down (I'm still working on the shooting part). I made the cannon out of pygame shapes. But when I run it the images of the ghosts are prefect but the images of the cannons lag and disappears and reappear and so on. Is there any way to stop this lag or disappear and reappear thing? I'm running python 2.6 with windows vista.
import pygame, sys, random, math
from pygame.locals import *
WINDOWHEIGHT = 600
WINDOWWIDTH = 600
FPS = 30
BACKGROUNDCOLOR = (255, 255, 255)
TEXTCOLOR = (0, 0, 0)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
BROWN = (139, 69, 19)
DARKGRAY = (128, 128, 128)
BGCOLOR = WHITE
GHOSTSPEED = 10
GHOSTSIZE = 20
ADDNEWGHOSTRATE = 8
def keyToPlayAgain():
while True:
for event in event.type.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
return
def getAngle(x1, y1, x2, y2):
# Return value is 0 for right, 90 for up, 180 for left, and 270 for down (and all values between 0 and 360)
rise = y1 - y2
run = x1 - x2
angle = math.atan2(run, rise) # get the angle in radians
angle = angle * (180 / math.pi) # convert to degrees
angle = (angle + 90) % 360 # adjust for a right-facing sprite
return angle
def Text(text, font, surface, x, y):
textobj = font.render(text, 2, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
pygame.init()
mainClock = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWHEIGHT, WINDOWWIDTH))
pygame.display.set_icon(pygame.image.load('s.icon'))
pygame.display.set_caption('Ghost Invasion Pacfighters')
pygame.mouse.set_visible(False)
font = pygame.font.SysFont(None, 48)
gameOverSound = pygame.mixer.Sound('gameover.wav')
pygame.mixer.music.load('background.mid')
ghostImage = pygame.image.load('ghosts.png')
dotImage = pygame.image.load('dot.png')
dotRect = dotImage.get_rect()
creditsPage = pygame.image.load('credits.png')
titlePage = pygame.image.load('title.png')
pygame.time.wait(10000)
DISPLAYSURF.blit(creditsPage, (0, 0))
pygame.time.wait(10000)
DISPLAYSURF.blit(titlePage, (0, 0))
pygame.display.update()
cannonSurf = pygame.Surface((100, 100))
cannonSurf.fill(BGCOLOR)
pygame.draw.circle(cannonSurf, DARKGRAY, (20, 50), 20)
pygame.draw.circle(cannonSurf, DARKGRAY, (80, 50), 20)
pygame.draw.rect(cannonSurf, DARKGRAY, (20, 30, 60, 40))
pygame.draw.circle(cannonSurf, BLACK, (80, 50), 15)
pygame.draw.circle(cannonSurf, BLACK, (80, 50), 20, 1)
pygame.draw.circle(cannonSurf, BROWN, (30, 70), 20)
pygame.draw.circle(cannonSurf, BLACK, (30, 70), 20, 1)
health = 100
score = 0
topScore = 0
while True:
ghosts = []
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
ghostAddCounter = 0
pygame.mixer.music.play(-1, 0.0)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_x:
bombs()
elif event.type == ESCAPE:
pygame.quit()
sys.exit()
mousex, mousey = pygame.mouse.get_pos()
for cannonx, cannony in ((100, 500), (500, 500)):
degrees = getAngle(cannonx, cannony, mousex, mousey)
rotatedSurf = pygame.transform.rotate(cannonSurf, degrees)
rotatedRect = rotatedSurf.get_rect()
rotatedRect.center = (cannonx, cannony)
DISPLAYSURF.blit(rotatedSurf, rotatedRect)
pygame.draw.line(DISPLAYSURF, BLACK, (mousex - 10, mousey), (mousex + 10, mousey))
pygame.draw.line(DISPLAYSURF, BLACK, (mousex, mousey - 10), (mousex, mousey + 10))
pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)
pygame.display.update()
if not reverseCheat and not slowCheat:
ghostAddCounter += 1
if ghostAddCounter == ADDNEWGHOSTRATE:
ghostAddCounter = 0
newGhost = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-GHOSTSIZE), 0 - GHOSTSIZE, GHOSTSIZE, GHOSTSIZE),
'speed': (GHOSTSIZE),
'surface':pygame.transform.scale(ghostImage, (GHOSTSIZE, GHOSTSIZE)),
}
ghosts.append(newGhost)
for s in ghosts:
if not reverseCheat and not slowCheat:
s['rect'].move_ip(0, s['speed'])
elif reverseCheat:
s['rect'].move_ip(0, -5)
elif slowCheat:
s['rect'].move_ip(0, -1)
for s in ghosts[:]:
if s['rect'].top > WINDOWHEIGHT:
health -= 10
DISPLAYSURF.fill(BACKGROUNDCOLOR)
Text('Score: %s' % (score), font, DISPLAYSURF, 10, 0)
Text('Top score: %s' % (topScore), font, DISPLAYSURF, 10, 40)
Text('Health: %s' % (health), font, DISPLAYSURF, 10, 560)
for s in ghosts:
DISPLAYSURF.blit(s['surface'], s['rect'])
pygame.display.update()
mainClock.tick(FPS)
pygame.mixer.music.stop()
gameOverSound.play()
Text('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
pygame.display.update()
keyToPlayAgain()
pygame.display.update()
gameOverSound.stop()
The problem is that you draw your cannons, update the display, then clear the display, draw the other stuff, and update the display again. You basically never see the falling ghosts and the cannons at the same time. This results in the flickering you see.
So remove pygame.display.update() from this for loop
for cannonx, cannony in ((100, 500), (500, 500)):
...
pygame.display.update()
and put DISPLAYSURF.fill(BACKGROUNDCOLOR) at the top of your while loop (or at least before you draw anything):
while True:
for event in pygame.event.get():
...
mousex, mousey = pygame.mouse.get_pos()
DISPLAYSURF.fill(BACKGROUNDCOLOR)
for cannonx, cannony in ((100, 500), (500, 500)):
...
It's best to clear the background once at the start of your code that draws everything, and call pygame.display.update() once at the end of that drawing code.