问题
So I am making a game in Python, and I am almost done, though I am stumped. There are a few things I want:
- I want to make a 30 second timer. The player has 30 seconds to collect as many pellets as he/she can.
- Second, after the timer is complete, the turtle is not controllable anymore.
What do I need to do to fix these?
Screen setup
import turtle
import math
import random
#screen
wn=turtle.Screen()
wn.bgcolor("lightblue")
speed=1
wn.tracer(2)
#Score Variable
score=0
#Turtle Player
spaceship= turtle.Turtle()
spaceship.pensize(1)
spaceship.color("red")
spaceship.penup()
turtle.delay(3)
spaceship.shapesize(1,1)
add=1
#Create Goals
maxpoints = 6
points = []
for count in range(maxpoints):
points.append(turtle.Turtle())
points[count].color("green")
points[count].shape("circle")
points[count].penup()
points[count].goto(random.randint(-300,300), random.randint(-200,200))
#Border
border = turtle.Turtle()
border.penup()
border.goto(-300,-200)
border.pendown()
border.pensize(5)
border.color("darkblue")
for side in range(2):
border.forward(600)
border.left(90)
border.forward(400)
border.left(90)
#Functions
def left():
spaceship.left(30)
def right():
spaceship.right(30)
def increasespeed():
global speed
speed += 1
def decreasespeed():
global speed
speed -= 1
def iscollision(turtle1,turtle2):
collect = math.sqrt(math.pow(turtle1.xcor()-turtle2.xcor(),2)+ math.pow(turtle1.ycor()-turtle2.ycor(),2))
if collect <20:
return True
else:
return False
Keyboard binding to move turtle around
#Keyboard Bindings
turtle.listen()
turtle.onkey(left,"Left")
turtle.onkey(right,"Right")
turtle.onkey(increasespeed ,"Up")
turtle.onkey(decreasespeed ,"Down")
turtle.onkey(quit, "q")
pen=100
while True:
spaceship.forward(speed)
#Boundary
if spaceship.xcor()>300 or spaceship.xcor()<-300:
spaceship.left(180)
if spaceship.ycor()>200 or spaceship.ycor()<-200:
spaceship.left(180)
#Point collection
for count in range(maxpoints):
if iscollision(spaceship, points[count]):
points[count].goto(random.randint(-300,300), random.randint(-200,200))
score=score+1
add+=1
spaceship.shapesize(add)
#Screen Score
border.undo()
border.penup()
border.hideturtle()
border.goto(-290,210)
scorestring = "Score:%s" %score
border.write(scorestring,False,align="left",font=("Arial",16,"normal"))
At the end of my program after the timer finishes, I want the turtle to stop moving; the user is unable to move the turtle.
回答1:
I was going to give you some turtle ontimer()
event code to handle your countdown but realized your code is not organized correctly to handle it. E.g. your infinite while True:
loop potentially blocks some events from firing and it definately prevents your boundary and collision code from running. Even if it didn't, your boundary and collision code are only setup to run once when they need to run on every spaceship movement.
I've reorganized your code around an ontimer()
event to run the spaceship and another to run the countdown timer. I've fixed the boundary and collision code to basically work. I've left out some features (e.g spaceship.shapesize(add)
) to simplify this example:
from turtle import Turtle, Screen
import random
MAXIMUM_POINTS = 6
FONT = ('Arial', 16, 'normal')
WIDTH, HEIGHT = 600, 400
wn = Screen()
wn.bgcolor('lightblue')
# Score Variable
score = 0
# Turtle Player
spaceship = Turtle()
spaceship.color('red')
spaceship.penup()
speed = 1
# Border
border = Turtle(visible=False)
border.pensize(5)
border.color('darkblue')
border.penup()
border.goto(-WIDTH/2, -HEIGHT/2)
border.pendown()
for _ in range(2):
border.forward(WIDTH)
border.left(90)
border.forward(HEIGHT)
border.left(90)
border.penup()
border.goto(-WIDTH/2 + 10, HEIGHT/2 + 10)
border.write('Score: {}'.format(score), align='left', font=FONT)
# Create Goals
points = []
for _ in range(MAXIMUM_POINTS):
goal = Turtle('circle')
goal.color('green')
goal.penup()
goal.goto(random.randint(20 - WIDTH/2, WIDTH/2 - 20), \
random.randint(20 - HEIGHT/2, HEIGHT/2 - 20))
points.append(goal)
# Functions
def left():
spaceship.left(30)
def right():
spaceship.right(30)
def increasespeed():
global speed
speed += 1
def decreasespeed():
global speed
speed -= 1
def iscollision(turtle1, turtle2):
return turtle1.distance(turtle2) < 20
# Keyboard Bindings
wn.onkey(left, 'Left')
wn.onkey(right, 'Right')
wn.onkey(increasespeed, 'Up')
wn.onkey(decreasespeed, 'Down')
wn.onkey(wn.bye, 'q')
wn.listen()
timer = 30
def countdown():
global timer
timer -= 1
if timer <= 0: # time is up, disable user control
wn.onkey(None, 'Left')
wn.onkey(None, 'Right')
wn.onkey(None, 'Up')
wn.onkey(None, 'Down')
else:
wn.ontimer(countdown, 1000) # one second from now
wn.ontimer(countdown, 1000)
def travel():
global score
spaceship.forward(speed)
# Boundary
if not -WIDTH/2 < spaceship.xcor() < WIDTH/2:
spaceship.left(180)
if not -HEIGHT/2 < spaceship.ycor() < HEIGHT/2:
spaceship.left(180)
# Point collection
for count in range(MAXIMUM_POINTS):
if iscollision(spaceship, points[count]):
points[count].goto(random.randint(20 - WIDTH/2, WIDTH/2 - 20), \
random.randint(20 - HEIGHT/2, HEIGHT/2 - 20))
score += 1
# Screen Score
border.undo()
border.write('Score: {}'.format(score), align='left', font=FONT)
if timer:
wn.ontimer(travel, 10)
travel()
wn.mainloop()
回答2:
Another simple way that to implement this is to do the following:
- Add a variable that holds the timestamp for when the game was begun
- Wrap the code that you want to respect the timeout inside of a while loop that runs while the difference between the current time and the the starting time is less than your time limit.
For example:
import time
starting_time = time.time()
time_limit = 30
while (time.time() - starting_time) < time_limit:
# YOUR GAME LOGIC HERE
回答3:
Something that is helpful for me is using time.time()
. If you set a variable(say startTime
) to time.time()
in the beginning of your code, you can then add an if in your main game loop. The if
will check if enough time has passed. For example:
if time.time() > startTime + 30:
#whatever you do to end the game
time.time()
gives the current time in seconds, so if you set a variable to time.time()
at the beginning of the code, that variable will give you the time that the game started. In the if
, you check if the current time has reached the time your game started plus 30 seconds.
I hope this helped; if it did be sure to upvote! :)
来源:https://stackoverflow.com/questions/43461439/i-want-to-add-a-countdown-timer-to-my-program