I was working on fixing up some code to make it look better and when I finished copying the code over and finishing fixing it, I ran it and nothing happened. Two things loaded then everything clears. I can't find the problem.
Original code works
import turtle
from random import randint
import time
"""-------------"""
t=turtle.Turtle()
s=turtle.Screen()
cube=turtle.Turtle()
title=turtle.Turtle()
"""--------------"""
WIDTH, HEIGHT=300, 300
LENGTH=(5)
"""--------------"""
x1 = randint(cube.xcor()/2 - WIDTH/2, WIDTH/2 - cube.xcor()/2)
y1 = randint(cube.ycor()/2 - HEIGHT/2, HEIGHT/2 - cube.ycor()/2)
"""------------"""
s.setup(WIDTH,HEIGHT)
"""------------"""
t.width(1)
s.bgcolor("dark green")
"""-----------------"""
#Title
title.color("Red")
title.hideturtle()
title.penup()
title.goto(0,130)
title.pendown()
title.write("SNAK3",align="center", font=("Lobster", 20, "Bold"))
"""-------------"""
class Food():
def block():
cube.hideturtle()
cube.color("red")
cube.penup()
cube.goto(x1,y1)
cube.speed(0)
cube.begin_fill()
for i in range(4):
cube.pendown()
cube.forward(10)
cube.right(90)
cube.end_fill()
"""---------------"""
t.shape("square")
class Player():
def move_up():
player=False
while player==False:
for i in range(10):
t.forward(LENGTH)
t.delay(25)
t.clear()
x, y = t.position()
if not -WIDTH / 2 < x < WIDTH / 2 or not -HEIGHT / 2 < y < HEIGHT / 2:
player=True
t.hideturtle()
cube.clear()
title.clear()
title.penup()
title.goto(0,0)
title.pendown()
title.write("GAMEOVER", align="center", font=("lobster", 18, "bold"))
def move_left():
t.speed(0)
t.left(90)
t.speed(3)
def move_right():
t.speed(0)
t.right(90)
t.speed(3)
"""------------"""
food=Food.block()
player1=Player()
"""----------------"""
s.onkey(Player.move_up,"up")
s.onkey(Player.move_left,"left")
s.onkey(Player.move_right,"right")
s.listen()
"""--------------"""
collision=Collision_check.check()
"""--------------------"""
t1=t.xcor(),t.ycor()
cube1=cube.xcor(),cube.ycor()
class Collision_check():
def check():
crash=True
if t1.xcor()>=cube.xcor() and t1.xcor()<=cube.xcor()+10 and t1.ycor>=cube.ycor() and t1.ycor()<=cube.ycor+10:
cube.clear()
cube.goto(x1,y1)
LENGTH=+1
elif t1!=cube1:
crash=False
return crash
Fixed code with slight changes
import turtle
from random import randint
t=turtle.Turtle()
s=turtle.Screen()
cube=turtle.Turtle()
title=turtle.Turtle()
t.width(1)
s.bgcolor("dark green")
#Title
title.color("red")
title.hideturtle()
title.penup()
title.goto(0,130)
title.write("SNAK3",align="center",font=("lobster",20,"Bold"))
WIDTH, HEIGHT=300, 300
LENGTH=[5]
s.setup(WIDTH,HEIGHT)
#Random cords
x1=randint(cube.xcor()/2-WIDTH/2, WIDTH/2-cube.xcor()/2)
y1=randint(cube.ycor()/2-HEIGHT/2, HEIGHT/2-cube.ycor()/2)
class Food():
def block():
cube.hideturtle()
cube.color("red")
cube.penup()
cube.goto(x1,y1)
cube.speed(0)
cube.begin_fill()
cube.pendown()
for i in range(4):
cube.forward(10)
cube.right(90)
cube.end_fill()
t.shape("square")
class Player():
def forward():
player=False
while player==False:
for i in range(10):
t.forward(LENGTH)
t.delay(25)
t.clear
x, y=t.position()
if not -WIDTH / 2 < x < WIDTH / 2 or not -HEIGHT / 2 < y < HEIGHT/2:
player=True
cube.clear()
t.hideturtle()
title.clear()
title.penup()
title.goto(0,0)
title.pendown()
title.write("GAMEOVER", align="center", font=("lobster",18,"bold"))
def left():
t.speed(0)
t.left(90)
t.speed(3)
def right():
t.speed(0)
t.right(90)
t.speed(3)
food=Food.block()
player1=Player()
s.onkey(player1.forward,("up"))
s.onkey(player1.left,("left"))
s.onkey(player1.left,("right"))
class Collision_check():
def check():
crash=True
if t.xcor()>=cube.xcor() and t.xcor()<=cube.xcor()+10 and t.ycor()>=cube.ycor() and t.ycor()<=cube.ycor()+10:
cube.clear()
cube.goto(x1,y1)
LENGTH+=1
if cube.xcor()>=t.xcor() and cube.xcor()<=t.xcor()+10 and cube.ycor()>=t.ycor() and cube.ycor()<=t.ycor()+10:
cube.clear()
cube.goto(x1,y1)
LENGTH+=1
else:
crash=False
return crash
collision=Collision_check.check()
Everything in the code above is nearly exactly the same as the original. Ive gone over the code several times and can not find the problem.
I've ruled out that the collision_check is not the problem, all the classes are in order and aligned. The only other thing I could think of is that i have spelled something wrong.
Let's first address some basic facts:
Neither version of this code works
The slight changes to make it look better don't make it look better
and aren't slight, there are significant differences
Neither version of the code uses Python classes correctly
repl.it provides its own implementation of turtle which is generally
a subset of the original
A program is like a story, you first explain the background of events and then you proceed to tell the story in an order that makes logical sense.
Here's my rework of your code to try to tell a better story, but it still doesn't work completely as there are parts of the story missing:
from turtle import Turtle, Screen
from random import randint
WIDTH, HEIGHT = 300, 300
class Food():
def block():
cube.penup()
cube.goto(x1, y1)
cube.pendown()
cube.begin_fill()
for _ in range(4):
cube.forward(10)
cube.right(90)
cube.end_fill()
class Player():
def forward():
for _ in range(10):
t.forward(LENGTH)
# t.delay(25) # no such turtle method, perhaps repl.it addition
t.clear()
x, y = t.position()
if not -WIDTH / 2 < x < WIDTH / 2 or not -HEIGHT / 2 < y < HEIGHT/2:
cube.clear()
t.hideturtle()
title.clear()
title.penup()
title.goto(0, 0)
title.pendown()
title.write("GAMEOVER", align='center', font=('lobster', 18, 'bold'))
def left():
t.speed(0)
t.left(90)
t.speed(3)
def right():
t.speed(0)
t.right(90)
t.speed(3)
class Collision_check():
def check():
global LENGTH
crash = True
if t.xcor() >= cube.xcor() and t.xcor() <= cube.xcor() + 10 and t.ycor() >= cube.ycor() and t.ycor() <= cube.ycor() + 10:
cube.clear()
cube.goto(x1, y1)
LENGTH += 1
if cube.xcor() >= t.xcor() and cube.xcor() <= t.xcor()+10 and cube.ycor() >= t.ycor() and cube.ycor() <= t.ycor()+10:
cube.clear()
cube.goto(x1, y1)
LENGTH += 1
else:
crash = False
return crash
s = Screen()
s.setup(WIDTH, HEIGHT)
s.bgcolor('dark green')
t = Turtle()
t.shape('square')
t.width(1)
cube = Turtle()
cube.hideturtle()
cube.color('red')
cube.speed('fastest')
# Title
title = Turtle()
title.hideturtle()
title.color('red')
title.penup()
title.goto(0, 130)
title.write("SNAK3", align='center', font=('lobster', 20, 'bold'))
LENGTH = 5
# Random cords
x1 = randint(cube.xcor()/2 - WIDTH/2, WIDTH/2 - cube.xcor()/2)
y1 = randint(cube.ycor()/2 - HEIGHT/2, HEIGHT/2 - cube.ycor()/2)
food = Food.block()
player1 = Player()
s.onkey(Player.forward, 'Up')
s.onkey(Player.left, 'Left')
s.onkey(Player.right, 'Right')
s.listen()
# this makes no sense here, needs to happen on a regular basis after moves
collision = Collision_check.check()
s.mainloop()
Related
I'm trying to make a program that is essentially an etchasketck, with some minor tweaks for my school project(the required use of a main function, wasd as movement controls, and q to quit the program and p to pick up or drop down the turtle pen). I was testing this code in trinket.io and it was working fine. You can see it working there with this link: https://trinket.io/python/99fd3ec305. However, when I go to run it from pycharm, cmd, or the python IDLE, it always leaves the turtle hanging and unresponsive. I get no errors, just the turtle to pop up for a few seconds, then it hangs, and I'm unable to do anything.
Here's my code:
import sys
import turtle
arg_len = len(sys.argv)
# store length of arguments
if arg_len < 3:
print("Too less arguments, using default values..")
WIDTH = 200
HEIGHT = 200
else:
WIDTH = int(sys.argv[1])
HEIGHT = int(sys.argv[2])
screen = turtle.Screen()
screen.setup(WIDTH, HEIGHT)
# create a turtle instance
t = turtle.Turtle()
t.speed(0)
# slow down the turtle
# declare flags
move = False
exit_flag = False
def up():
global move
move = True
t.setheading(90)
def down():
global move
move = True
t.setheading(270)
def left():
global move
move = True
t.setheading(180)
def right():
global move
move = True
t.setheading(0)
# toggle pen up and down
def toggle_pen():
if t.isdown():
t.penup()
else:
t.pendown()
# set exit flag
def quit_program():
global exit_flag
exit_flag = True
def check_border():
if t.xcor() == WIDTH / 2:
t.penup()
t.setx(-WIDTH / 2)
elif t.xcor() == -WIDTH / 2:
t.penup()
t.setx(WIDTH / 2)
if t.ycor() == HEIGHT / 2:
t.penup()
t.sety(-HEIGHT / 2)
elif t.ycor() == -HEIGHT / 2:
t.penup()
t.sety(HEIGHT / 2)
def listen_keys():
screen.listen()
screen.onkey(up, "w")
screen.onkey(down, "s")
screen.onkey(left, "a")
screen.onkey(right, "d")
screen.onkey(toggle_pen, "p")
screen.onkey(quit_program, "q")
# main loop
def main():
listen_keys()
while not exit_flag:
global move
if move:
t.forward(0.5)
screen.update()
check_border()
else:
t.done()
main()
I'm using python 3.10, and I mainly use pycharm for the running.
I was trying to get the turtle to move indefinitly without user input after the first user input, I was going to achieve this with the while loop, but it just leaves my program unresponsive. Can anyone tell me what's wrong that I'm not seeing?
You've effectively put a while True: loop in an event-driven program where one should never be used. If I were writing this for the command line, with the constraints listed, I might go about it this way (dropping command line processing for example simplicity):
from turtle import Screen, Turtle
WIDTH, HEIGHT = 200, 200
def up():
turtle.setheading(90)
start_motion()
def down():
turtle.setheading(270)
start_motion()
def left():
turtle.setheading(180)
start_motion()
def right():
turtle.setheading(0)
start_motion()
def toggle_pen():
if turtle.isdown():
turtle.penup()
else:
turtle.pendown()
def quit_program():
screen.bye()
def check_border():
x, y = turtle.position()
if x >= WIDTH / 2:
turtle.penup()
turtle.setx(-WIDTH / 2)
elif x <= -WIDTH / 2:
turtle.penup()
turtle.setx(WIDTH / 2)
if y >= HEIGHT / 2:
turtle.penup()
turtle.sety(-HEIGHT / 2)
elif y <= -HEIGHT / 2:
turtle.penup()
turtle.sety(HEIGHT / 2)
def main():
screen.onkey(up, 'w')
screen.onkey(down, 's')
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.onkey(toggle_pen, 'p')
screen.onkey(quit_program, 'q')
screen.listen()
screen.mainloop()
def move():
turtle.forward(1)
check_border()
screen.ontimer(move, 25)
moving = False
def start_motion():
global moving
if not moving:
moving = True
move()
screen = Screen()
screen.setup(WIDTH, HEIGHT)
turtle = Turtle()
turtle.speed('fastest')
main()
See if this still works with trinket.io, IDLE and PyCharm, or if it can be made to do so.
Someone can help me please?
I spent many hours to understand the problem.. (Without success 🤣)
I tried to built a 80s hit game.
The problem is that when the ball goes on one of the stones, I catch the event (shows me in the console) and update the list of blocks but the block is not deleted from the screen as if nothing happened and I did not update any list
this is my code:
import time
from turtle import Screen, Turtle
import random
screen = Screen()
screen.bgcolor("black")
screen.setup(width=800, height=600)
screen.tracer(0)
player = Turtle("square")
player.shapesize(1.0, 4.0, 0)
player.color("blue")
player.penup()
player.goto(0, -250)
screen.tracer(0)
blue_turtle = []
blue_positions = []
for i in range(7):
turtle = Turtle("square")
turtle.shapesize(2.0 ,4.0, 0)
turtle.color("blue")
turtle.penup()
blue_positions.append((-300 + i * 100, 200))
blue_turtle.append(turtle)
def renderBlocks(b):
for i in range(len(b) - 1):
if b[i] == None:
print("Skipped")
continue
else:
x, y= blue_positions[i]
b[i].goto(x=x, y=y)
# total += 100
ball = Turtle("circle")
ball.color("white")
game_on = True
def move():
x = ball.xcor() + 10
y = ball.ycor()+ 10
ball.goto(x=x, y=y)
while game_on:
move()
renderBlocks(blue_turtle)
for i in range(len(blue_turtle) - 1):
if (blue_turtle[i] != None) and ball.distance(blue_turtle[i]) < 20:
blue_turtle[i] = (None)
time.sleep(0.1)
screen.update()
screen.exitonclick()
I believe the problem is here:
blue_turtle[i] = (None)
You tell your code that the turtle has been eliminated but you don't tell turtle graphics that it should be removed. Instead consider:
blue_turtle[i].hideturtle()
blue_turtle[i] = None
My rework of your code addressing this issue and some others:
from turtle import Screen, Turtle
def renderBlocks(b):
for i in range(len(b) - 1):
if b[i]:
x, y = blue_positions[i]
b[i].goto(x, y)
def move():
if game_on:
x = ball.xcor() + 10
y = ball.ycor() + 10
ball.goto(x, y)
renderBlocks(blue_turtles)
for i in range(len(blue_turtles) - 1):
if blue_turtles[i] and ball.distance(blue_turtles[i]) < 20:
blue_turtles[i].hideturtle()
blue_turtles[i] = None
screen.update()
screen.ontimer(move, 100) # milliseconds
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor('black')
screen.tracer(0)
player = Turtle('square')
player.shapesize(1, 4, 0)
player.color('blue')
player.penup()
player.sety(-250)
blue_turtles = []
blue_positions = []
for i in range(7):
turtle = Turtle('square')
turtle.shapesize(2, 4, 0)
turtle.color('blue')
turtle.penup()
blue_positions.append((-300 + i * 100, 200))
blue_turtles.append(turtle)
ball = Turtle('circle')
ball.color('white')
game_on = True
move()
screen.exitonclick()
So, I've been trying to make a maze using python, and it's been going well, except that I can't stop the character from getting out of the maze's box! This is my code:
import turtle
wn = turtle.Screen()
wn.setup(width=1000, height=700)
wn.bgcolor('white')
wn.title('test')
wn.tracer(0)
box_1 = turtle.Turtle()
box_1.shape('square')
box_1.penup()
box_1.color('black')
box_1.goto(-485, 0)
box_1.shapesize(stretch_len=1.5, stretch_wid=35)
box_2 = turtle.Turtle()
box_2.shape('square')
box_2.penup()
box_2.color('black')
box_2.goto(-500, -95)
box_2.shapesize(stretch_len=35, stretch_wid=1.5)
box_3 = turtle.Turtle()
box_3.shape('square')
box_3.penup()
box_3.color('black')
box_3.goto(-325, 0)
box_3.shapesize(stretch_len=1.5, stretch_wid=10)
box_4 = turtle.Turtle()
box_4.shape('square')
box_4.penup()
box_4.color('black')
box_4.goto(-145, -180)
box_4.shapesize(stretch_len=1.5, stretch_wid=10)
box_4 = turtle.Turtle()
box_4.shape('square')
box_4.penup()
box_4.color('black')
box_4.goto(-240, -265)
box_4.shapesize(stretch_len=10, stretch_wid=1.5)
box_4 = turtle.Turtle()
box_4.shape('square')
box_4.penup()
box_4.color('black')
box_4.goto(-345, -220)
box_4.shapesize(stretch_len=1.5, stretch_wid=6)
box_4 = turtle.Turtle()
box_4.shape('square')
box_4.penup()
box_4.color('black')
box_4.goto(-190, 90)
box_4.shapesize(stretch_len=15, stretch_wid=1.5)
character = turtle.Turtle()
character.shape('square')
character.speed(0)
character.penup()
character.color('yellow')
character.goto(-485, 335)
character.shapesize(stretch_wid=1, stretch_len=1)
def character_up():
y = character.ycor()
y += 10
character.sety(y)
def character_down():
y = character.ycor()
y -= 10
character.sety(y)
def character_right():
x = character.xcor()
x += 10
character.setx(x)
def character_left():
x = character.xcor()
x -= 10
character.setx(x)
wn.listen()
wn.onkeypress(character_up, "Up")
wn.onkeypress(character_down, "Down")
wn.onkeypress(character_right, "Right")
wn.onkeypress(character_left, "Left")
while True:
wn.update()
x = character.xcor()
y = character.ycor()
You can try this out yourself and you'll see that you can just easily get the character out of the maze, but I want to prevent it. Can someone help me?
I lack the ability to run this code at the moment, but I could give the following points:
Don't reuse the box_4 variable. Set box_5, box_6, and box_7.
In your character_[up/down/right/left] functions, check if the X value is above or below a certain value, and don't accept the move if so. For example:
def character_up():
y = character.ycor()
if (y < 100) { // Only do this if the Y variable is within bounds
y += 10
}
character.sety(y)
def character_down():
y = character.ycor()
if (y > -100) {
y -= 10
}
character.sety(y)
def character_right():
x = character.xcor()
if (x < 100) {
x += 10
}
character.setx(x)
def character_left():
x = character.xcor()
if (x > -100) {
x -= 10
}
character.setx(x)
You may have to adjust the bounds (-100 --> -200, 100 --> 200)
It seems to me you're trying to find a simple way out of a difficult problem. You want to draw black lines of a maze, and have your yellow character bound to those lines. Folks often approach this as drawing the walls of the maze and keeping the character from moving onto them. You've reversed this in that everything is a wall and you want to draw the path, keeping your character on the path. We can do this.
The approach here, is we build the path out of homogenous, small square blocks that are turtles. We keep a list of those blocks, and anytime the character moves, we validate the move by making sure they are always within a short distance of some block:
from turtle import Screen, Turtle
BLOCK_SIZE = 30
CURSOR_SIZE = 20
CHARACTER_SIZE = CURSOR_SIZE
def character_up():
character.sety(character.ycor() + CHARACTER_SIZE/2)
if not any(box.distance(character) < BLOCK_SIZE/2 for box in boxes):
character.undo()
def character_down():
character.sety(character.ycor() - CHARACTER_SIZE/2)
if not any(box.distance(character) < BLOCK_SIZE/2 for box in boxes):
character.undo()
def character_right():
character.setx(character.xcor() + CHARACTER_SIZE/2)
if not any(box.distance(character) < BLOCK_SIZE/2 for box in boxes):
character.undo()
def character_left():
character.setx(character.xcor() - CHARACTER_SIZE/2)
if not any(box.distance(character) < BLOCK_SIZE/2 for box in boxes):
character.undo()
screen = Screen()
screen.setup(width=1000, height=700)
screen.tracer(False)
box = Turtle()
box.shape('square')
box.penup()
box.color('black')
box.shapesize(BLOCK_SIZE / CURSOR_SIZE)
boxes = []
box.goto(-485, 335)
box.setheading(270)
for _ in range(23):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.backward(9 * BLOCK_SIZE)
box.setheading(0)
for _ in range(13):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.backward(8 * BLOCK_SIZE)
box.setheading(90)
for _ in range(7):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.setheading(0)
for _ in range(10):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.backward(3 * BLOCK_SIZE)
box.setheading(270)
box.forward(7 * BLOCK_SIZE)
for _ in range(6):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.setheading(180)
for _ in range(6):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.setheading(90)
for _ in range(4):
boxes.append(box.clone())
box.forward(BLOCK_SIZE)
box.hideturtle()
screen.tracer(True)
character = Turtle()
character.shape('square')
character.speed('fastest')
character.color('yellow')
character.penup()
character.goto(-485, 335)
character.shapesize(CHARACTER_SIZE / CURSOR_SIZE)
screen.onkeypress(character_up, 'Up')
screen.onkeypress(character_down, 'Down')
screen.onkeypress(character_right, 'Right')
screen.onkeypress(character_left, 'Left')
screen.listen()
screen.mainloop()
My maze drawing code may seem complicated, but by using relative drawing of the blocks, instead of absolute positions, it actually simplifies the problem, as we start thinking in a block-oriented coordinate system, instead of pixels.
The enemy1, enemy2, and enemy3 functions should run instantaniously using the ontimer function, moving the turtles inside them while running a nested checkcollision function to check if the turtles collide with the user. Along that running a nested checkbullet function to check distance see if they collide with the bullet turtle, and a nested check earth function to check their distance from the earth turtle which is the blue circle in the bottom right of the screen. However these 3 functions are running at hypersonic speed and I can't seem to find out why.
from turtle import Screen, Turtle
import random
from random import randint
#screen setup
screen = Screen()
screen.setup(width=450, height=450)
screen.bgcolor('black')
screen.tracer(3)
#user
player = Turtle()
player.shape('square')
player.color("green")
player.penup()
#First enemy
player2 = Turtle()
player2.color("green")
player2.shape('turtle')
player2.penup()
player2.setpos(random.randint(-200,200), random.randint(-200,200))
player2.setheading(random.randint(1,360))
#Second enemy
player3 = Turtle()
player3.color("green")
player3.shape('square')
player3.penup()
player3.setpos(random.randint(-200,200), random.randint(-200,200))
player3.setheading(random.randint(1,360))
#third enemy
player4 = Turtle()
player4.color("green")
player4.shape('triangle')
player4.penup()
player4.setpos(random.randint(-200,200), random.randint(-200,200))
player4.setheading(random.randint(1,360))
#earth
earth = Turtle()
earth.penup()
earth.shape("circle")
earth.color("blue")
earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6)
earth.setpos(150,-150)
#bullet
bullet = Turtle()
bullet.shape("turtle")
bullet.color("purple")
bullet.hideturtle()
bullet.penup()
bullet.setpos(random.randint(-200,200),random.randint(-200,200))
bullet.hideturtle()
bullet.penup()
px = 0
py = 0
def up():
global px
global py
py = player.ycor() + 5
if py >= 200:
py -= 15
player.sety(py)
def down():
global px
global py
py = player.ycor() - 5
if py < -200:
py += 15
player.sety(py)
def left():
global px
global py
px = player.xcor() - 5
if px <= -200:
px += 15
player.setx(px)
def right():
global px
global py
px = player.xcor() + 5
if px >= 200:
px -= 15
player.setx(px)
#distance calculator
def checkcollision(t1, t2):
while t1.distance(t2) < 10:
t2.setpos(randint(-100, 100), randint(-100, 100))
# the x and y distance that the player2 turtle moves
dx = 5
dy = 5
damage = 0
def checkbullet(bullet,turtle):
while bullet.distance(turtle) < 10:
turtle.hideturtle()
def check_earth(planet,turtle):
global damage
damage+=1
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
#1st enemy(switch heading)
head = 0
def enemy1():
checkcollision(player,player2)
check_earth(earth,player2)
global head
player2.fd(5)
x2, y2 = player2.position()
head = player2.heading()
if y2 <= -200 or y2 >= 200:
player2.fd(0)
player2.backward(7.5)
player2.setheading((head)* -1)
if x2 <= -200 or x2 >= 200:
player2.fd(0)
player2.backward(7.5)
if head < 90:
player2.setheading(0 - ((head) * 2))
if head>90<179:
player2.setheading((head)/2)
if head>179<260:
player2.setheading((head)/3)
if head>260<361:
player2.setheading((head)/2)
screen.ontimer(enemy1,50)
#Second enemy(dx,dy)
def enemy2():
checkcollision(player, player3)
check_earth(earth,player3)
global dx
global dy
x3, y3 = player3.position()
player3.setposition(x3 + dx, y3 + dy)
if y3 <= -200 or y3 >= 200:
dy *= -1
player3.sety(y3 + dy)
if x3 <= -200 or x3 >= 200:
dx *= -1
player3.setx(x3 + dx)
screen.ontimer(enemy2,50)
def enemy3():
checkcollision(player,player4)
check_earth(earth,player4)
player4.fd(5)
x4, y4 = player4.position()
head3 = player4.heading()
if y4 <= -200 or y4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
player4.setheading((head3)* -1)
if x4 <= -200 or x4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
if head3 < 90:
player4.setheading(0 - ((head3) * 2))
if head3>90<179:
player4.setheading((head3)/2)
if head3>179<260:
player4.setheading((head3)/3)
if head3>260<361:
player4.setheading((head3)/2)
screen.ontimer(enemy3,50)
#When bullet hits wall
def bullet_end():
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
def shoot_key():
bullet.setposition(px,py)
bullet.shape("circle")
bullet.showturtle()
bullet.penup()
def shoot():
checkbullet(bullet,player2)
checkbullet(bullet,player3)
checkbullet(bullet,player4)
bx = bullet.xcor()
by = bullet.ycor()
bullet.fd(5)
if bx>=200 or bx<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
if by>=200 or by<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
screen.ontimer(shoot,50)
shoot()
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
enemy1()
enemy2()
enemy3()
screen.mainloop()
The problem is caused by the function check_earth. As far as I can see, you are trying to prevent the enemy from being too close to earth - if it gets there, it should receive a new, random position. Obviously, this new position also shouldn't be too near to earth, so you are doing it in a loop. However, there are three errors in the loop.
Firstly, the condition for looking for a new position: while planet.distance(turtle)>10: is always met for a valid place.
Secondly, you immediately move the enemy to new random position, without checking the condition, which creates a lot of traffic. Instead, you should set position only when you are sure that it's correct.
Lastly, where did the '10' value come from? To declare your circle's size, you used: earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6). There is a following dependency between earth radius and stretch length: 2*RADIUS/CURSOR_SIZE. As default value of CURSOR_SIZE is 20, it would mean that the radius of your circle is 56. If we want to detect the collision as soon as any part of enemy's turtle touches the earth, we should also add the length of the enemy's cursor.
So, instead of:
def check_earth(planet,turtle):
global damage
damage+=1
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
You should define function check_earth as:
CURSOR_SIZE = 20
EARTH_RADIUS = 56
def check_earth(planet,turtle):
global damage
damage+=1
(turtle_x, turtle_y) = turtle.pos()
while True:
if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
turtle.setpos(turtle_x,turtle_y)
break
turtle_x = random.randint(-200,200)
turtle_y = random.randint(-200,200)
Not: while planet.distance(turtle)>10:
Yes: while planet.distance(turtle)<10:
The solution was simple and we both overlooked it,
I ask dumb questions sometimes. Anyways thanks for helping
When I run my code and I move my turtle up with the space bar, all the obstacles, that are supposed to be moving, stop moving. What causes the problem and how do I fix this?
I have no idea what can cause this problem and I've tried Googling but can't find anything. Since this is my first week of trying out Python, or programming in general, I have no idea what I've done wrong.
import turtle
import math
import random
#starting conditions
player = turtle.Turtle()
player.hideturtle()
player.penup()
player.shape("turtle")
player.setheading(90)
player.setpos(-200,0)
player.speed(1)
player.color("yellow")
canvas = turtle.Screen()
canvas.bgcolor("black")
canvas.title("gamescreen")
gameover = turtle.Turtle()
gameover.penup()
gameover.hideturtle()
gameover.color("red")
gameover.speed(0)
gameover.setpos(-150, 330)
scoreboard = turtle.Turtle()
scoreboard.hideturtle()
scoreboard.color("blue")
scoreboard.penup()
scoreboard.setpos(-300,320)
#borders
box = turtle.Turtle()
box.speed(0)
box.hideturtle()
box.setheading(0)
box.color("blue")
box.pensize(3)
box.penup()
box.setpos(-300,-300)
for i in range(4):
box.pendown()
box.forward(600)
box.left(90)
player.showturtle()
#movement
spd = 50
def playerup():
player.sety(player.ycor()+ spd)
if (player.ycor()+ spd) > 287:
player.speed(0)
player.sety(287)
player.speed(1)
def playerdown():
player.sety(player.ycor()- spd)
if (player.ycor()+ spd) < -287:
player.speed(0)
player.sety(-287)
player.speed(1)
turtle.listen()
gravity = 3
obsspd = 3
#collision
def hit(t1, t2):
xdistance = t1.xcor()-t2.xcor()
ydistance = t1.ycor()-t2.ycor()
if (abs(xdistance) < 20) and (abs(ydistance) < 130):
return True
else:
return False
#obstacle list
number_obstacles = 2
obstacles = []
numberslistx = list(range(-100,280))
numberslisty = list(range(143,190))
for i in range(number_obstacles):
obstacles.append(turtle.Turtle())
for obstacle in obstacles:
obstacle.hideturtle()
obstacle.speed(0)
obstacle.color("green")
obstacle.penup()
obstacle.shape("square")
obstacle.turtlesize(12,3)
xobs = random.choice(numberslistx)
yobs = random.choice(numberslisty)
obstacle.setposition(xobs,yobs)
obstacle.showturtle()
#obstacle2 list
number_obstacles2 = 2
obstacles2 = []
numberslistx = list(range(-100,280))
numberslisty = list(range(160,190))
for i in range (number_obstacles2):
obstacles2.append(turtle.Turtle())
for obstacle2 in obstacles2:
obstacle2.hideturtle()
obstacle2.speed(0)
obstacle2.color("green")
obstacle2.penup()
obstacle2.shape("square")
xobs = random.choice(numberslistx)
yobs = random.choice(numberslisty)
obstacle2.turtlesize(12,3)
obstacle2.setposition(xobs,-yobs)
obstacle2.showturtle()
if(obstacle.xcor()-obstacle2.xcor())> 10:
obstacle.setposition(xobs,yobs)
obstacle2.setposition(xobs,-yobs)
#border
def fall():
if (player.ycor()< -300):
return True
def ceiling():
if (player.ycor() > 300):
return True
colors = ["red", "green","yellow","blue","purple","pink"]
points = 1
while True:
player.sety(player.ycor()-gravity)
xresetpos = random.choice(range(230,300))
yresetpos = random.choice(range(140,190))
for obstacle in obstacles:
obstacle.setx(obstacle.xcor()-obsspd)
if (obstacle.xcor()-obsspd) < -270:
obstacle.hideturtle()
obstacle.setx(xresetpos)
obstacle.sety(yresetpos)
obstacle.showturtle()
obsspd+=1
points += 1
display = points
scoreboard.clear()
scoreboard.write(display)
player.color(random.choice(colors))
obstacle.color(random.choice(colors))
for obstacle2 in obstacles2:
obstacle2.setx(obstacle2.xcor()-(obsspd))
if (obstacle2.xcor()-obsspd) < -270:
obstacle2.hideturtle()
obstacle2.setx(xresetpos)
obstacle2.sety(-(int(yresetpos))-15)
obstacle2.showturtle()
player.color(random.choice(colors))
obstacle2.color(random.choice(colors))
if hit(player, obstacle):
player.hideturtle()
player.setpos(400,0)
gameover.color("red")
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if hit(player, obstacle2):
player.hideturtle()
player.setpos(400,0)
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if fall():
player.hideturtle()
player.setpos(400,0)
gameover.setpos(-150,-20)
gameover.write("Game over",False,"left",("Arial",50,))
gameover.setpos(-160,-200)
gameover.write("Press x to play again",False,"left",("Arial",30,))
break
if ceiling():
player.setycor(280)
#if score(player,obstacle1):
# points += 1
# display = points
# scoreboard.clear()
# scoreboard.write(display)
turtle.onkeypress(playerup, "space")
#turtle.onkeypress(playerdown, "Down")
#if player.xcor() is obstacle1.xcor():
# points += 1
# scoreboard.clear()
# scoreboard.write(points)
#balken stoppen niet als jij beweegt
One problem is that your horizontal motion is controlled, out of sync, by a while True: loop but your vertical motion is controlled, in sync, by a keyboard event. We need to get both motions in sync using events via replacing your while True: with an ontimer() event. Here's my complete rework of your code along these lines with a few simplifications for example purposes:
from turtle import Screen, Turtle
from random import choice, randrange
COLORS = ["red", "green", "yellow", "blue", "purple", "pink"]
PLAYER_SPEED = 50
GRAVITY = 3
NUMBER_OBSTACLES_UPPER = 2
NUMBER_OBSTACLES_LOWER = 2
# movement
def playerup():
screen.onkeypress(None, 'space') # disable handler inside handler
player.sety(player.ycor() + PLAYER_SPEED)
if player.ycor() > 287:
player.speed('fastest')
player.sety(287)
player.speed('slowest')
screen.onkeypress(playerup, 'space')
# collision
def hit(t1, t2):
xdistance = abs(t1.xcor() - t2.xcor())
if xdistance >= 20:
return False
ydistance = abs(t1.ycor() - t2.ycor())
return ydistance < 130
# border
def fall():
return player.ycor() < -300
def ceiling():
return player.ycor() > 300
# main program loop
def move():
global points, obstacle_speed_upper, obstacle_speed_lower
player.sety(player.ycor() - GRAVITY)
for obstacle in obstacles_upper:
obstacle.setx(obstacle.xcor() - obstacle_speed_upper)
if obstacle.xcor() < -270:
obstacle.hideturtle()
obstacle.setposition(randrange(230, 300), randrange(140, 190))
obstacle.showturtle()
obstacle_speed_upper += 1
points += 1
scoreboard.clear()
scoreboard.write(points, font=('Arial', 30,))
if hit(player, obstacle):
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
for obstacle in obstacles_lower:
obstacle.setx(obstacle.xcor() - obstacle_speed_lower)
if obstacle.xcor() < -270:
obstacle.hideturtle()
obstacle.setposition(randrange(230, 300), - randrange(160, 190))
obstacle.showturtle()
obstacle_speed_lower += 1
points += 1
scoreboard.clear()
scoreboard.write(points, font=('Arial', 30,))
if hit(player, obstacle):
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
if ceiling() or fall():
player.hideturtle()
gameover.write("Game Over", align='center', font=('Arial', 50,))
return
screen.ontimer(move, 100)
# starting conditions
screen = Screen()
screen.setup(750, 750)
screen.bgcolor('black')
screen.title("Game Screen")
# borders
box = Turtle()
box.hideturtle()
box.color('blue')
box.speed('fastest')
box.pensize(3)
box.penup()
box.setpos(-300, -300)
box.pendown()
for _ in range(4):
box.forward(600)
box.left(90)
gameover = Turtle()
gameover.hideturtle()
gameover.color('red')
gameover.penup()
gameover.sety(-25)
points = 0
scoreboard = Turtle()
scoreboard.hideturtle()
scoreboard.color('blue')
scoreboard.penup()
scoreboard.setpos(-300, 320)
scoreboard.write(points, font=('Arial', 30,))
player = Turtle()
player.hideturtle()
player.shape('turtle')
player.speed('slowest')
player.color('yellow')
player.setheading(90)
player.penup()
player.setx(-200)
player.showturtle()
# obstacle list
obstacle_speed_upper = 3
obstacles_upper = []
for _ in range(NUMBER_OBSTACLES_UPPER):
obstacle = Turtle()
obstacle.hideturtle()
obstacle.shape('square')
obstacle.turtlesize(12, 3)
obstacle.speed('fastest')
obstacle.color(choice(COLORS))
obstacle.penup()
xobs = randrange(-100, 280)
yobs = randrange(145, 190)
obstacle.setposition(xobs, yobs)
obstacle.showturtle()
obstacles_upper.append(obstacle)
# lower obstacles list
obstacle_speed_lower = 3
obstacles_lower = []
for _ in range(NUMBER_OBSTACLES_LOWER):
obstacle = Turtle()
obstacle.hideturtle()
obstacle.shape('square')
obstacle.turtlesize(12, 3)
obstacle.speed('fastest')
obstacle.color(choice(COLORS))
obstacle.penup()
xobs = randrange(-100, 280)
yobs = randrange(160, 190)
obstacle.setposition(xobs, -yobs)
obstacle.showturtle()
obstacles_lower.append(obstacle)
screen.onkeypress(playerup, 'space')
screen.listen()
move()
screen.mainloop()