简体   繁体   中英

python ontimer vs thread

This is an extension of my recent post. Now that I know about onTimer and Thread, starting a new post.

I did away w/ the while loop in the main. Replaced with onTimer() and Thread. But same results, cant move both objects simultaneously. Code for both listed below: Any advice is appreciated...this is my first go at graphics w/ Python.

code using onTimer

import turtle
import math

screen = turtle.Screen()
screen.screensize(1000, 1000)
screen.bgcolor("light green")

player = turtle.Turtle()
player.hideturtle()
player.penup()
player.shape("circle")
player.color("red")
player.fillcolor("yellow")
player.setposition(-50, -40)
player.showturtle()
player.speed(0)

s = turtle.Turtle()
s.hideturtle()
s.penup()
s.shape("square")
s.color("black")
s.fillcolor("white")
s.setposition(-50, -60)
s.showturtle()

# first tier
s1 = turtle.Turtle()
s1.hideturtle()
s1.penup()
s1.shape("square")
s1.color("black")
s1.fillcolor("white")
s1.showturtle()

s2 = turtle.Turtle()
s2.hideturtle()
s2.penup()
s2.shape("square")
s2.color("black")
s2.fillcolor("white")
s2.setposition(s1.xcor() + 20, 0)
s2.showturtle()

s3 = turtle.Turtle()
s3.hideturtle()
s3.penup()
s3.shape("square")
s3.color("black")
s3.fillcolor("white")
s3.setposition(s2.xcor() + 20, 0)
s3.showturtle()

s4 = turtle.Turtle()
s4.hideturtle()
s4.penup()
s4.shape("square")
s4.color("black")
s4.fillcolor("white")
s4.setposition(s3.xcor() + 20, 0)
s4.showturtle()

# second tier
s5 = turtle.Turtle()
s5.hideturtle()
s5.penup()
s5.shape("square")
s5.color("black")
s5.fillcolor("white")
s5.setposition(s4.xcor() + 30, 60)
s5.showturtle()

s6 = turtle.Turtle()
s6.hideturtle()
s6.penup()
s6.shape("square")
s6.color("black")
s6.fillcolor("white")
s6.setposition(s5.xcor() + 20, 60)
s6.showturtle()

s7 = turtle.Turtle()
s7.hideturtle()
s7.penup()
s7.shape("square")
s7.color("black")
s7.fillcolor("white")
s7.setposition(s6.xcor() + 20, 60)
s7.showturtle()

s8 = turtle.Turtle()
s8.hideturtle()
s8.penup()
s8.shape("square")
s8.color("black")
s8.fillcolor("white")
s8.setposition(s7.xcor() + 20, 60)
s8.showturtle()

# third tier
s9 = turtle.Turtle()
s9.hideturtle()
s9.penup()
s9.shape("square")
s9.color("black")
s9.fillcolor("white")
s9.setposition(s8.xcor() + 30, 120)
s9.showturtle()

s10 = turtle.Turtle()
s10.hideturtle()
s10.penup()
s10.shape("square")
s10.color("black")
s10.fillcolor("white")
s10.setposition(s9.xcor() + 20, 120)
s10.showturtle()

s11 = turtle.Turtle()
s11.hideturtle()
s11.penup()
s11.shape("square")
s11.color("black")
s11.fillcolor("white")
s11.setposition(s10.xcor() + 20, 120)
s11.showturtle()

s12 = turtle.Turtle()
s12.hideturtle()
s12.penup()
s12.shape("square")
s12.color("black")
s12.fillcolor("white")
s12.setposition(s11.xcor() + 20, 120)
s12.showturtle()

#moving enemy
s13 = turtle.Turtle()
s13.hideturtle()
s13.penup()
s13.shape("square")
s13.color("black")
s13.fillcolor("red")
s13.setposition(s11.xcor() + 5, 140)
s13.showturtle()

#static turtle
s14 = turtle.Turtle()
s14.hideturtle()
s14.penup()
s14.shape("turtle")
s14.color("black")
s14.fillcolor("red")
s14.setposition(s6.xcor() + 20, 80)
s14.showturtle()

squareList = [s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12]

falling = False

def jump():
    speed = 2

    while speed > 0:
        y = player.ycor()
        x = player.xcor()
        y += 6
        x += 1.3
        speed -= 0.09
        player.setposition(x, y)
        collision()
    if speed < 0:
        falling = True
        while falling:
            y = player.ycor()
            x = player.xcor()
            y -= 2
            x += 1
            speed += .10
            player.setposition(x, y)
            collision()
            for squares in squareList:
                if (player.xcor() >= 0 and player.xcor() <= 80) and player.ycor() == 20:
                    falling = False
                if (player.xcor() >= 80 and player.xcor() <= 160) and player.ycor() == 80:
                    falling = False
                if (player.xcor() >= 160 and player.xcor() <= 240) and player.ycor() == 140:
                    falling = False


def right():
    x = player.xcor()
    x += 2
    player.setx(x)
    collision()

def moveEnemy():
    s13.backward(3)
    if s13.xcor() > 250:
        s13.setheading(0)
    if s13.xcor() < 180:
        s13.setheading(180)
    screen.ontimer(moveEnemy(), 5)
    collision()

def collision():
    distance1 = math.sqrt(math.pow(player.xcor()-s13.xcor(),2) + math.pow(player.ycor()-s13.ycor(), 2))
    if distance1 < 20:
        player.hideturtle()

    distance2 = math.sqrt(math.pow(player.xcor() - s14.xcor(), 2) + math.pow(player.ycor() - s14.ycor(), 2))
    if distance2 < 20:
        s14.hideturtle()

turtle.listen()
turtle.onkey(jump, "Up")
turtle.onkey(right, "Right")

screen.ontimer(moveEnemy(), 5)

turtle.mainloop()

code using Thread

import turtle
import math
import threading
from threading import Thread

screen = turtle.Screen()
screen.screensize(1000, 1000)
screen.bgcolor("light green")

player = turtle.Turtle()
player.hideturtle()
player.penup()
player.shape("circle")
player.color("red")
player.fillcolor("yellow")
player.setposition(-50, -40)
player.showturtle()
player.speed(0)

s = turtle.Turtle()
s.hideturtle()
s.penup()
s.shape("square")
s.color("black")
s.fillcolor("white")
s.setposition(-50, -60)
s.showturtle()

# first tier
s1 = turtle.Turtle()
s1.hideturtle()
s1.penup()
s1.shape("square")
s1.color("black")
s1.fillcolor("white")
s1.showturtle()

s2 = turtle.Turtle()
s2.hideturtle()
s2.penup()
s2.shape("square")
s2.color("black")
s2.fillcolor("white")
s2.setposition(s1.xcor() + 20, 0)
s2.showturtle()

s3 = turtle.Turtle()
s3.hideturtle()
s3.penup()
s3.shape("square")
s3.color("black")
s3.fillcolor("white")
s3.setposition(s2.xcor() + 20, 0)
s3.showturtle()

s4 = turtle.Turtle()
s4.hideturtle()
s4.penup()
s4.shape("square")
s4.color("black")
s4.fillcolor("white")
s4.setposition(s3.xcor() + 20, 0)
s4.showturtle()

# second tier
s5 = turtle.Turtle()
s5.hideturtle()
s5.penup()
s5.shape("square")
s5.color("black")
s5.fillcolor("white")
s5.setposition(s4.xcor() + 30, 60)
s5.showturtle()

s6 = turtle.Turtle()
s6.hideturtle()
s6.penup()
s6.shape("square")
s6.color("black")
s6.fillcolor("white")
s6.setposition(s5.xcor() + 20, 60)
s6.showturtle()

s7 = turtle.Turtle()
s7.hideturtle()
s7.penup()
s7.shape("square")
s7.color("black")
s7.fillcolor("white")
s7.setposition(s6.xcor() + 20, 60)
s7.showturtle()

s8 = turtle.Turtle()
s8.hideturtle()
s8.penup()
s8.shape("square")
s8.color("black")
s8.fillcolor("white")
s8.setposition(s7.xcor() + 20, 60)
s8.showturtle()

# third tier
s9 = turtle.Turtle()
s9.hideturtle()
s9.penup()
s9.shape("square")
s9.color("black")
s9.fillcolor("white")
s9.setposition(s8.xcor() + 30, 120)
s9.showturtle()

s10 = turtle.Turtle()
s10.hideturtle()
s10.penup()
s10.shape("square")
s10.color("black")
s10.fillcolor("white")
s10.setposition(s9.xcor() + 20, 120)
s10.showturtle()

s11 = turtle.Turtle()
s11.hideturtle()
s11.penup()
s11.shape("square")
s11.color("black")
s11.fillcolor("white")
s11.setposition(s10.xcor() + 20, 120)
s11.showturtle()

s12 = turtle.Turtle()
s12.hideturtle()
s12.penup()
s12.shape("square")
s12.color("black")
s12.fillcolor("white")
s12.setposition(s11.xcor() + 20, 120)
s12.showturtle()

#moving enemy
s13 = turtle.Turtle()
s13.hideturtle()
s13.penup()
s13.shape("square")
s13.color("black")
s13.fillcolor("red")
s13.setposition(s11.xcor() + 5, 140)
s13.showturtle()

#static turtle
s14 = turtle.Turtle()
s14.hideturtle()
s14.penup()
s14.shape("turtle")
s14.color("black")
s14.fillcolor("red")
s14.setposition(s6.xcor() + 20, 80)
s14.showturtle()

squareList = [s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12]

falling = False

def jump():
    speed = 2

    while speed > 0:
        y = player.ycor()
        x = player.xcor()
        y += 6
        x += 1.3
        speed -= 0.09
        player.setposition(x, y)
        collision()
    if speed < 0:
        falling = True
        while falling:
            y = player.ycor()
            x = player.xcor()
            y -= 2
            x += 1
            speed += .10
            player.setposition(x, y)
            collision()
            for squares in squareList:
                if (player.xcor() >= 0 and player.xcor() <= 80) and player.ycor() == 20:
                    falling = False
                if (player.xcor() >= 80 and player.xcor() <= 160) and player.ycor() == 80:
                    falling = False
                if (player.xcor() >= 160 and player.xcor() <= 240) and player.ycor() == 140:
                    falling = False


def right():
    x = player.xcor()
    x += 2
    player.setx(x)
    collision()

def moveEnemy():
    s13.backward(3)
    if s13.xcor() > 250:
        s13.setheading(0)
    if s13.xcor() < 180:
        s13.setheading(180)
    screen.ontimer(moveEnemy(), 5)
    collision()

def collision():
    distance1 = math.sqrt(math.pow(player.xcor()-s13.xcor(),2) + math.pow(player.ycor()-s13.ycor(), 2))
    if distance1 < 20:
        player.hideturtle()

    distance2 = math.sqrt(math.pow(player.xcor() - s14.xcor(), 2) + math.pow(player.ycor() - s14.ycor(), 2))
    if distance2 < 20:
        s14.hideturtle()

turtle.listen()
turtle.onkey(jump, "Up")
turtle.onkey(right, "Right")

Thread(target = moveEnemy).start()

turtle.mainloop()

You made the same error as in your original code, where you made the motion atomic -- you can't stop everything while you implement the jump. You need to break the jump into discrete steps. Here's my ontimer() based solution:

from turtle import Turtle, Screen
import math

screen = Screen()
screen.screensize(1000, 1000)
screen.bgcolor('light green')

player = Turtle('circle', visible=False)
player.penup()
player.color('red', 'yellow')
player.setposition(-50, -40)
player.showturtle()
player.speed('fastest')

