Jump to content

? servers

? players online

Creating Pong with Python

Recommended Posts


  • Content Count:  788
  • Joined:  03/13/16
  • Status:  Offline

Hey all,

 

I know I'm not all too active anymore but I could really use some help here.

 

I'm trying to create a Pong program using the Python (turtle) scripting program.

 

In the spoiler is my program

 

 

 

from turtle import *

from random import *

 

tracer(False)

Screen().setup(500, 500)

colormode(255)

bgcolor("white")

 

# The Ball ***********************************************

 

class ball(Turtle):

def __init__(self):

penup()

shape("circle")

self.x = self.y = 0

self.dx = randint(1, 3)/30

self.dy = randint(-3, -1)/30

self.alive = True

update()

def glide(self):

self.x += self.dx

self.y += self.dy

goto(self.x, self.y)

update()

def ifOnEdgeBounce(self):

if self.x > 235:

if player1.ycor() - 5

self.dx = -self.dx

else:

self.alive = False

if self.x

if player2.ycor() - 5

self.dx = -self.dx

else:

self.alive = False

endgame("Game Over!")

elif self.y > 175 or self.y

self.dy = -self.dy

 

ball = ball()

 

# Paddles ***************************************************

 

Screen().register_shape("paddle.gif")

 

player1 = Turtle()

player1.shape("paddle.gif")

player1.penup()

player1.setx(230)

 

def up1():

player1.sety(player1.ycor() + 15)

def down1():

player1.sety(player1.ycor() - 15)

 

player2 = Turtle()

player2.shape("paddle.gif")

player2.penup()

player2.setx(-230)

 

def up2():

player2.sety(player2.ycor() + 15)

def down2():

player2.sety(player2.ycor() - 15)

 

# THE GAME LOOP **********************************************

 

while ball.alive == True:

ball.glide()

ball.ifOnEdgeBounce()

onkey(up1, "Up")

onkey(down1, "Down")

onkey(up2, "w")

onkey(down2, "s")

def move():

global score1, score2

 

ball.forward(ballspeed)

 

x, y = ball.position()

 

if y > court_height/2 - cursor_size or y

ball.setheading(-ball.heading())

else:

distance(player1, ball)

distance(player2, ball)

 

screen.ontimer(move, 20)

listen()

 

 

Screen().exitonclick()

 

 

 

I'm having an issue on trying to get the ball and the paddles to collide and to have a border for the paddles to stay in since they can keep moving off the screen to the end of the world.

 

If anyone can help, it would be appreciated greatly! The assignment is due this Sunday (4/22) at midnight.

Link to comment

  • Content Count:  331
  • Joined:  01/08/13
  • Status:  Offline

First of all: Is this the same formatting you have in your file? Indentation is important in Python, as it decides whether certain portions of code are part of a if / then / for loop or not, although I don't think it'll be a problem in this case.

 

Have you tried anything so far with collision that didn't work out?

Link to comment

  • Content Count:  9
  • Joined:  05/17/18
  • Status:  Offline

Necroing this thread since it's one of the only actual programming threa

I'll start with a little advice before getting into the code. I'm not sure I would start with turtle for a pong game. Perhaps as a pong animation, but controls and collision are going to be expensive and not very practical.

 

If you're interested in applying coding to games, I recommend taking a look at pygame(probably one of the largest python game libraries).

If you cannot (this looks like a school project to me) use external libraries take a look at tkinter, python's defacto GUI package (turtle is actually built with tkinter).

 

>And to have a border for the paddles to stay in since they can keep moving off the screen to the end of the world.

To bind the paddles to the box check for the position of player1 and player2's bounding box with player1.rect and check against the screen's rectangle by calling get_rect. Then you can setup some logic to check for the paddle's location against the bounding area and change the dx/dy velocity.

 

I would probably wrap the player in a class, but this'll do.

def checkBoundingRects(player, screen):
   if player.right > screen.right or player.left         or player.bottom > screen.bottom or player.top         return False
   return True

 

>trying to get the ball and the paddles to collide

 

If we're clever we may be able to fix this issue by modifying the code above. For the first question (bounding box) we're checking "are we inside this box", this next question is also "are we inside the box". The function above can be refactored and applied to this question as well.

def checkCollision(actor, bounding):
   if actor.right > bounding.right or actor.left         or actor.bottom > bounding.bottom or actor.top         return False
   return True

 

Now we can call the function for checking the bounding area:

touching = checkCollision(player1, screen.get_rect())

If touching is true we know the player is touching the bounding box OR outside of it already.

 

collision = not checkCollision(ball, player1)

*We would also need to do this with player2 and possibly the bounding rectangle.

If collision is set, we know the ball is either inside the paddle, or at least touching it.

 

The signs in my logic may be a little flawed here as I wrote some quick unit tests to help me visualize it, but didn't boot up tkinter. Hope you did well on this project!

Link to comment

  • Content Count:  2095
  • Joined:  07/05/08
  • Status:  Offline

