简体   繁体   English

使其功能在两次或更多次按下时执行

[英]Make it so function executes on 2 or more key presses

I'm new to Python and I need some help. 我是Python的新手,我需要一些帮助。 How do I make it so a function executes after 2 or more key presses? 如何使它在2次或更多次按键后执行功能? I'm trying to make a game using turtle similar to Minicraft (a 2D top-down action game) where you can use materials you get from stone and wood to craft a variety of different items. 我正在尝试使用类似于Minicraft的乌龟制作游戏(2D自上而下的动作游戏),在这里您可以使用从石头和木头中得到的材料来制作各种不同的物品。 The code isn't finished yet. 代码尚未完成。

Code I need help with: 我需要帮助的代码:

stone = turtle.Turtle()
stone.shape("circle")
stone.color("gray")
stone.penup()
stone.setposition(-220, 180)
stone.shapesize(stretch_wid=2, stretch_len=3)

def stonebreak():
    stone = turtle.Turtle ()
    stone.shape ("circle")
    stone.color ("gray")
    stone.penup ()
    stone.setposition (-220, 180)
    stone.shapesize (stretch_wid=2, stretch_len=3)
    stone.speed("slow")
    stone.hideturtle()
    stone = 0
    stone += 9
    stonestring = "Stone: %s" % stone
    penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))
    penstone1.clear()
    penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))


if isCollision(player, stone):
    wn.onkeypress(stonebreak, "space")
    stone.hideturtle()

Full code: 完整代码:

import turtle
import random
import math
import time
turtle.tracer(5)
score = 0

# Turtles

wn = turtle.Screen()
wn.tracer(0)
wn.bgcolor("black")
wn.title("Catcher")
wn.setup(800, 600)


penwood1 = turtle.Turtle()
penwood1.penup()
penwood1.color("white")
penwood1.hideturtle()
penwood1.goto(-280, 275)
wood = 0
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)
stone = 0
stonestring = "Stone: %s" %stone
penstone1.write(stonestring, False, align ="left", font = ("system", 15, "normal"))

player = turtle. Turtle()
player.hideturtle()
player.color("white")
player.shape("triangle")
player.penup()
player.setheading(180)
player.setposition(180, 0)
player.showturtle()
player.penup()
player.speed(0)

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)


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"))


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)
stone1.speed ("slow")

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 features

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)


wn.listen()
wn.onkeypress(pleft, "Left")
wn.onkeypress(pright, "Right")
wn.onkeypress(pup, "Up")
wn.onkeypress(pdown, "Down")



while True:
    wn.update()


    def treebreak():
        tree.speed("slow")
        tree.hideturtle()
        wood = 0
        wood += 2
        woodstring = "Wood: %s" % wood
        penwood1.write (woodstring, False, align="left", font=("system", 15, "normal"))
        penwood1.clear()
        penwood1.write (woodstring, False, align="left", font=("system", 15, "normal"))

        def treebbreak():
            treedown.speed ("slow")
            treedown.hideturtle ()
            wood = 2
            wood += 3
            woodstring = "Wood: %s" % wood
            penwood1.write (woodstring, False, align="left", font=("system", 15, "normal"))
            penwood1.clear ()
            penwood1.write (woodstring, False, align="left", font=("system", 15, "normal"))

        if player.xcor () == -240 and player.ycor () == -140:
            wn.onkeypress (treebbreak, "space")


    if player.xcor() == 180 and player.ycor() == 140:
        wn.onkeypress(treebreak, "space")

    if player.xcor() == 200 and player.ycor() == 120:
        wn.onkeypress(treebreak, "space")

    if player.xcor() == 200 and player.ycor() == 160:
        wn.onkeypress(treebreak, "space")

    if player.xcor() == 221 and player.ycor() == 141:
        wn.onkeypress(treebreak, "space")

    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

    def stonebreak():
        stone = turtle.Turtle ()
        stone.shape ("circle")
        stone.color ("gray")
        stone.penup ()
        stone.setposition (-220, 180)
        stone.shapesize (stretch_wid=2, stretch_len=3)
        stone.speed("slow")
        stone.hideturtle()
        stone = 0
        stone += 9
        stonestring = "Stone: %s" % stone
        penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))
        penstone1.clear()
        penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))


    if isCollision(player, stone):
        wn.onkeypress(stonebreak, "space")
        stone.hideturtle()

    def stone1break():
        stone1 = turtle.Turtle ()
        stone1.shape ("circle")
        stone1.color ("gray")
        stone1.penup ()
        stone1.setposition (-200, 140)
        stone1.shapesize (stretch_wid=2, stretch_len=3)
        stone1.speed("slow")
        stone1.hideturtle()
        stone = 0
        stone += 9
        stonestring = "Stone: %s" % stone
        penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))
        penstone1.clear()
        penstone1.write (stonestring, False, align="left", font=("system", 15, "normal"))


    if isCollision(player, stone1):
        wn.onkeypress(stone1break, "space")
        stone1.hideturtle()



wn.mainloop()

I'm trying to make it so you gain the materials after 2 or more hits on the targets. 我正在努力做到这一点,以便您在击中目标2次或以上后获得材料。

First of all, you shouldn't set onkeypress() event handler every time collision occurs. 首先,您不应该在每次发生冲突时都设置onkeypress()事件处理程序。 Try to handle it other way: 尝试以其他方式处理它:

def checkCollisions():
    if isCollision(player, stone1):
        stone1break()
    if isCollision(player, stone2):
        stone2break()
    ...

wn.onkeypress(checkCollisions, "space")

This code and all of your function defs you should put before your main ( while True: ) loop. 该代码和所有函数def应该放在主循环( while True: :)之前。

Then, you will need some state of your game objects. 然后,您将需要游戏对象的某种状态。 Trivial way is to add variables stone1strength=2, stone2strength=2, ..., and decrease them in coresponding stonebreak() function, clearing the stone after its strength goes below 1. 简单的方法是添加变量stone1strength = 2,stone2strength = 2,...,并在coresponding stonebreak()函数中将其减小,然后在强度低于1时清除石头。

I like your effort very much. 我非常喜欢你的努力。 It reminds me my first game programming steps. 这使我想起了我的第一个游戏编程步骤。 :) :)

The next step could be rewriting of your code to store your stone objects into a list and iterate them instead of handling tens of stoneX variables... 下一步可能是重写代码以将石头对象存储到列表中并对其进行迭代,而不是处理数十个stoneX变量...

First, I don't see a problem with setting the onkeypress() handler every time a collision is detected. 首先,每次检测到冲突时,我都不会设置onkeypress()处理程序出现问题。 Second, your code is a mess! 其次,您的代码一团糟! For example, you have two unrelated global variables with the same name, stone the score value and stone the turtle: 例如,你有相同的名字,两个不相关的全局变量stone的得分值和stone乌龟:

stone = 0
# ...
stone = turtle.Turtle()

You shape and shapesize() the pen turtle which is never visible anyway. 您可以对pen龟进行shapeshapesize() ,无论如何它都不可见。 And what's going on here: 而且这里发生了什么:

wood = 2
wood += 3

which happens multiple times, keeping your scores at fixed values rather than increasing. 这会发生多次,使您的分数保持固定值而不是增加。 Trying to detect a turtle on an exact position is futile: 试图在精确位置上检测到乌龟是徒劳的:

 if player.xcor() == 180 and player.ycor() == 140:

As the player moves 20 pixels at a time and this is a floating point plane. 当播放器一次移动20个像素时,这就是一个浮点平面。 And turtle has a distance() method, no reason to reinvent it. 而且turtle有distance()方法,没有理由重新发明它。

I believe @BoboDarph's state machine suggestion is a good one. 我相信@BoboDarph的状态机建议是一个很好的建议。 Below is my rework, and simplification, of your code that does something simpler. 以下是我对您的代码的重做和简化,它们使事情变得更简单。 The first time you touch the stone or the tree, it just changes color. 第一次触摸石头或树木时,它只会改变颜色。 After that, you start to earn points: 之后,您开始获得积分:

from turtle import Screen, Turtle

FONT = ('system', 15, 'normal')

# Movement features

def player_left():
    player.setheading(180)

    x = player.xcor() - 20
    if x < -360:
        x = -360

    player.setx(x)

def player_right():
    player.setheading(0)

    x = player.xcor() + 20
    if x > 360:
        x = + 360

    player.setx(x)

def player_down():
    player.setheading(270)

    y = player.ycor() - 20
    if y < -275:
        y = - 275

    player.sety(y)

def player_up():
    player.setheading(90)

    y = player.ycor() + 20
    if y > 275:
        y = + 275

    player.sety(y)

def isCollision(t1, t2):
    return t1.distance(t2) < 25

def tree_touch():
    tree.color('dark green')
    tree.touched = True

def tree_break():
    global wood

    screen.onkeypress(None, 'space')
    tree.color('brown')

    wood += 2

    woodstring = "Wood: %s" % wood
    pen_wood.clear()
    pen_wood.write(woodstring, align='left', font=FONT)

def stone_touch():
    rock.color('gray')
    rock.touched = True

def stone_break():
    global stone

    screen.onkeypress(None, 'space')
    rock.color('light gray')

    stone += 9

    stonestring = "Stone: %s" % stone
    pen_stone.clear()
    pen_stone.write(stonestring, align='left', font=FONT)

# Turtles

screen = Screen()
screen.setup(800, 600)
screen.bgcolor('black')
screen.title("Catcher")
screen.tracer(0)

pen_wood = Turtle()
pen_wood.hideturtle()
pen_wood.color('white')
pen_wood.penup()
pen_wood.goto(-280, 275)

wood = 0
wood_string = "Wood: %s" %wood
pen_wood.write(wood_string, align='left', font=FONT)

pen_stone = Turtle()
pen_stone.hideturtle()
pen_stone.color('white')
pen_stone.penup()
pen_stone.goto(-200, 275)

stone = 0
stone_string = "Stone: %s" %stone
pen_stone.write(stone_string, align='left', font=FONT)

pen = Turtle()
pen.hideturtle()
pen.shape('circle')
pen.color('white')
pen.penup()
pen.setposition(360, 275)
pen.pendown()
pen.setposition(360, -275)
pen.setposition(-360, -275)
pen.setposition(-360, 275)
pen.setposition(360, 275)

rock = Turtle()
rock.shape('circle')
rock.color('dark gray')
rock.penup()
rock.setposition(-220, 180)
rock.shapesize(stretch_wid=2, stretch_len=3)

rock.touched = False

tree = Turtle()
tree.shape('circle')
tree.color('green')
tree.penup()
tree.setposition(200, 140)

tree.touched = False

player = Turtle()
player.hideturtle()
player.shape('triangle')
player.speed('fastest')
player.color('white')
player.setheading(180)
player.penup()
player.setx(180)
player.showturtle()

screen.onkeypress(player_left, 'Left')
screen.onkeypress(player_right, 'Right')
screen.onkeypress(player_up, 'Up')
screen.onkeypress(player_down, 'Down')
screen.listen()

while True:

    if isCollision(player, tree):
        if tree.touched:
            screen.onkeypress(tree_break, "space")
        else:
            screen.onkeypress(tree_touch, "space")
    elif isCollision(player, rock):
        if rock.touched:
            screen.onkeypress(stone_break, "space")
        else:
            screen.onkeypress(stone_touch, "space")
    else:
            screen.onkeypress(None, "space")

    screen.update()

screen.mainloop()  # never reached

TODO 去做

  • Gracefully incorporate multiple trees and stones. 优雅地合并多个树木和石头。

  • Change the fixed value 25 in isCollision() to a value calculated based on the shapesize() of the object. isCollision()的固定值25更改为基于对象的shapesize()计算的值。

  • Replace the while True: loop with a function and timed event. 用函数和定时事件替换while True:循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM