Ball bounce in pong - python

I have written some code but can't get the ball to bounce on the floor or the ceiling naturally. Please help!
I've already tried getting the ball heading with ball_heading = ball.heading, but that didn't work
#Python 3.6.3
from turtle import *
import math
import random
#Screen Setup
bgcolor("black")
wn = Screen()
wn.title("Pong")
#Drawing Border
bd = Turtle()
bd.pencolor("white")
bd.pensize(3)
bd.hideturtle()
bd.penup()
bd.setposition(-400, -300)
bd.pendown()
bd.speed(0)
bd.pendown()
for line in range(2):
bd.forward(800)
bd.left(90)
bd.forward(600)
bd.left(90)
bd.penup()
bd.setposition(0, 300)
bd.setheading(270)
bd.pendown()
for dash in range(30):
bd.forward(10)
bd.penup()
bd.forward(10)
bd.pendown()
#Creating Paddles
#Paddle 1
player1 = Turtle()
player1.color("white")
player1.shape("square")
player1.shapesize(stretch_wid=5, stretch_len=1)
player1.penup()
player1.setposition(-370, 0)
#Paddle 2
player2 = Turtle()
player2.color("white")
player2.shape("square")
player2.shapesize(stretch_wid=5, stretch_len=1)
player2.penup()
player2.setposition(370, 0)
#Creating the ball
ball = Turtle()
ball.color("white")
ball.shape("square")
ball.speed(0)
ball.penup()
ball.setposition(0, 0)
ball.setheading(random.randint(0, 360))
#Moving the player
playerspeed = 15
#p1
def move_up():
y = player1.ycor()
y += playerspeed
#Setting the boundries
if y > 245:
y = 245
player1.sety(y)
def move_down():
y = player1.ycor()
y -= playerspeed
#Setting the boundries
if y < -245:
y = -245
player1.sety(y)
#p2
def move_up2():
y = player2.ycor()
y += playerspeed
#Setting the boundries
if y > 245:
y = 245
player2.sety(y)
def move_down2():
y = player2.ycor()
y -= playerspeed
#Setting the boundries
if y < -245:
y = -245
player2.sety(y)
#Ball movement
def ball_fd():
ball.forward(3)
#Ball ceiling / floor bounce
def ball_bounce():
by = ball.ycor()
if by > 279:
by = 279
ball.sety(by)
bx = ball.ycor()
if bx < -279:
bx = -279
ball.setx(bx)
#binding
listen()
onkey(move_up, "Up")
onkey(move_down, "Down")
onkey(move_up2, "w")
onkey(move_down2, "s")
#Making the ball move / main game loop
while True:
ball_fd()
ball_bounce()
Sorry the code is kind of long, but feel free to copy + paste it into IDLE or whatever.
Thank you

You didn't turn the ball when it hit the floor or ceiling.
while True:
ball.fd(3)
by = ball.ycor()
if abs(by) > 279:
ball.setheading(-ball.heading())

Related

Turtle window hanging