s = Turtle('square', visible=False)
s.penup()
s.color('black', 'white')
s.setposition(-50, -60)
s.showturtle()

# first tier
s1 = Turtle('square', visible=False)
s1.penup()
s1.color('black', 'white')

s2 = s1.clone()
s2.setx(s1.xcor() + 20)
s2.showturtle()

s3 = s1.clone()
s3.setx(s2.xcor() + 20)
s3.showturtle()

s4 = s1.clone()
s4.setx(s3.xcor() + 20)
s4.showturtle()

s1.showturtle()

# second tier
s5 = Turtle('square', visible=False)
s5.penup()
s5.color('black', 'white')
s5.setposition(s4.xcor() + 30, 60)

s6 = s5.clone()
s6.setx(s5.xcor() + 20)
s6.showturtle()

s7 = s5.clone()
s7.setx(s6.xcor() + 20)
s7.showturtle()

s8 = s5.clone()
s8.setx(s7.xcor() + 20)
s8.showturtle()

s5.showturtle()

# third tier
s9 = Turtle('square', visible=False)
s9.penup()
s9.color('black', 'white')
s9.setposition(s8.xcor() + 30, 120)

s10 = s9.clone()
s10.setx(s9.xcor() + 20)
s10.showturtle()

s11 = s9.clone()
s11.setx(s10.xcor() + 20)
s11.showturtle()

s12 = s9.clone()
s12.setx(s11.xcor() + 20)
s12.showturtle()

s9.showturtle()

# moving enemy
s13 = Turtle('square', visible=False)
s13.penup()
s13.color('black', 'red')
s13.setposition(s11.xcor() + 5, 140)
s13.showturtle()

# static turtle
s14 = Turtle('turtle', visible=False)
s14.penup()
s14.color('black', 'red')
s14.setposition(s6.xcor() + 20, 80)
s14.showturtle()

squareList = [s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12]

RISING, FALLING = 0, 1
state = None
speed = -1

def jump():
    global speed, state
    speed = 2
    state = RISING
    screen.ontimer(jumping, 7)

def jumping():
    global speed, state

    if state == RISING:
        x, y = player.position()
        y += 6
        x += 1.3
        speed -= 0.09
        player.setposition(x, y)
        collision()

    if speed < 0:
        state = FALLING

    if state == FALLING:
        x, y = player.position()
        y -= 2
        x += 1
        speed += 0.10
        player.setposition(x, y)
        collision()

        for _ in squareList:
            if (0 <= player.xcor() <= 80) and player.ycor() == 20:
                state = None
            if (80 <= player.xcor() <= 160) and player.ycor() == 80:
                state = None
            if (160 <= player.xcor() <= 240) and player.ycor() == 140:
                state = None

    if state in [RISING, FALLING]:
        screen.ontimer(jumping, 7)

def right():
    player.setx(player.xcor() + 2)
    collision()

def moveEnemy():
    s13.backward(3)
    if s13.xcor() > 250:
        s13.setheading(0)
    elif s13.xcor() < 180:
        s13.setheading(180)
    screen.ontimer(moveEnemy(), 5)
    collision()

def collision():
    distance = math.sqrt(math.pow(player.xcor() - s13.xcor(), 2) + math.pow(player.ycor() - s13.ycor(), 2))
    if distance < 20:
        player.hideturtle()

    distance = math.sqrt(math.pow(player.xcor() - s14.xcor(), 2) + math.pow(player.ycor() - s14.ycor(), 2))
    if distance < 20:
        s14.hideturtle()

screen.onkey(jump, 'Up')
screen.onkey(right, 'Right')
screen.listen()

screen.ontimer(moveEnemy(), 5)

screen.mainloop()

I also reworked other stuff while I was at it, tossing 30% of your code. There's still stuff you need to add about stopping the jumping timer when the player collides or falls off the bottom of the window.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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