我正在尝试在实验室#8中为程序街机游戏书创建最后一个示例。
我尝试实现的最后一件事是一个红绿灯,它根据三个事件和计时器改变颜色。
我知道我必须一度使用pygame.time.set_timer()
,但我还没有接触过 Pygame 中的事件处理。我不知道我应该如何制作三个独立的事件,使每个相应的交通信号灯变成明亮的颜色。
这就是我到目前为止所拥有的,如果你省略258
行266
,动画使用 Pygame 和 Python 3 工作(我尝试连接"事件",但它只是不明显工作)。
这是一个修订版本,我尝试使用计时器从字面上更改颜色而不是制作单独的事件,但在这种情况下也不起作用;(
import random
import math
# Requirements:
# Modify the prior Create-a-Picture lab, or start a new one.
# Animate the image. Try one or more of the following:
# Move an item across the screen.
# Move an item back and forth.
# Move up/down/diagonally.
# Move in circles.
# Have a person wave his/her arms.
# Create a stoplight that changes colors.
# import statement
import pygame
# Define colors:
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
DULLRED = (153, 50, 51)
GREEN = (0, 255, 0)
DULLGREEN = (55, 154, 54)
BLUE = (0, 0, 255)
LIGHTBLUE = (103, 255, 246)
YELLOW = (252, 255, 31)
DULLYELLOW = (156, 157, 50)
# initialize pygame:
pygame.init()
# screen:
size = (700, 500)
screen = pygame.display.set_mode(size)
# Set the caption:
pygame.display.set_caption("Chapter 8 Lab")
# Clock:
clock = pygame.time.Clock()
# FPS:
FPS = 60
# boolean variable for game:
done = False
# For loop for white circles:
whiteCircleList = []
for i in range(25):
x = random.randrange(0, 700)
y = random.randrange(0, 50)
whiteCircleList.append([x,y])
# For Loop for Blue Circles:
blueCircleList = []
for i in range(100):
circleX = random.randrange(0, 500)
circleY = random.randrange(0, 700)
blueCircleList.append([circleX, circleY])
# Light Blue Circle For Loop:
lightBlueCircleList = []
for i in range(100):
circleX = random.randrange(0, 500)
circleY = random.randrange(0, 700)
lightBlueCircleList.append([circleX, circleY])
# Surfboard's Rectangle (x-pos, y-pos, x-length, y-length):
surfboardRect = pygame.Rect(325, 225, 50, 150)
boardY = 255.
rectYChange = -5
phase = 0
# Diagonal Rectangle in Top Left Corner:
topLeftDiagonalRect = pygame.Rect(0, 0, 10, 10)
# Diagonal Rectangle in Top Right Corner:
topRightDiagonalRect = pygame.Rect(500, 1, 10, 10)
# Diagonal Rectangle Vectors for Top Left Rectangle:
topLeftDiagonalRectXChange = 5
topLeftDiagonalRectYChange = 5
# Diagonal Rectangle Vectors for Top Right Rectangle:
topRightDiagonalRectXChange = -5
topRightDiagonalRectYChange = -5
# Angle for Hand Rotation
handAngle = 0
# Variable for Traffic Light Cover:
currentTopColor = DULLRED
currentMiddleColor = DULLYELLOW
currentBottomColor = GREEN
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Game Logic:
phase += 1
if phase > 180:
phase = phase * -1
# Save exact position as a float to avoid floating point errors:
boardY += math.cos(math.radians(phase))*2
surfboardRect.y = int(boardY)
# Clear the screen:
screen.fill(RED)
# Drawing Code:
# Falling Down circles:
for i in range(len(whiteCircleList)):
pygame.draw.circle(screen, WHITE, [whiteCircleList[i][0], whiteCircleList[i][1]], 3)
whiteCircleList[i][1] += 5
# If the rectangles have hit the bottom of the screen, make them appear 10 pixels above the top:
if whiteCircleList[i][1] > 450:
x = random.randrange(0, 700)
whiteCircleList[i][0] = x
y = random.randrange(-50, -10)
whiteCircleList[i][1] = y
# Red Falling Up Circles:
for i in range(len(blueCircleList)):
pygame.draw.circle(screen, BLUE, [blueCircleList[i][0], blueCircleList[i][1]], 5, 5)
blueCircleList[i][1] -= 5
if blueCircleList[i][1] < 50:
circleX = random.randrange(0,700)
circleY = random.randrange(400, 500)
blueCircleList[i][0] = circleX
blueCircleList[i][1] = circleY
# Light Blue Falling Up Circles:
for i in range(len(lightBlueCircleList)):
pygame.draw.circle(screen, LIGHTBLUE, [lightBlueCircleList[i][0], lightBlueCircleList[i][1]], 3, 3)
lightBlueCircleList[i][1] -= 5
if lightBlueCircleList[i][1] < 50:
circleX = random.randrange(0, 700)
circleY = random.randrange(400, 450)
lightBlueCircleList[i][0] = circleX
lightBlueCircleList[i][1] = circleY
# Revised Surfboard Rectangle Code:
pygame.draw.rect(screen, BLACK, surfboardRect, 0)
# Top Left Diagonal Rectangle Code:
pygame.draw.rect(screen, BLACK, topLeftDiagonalRect, 0)
# Add The Top Left Diagonal Rectangle Change Vectors
topLeftDiagonalRect.x += topLeftDiagonalRectXChange
topLeftDiagonalRect.y += topLeftDiagonalRectYChange
# Top and Bottom Screen Collision:
if topLeftDiagonalRect.y >= 500 or topLeftDiagonalRect.y <= 0:
topLeftDiagonalRectYChange = topLeftDiagonalRectYChange * -1
# Left and Right Screen Collision:
if topLeftDiagonalRect.x <= 0 or topLeftDiagonalRect.x >= 700:
topLeftDiagonalRectXChange = topLeftDiagonalRectXChange * -1
# Draw the top right rectangle:
pygame.draw.rect(screen, BLACK, topRightDiagonalRect, 0)
# Add the change vectors for the Top Right Rectangle:
topRightDiagonalRect.x += topRightDiagonalRectXChange
topRightDiagonalRect.y += topRightDiagonalRectYChange
# Top and Bottom Screen Collision:
if topRightDiagonalRect.y <= 0 or topRightDiagonalRect.y >= 500:
topRightDiagonalRectYChange = topRightDiagonalRectYChange * -1
# Left and Right Screen Collision:
if topRightDiagonalRect.x <= 0 or topRightDiagonalRect.x >= 700:
topRightDiagonalRectXChange = topRightDiagonalRectXChange * -1
# Person Waving His Arms:
# Head:
pygame.draw.circle(screen, WHITE, [575, 300], 15)
# Body:
pygame.draw.rect(screen, BLUE, [560, 315, 30, 60], 0)
# Left Rotating Hand:
# Left Hand's Original Dimensions:
# pygame.draw.line(screen, WHITE, [560, 315], [540, 295], 5)
# Original Hand's x position based on the rotating circle idea:
# handX = 40 * math.sin(handAngle) + 560
# Original Hand's y position based on the rotating circle idea:
# handY = 40 * math.cos(handAngle) + 315
handPosition = (40 * math.sin(handAngle) + 560, 40 * math.cos(handAngle) + 315)
pygame.draw.line(screen, WHITE, [560, 315], handPosition, 4)
# Increase the hand angle by 0.05 Radians:
handAngle = handAngle + 0.05
# Reset the angle after a full sweep:
pi = 3.141592653
if handAngle > 2 * pi:
handAngle = handAngle - 2*pi
# Right Immobile Hand:
pygame.draw.line(screen, WHITE, [590, 315], [590, 340], 4)
# Left Leg:
pygame.draw.rect(screen, WHITE, [560, 375, 10, 20], 0)
# Right Leg:
pygame.draw.rect(screen, WHITE, [580, 375, 10, 20], 0)
# Left Shoe Ellipse
# Ellipse Notes: ellipse(Surface, color, Rect, width=0) -> Rect
pygame.draw.ellipse(screen, BLACK, [550, 390, 20, 15], 0)
# Right Shoe Ellipse:
pygame.draw.ellipse(screen, BLACK, [580, 390, 20, 15], 0)
# Add in a changing traffic light
# Rectangle for Traffic Light:
pygame.draw.rect(screen, WHITE, [50, 350, 50, 100], 0)
# Traffic Light Post:
pygame.draw.rect(screen,BLACK, [65, 450, 20, 40], 0)
# Top light:
pygame.draw.circle(screen, currentTopColor, [75, 370], 12)
# Second light:
pygame.draw.circle(screen, currentMiddleColor, [75, 400], 12)
# Third light:
pygame.draw.circle(screen, currentBottomColor, [75, 430], 12)
# Three events must be cycled to change each of the traffic light colors
# from their dull versions to their fullest color forms
# The question is, can this be achieved through a timer?
# 60 frames per second is on the timer itself so every 180 frames would mean
# 3 seconds, or every 300 frames would mean 5 seconds
# DOCS on set timer: set_timer(eventid, milliseconds)
## turnRedLightOn = pygame.draw.circle(screen, RED, [75, 370], 12)
## + pygame.draw.circle(screen, DULLYELLOW, [75, 400], 12)
## + pygame.draw.circle(screen, DULLGREEN, [75, 430], 12)
# Turn the top light red and all other lights dull every three seconds
pygame.time.set_timer(currentTopColor = RED, 3000)
pygame.time.set_timer(currentMiddleColor = DULLYELLOW, 3000)
pygame.time.set_timer(currentBottomColor = DULLGREEN, 3000)
# Turn the middle light yellow and all other lights dull every six seconds
pygame.time.set_timer(currentTopColor = DULLRED, 6000)
pygame.time.set_timer(currentMiddleColor = YELLOW, 6000)
pygame.time.set_timer(currentBottomColor = DULLGREEN, 6000)
# Turn the bottom light green and all other lights dull every nine seconds
pygame.time.set_timer(currentTopColor = DULLRED, 9000)
pygame.time.set_timer(currentMiddleColor = DULLYELLOW, 9000)
pygame.time.set_timer(currentBottomColor = GREEN, 9000)
# Update the screen:
pygame.display.flip()
# Clock FPS:
clock.tick(FPS)
# Quit after main game loop ends:
pygame.quit()
set_timer
不应该在主循环的每个周期中执行,你可以在外面调用它,它会每 3000 毫秒重复一次。
# Current Light
light_on = 0 # 0-red 1-yellow 2-green
LIGHTS_EVENT = pygame.USERVENT + 0 # Event code for Lights change
pygame.time.set_timer(LIGHTS_EVENT, 3000)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == LIGHTS_EVENT:
light_on += 1
if light_on == 3:
light_on = 0
currentTopColor = DULLRED
currentMiddleColor = DULLYELLOW
currentBottomColor = DULLGREEN
if light_on == 0:
currentTopColor = RED
if light_on == 1:
currentMiddleColor = YELLOW
if light_on == 2:
currentBottomColor = GREEN
# Top light:
...