When I try to run my code, my python turtle window just hangs; I can't move also. I've tried removing the win_pen and it worked, but I don't know what inside the win_pen is making it hang.
It also gives me the spinning wheel since I am on Mac, and I am not sure if that is the problem for this. I'm on Big Sur 11.1 by the way.
edit: The indents are right on my screen, just a copy and paste problem
Code:
import turtle
import os
import math
import random
from random import randint
score = 0
# Set Up Screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("test")
# Draw border
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300,-300)
border_pen.pendown()
border_pen.hideturtle()
border_pen.pensize(3)
for side in range(4):
border_pen.fd(600)
border_pen.lt(90)
# Draw Winning Area
win_pen = turtle.Turtle()
win_pen.hideturtle()
win_pen.shape("square")
win_pen.penup()
win_pen.setposition(0,267.7)
win_pen.shapesize(3,29.8)
# Show Score on Screen
score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 303)
scorestring = "Score: %s" %score
score_pen.write(scorestring, False, align="left", font=("Ubuntu", 14, "normal"))
score_pen.hideturtle()
# Set up Player 1
player1 = turtle.Turtle()
player1.color("blue")
player1.shape("triangle")
player1.penup()
player1.speed(0)
player1.setposition(0, -250)
player1.setheading(90)
player1speed = 15
# Set Up Enemies
en = 8
enemies = []
for i in range(en):
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.color("red")
enemy.shape("square")
enemy.penup()
enemy.speed(0)
enemy.goto(randint(-280,280),randint(-280,280))
enemy.shapesize(2,2)
enemyspeed = 2
# Draw Winning Area
win_pen = turtle.Turtle()
win_pen.hideturtle()
win_pen.shape("square")
win_pen.penup()
win_pen.setposition(0,267.7)
win_pen.shapesize(3,29.8)
#Define bullet state
#ready - ready to fire
#fire - bullet is firing
bulletstate = "ready"
def left():
x = player1.xcor()
player1.setheading(180)
player1.forward(player1speed)
if x < -280:
x = - 280
player1.setx(x)
def right():
x = player1.xcor()
player1.setheading(0)
player1.forward(player1speed)
if x > 280:
x = 280
player1.setx(x)
def up():
y = player1.ycor()
player1.setheading(90)
player1.forward(player1speed)
if y > 280:
y = 280
player1.sety(y)
def down():
y = player1.ycor()
player1.setheading(270)
player1.forward(player1speed)
if y < -280:
y = 280
player1.sety(y)
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2)+math.pow(t1.ycor()-t2.ycor(),2))
if distance < 15:
return True
else:
return False
turtle.listen()
turtle.onkey(left, "a")
turtle.onkey(right, "d")
turtle.onkey(up, "w")
turtle.onkey(down, "s")
# Main Game Loop
while True:
if isCollision(player1, win_pen):
player1.setposition(0, -250)
player1.setheading(90)
There are several problems with your code: don't use while True: in an event-driven world like turtle -- let the event handler do its job; your collision logic is incorrect as it measures from the center of the turtles whereas we're really only concerned with the y position of the two turtles; you seem to be resetting the player in the wrong direction; you implement the winning area twice.
I've rewritten, and simplified, your code below incorporating the above changes and some other tweaks:
from turtle import Screen, Turtle
from random import randint
ENEMY_COUNT = 8
PLAYER_SPEED = 15
def left():
player.setheading(180)
player.setx(max(-280, player.xcor() - PLAYER_SPEED))
check_collision(player, win_pen)
def right():
player.setheading(0)
player.setx(min(280, player.xcor() + PLAYER_SPEED))
check_collision(player, win_pen)
def up():
player.setheading(90)
player.sety(min(280, player.ycor() + PLAYER_SPEED))
check_collision(player, win_pen)
def down():
player.setheading(270)
player.sety(max(-280, player.ycor() - PLAYER_SPEED))
check_collision(player, win_pen)
def check_collision(player, win_pen):
if abs(player.ycor() - win_pen.ycor()) < 15:
player.sety(-250)
player.setheading(90)
score = 0
# Set Up Screen
screen = Screen()
screen.bgcolor('black')
# Draw border
border_pen = Turtle()
border_pen.hideturtle()
border_pen.pensize(3)
border_pen.color('white')
border_pen.speed('fastest')
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
for _ in range(4):
border_pen.forward(600)
border_pen.left(90)
# Draw Winning Area
win_pen = Turtle()
win_pen.shape('square')
win_pen.shapesize(3, 29.8)
win_pen.color('gray')
win_pen.penup()
win_pen.sety(267.7)
# Show Score on Screen
score_pen = Turtle()
score_pen.hideturtle()
score_pen.color('white')
score_pen.penup()
score_pen.setposition(-290, 303)
scorestring = "Score: %s" %score
score_pen.write(scorestring, False, align='left', font=('Ubuntu', 14, 'normal'))
# Set up Player
player = Turtle()
player.shape('triangle')
player.color('blue')
player.speed('fastest')
player.setheading(90)
player.penup()
player.setx(-250)
# Set Up Enemies
enemies = []
for _ in range(ENEMY_COUNT):
enemy = Turtle()
enemy.color('red')
enemy.shape('square')
enemy.shapesize(2)
enemy.speed('fastest')
enemy.penup()
enemy.goto(randint(-280, 280), randint(-280, 280))
enemies.append(enemy)
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.onkey(up, 'w')
screen.onkey(down, 's')
screen.listen()
screen.mainloop()

