Pong Created in Python Turtle

2024/10/5 15:11:10

I'm new to Python but I've coded in other languages, mainly for hardware. I made pong in Python using turtle but it's a little glitchy. I was wondering if any of you could check it out and give advice. I also want to add a start screen and end screen but am a little unsure how to. Also if you have any advice on how to improve collision detection, please let me know.

I'm pasting code below


import os
import math
import random
import time#set up screen
screen = turtle.Screen()
screen.bgcolor("green")
screen.title("Pong")# set up 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.pensize(3)
for side in range(4):border_pen.fd(600)border_pen.lt(90)
border_pen.hideturtle()#set score to 0
score = 0#set time to zero
time = 0
seconds = 0#Draw score
score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 310)
scorestring = "Score %s" %score
score_pen.write(scorestring, False, align="left", font=     ("Arial", 14, "normal"))
score_pen.hideturtle()#Draw timer
time_pen = turtle.Turtle()
time_pen.speed(0)
time_pen.color("white")
time_pen.penup()
time_pen.setposition(260, 310)
timestring = "Time %s" %time
time_pen.write(timestring, False, align="left", font= ("Arial", 14, "normal"))
time_pen.hideturtle()#create the player turtle
player = turtle.Turtle()
player.color("blue")
player.shape("square")
player.shapesize(0.5, 4)
player.penup()
player.speed(0)
player.setposition(-280,-250)#(x,y)
player.setheading(90)
playerspeed = 15#create the AIplayer turtle
AIplayer = turtle.Turtle()
AIplayer.color("black")
AIplayer.shape("square")
AIplayer.shapesize(0.5, 4)
AIplayer.penup()
AIplayer.speed(0)
AIplayer.setposition(280,250)#(x,y)
AIplayer.setheading(90)
AIplayerspeed = 15#create the pong
pong = turtle.Turtle()
pong.color("red")
pong.shape("circle")
pong.shapesize(0.5, 0.5)
pong.penup()
pong.speed(10)
pong.setposition(0,0)#(x,y)
pongspeed = 15
pong.goto(0, 265)
pong.dy = -5
pong.dx = 5#Move player up and down
def move_up():y = player.ycor()y += playerspeedif y > 265:y = 260player.sety(y)def move_down():y = player.ycor()y -= playerspeedif y < -265:y = -260player.sety(y)#keyboard bindings
turtle.listen()
turtle.onkey(move_up, "Up")
turtle.onkey(move_down, "Down")
#turtle.onkey(fire_bullet, "space")def isCollision(t1, t2):distance = math.sqrt(math.pow(t1.xcor()-    t2.xcor(),2)+math.pow(t1.ycor()-t2.ycor(),2))if distance < 20:return Trueelse:return False#main game loop
while True:#move pong ballpong.sety(pong.ycor() +pong.dy)pong.setx(pong.xcor() +pong.dx)#check for bounce and redirect itif pong.ycor() < -300:pong.dy *= -1if pong.ycor() > 300:pong.dy *= -1if pong.xcor() < -300:pong.dx *= -1print("Game Over")exit()if pong.xcor() > 300:pong.dx *= -1#move AI paddle (might speed up pong movement)y = pong.ycor()y += AIplayerspeedAIplayer.sety(y)if AIplayer.ycor() > 265:AIplayerspeed *= -1       if AIplayer.ycor() < -250:AIplayerspeed *= -1#collision pong and playerif isCollision(pong, player):pong.dy *= -1pong.dx *= -1#Update the scorescore += 10scorestring = "Score: %s" %scorescore_pen.clear()score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))#collision pong and AIplayerif isCollision(pong, AIplayer):pong.dy *= -1pong.dx *= -1#updates timer and increases ball speedif seconds > 29:pong.dy *= -2pong.dx *= -2if seconds > 59:pong.dy *= -3pong.dx *= -3#displays timer but makes game laggy
#    seconds += 0.1
#    time = seconds
#    timestring = "Time: %s" %time
#    time_pen.clear()
#    time_pen.write(timestring, False, align="Left", font=("Arial", 14, "normal"))
Answer

Some issues I see:

  • You've stretched a 20 by 20 square to be 10 by 80:

    AIplayer.shapesize(0.5, 4)
    

    But your collision distance is only 20 from center, so your ball can cross over the bottom or top of the paddle without actually colliding.

  • Your isCollision() function is mostly redundant with turtle's own .distance() method.

  • You shouldn't have while True: in an event-driven world like turtle as it potentially prevents some events from firing. Better to replace it with a timer event.

  • Some of your collisions change both x and y deltas when they should only change one of them.

  • You should avoid redundant queries of the turtle in your main loop as well as checking conditions that are negated by other logic clauses. I.e. do as little as you can get away with in the main loop.

Below is my rework of your game along the above lines, plus lots of other style and logic changes:

from turtle import Turtle, ScreenFONT = ("Arial", 16, "normal")def isCollision(t1, t2):return t1.distance(t2) < 15# set up screen
screen = Screen()
screen.bgcolor("darkgreen")
screen.title("Pong")# set up border
border_pen = Turtle(visible=False)
border_pen.speed('fastest')
border_pen.color('white')
border_pen.pensize(3)border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()for _ in range(4):border_pen.forward(600)border_pen.left(90)# set score to 0
score = 0# set time to zero
seconds = 0# Draw score
score_pen = Turtle(visible=False)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 310)score_pen.write("Score {}".format(score), False, align="left", font=FONT)# Draw timer
time_pen = Turtle(visible=False)
time_pen.color("white")
time_pen.penup()
time_pen.setposition(260, 310)time_pen.write("Time {}".format(int(seconds)), False, align="left", font=FONT)# create the player turtle
player = Turtle("square", visible=False)
player.shapesize(0.5, 3)
player.speed('fastest')
player.setheading(90)
player.color("blue")
player.penup()player.setposition(-280, -250)  # (x,y)
player.showturtle()playerspeed = 15# create the AIplayer turtle
AIplayer = Turtle("square", visible=False)
AIplayer.shapesize(0.5, 3)
AIplayer.speed('fastest')
AIplayer.setheading(90)
AIplayer.color("black")
AIplayer.penup()AIplayer.setposition(280, 250)  # (x,y)
AIplayer.showturtle()AIplayerspeed = 15# create the pong
pong = Turtle("circle", visible=False)
pong.shapesize(0.5, 0.5)
pong.speed('fast')
pong.color("red")
pong.penup()pong.sety(265)
pong.showturtle()pongspeed = 15
pong_dx, pong_dy = 5, -5# Move player up and down
def move_up():player.forward(playerspeed)y = player.ycor()if y > 265:y = 260player.sety(y)screen.update()def move_down():player.backward(playerspeed)y = player.ycor()if y < -265:y = -260player.sety(y)screen.update()# keyboard bindings
screen.onkey(move_up, "Up")
screen.onkey(move_down, "Down")screen.listen()# main game loop
def move():global pong_dx, pong_dy, AIplayerspeed, seconds, score# move pong ballx, y = pong.position()x += pong_dxy += pong_dypong.setposition(x, y)if isCollision(pong, player): # collision pong and playerpong_dx *= -1# Update the scorescore += 10score_pen.undo()score_pen.write("Score: {}".format(score), align="left", font=FONT)elif isCollision(pong, AIplayer):  # collision pong and AIplayerpong_dx *= -1elif y < -300 or y > 300:  # check for bounce and redirect itpong_dy *= -1elif x > 300:pong_dx *= -1elif x < -300:print("Game Over")screen.bye()return# move AI paddle (might speed up pong movement)AIplayer.forward(AIplayerspeed)y = AIplayer.ycor()if y < -250 or y > 250:AIplayerspeed *= -1# display timerseconds += 0.05time_pen.undo()time_pen.write("Time: {}".format(int(seconds)), False, align="Left", font=FONT)screen.ontimer(move, 50)screen.update()screen.tracer(False)
move()
screen.mainloop()

I couldn't make sense of your "increases ball speed" logic so I left it out. I used a darker background color as the original was difficult to look at on my screen.

https://en.xdnf.cn/q/119918.html

Related Q&A

How to build a Neural Network with sentence embeding concatenated to pre-trained CNN

I want to build a neural network that will take the feature map from the last layer of a CNN (VGG or resnet for example), concatenate an additional vector (for example , 1X768 bert vector) , and re-tra…

Obtaining values from columns in python

I want to obtain the top 3 cities and items based on their sales, but the only thing I can do now is return the all cities and items with their respective sales. Without using dict, can I obtain my des…

Is there a really efficient (FAST) way to read large text files in python?

I am looking to open and fetch data from a large text file in python as fast as possible (It almost has 62603143 lines - size 550MB). As I dont want to stress my computer, I am doing it by following wa…

How to extract all K*K submatrix of matrix with or without NumPy?

This is my input: row=6 col=9 6 9 s b k g s y w g f r g y e q j j a s s m s a s z s l e u s q u e h s s s g s f h s s e s g x d r h g y s s sThis is my code: r=int(input()) c=int(input()) n=min(r,c) k=…

How to scrape multiple result having same tags and class

My code is accurate for single page but when I run this code for multiple records using for loop and if there are some data missing like person then (as I used index no[1] and [2] for person variable ,…

Is there an alternative for sys.exit() in python?

try:x="blaabla"y="nnlfa" if x!=y:sys.exit()else:print("Error!") except Exception:print(Exception)Im not asking about why it is throwing an error. I know that it raises e…

Adding items to Listbox in Python Tkinter

I would like my Listbox widget to be updated upon clicking of a button. However I encountered a logic error. When I click on the button, nothing happens. No errors at all.listOfCompanies: [[1, ], [2, -…

Policy based design in Python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 9 years ago.Improve…

Exception raised: cannot import name manual_seed from torch

im trying to run the AutoClean project on my device (heres my code): import random from AutoClean import AutoClean import pandas as pddef __init__(self, pipeline, resultat ):self.pipeline = pipelinesel…

Compile a C/C++ Program and store standard output in a File via Python

Lets say I have a C/C++ file named userfile.c. Using Python, how can I invoke the local gcc compiler so that the file is compiled and an executable is made? More specifically, I would like to provide …