First of all: Is this the same formatting you have in your file? Indentation is important in Python, as it decides whether certain portions of code are part of a if / then / for loop or not, although I don't think it'll be a problem in this case.

 

Have you tried anything so far with collision that didn't work out?

 

Python is a whitespace language. Indentation denotes blocks of code, not just conditional statements; it's integral for functions and blocks of code. Look at a language like C# which uses { & }, that's essentially what whitespace replaces in Python.

 

Necroing this thread since it's one of the only actual programming threa

I'll start with a little advice before getting into the code. I'm not sure I would start with turtle for a pong game. Perhaps as a pong animation, but controls and collision are going to be expensive and not very practical.

 

If you're interested in applying coding to games, I recommend taking a look at pygame(probably one of the largest python game libraries).

If you cannot (this looks like a school project to me) use external libraries take a look at tkinter, python's defacto GUI package (turtle is actually built with tkinter).

 

Turtle isn't really an issue, you can use whatever framework you want. In fact, pygame is probably a bit overkill when it's just a pong game and you just need bareback animation for paddles and a ball, which honestly is usually done in ASCII for beginners.

 

Instead of having complex and convoluted conditional statements, I'd recommend a completely different approach starting with a redefinition of how the game is built.

 

Firstly, define the game arena. From this you'll have the width/height whose values are referenced to ensure the paddles don't exceed the height of the game.

 

Secondly, define a class for the paddles and just instantiate the class for both players. If the ball ever touches a paddle, reverse direction- bonus points for capturing what height of the paddle the ball contacted and use this value to calculate the angle and trajectory of the ball.

 

Loop the game, if the ball exceeds the width of the game which you defined previously trigger the end of the game, using the width to define where the ball exceeded to pick a winner.

Link to comment

  • Content Count:  9
  • Joined:  05/17/18
  • Status:  Offline

In fact, pygame is probably a bit overkill when it's just a pong game and you just need bareback animation for paddles and a ball, which honestly is usually done in ASCII for beginners.

 

I agree that pygame is a bit overkill, but there are built in functions and quite a bit more tutorials on simple games -- turtle is mainly used for graphics, but the OP says it's a school project so I don't think they can use anything else. I think ASCII pong would be much more of a challenge, especially for a beginner.

 

Instead of having complex and convoluted conditional statements, I'd recommend a completely different approach starting with a redefinition of how the game is built.

 

Firstly, define the game arena. From this you'll have the width/height whose values are referenced to ensure the paddles don't exceed the height of the game.

 

The play area is defined with

Screen().setup(500, 500)

and the size can be retrieved with

turtle.screensize()

.

 

Secondly, define a class for the paddles and just instantiate the class for both players. If the ball ever touches a paddle, reverse direction...

 

I agree that a player class is a good idea, and getting the procedural logic out of the main loop is a good idea, but you're not going to be able to change the complex conditional statements.

Link to comment

  • Content Count:  2095
  • Joined:  07/05/08
  • Status:  Offline

I agree that pygame is a bit overkill, but there are built in functions and quite a bit more tutorials on simple games -- turtle is mainly used for graphics, but the OP says it's a school project so I don't think they can use anything else. I think ASCII pong would be much more of a challenge, especially for a beginner.

 

The play area is defined with Screen().setup(500, 500) and the size can be retrieved with turtle.screensize().

 

I agree that a player class is a good idea, and getting the procedural logic out of the main loop is a good idea, but you're not going to be able to change the complex conditional statements.

 

Don't do

Screen().setup(500, 500)

 

Assign the values to variables.

WINDOWWIDTH = 500

WINDOWHEIGHT = 500

 

When you call turtle.screensize() you're going to receive (500, 500), which you need to split/index/do whatever to retrieve the height/width and assign to variables anyways. So just skip the steps and assign it to variables. If you could resize the window, then you'd want to dynamically accept the values to assign to the variables- but it's just hardcoding here. (The ability to resize the window would heavily affect how you design this too.)

 

 

As for the complex conditionals;

def checkCollision(actor, bounding):
   if actor.right > bounding.right or actor.left         or actor.bottom > bounding.bottom or actor.top         return False
   return True

 

Is unnecessarily complex and requires additional steps, do:

def checkCollision(ball, ballDirX, ballDirY):
   if ball.top == (LINETHICKNESS) or ball.bottom == (WINDOWHEIGHT - LINETHICKNESS):
       ballDirY = ballDirY * -1
   if ball.left == (LINETHICKNESS) or ball.right == (WINDOWWIDTH - LINETHICKNESS):
       ballDirX = ballDirX * -1
   return ballDirX, ballDirY

(LINETHICKNESS is the paddles physical size)

This is a hundred times more efficient and reverses the ball trajectory if it's impacted. All you did was check if it touched in a hundred different ways without interacting with it.

 

You can also see if the paddles exceed top/bottom by:

if paddle.bottom > WINDOWHEIGHT - LINETHICKNESS

 

Which is another reason why you should have just made the height a variable instead of having 10 different steps for assigning it, getting it, splitting it, ext.

Link to comment

Reply to Thread

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...