How to prevent Python Turtle from going through lines it has drawn?

I'm making a game using Turtle in Python 3.
My main problem is that the turtle can move through the "drawn" lines in the game. It's basically a randomized "flappy-bird" game, different each time you run the program.
Is it possible to prevent the Turtle from going through lines it has drawn?
The program creates both walls and holes the player should be able to get through, like flappy bird where it's a pipe-hole-pipe with different lengths on the pipes.
And if I run print(hole) at the end of the program it returns None. Why is this?
Here is my program:
import turtle
import random
GameOver=False
import math
import time
board = turtle.Screen()
board.screensize(50.50)
board.bgcolor("black")
board.title("Labyrinten")
Hast_på_ritande_av_bana= 0
TURTLE_SIZE = 20
playerspeed = 50
n=1 #variabeler som gör att den hoppar ett steg åt höger när den gör raderna t.ex. ((930/8)*n)
b=2 #
global player
#SÄTTER UPP SKÄRM
border = turtle.Turtle()
border.speed(Hast_på_ritande_av_bana)
border.hideturtle()
border.color("white")
border.shape("triangle")
border.penup()
border.goto(TURTLE_SIZE/2 - board.window_width()/2, board.window_height()/2 - TURTLE_SIZE/2)
border.pendown()
border.showturtle()
border.rt(90)
border.fd(780)
border.penup()
#ritar banan
for rader in range(4): #creating the maze
border.lt(90)
border.fd(930/8)
border.pendown()
border.lt(90)
wall_ett = border.fd(random.randint(50,630)) #lower wall on row 1
border.penup()
hole=border.fd(random.randint(30,70)) #hole on row 1
border.pendown()
wall_ett_ett = border.goto (TURTLE_SIZE/2 - board.window_width()/2 + (930/8*n), board.window_height()/2 - TURTLE_SIZE/2) #higher wall on row 1
border.rt(90)
border.fd(930/8)
border.rt(90)
wall_två_ett = border.fd(random.randint(50, 630)) #lower wall on row 2
border.penup()
hole2 = border.fd(random.randint(30, 70)) #hole on row 2
border.pendown()
wall_två_två = border.goto(TURTLE_SIZE/2 - board.window_width()/2 + (930/8*b), + TURTLE_SIZE/2 - board.window_height()/2 ) # higher wall on row 2
n = n + 2
b = b + 2
border.goto(TURTLE_SIZE/2 - board.window_width()/2 , TURTLE_SIZE/2 - board.window_height()/2 )
border.goto(TURTLE_SIZE/2 - board.window_width()/2, board.window_height()/2 - TURTLE_SIZE/2)
border.penup()
border.lt(90)
border.fd(930/8)
border.pendown()
border.goto(-TURTLE_SIZE + board.window_width()/2, board.window_height()/2 - TURTLE_SIZE/2)
border.hideturtle()
player=turtle.Turtle()
player.color("green")
player.shape("turtle")
player.hideturtle()
player.penup()
player.goto(TURTLE_SIZE/2 - board.window_width()/2, board.window_height()/2 - TURTLE_SIZE/2)
player.rt(90)
player.fd(30)
player.lt(90)
player.fd((930/8)/2)
player.rt(90)
player.showturtle()
coordinates = player.pos()
#Skapa spelaren (som går igenom banan)
def spawna_spelare():
spawn = turtle.Turtle()
spawn.color("green")
spawn.shape("turtle")
spawn.hideturtle()
spawn.penup()
spawn.goto(TURTLE_SIZE/2 - board.window_width()/2, board.window_height()/2 - TURTLE_SIZE/2)
spawn.rt(90)
spawn.fd(30)
spawn.lt(90)
spawn.fd((930/8)*(random.randint(1,8)))
spawn.rt(90)
spawn.showturtle()
#Gå med spelaren
def move_left():
x = player.xcor()
x -= playerspeed
if x < -460:
x = -460
player.setx(x)
def move_right():
x = player.xcor()
x += playerspeed
if x > 450:
x = 450
player.setx(x)
if x.distance(wall_ett) >20: #or wall_ett_ett or wall_två_ett or wall_två_två) == 1: #
player.shape("triangle")
def move_down():
y = player.ycor()
y -= playerspeed
if y < -375:
y = -375
player.sety(y)
def move_up():
y = player.ycor()
y += playerspeed
if y > 380:
y = 380
player.sety(y)
turtle.listen()
turtle.onkey(spawna_spelare, "space")
turtle.onkey(move_left, "Left")
turtle.onkey(move_right, "Right")
turtle.onkey(move_down, "Down")
turtle.onkey(move_up, "Up")
wall_ett = border.xcor()
wall_två_ett=border.xcor()
print(wall_ett)
print(wall_ett)
print(hole)
board.mainloop()
So you need to draw the walls in a way you can check afterwards if the move the player requested is crossing any wall (or border).
here is a suggestion:
SCREEN_WIDTH = 800
HOLE_HEIGHT = 50
SCREEN_HEIGHT = 600
NUM_WALLS = 8
board = turtle.Screen()
board.setup(SCREEN_WIDTH+10, SCREEN_HEIGHT+10)
board.screensize(SCREEN_WIDTH, SCREEN_HEIGHT)
board.setworldcoordinates(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)
border = turtle.Turtle()
border.speed(10) # draw walls as fast as possible
border.color('white')
border.hideturtle()
# list of the drawn walls, each wall is represented by a tuple:
# (wall_x, wall_hole_lower_y, wall_hole_upper_y)
walls = []
for wall_ix in range(NUM_WALLS):
# compute coordinates of wall and store them
wall_x = int((1+wall_ix) * SCREEN_WIDTH / (1+NUM_WALLS))
wall_ybottom = random.randint(0, SCREEN_HEIGHT - HOLE_HEIGHT)
wall_ytop = wall_ybottom + HOLE_HEIGHT
walls.append((wall_x, wall_ytop, wall_ybottom))
# draw wall
border.penup()
border.goto(wall_x, 0)
border.pendown()
border.goto(wall_x, wall_ybottom)
border.penup()
border.goto(wall_x, wall_ytop)
border.pendown()
border.goto(wall_x, SCREEN_HEIGHT)
def move_right():
old_x = player.xcor()
new_x = old_x + playerspeed
y = player.ycor()
for wall_x, wall_ytop, wall_ybottom in walls:
if old_x <= wall_x <= new_x:
# player is possibly moving across the wall, check that y is valid
if wall_ybottom < y < wall_ytop:
# OK ! player moves through the hole
player.setx(new_x)
else:
# invalid, player is crossing a wall line
# resetting to old position, but you might want to stop the game
player.setx(old_x)

How to bind enter key to a function using turtle

I'm trying to make a tic tac toe game where you use arrow keys to move a turtle around the board, and when you press the enter key it draws a circle (nought in the code) or a cross.
I've tried using similar code to what I used for the movement keys but replace it for the enter key and C key (for cross) but they don't work and automatically draw the cross when it starts up. I've also tried using monkey but that doesn't work.
import turtle
sc = turtle.Screen()
bo = turtle.Turtle()
#screen
sc.bgcolor("black")
sc.title("tic tac toe")
#board
bo.color("white")
bo.penup()
bo.speed(0)
bo.setposition(-100, -300)
bo.pendown()
bo.setposition(-100, 300)
bo.penup()
bo.setposition(100, 300)
bo.pendown()
bo.setposition(100, -300)
bo.penup()
bo.setposition(-300, 100)
bo.pendown()
bo.setposition(300, 100)
bo.penup()
bo.setposition(300, -100)
bo.pendown()
bo.setposition(-300,-100)
bo.penup()
bo.setposition(0,0)
#naught and cross function
def c() :
bo.pendown()
x = bo.xcor()-80
y = bo.ycor()+80
bo.penup()
bo.setposition(x,y)
bo.pendown()
x = bo.xcor()+160
y = bo.ycor()-160
bo.setposition(x,y)
bo.penup()
x = bo.xcor()-160
bo.setposition(x,y)
bo.pendown()
x = bo.xcor()+160
y = bo.ycor()+160
bo.setposition(x,y)
bo.penup()
bo.setposition(0,0)
def n() :
y = bo.ycor()-80
x = bo.xcor()
bo.setposition(x, y)
bo.pendown()
bo.circle(80)
bo.penup()
bo.setposition(0,0)
#movment
def move_left(event):
x = bo.xcor()
x -= 200
if x < -300:
x = -200
bo.setx(x)
def move_right(event):
x = bo.xcor()
x += 200
if x > 300:
x = 200
bo.setx(x)
def move_down(event):
y = bo.ycor()
y -= 200
if y < -300:
y = -200
bo.sety(y)
def move_up(event):
y = bo.ycor()
y += 200
if y > 300:
y = 200
bo.sety(y)
#Keybinding
turtle.listen()
turtle.getcanvas().bind("<Left>", move_left)
turtle.getcanvas().bind("<Right>", move_right)
turtle.getcanvas().bind("<Up>", move_up)
turtle.getcanvas().bind("<Down>", move_down)
I'd eventually like to have it where once you draw a cross, and press enter, it draws a circle where there isn't a cross.
There's no need to drop down to the Tk Canvas to configure your key events:
turtle.getcanvas().bind("<Left>", move_left)
You can do the same from turtle itself:
sc.onkey(move_left, "Left")
I've reworked your code below, adding a key event for "Return" that draws the naughts and crosses. Since you don't have an underlying data structure for your game, I set it up to simply alternate between the two:
from turtle import Screen, Turtle
# naught and cross functions
def cross():
x, y = board.position()
board.penup()
board.setposition(x - 80, y - 80)
board.pendown()
board.setposition(x + 80, y + 80)
board.penup()
board.setx(x - 80)
board.pendown()
board.setposition(x + 80, y - 80)
board.penup()
board.home()
def naught():
board.sety(board.ycor() - 80)
board.pendown()
board.circle(80)
board.penup()
board.home()
first_player = True
def choose():
global first_player
if first_player:
naught()
else:
cross()
first_player = not first_player
# movement
def move_left():
x = board.xcor() - 200
if x < -300:
x = -200
board.setx(x)
def move_right():
x = board.xcor() + 200
if x > 300:
x = 200
board.setx(x)
def move_down():
y = board.ycor() - 200
if y < -300:
y = -200
board.sety(y)
def move_up():
y = board.ycor() + 200
if y > 300:
y = 200
board.sety(y)
# screen
screen = Screen()
screen.bgcolor("black")
screen.title("tic tac toe")
# board
board = Turtle()
board.color("white")
board.speed('fastest')
# vertical lines
board.penup()
board.setposition(-100, -300)
board.pendown()
board.sety(300)
board.penup()
board.setx(100)
board.pendown()
board.sety(-300)
board.penup()
# horizontal lines
board.setposition(-300, 100)
board.pendown()
board.setx(300)
board.penup()
board.sety(-100)
board.pendown()
board.setx(-300)
board.penup()
board.home()
# Keybinding
screen.onkey(move_left, "Left")
screen.onkey(move_right, "Right")
screen.onkey(move_up, "Up")
screen.onkey(move_down, "Down")
screen.onkey(choose, "Return")
screen.listen()
screen.mainloop()
This allows two people to play the game and should be something you can build upon.

When I make 2 turtles collide, Python freezes and crashes

import turtle
import os
import math
ms = turtle.Screen()
ms.bgcolor("grey")
ms.title("ok")
ground = turtle.Turtle()
ground.speed(0)
ground.color("black")
ground.penup()
ground.setposition(-500, -500)
ground.shape("square")
ground.shapesize(20, 200)
player = turtle.Turtle()
player.shape("square")
player.color("blue")
player.penup()
player.speed(0)
player.setposition(-450, -280)
playerspeed = 15
prop = turtle.Turtle()
prop.speed(0)
prop.shape("square")
prop.penup()
prop.color("red")
prop.setposition(-200, -50)
def move_left():
x = player.xcor()
x-= playerspeed
if x <-460:
x = - 460
player.setx(x)
def move_right():
x = player.xcor()
x+= playerspeed
if x >460:
x = 460
player.setx(x)
def move_down():
y = player.ycor()
y-= playerspeed
if y <-290:
y = - 290
player.sety(y)
def move_up():
y = player.ycor()
y+= playerspeed
if y >290:
y = 290
player.sety(y)
turtle.listen()
turtle.onkey(move_left, "Left")
turtle.onkey(move_right, "Right")
turtle.onkey(move_up, "Up")
turtle.onkey(move_down, "Down")
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor() - t2.xcor(), 2) + math.pow(t1.ycor() - t2.ycor(), 2))
if distance < 10:
return True
else:
return False
while True:
if isCollision(player, prop):
player.setposition(100, 100)
If I change the distance to > 10
it works but not as I want it to.
I want it to change the position of the player when prop and player are 10 pixels or less away from each other.
I've tried most things I know about, but I am still new to Python, or any programming language.
But I don't know what would cause it to freeze and crash -- any help is appreciated.
The primary issue I see with your code is while True: which shouldn't be used in an event-based environment. By creating a tight loop, you can keep events (key pressed, cursor movements, window closing) from being processed.
Below is a rework of your code using a timer event instead of while True:. I've also parameterized it as every turtle user sees a different size default window based on the dimensions of their screen. So you either need to use setup() to force a fixed size window or have your code adust to the window size. Now it adjusts to the window size. I've also made prop move to a random location upon collision, just to make the game more fun for me to play. And I've tossed your distance code in favor of turtle's own implementation:
from turtle import Screen, Turtle, mainloop
from random import randint
PLAYER_SPEED = 15
GROUND_HEIGHT = 100
PROXIMITY = 10
CURSOR_SIZE = 20
def move_left():
x = player.xcor() - PLAYER_SPEED
if x < CURSOR_SIZE - width/2:
x = CURSOR_SIZE - width/2
player.setx(x)
def move_right():
x = player.xcor() + PLAYER_SPEED
if x > width/2 - CURSOR_SIZE:
x = width/2 - CURSOR_SIZE
player.setx(x)
def move_down():
y = player.ycor() - PLAYER_SPEED
if y < CURSOR_SIZE/2 + GROUND_HEIGHT - height/2:
y = CURSOR_SIZE/2 + GROUND_HEIGHT - height/2
player.sety(y)
def move_up():
y = player.ycor() + PLAYER_SPEED
if y > height/2 - CURSOR_SIZE:
y = height/2 - CURSOR_SIZE
player.sety(y)
def isCollision(t1, t2):
return t1.distance(t2) < PROXIMITY
def random_position():
x = randint(CURSOR_SIZE - width//2, width//2 - CURSOR_SIZE)
y = randint(CURSOR_SIZE + GROUND_HEIGHT - height//2, height//2 - CURSOR_SIZE)
return x, y
def check():
if isCollision(player, prop):
prop.setposition(random_position())
ms.ontimer(check, 100)
ms = Screen()
ms.bgcolor('grey')
ms.title("ok")
width, height = ms.window_width(), ms.window_height()
ground = Turtle('square')
ground.shapesize(GROUND_HEIGHT / CURSOR_SIZE, width / CURSOR_SIZE)
ground.speed('fastest')
ground.penup()
ground.sety(GROUND_HEIGHT/2 - height/2)
player = Turtle('square')
player.speed('fastest')
player.color('blue')
player.penup()
player.setposition(CURSOR_SIZE/2 - width/2, GROUND_HEIGHT + CURSOR_SIZE/2 - height/2)
prop = Turtle('square')
prop.speed('fastest')
prop.color('red')
prop.penup()
prop.setposition(random_position())
ms.onkey(move_left, 'Left')
ms.onkey(move_right, 'Right')
ms.onkey(move_up, 'Up')
ms.onkey(move_down, 'Down')
ms.listen()
check()
mainloop()

Making snake in Python, can't get bodies to follow head etc

I wanted to make a snake game in turtle but I can't seem to get the tail segments to follow the leader. As if to say I can't get the first body part to follow the head, and then the second body part to follow the first body, etc.
I tried using what maths I have but I can't seem to get it to calculate where the head just was or where the body in front of it just was.
here is my code:
#libraries
import turtle
import random
import math
#screen
the_screen = turtle.Screen()
the_screen.bgcolor("lightgreen")
the_screen.title("Catapillar")
#border
border_writer = turtle.Turtle()
border_writer.speed(0)
border_writer.color("green")
border_writer.penup()
border_writer.setposition(-275, -275)
border_writer.pendown()
border_writer.pensize(7)
for side in range(4):
border_writer.fd(550)
border_writer.lt(90)
border_writer.hideturtle()
#player
player = turtle.Turtle()
player.color("yellow")
player.shape("circle")
player.penup()
player.speed(0)
player.setposition(0,0)
player.setheading(0)
playerspeed = 2
#fruit
fruit = 1
fruit = turtle.Turtle()
fruit.color("red")
fruit.shape("circle")
fruit.penup()
fruit.speed(0)
fruit.shapesize(0.6, 0.6)
x = random.randint(-200, 200)
y = random.randint(100, 250)
fruit.setposition(x, y)
#moving and collision checker
def turnleft():
player.left(24.5)
def turnright():
player.right(24.5)
def increasespeed():
global playerspeed
playerspeed += 1
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(), 2) + math.pow(t1.ycor()-t2.ycor(), 2))
if distance < 24:
return True
else:
return False
#making the tail(s) and hiding them
tail1 = turtle.Turtle()
tail1.hideturtle()
tail1.color("yellow")
tail1.shape("circle")
tail1.penup()
tail1.speed(0)
tail1.setposition(+700,700)
tail1.shapesize(0.6, 0.6)
tail1state = 'off'
#key presses
turtle.listen()
turtle.onkeypress(turnleft, "Left")
turtle.onkeypress(turnright, "Right")
turtle.onkeypress(increasespeed, "Up")
#main loop player always moves forward, out of bound set, reset fruit
#randomly when collided, create tail1...
while True:
player.forward(playerspeed)
#gameovers'
if (player.xcor() > 275) or (player.xcor() < -275):
playerspeed += 7
print("GAME OVER")
if (player.ycor() > 275) or (player.ycor() < -275):
playerspeed += 7
print("GAME OVER")
#collision check between fruit and head
if isCollision(player, fruit):
#resets the fruit, moves it randomly
fruit.hideturtle()
if tail1state == 'off':
uuu = player.xcor()
vvv = player.ycor()
tail1.setposition(uuu,vvv)
tail1.showturtle()
tail1state = 'on'
#reset the fruit
x = random.randint(-200, 200)
y = random.randint(-100, 250)
fruit.setposition(x, y)
fruit.showturtle()
#playerspeed +=1
If you have any idea on how you think I should approach it, please let me know what you think.
Thank you.
Since this comes up over and over (but effort to effect it is rarely shown) here's my minimal, generic, slithering around a screen effect that you should be able to adapt for your own purposes:
from turtle import Turtle, Screen
SNAKE_LENGTH = 10
SNAKE_SIZE = 15
WIDTH, HEIGHT = 375, 375
CURSOR_SIZE = 20
def slither():
segment = snake[-1].clone() if len(snake) < SNAKE_LENGTH else snake.pop(0)
screen.tracer(False) # segment.hideturtle()
segment.setposition(snake[-1].position())
segment.setheading(snake[-1].heading())
segment.forward(SNAKE_SIZE)
while not -WIDTH/2 < segment.xcor() < WIDTH/2 or not -HEIGHT/2 < segment.ycor() < HEIGHT/2:
segment.undo()
segment.right(95)
segment.forward(SNAKE_SIZE)
screen.tracer(True) # segment.showturtle()
snake.append(segment)
screen.ontimer(slither, 100)
boundary = Turtle(shape='square', visible=False)
boundary.shapesize(HEIGHT / CURSOR_SIZE, WIDTH / CURSOR_SIZE)
boundary.fillcolor("white")
boundary.stamp()
head = Turtle("circle")
head.shapesize(SNAKE_SIZE / CURSOR_SIZE)
head.penup()
snake = [head]
screen = Screen()
slither()
screen.exitonclick()

Categories