Python Turtle游戏开发:实现多次按键触发函数需求咨询
Solution: Require 2+ Hits to Collect Materials in Your Turtle Game
Hey there! Let's get your Minicraft-style game working so players need to hit targets at least twice before they can collect materials. Your current code has a few small issues (like resetting counts every time you call a function and checking collisions only once), so let's fix those step by step.
Key Changes We'll Make:
- Add hit counters for each target to track how many times they've been struck
- Move collision checks into the main game loop (so they run constantly as the game plays)
- Update resource collection logic to only trigger when the hit count reaches 2 or more
- Fix variable scoping issues so your resource counts actually update globally instead of being stuck in local function variables
Modified Full Code
import turtle import random import math import time turtle.tracer(5) score = 0 wood = 0 stone = 0 # Hit counters for each target to track strikes stone_hits = 0 stone1_hits = 0 tree_hits = 0 treedown_hits = 0 # Turtles wn = turtle.Screen() wn.tracer(0) wn.bgcolor("black") wn.title("Catcher") wn.setup(800, 600) # Resource display pens penwood1 = turtle.Turtle() penwood1.penup() penwood1.color("white") penwood1.hideturtle() penwood1.goto(-280, 275) woodstring = "Wood: %s" % wood penwood1.write(woodstring, False, align="left", font=("system", 15, "normal")) penstone1 = turtle.Turtle() penstone1.penup() penstone1.color("white") penstone1.hideturtle() penstone1.goto(-200, 275) stonestring = "Stone: %s" % stone penstone1.write(stonestring, False, align="left", font=("system", 15, "normal")) # Player setup player = turtle.Turtle() player.hideturtle() player.color("white") player.shape("triangle") player.penup() player.setheading(180) player.setposition(180, 0) player.showturtle() player.speed(0) # Border pen pen = turtle.Turtle() pen.color("white") pen.shape("circle") pen.hideturtle() pen.penup() pen.setposition(360, 275) pen.pendown() pen.setposition(360, -275) pen.setposition(-360, -275) pen.setposition(-360, 275) pen.setposition(360, 275) pen.shapesize(stretch_wid=3, stretch_len=3) # Score pen pen1 = turtle.Turtle() pen1.color("white") pen1.shape("circle") pen1.hideturtle() pen1.penup() pen1.goto(-360, 275) scorestring = "Score: %s" % score pen1.write(scorestring, False, align="left", font=("system", 15, "normal")) # Targets tree = turtle.Turtle() tree.shape("circle") tree.color("green") tree.penup() tree.setposition(200, 140) stone1 = turtle.Turtle() stone1.shape("circle") stone1.color("gray") stone1.penup() stone1.setposition(-200, 140) stone1.shapesize(stretch_wid=2, stretch_len=3) stone = turtle.Turtle() stone.shape("circle") stone.color("gray") stone.penup() stone.setposition(-220, 180) stone.shapesize(stretch_wid=2, stretch_len=3) treedown = turtle.Turtle() treedown.shape("circle") treedown.color("green") treedown.penup() treedown.setposition(-250, -140) # Movement functions def pleft(): player.setheading(180) x = player.xcor() x -= 20 if x < -360: x = -360 player.setx(x) def pright(): player.setheading(0) x = player.xcor() x += 20 if x > 360: x = 360 player.setx(x) def pdown(): player.setheading(270) y = player.ycor() y -= 20 if y < -275: y = -275 player.sety(y) def pup(): player.setheading(90) y = player.ycor() y += 20 if y > 275: y = 275 player.sety(y) # Collision detection function def isCollision(t1, t2): distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2)+math.pow(t1.ycor()-t2.ycor(),2)) if distance < 25: return True else: return False # Resource collection functions with hit count logic def stonebreak(): global stone, stone_hits, stonestring # Only count hits if player is near the stone if isCollision(player, stone): stone_hits += 1 if stone_hits >= 2: # Award stone, reset hits, and hide the target stone += 9 stone_hits = 0 stone.hideturtle() # Update display penstone1.clear() stonestring = "Stone: %s" % stone penstone1.write(stonestring, False, align="left", font=("system", 15, "normal")) def stone1break(): global stone, stone1_hits, stonestring if isCollision(player, stone1): stone1_hits += 1 if stone1_hits >= 2: stone += 9 stone1_hits = 0 stone1.hideturtle() penstone1.clear() stonestring = "Stone: %s" % stone penstone1.write(stonestring, False, align="left", font=("system", 15, "normal")) def treebreak(): global wood, tree_hits, woodstring if isCollision(player, tree): tree_hits += 1 if tree_hits >= 2: wood += 2 tree_hits = 0 tree.hideturtle() penwood1.clear() woodstring = "Wood: %s" % wood penwood1.write(woodstring, False, align="left", font=("system", 15, "normal")) def treebbreak(): global wood, treedown_hits, woodstring if isCollision(player, treedown): treedown_hits += 1 if treedown_hits >= 2: wood += 3 treedown_hits = 0 treedown.hideturtle() penwood1.clear() woodstring = "Wood: %s" % wood penwood1.write(woodstring, False, align="left", font=("system", 15, "normal")) # Key bindings wn.listen() wn.onkeypress(pleft, "Left") wn.onkeypress(pright, "Right") wn.onkeypress(pup, "Up") wn.onkeypress(pdown, "Down") wn.onkeypress(stonebreak, "space") wn.onkeypress(stone1break, "space") wn.onkeypress(treebreak, "space") wn.onkeypress(treebbreak, "space") # Main game loop while True: wn.update() wn.mainloop()
What We Fixed:
- Hit Counters: Added
stone_hits,stone1_hits, etc., to track how many times each target has been hit. - Global Variables: Used the
globalkeyword in collection functions to modify the actual resource counts (instead of creating local copies that don't update the UI). - Conditional Collection: Each space press only counts if the player is near the target. Once hits reach 2, we award materials, reset the counter, and hide the target.
- Continuous Collision Checks: Integrated collision checks directly into the hit functions so the game only counts strikes when the player is in range.
Now when players approach a stone or tree, they'll need to press space twice to collect the materials. The target will disappear once collected, and the resource count will update correctly!
内容的提问来源于stack exchange,提问作者user11808386




