How to cause collision in Python Turtle - python

I am new to Python 3 and I am currently making a turtle game where if you hit a red turtle, you go to the start. I do not know how to make the player move to make them collide. My code:
from turtle import Turtle, Screen
wn = Screen()
wn.bgcolor("black")
artist = Turtle()
artist.color('white')
artist.speed(0)
artist.penup()
artist.setposition(-300, -300)
artist.pendown()
artist.pensize(4)
for side in range(4):
artist.fd(600)
artist.lt(90)
artist.hideturtle()
player = Turtle()
player.color("white")
player.penup()
player.setposition(260, 260)
player.speed(10)
enemy = Turtle('circle')
enemy.color('red')
enemy.penup()
enemy.speed(9)
if player.distance(enemy) < 5:
player.hideturtle()
player.setposition(260, 260)
player.showturtle()

I do not know how to make them collide and move the player, it won't
move.
Since the OP used a proper turtle import (for turtle's Object-Oriented API) and used the distance() method instead of reimplementing one like many folks, +1!
Below I've reworked the code to provide player movement, so that it can finally collide with the enemy. To keep this example minimalist, I've made the boundary circular instead of rectangular as in the original:
from turtle import Screen, Turtle
RADIUS = 300
CURSOR_RADIUS = 10
CURSOR_DIAMETER = CURSOR_RADIUS * 2
START = RADIUS / 2 ** 0.5 - CURSOR_DIAMETER
def move_forward():
screen.onkey(None, 'Up') # disable handler inside handler
player.forward(CURSOR_RADIUS)
if player.distance(0, 0) >= RADIUS:
player.undo()
if player.distance(enemy) < CURSOR_RADIUS:
player.hideturtle()
player.setposition(START, START)
player.showturtle()
screen.onkey(move_forward, 'Up') # reenable handler
screen = Screen()
screen.bgcolor('black')
artist = Turtle(visible=False)
artist.color('white')
artist.speed('fastest')
artist.pensize(4)
artist.penup()
artist.sety(-RADIUS)
artist.pendown()
artist.circle(RADIUS)
artist.penup()
artist.setposition(START, START)
artist.pendown()
artist.dot(CURSOR_DIAMETER, 'green')
enemy = Turtle('circle')
enemy.color('red')
enemy.penup()
player = Turtle()
player.speed('fastest')
player.color('white')
player.penup()
player.setposition(START, START)
player.setheading(player.towards(enemy))
screen.onkey(lambda: player.right(45), 'Right')
screen.onkey(lambda: player.left(45), 'Left')
screen.onkey(move_forward, 'Up')
screen.listen()
screen.mainloop()
You can control the player with the arrow keys. Now the enemy needs to be made to do something other than just sit in the middle.

Related

How do I move 2 turtle shapes at the same time?

I am making a simple jump game in python, and so far have a player and a spike. The spike moves infinitely to the left of the screen and then immediately goes back to the right side. The player jumps when you press space. My issue is that I cannot have the player jumping and the sprite moving at the same time.
#Imports and other setup
import turtle
import time
turtle.speed(5)
air = 0
#Window customization
wn = turtle.Screen()
wn.title('Jump Game')
wn.bgcolor('black')
wn.setup(width=600, height=600)
#Player creation
player = turtle.Turtle()
player.penup()
player.ht()
player.shape('square')
player.color('blue')
player.goto(-200, -200)
player.st()
player.down()
#Floor creation
floorCors = ((210, -300), (210, 300), (300, 300), (300, -300))
wn.register_shape('rectangle', floorCors)
floor = turtle.Turtle()
floor.shape('rectangle')
floor.color('white')
#Obstacle creation
obstacle = turtle.Turtle()
obstacle.penup()
obstacle.ht()
obstacle.shape('triangle')
obstacle.color('red')
obstacle.goto(200, -202)
obstacle.tilt(90)
obstacle.st()
obstacle.down()
turtle.update()
#Player jump
def jump():
global air
if air == 0:
air = 1
player.penup()
player.speed(1)
y = player.ycor()
player.sety(y+100)
player.sety(y-0)
air = 0
wn.listen()
wn.onkeypress(jump, 'space')
#Obstacle movement
while True:
obstacle.penup()
obstacle.speed(3)
x = obstacle.xcor()
if x > -300:
obstacle.goto(x-10, -202)
else:
obstacle.ht()
obstacle.speed(0)
obstacle.goto(300, -202)
obstacle.speed(3)
obstacle.st()
I thought about combining the two movement chunks but I have no idea how to approach that.

Python : Using Turtle-graphics, having issue with Screen.tracer() and Screen.update(). Placement of’ update() ‘ makes my code run / not-run properly

I am trying to make a Pong game and as you can see in the screenshot ( at the end of this question ), In the right hand side I have created a paddle.
Everything works fine in following code, when I press Up and Down arrows, the paddle moves up and down.
Kindly note placement of statement “ screen.update()”
from turtle import Turtle,Screen
import time
screen = Screen()
screen.setup(width=800,height=600)
screen.bgcolor("black")
screen.title("Pong")
screen.tracer(0)
paddle = Turtle()
paddle.shape("square")
paddle.color("white")
paddle.shapesize(stretch_wid=5,stretch_len=1)
paddle.penup()
paddle.goto(350,0)
def go_up():
new_y = paddle.ycor() + 20
paddle.goto(paddle.xcor(),new_y)
def go_down():
new_y = paddle.ycor() - 20
paddle.goto(paddle.xcor(),new_y)
screen.listen()
screen.onkey(go_up,"Up")
screen.onkey(go_down,"Down")
game_is_on = True
while game_is_on:
screen.update()
screen.exitonclick()
But when I take out statement “ screen.update()” from while look , delete while loop and place the statement “ screen.update()” after paddle.goto(350,0) statement , the movement of paddle stops working , the changed code ( non-working code ) is as below:
(Kindly note placement of statement “ screen.update()” again below)
from turtle import Turtle,Screen
import time
screen = Screen()
screen.setup(width=800,height=600)
screen.bgcolor("black")
screen.title("Pong")
screen.tracer(0)
paddle = Turtle()
paddle.shape("square")
paddle.color("white")
paddle.shapesize(stretch_wid=5,stretch_len=1)
paddle.penup()
paddle.goto(350,0)
screen.update()
def go_up():
new_y = paddle.ycor() + 20
paddle.goto(paddle.xcor(),new_y)
def go_down():
new_y = paddle.ycor() - 20
paddle.goto(paddle.xcor(),new_y)
screen.listen()
screen.onkey(go_up,"Up")
screen.onkey(go_down,"Down")
screen.exitonclick()
I want to know :-
Why is my code not working in SECOND CASE
Why makes my code work in FIRST CASE
ThankYou.
Why is my code not working in SECOND CASE
Because you haven't put a screen.update() everywhere you make a change that you want the user to see. Specifically the go_up() and go_down() methods:
from turtle import Turtle, Screen
def go_up():
paddle.sety(paddle.ycor() + 20)
screen.update()
def go_down():
paddle.sety(paddle.ycor() - 20)
screen.update()
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor('black')
screen.title("Pong")
screen.tracer(0)
paddle = Turtle()
paddle.shape('square')
paddle.color('white')
paddle.shapesize(stretch_wid=5, stretch_len=1)
paddle.penup()
paddle.setx(350)
screen.update()
screen.onkey(go_up, 'Up')
screen.onkey(go_down, 'Down')
screen.listen()
screen.exitonclick()
Why makes my code work in FIRST CASE
Because you call screen.update() continuously, i.e. way too often and so it happens to catch all the changes.

Update the score when two turtles collide

I'm doing an assignment where I have to write a small game. When a turtle collides with a dot (bug) on the screen, it will add one point to the score value in the top left and teleport the bug to another random spot. I'm having trouble getting the score to update when they collide.
I tried to put the score update within the game loop but that did not work as it kept telling me that the value is not defined. I tried solving that with a global value, but that didn't do anything:
import turtle
import math
import random
#Set up the constants for the game.
WINDOW_HEIGHT = 300
WINDOW_WIDTH = 300
FORWARD_STEP = 10 #how much does the turtle move forward
TURN_STEP = 30 #how much does the turtle turn (in degrees)
SHRINK_FACTOR = 0.95 #how much does the turtle shrink when it moves
DEATH_WIDTH = 0.05 #the size at which you stop the game because the user lost
COLLISION_THRESHOLD = 10;#we say that two turtles collided if they are this much away
#from each other
#Define functions
def game_setup():
'''set up the window for the game, a bug and the player turtle '''
#create the screen
wn = turtle.Screen()
wn.screensize(WINDOW_HEIGHT,WINDOW_WIDTH)
wn.bgcolor("light green")
#Create player turtle
player = turtle.Turtle()
player.color("blue")
player.shape("turtle")
player.penup()
player.setpos (random.randrange(1,301), random.randrange(1,301))
#create a bug
bug1 = turtle.Turtle()
bug1.color("black")
bug1.shape("circle")
bug1.shapesize(stretch_wid=0.2, stretch_len=0.2)
bug1.penup()
bug1.speed(0) #the bug is not moving
bug1.setposition(-200, 200)
#create score turtle
score_keeper = turtle.Turtle()
score_keeper.hideturtle()
score_keeper.penup()
score_keeper.setposition (-400,360)
score = 0
scorestring = "Score: %s" %score
score_keeper.write(scorestring, False, align="left", font=("Arial",14, "normal"))
return (wn,player,bug1,score_keeper)
def is_collision (player, bug1):
distance = (math.sqrt((player.xcor()-bug1.xcor())**2 + (player.ycor() - bug1.ycor())**2))
if distance < COLLISION_THRESHOLD:
return True
else:
return False
def main():
#set up the window, player turtle and the bug
(wn,player,bug1,score_keeper) = game_setup()
#make the arrow keys move the player turtle
bindKeyboard(player)
#Set this veriableto True inside the loop below if you want the game to end.
game_over = False
player_width = get_width(player)
#This is the main game loop - while the game is not over and the turtle is large enough print the width of the turtle
#on the screen.
while not game_over and player_width > DEATH_WIDTH:
#your collision detection should go here
if is_collision (player, bug1):
bug1.setpos (random.randrange(1,301), random.randrange(1,301))
player.shapesize(stretch_wid=1, stretch_len=1)
player_width = get_width(player)
player.showturtle()
print(player_width)
print("Done")
wn.exitonclick()
main()
This is most of the code. All I want it to do is when the is_collision() function happens, it adds 1 to the value of score and the score_keeper turtle then prints that value in the window.
Im havign trouble getting the score to update when they collide.
I've done a stripped down rework of your code below (substuting for methods you left out) to show how to update the score on the screen. Code like this shouldn't have an explicit main loop as it's all event driven and should instead call turtle's main event loop:
from turtle import Screen, Turtle
from random import randrange
from functools import partial
# Set up the constants for the game.
WINDOW_WIDTH, WINDOW_HEIGHT = 500, 500
FORWARD_STEP = 10 # how much does the turtle move forward
TURN_STEP = 30 # how much does the turtle turn (in degrees)
COLLISION_THRESHOLD = 10 # we say that two turtles collided if they are this much away from each other
CURSOR_SIZE = 20
FONT = ('Arial', 14, 'normal')
# Define functions
def is_collision(player, bug):
return player.distance(bug) < COLLISION_THRESHOLD
def random_position(turtle):
scale, _, _ = turtle.shapesize()
radius = CURSOR_SIZE * scale
return randrange(radius - WINDOW_WIDTH/2, WINDOW_WIDTH/2 - radius), randrange(radius - WINDOW_HEIGHT/2, WINDOW_HEIGHT/2 - radius)
def forward():
global score
player.forward(FORWARD_STEP)
if is_collision(player, bug):
bug.setposition(random_position(bug))
score += 1
score_keeper.clear()
score_keeper.write(f"Score: {score}", font=FONT)
# Set up the window for the game, a bug and the player turtle.
# Create the screen
screen = Screen()
screen.setup(WINDOW_WIDTH, WINDOW_HEIGHT)
screen.bgcolor('light green')
# Create score turtle
score_keeper = Turtle(visible=False)
score_keeper.penup()
score_keeper.setposition(-230, 230)
score = 0
score_keeper.write(f"Score: {score}", font=FONT)
# Create a bug
bug = Turtle('circle', visible=False)
bug.shapesize(4 / CURSOR_SIZE)
bug.penup()
bug.setposition(random_position(bug))
bug.showturtle()
# Create player turtle
player = Turtle('turtle', visible=False)
player.color('blue')
player.speed('fastest')
player.penup()
player.setposition(random_position(player))
player.showturtle()
# make the arrow keys move the player turtle
screen.onkey(partial(player.left, TURN_STEP), 'Left')
screen.onkey(partial(player.right, TURN_STEP), 'Right')
screen.onkey(forward, 'Up')
screen.listen()
screen.mainloop()

players not moving simultaneously

I am attempting to make a game in python with the turtle module, I have the square moving towards the player (the circle) and the aim is for the circle to jump over the square and not get hit.
The player can jump by pressing the spacebar,
but every time you hit the space bar to jump the player jumps, but the square stops moving and you are unable to jump over.
here is my code:
import turtle
import time
wn = turtle.Screen()
wn.bgcolor("white")
wn.title("dinosaur run")
wn.tracer(1,20)
floor = turtle.Turtle()
floor.fd(370)
floor.bk(370*2)
floor.ht()
player = turtle.Turtle()
player.shape("circle")
player.penup()
player.setpos(-370,14)
def jump():
player.lt(90)
player.fd(40)
time.sleep(0.5)
player.bk(40)
player.rt(90)
turtle.listen()
turtle.onkey(jump, "space")
class cactus(turtle.Turtle):
turtle.shape("square")
turtle.penup()
turtle.speed(0)
turtle.setpos(370,14)
cactusspeed = 2
while True:
x = turtle.xcor()
x -= cactusspeed
turtle.setx(x)
Thanks a lot,
all ideas welcome,
I've tried wn.update() at the end
As provided above, your code doesn't run at all as cactusspeed never gets defined. And your class cactus doesn't have a hope of working as currently laid out (reread about Python classes.) Finally, your while True: has no business in an event driven world like turtle.
Below is my rework of your code to use an ontimer() event to control the cactus independent of the player. I also eliminated the sleep() and simply made the player move slower and jump higher. I believe this should give you the dynamic you're looking for:
from turtle import Turtle, Screen
def jump():
player.forward(100)
player.backward(100)
def move():
if cactus.xcor() < -screen.window_width()/2:
cactus.hideturtle()
cactus.setx(370)
cactus.showturtle()
else:
cactus.forward(cactusspeed)
screen.ontimer(move, 40)
screen = Screen()
floor = Turtle(visible=False)
floor.speed('fastest')
floor.fd(370)
floor.bk(370 * 2)
player = Turtle("circle", visible=False)
player.penup()
player.setpos(-370, 14)
player.setheading(90)
player.speed('slowest')
player.showturtle()
cactusspeed = 4
cactus = Turtle("square", visible=False)
cactus.speed('fastest')
cactus.penup()
cactus.setpos(370, 14)
cactus.setheading(180)
cactus.showturtle()
screen.onkey(jump, "space")
screen.listen()
move()
screen.mainloop()

Troubles implementing a video game using Python turtle graphics

Basically what I'm trying to do is create a two player game using Python's turtle module. There are two turtles at the bottom which are the players and two circles at the top which act as checkpoints. One turtle is supposed to go back and forth between the two checkpoints—this turtle is the target. The bottom turtles shoot circles at the target.
My issues:
The target turtle moves way too rapidly.
The bullets for the turtles at the bottom spawn from the middle of the screen.
Note: There may be some parts of the code which are confusing and/or not needed.
Here's the code:
from turtle import*
import math
def k1():#Enemy Key Commands
enemy.left(90)
enemy.forward(10)
enemy.right(90)
def k2():
enemy.left(90)
enemy.backward(10)
enemy.right(90)
def k3():#Yertle Key Commands
yertle.left(90)
yertle.forward(10)
yertle.right(90)
def k4():
yertle.left(90)
yertle.backward(10)
yertle.right(90)
def k5():
a=bullet_red()
a.speed(10)
a.forward(400)
collision= math.sqrt(math.pow(a.xcor()-yertle.xcor(),2)+math.pow(a.ycor()-yertle.ycor(),2))
if(collision<10):
text=enemy.write("Game Over", align="center" , font=("Arial", 16, "normal"))
a.hideturtle()
def k6():
a=bullet_blue()
a.speed(10)
a.forward(400)
collision= math.sqrt(math.pow(a.xcor()-yertle.xcor(),2)+math.pow(a.ycor()-yertle.ycor(),2))
if(collision<10):
text=enemy.write("Game Over", align="center" , font=("Arial", 16, "normal"))
a.hideturtle()
def collision(a, b):
collision= math.sqrt(math.pow(a.xcor()-b.xcor(),2)+math.pow(a.ycor()-b.ycor(),2))
if(collision<5):
print("Bottom Player Wins")
print("Game Over")
def bullet_red():
bullet=Turtle("circle")#Description For Bullet
bullet.color("red")
bullet.penup()
bullet.goto(enemy.pos())
bullet.setheading(180)
bullet.right(90)
return bullet
def bullet_blue():
bullet=Turtle("circle")#Description For Bullet
bullet.color("blue")
bullet.penup()
bullet.goto(yertle.pos())
bullet.setheading(180)
bullet.right(90)
return bullet
ops = Screen()
ops.setup(500, 500)
ops.onkey(k1, "a")#Enemy
ops.onkey(k2, "d")#Enemy
ops.onkey(k3, "Left")#Yertle
ops.onkey(k4, "Right")#Yertle
ops.onkey(k5, "w")#Shoot(Enemy)
ops.onkey(k6, "Up")#Shoot(Enemy)
ops.listen()
checkpoint_1=Turtle(shape="circle")#Turtle Description for Checkpoint 1
checkpoint_1.color("red")
checkpoint_1.setheading(180)
checkpoint_1.right(90)
checkpoint_1.penup()
checkpoint_1.setx(-220)
checkpoint_1.sety(230)
checkpoint_1.speed(0)
#_____________________________
checkpoint_2=Turtle(shape="circle")#Turtle Description for Checkpoint 2
checkpoint_2.color("red")
checkpoint_2.setheading(180)
checkpoint_2.right(90)
checkpoint_2.penup()
checkpoint_2.setx(220)
checkpoint_2.sety(230)
checkpoint_2.speed(0)
#____________________________
runner=Turtle(shape="turtle")#Turtle Description for Checkpoint 2
runner.color("yellow")
while(runner!=collision):
runner.penup()
runner.goto(checkpoint_1.pos())
runner.goto(checkpoint_2.pos())
runner.speed(0)
#_____________________________
enemy=Turtle(shape="turtle")#Turtle Description for Player 1
enemy.color("red")
enemy.setheading(180)
enemy.right(90)
enemy.penup()
enemy.setx(-20)
enemy.sety(-200)
enemy.speed(0)
#_____________________________
yertle = Turtle(shape="turtle")#Turtle Description for Player 2
yertle.color("blue")
yertle.setheading(180)
yertle.right(90)
yertle.penup()
yertle.setx(20)
yertle.sety(-200)
yertle.speed(0)
#_____________________________
Below is my rework of your code to get it to just basically play the game -- it still needs work to become a finished program.
from turtle import Turtle, Screen
FONT = ("Arial", 32, "bold")
def k1(): # Enemy Key Commands
enemy.backward(10)
def k2():
enemy.forward(10)
def k3(): # Yertle Key Commands
yertle.backward(10)
def k4():
yertle.forward(10)
def k5(): # enemy shoot
bullet.color("red")
bullet.goto(enemy.position())
bullet.showturtle()
bullet.forward(430)
if bullet.distance(runner) < 10:
magic_marker.write("Game Over", align="center", font=FONT)
bullet.hideturtle()
def k6(): # yertle shoot
bullet.color("blue")
bullet.goto(yertle.position())
bullet.showturtle()
bullet.forward(430)
if bullet.distance(runner) < 10:
magic_marker.write("Game Over", align="center", font=FONT)
bullet.hideturtle()
def move_runner():
if runner.distance(checkpoint_1) < 5 or runner.distance(checkpoint_2) < 5:
runner.left(180)
runner.forward(2)
screen.ontimer(move_runner, 50)
screen = Screen()
screen.setup(500, 500)
bullet = Turtle("circle", visible=False) # Description For Bullet
bullet.speed('normal')
bullet.penup()
bullet.setheading(90)
checkpoint_1 = Turtle("circle", visible=False) # Turtle Description for Checkpoint 1
checkpoint_1.color("red")
checkpoint_1.penup()
checkpoint_1.goto(-220, 230)
checkpoint_2 = checkpoint_1.clone() # Turtle Description for Checkpoint 2
checkpoint_2.goto(220, 230)
runner = Turtle("turtle", visible=False)
runner.color("orange")
runner.speed('fastest')
runner.penup()
runner.sety(230)
yertle = Turtle(shape="turtle", visible=False) # Turtle Description for Player 1
yertle.tiltangle(90) # face one way but move another!
yertle.speed('fastest')
yertle.penup()
yertle.color("blue")
yertle.goto(20, -200)
enemy = yertle.clone() # Turtle Description for Player 2
enemy.color("red")
enemy.goto(-20, -200)
checkpoint_1.showturtle()
checkpoint_2.showturtle()
runner.showturtle()
yertle.showturtle()
enemy.showturtle()
magic_marker = Turtle(visible=False) # for writing text
screen.onkey(k1, "a") # Enemy
screen.onkey(k2, "d") # Enemy
screen.onkey(k3, "Left") # Yertle
screen.onkey(k4, "Right") # Yertle
screen.onkey(k5, "w") # Shoot(Enemy)
screen.onkey(k6, "Up") # Shoot(Yertle)
screen.listen()
move_runner()
screen.mainloop()
Your code had errors (as did your comments) but my primary advice is to review the turtle documentation to see all the features available to you -- when writing a game, you need to know what a turtle can do.
I changed the bullets into a single shared bullet -- turtles don't go away when you're finished with them so this seemed better resource-wise. But it's also buggy, however. If you continue with a single bullet model, you'll want to interlock the firing events to prevent overlap. If you instead go with multiple bullets firing at the same, you'll want to add more ontimer events like the runner uses to control their motion.

Categories

Resources