Skip to content

Instantly share code, notes, and snippets.

@arpruss
Created March 15, 2020 16:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arpruss/b1cf4fa767d25cb1466a2415fa2067f7 to your computer and use it in GitHub Desktop.
Save arpruss/b1cf4fa767d25cb1466a2415fa2067f7 to your computer and use it in GitHub Desktop.
pong
#
# http://programarcadegames.com/python_examples/show_file.php?file=pong.py
#
import math
import pygame
import random
from ctypes import windll, Structure, c_long, byref
user32 = windll.user32
screensize = user32.GetSystemMetrics(78), user32.GetSystemMetrics(79)
class POINT(Structure):
_fields_ = [("x", c_long), ("y", c_long)]
def queryMousePosition():
pt = POINT()
windll.user32.GetCursorPos(byref(pt))
return (pt.x, pt.y)
# Define some colors
BLACK = (0 ,0, 0)
WHITE = (255, 255, 255)
class MousePositioner(object):
def __init__(self, index):
self.index = index
def getPosition(self, prev):
#return pygame.mouse.get_pos()[self.index] # / float(pygame.display.get_surface().get_size()[self.index])
return queryMousePosition()[self.index]*float(pygame.display.get_surface().get_size()[0])/screensize[self.index]
class JoystickPositioner(object):
def __init__(self, joystick, axis=0):
self.axis = axis
self.joystick = joystick
joystick.init()
def getPosition(self, prev):
return prev + 15/800. * self.joystick.get_axis(self.axis) * float(pygame.display.get_surface().get_size()[self.axis])
# This class represents the ball
# It derives from the "Sprite" class in Pygame
class Ball(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self):
# Call the parent class (Sprite) constructor
super().__init__()
# Create the image of the ball
self.image = pygame.Surface([10, 10])
# Color the ball
self.image.fill(WHITE)
# Get a rectangle object that shows where our image is
self.rect = self.image.get_rect()
# Get attributes for the height/width of the screen
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()
# Speed in pixels per cycle
self.speed = 0
# Floating point representation of where the ball is
self.x = 0
self.y = 0
# Direction of ball in degrees
self.direction = 0
# Height and width of the ball
self.width = 10
self.height = 10
# Set the initial ball speed and position
self.reset()
def reset(self):
self.x = random.randrange(50,750)
self.y = 350.0
self.speed=8.0
# Direction of ball (in degrees)
self.direction = random.randrange(-45,45)
# Flip a 'coin'
if random.randrange(2) == 0 :
# Reverse ball direction, let the other guy get it first
self.direction += 180
self.y = 50
# This function will bounce the ball off a horizontal surface (not a vertical one)
def bounce(self,diff):
self.direction = (180-self.direction)%360
self.direction -= diff
# Speed the ball up
self.speed *= 1.1
# Update the position of the ball
def update(self):
# Sine and Cosine work in degrees, so we have to convert them
direction_radians = math.radians(self.direction)
# Change the position (x and y) according to the speed and direction
self.x += self.speed * math.sin(direction_radians)
self.y -= self.speed * math.cos(direction_radians)
if self.y < 0:
self.reset()
if self.y > 600:
self.reset()
# Move the image to where our x and y are
self.rect.x = self.x
self.rect.y = self.y
# Do we bounce off the left of the screen?
if self.x <= 0:
self.direction = (360-self.direction)%360
print(self.direction)
#self.x=1
# Do we bounce of the right side of the screen?
if self.x > self.screenwidth-self.width:
self.direction = (360-self.direction)%360
# This class represents the bar at the bottom that the player controls
class Player(pygame.sprite.Sprite):
# Constructor function
def __init__(self, joystick, y_pos):
# Call the parent's constructor
super().__init__()
self.width=75
self.height=15
self.image = pygame.Surface([self.width, self.height])
self.image.fill(WHITE)
self.joystick = joystick
# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()
self.rect.x = 0
self.rect.y = y_pos
# Update the player
def update(self):
# This gets the position of the axis on the game controller
# It returns a number between -1.0 and +1.0
self.rect.x = int(self.joystick.getPosition(self.rect.x))
# Make sure we don't push the player paddle off the right side of the screen
if self.rect.x > self.screenwidth - self.width:
self.rect.x = self.screenwidth - self.width
elif self.rect.x < 0:
self.rect.x = 0
score1 = 0
score2 = 0
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])
# Set the title of the window
pygame.display.set_caption('Pong')
# Enable this to make the mouse disappear when over our window
pygame.mouse.set_visible(0)
# This is a font we use to draw text on the screen (size 36)
font = pygame.font.Font(None, 36)
# Create a surface we can draw on
background = pygame.Surface(screen.get_size())
# Create the ball
ball = Ball()
# Create a group of 1 ball (used in checking collisions)
balls = pygame.sprite.Group()
balls.add(ball)
# Count the joysticks the computer has
joystick_count = pygame.joystick.get_count()
if joystick_count < 1:
joystick1 = MousePositioner(0)
joystick2 = MousePositioner(1)
else:
joystick1 = JoystickPositioner(pygame.joystick.Joystick(0))
joystick2 = JoystickPositioner(pygame.joystick.Joystick(1))
# Create the player paddle object
player1 = Player(joystick1,580)
player2 = Player(joystick2,25)
movingsprites = pygame.sprite.Group()
movingsprites.add(player1)
movingsprites.add(player2)
movingsprites.add(ball)
clock = pygame.time.Clock()
done = False
exit_program = False
while not exit_program:
# Clear the screen
screen.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_program = True
# Stop the game if there is an imbalance of 3 points
if abs(score1 - score2) > 3:
done = True
if not done:
# Update the player and ball positions
player1.update()
player2.update()
ball.update()
# If we are done, print game over
if done:
text = font.render("Game Over", 1, (200, 200, 200))
textpos = text.get_rect(centerx=background.get_width()/2)
textpos.top = 50
screen.blit(text, textpos)
# See if the ball hits the player paddle
if pygame.sprite.spritecollide(player1, balls, False):
# The 'diff' lets you try to bounce the ball left or right depending where on the paddle you hit it
diff = (player1.rect.x + player1.width/2) - (ball.rect.x+ball.width/2)
# Set the ball's y position in case we hit the ball on the edge of the paddle
ball.y = 570
ball.bounce(diff)
score1 += 1
# See if the ball hits the player paddle
if pygame.sprite.spritecollide(player2, balls, False):
# The 'diff' lets you try to bounce the ball left or right depending where on the paddle you hit it
diff = (player2.rect.x + player2.width/2) - (ball.rect.x+ball.width/2)
# Set the ball's y position in case we hit the ball on the edge of the paddle
ball.y = 40
ball.bounce(diff)
score2 += 1
# Print the score
scoreprint = "Player 1: "+str(score1)
text = font.render(scoreprint, 1, WHITE)
textpos = (0, 0)
screen.blit(text, textpos)
scoreprint = "Player 2: "+str(score2)
text = font.render(scoreprint, 1, WHITE)
textpos = (300, 0)
screen.blit(text, textpos)
# Draw Everything
movingsprites.draw(screen)
# Update the screen
pygame.display.flip()
clock.tick(30)
pygame.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment