Skip to content

Instantly share code, notes, and snippets.

@ramytamer
Created December 7, 2016 04:31
Show Gist options
  • Select an option

  • Save ramytamer/f7f374fa8efe464f244e2dcfed49952d to your computer and use it in GitHub Desktop.

Select an option

Save ramytamer/f7f374fa8efe464f244e2dcfed49952d to your computer and use it in GitHub Desktop.
OpenGL Pong
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import sys, math
GAME_OBJECT = { 'width': 500, 'height': 200, 'delay': 1, 'started': False }
SCORE = { 'left': 0, 'right': 0 }
RACKET = { 'width': 10, 'height': 80, 'speed': 5 }
RACKET_POS = { 'left': [10.0, 50.0], 'right': [GAME_OBJECT['width'] - RACKET['width'] - 10, 50.0] }
BALL = { 'position': [ GAME_OBJECT['width'] / 2, GAME_OBJECT['height'] / 2 ], 'direction': [ -1.0, 0.0 ], 'size': 8, 'speed': 2 }
KEYBOARD = { 100: 'left' , 101: 'up' , 102: 'right' , 103: 'down', 'a': 'left', 'w': 'up', 'd': 'right', 's': 'down', ' ': 'space' }
def update_ball():
if GAME_OBJECT['started'] == False:
return
BALL['position'][0] += BALL['direction'][0] * BALL['speed']
BALL['position'][1] += BALL['direction'][1] * BALL['speed']
# collision with left racket
if (BALL['position'][0] < RACKET_POS['left'][0] + RACKET['width'] and
BALL['position'][0] > RACKET_POS['left'][0] and
BALL['position'][1] < RACKET_POS['left'][1] + RACKET['height'] and
BALL['position'][1] > RACKET_POS['left'][1]):
# set fly direction depending on where it hit the racket
# (t is 0.5 if hit at top, 0 at center, -0.5 at bottom)
t = ((BALL['position'][1] - RACKET_POS['left'][1]) / RACKET['height']) - 0.5
BALL['direction'][0] = math.fabs(BALL['direction'][0]) # force it to be positive
BALL['direction'][1] = t
# collision with right racket
if (BALL['position'][0] > RACKET_POS['right'][0] - RACKET['width'] and
BALL['position'][0] < RACKET_POS['right'][0] + RACKET['width'] and
BALL['position'][1] < RACKET_POS['right'][1] + RACKET['height'] and
BALL['position'][1] > RACKET_POS['right'][1]):
# set fly direction depending on where it hit the racket
# (t is 0.5 if hit at top, 0 at center, -0.5 at bottom)
t = ((BALL['position'][1] - RACKET_POS['right'][1]) / RACKET['height']) - 0.5
BALL['direction'][0] = -math.fabs(BALL['direction'][0]) # force it to be positive
BALL['direction'][1] = t
# hit left wall
if (BALL['position'][0] < 0):
SCORE['right'] += 1
BALL['position'][0] = GAME_OBJECT['width'] / 2
BALL['position'][1] = GAME_OBJECT['height'] / 2
BALL['direction'][0] = math.fabs(BALL['direction'][0]) # force it to be negative
BALL['direction'][1] = 0
# hit right wall
if (BALL['position'][0] > GAME_OBJECT['width']):
SCORE['left'] += 1
BALL['position'][0] = GAME_OBJECT['width'] / 2
BALL['position'][1] = GAME_OBJECT['height'] / 2
BALL['direction'][0] = -math.fabs(BALL['direction'][0]) # force it to be negative
BALL['direction'][1] = 0
# hit top wall?
if (BALL['position'][1] > GAME_OBJECT['height'] - 10):
BALL['direction'][1] = -math.fabs(BALL['direction'][1]) # force it to be negative
# hit bottom wall?
if (BALL['position'][1] < 0):
BALL['direction'][1] = math.fabs(BALL['direction'][1]) # force it to be positive
length = math.sqrt((BALL['direction'][0] * BALL['direction'][0]) + (BALL['direction'][1] * BALL['direction'][1]));
if (length != 0.0):
length = 1.0 / length;
BALL['direction'][0] *= length;
BALL['direction'][1] *= length;
def update(value):
update_ball()
glutPostRedisplay()
glutTimerFunc(GAME_OBJECT['delay'], update, 0)
def drawRect(x, y, width, height, color=(1.0, 1.0, 1.0)):
glColor3f(color[0], color[1], color[2])
glBegin(GL_QUADS)
glVertex2f(x, y)
glVertex2f(x + width, y)
glVertex2f(x + width, y + height)
glVertex2f(x, y + height)
glEnd()
def drawText(x, y, txt, width=GAME_OBJECT['width'], height=GAME_OBJECT['height'], color=(1, 1, 1)):
glColor3f(color[0], color[1], color[2])
glMatrixMode(GL_PROJECTION)
matrix = glGetDouble( GL_PROJECTION_MATRIX )
glLoadIdentity()
glOrtho(0.0, width, 0.0, height, -1.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glRasterPos2i(x, y)
for character in txt:
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord(character))
glPopMatrix()
glMatrixMode(GL_PROJECTION)
glLoadMatrixd( matrix )
glMatrixMode(GL_MODELVIEW)
def draw():
glClear(GL_COLOR_BUFFER_BIT)
# Draw our scene
# Draw score
score_str = "%d:%d" % (SCORE['left'], SCORE['right'])
drawText(GAME_OBJECT['width']/2-10, GAME_OBJECT['height']-15, score_str, color=(0, 1, 0))
# Draw rackets
drawRect(RACKET_POS['left'][0], RACKET_POS['left'][1], RACKET['width'], RACKET['height'], (1, 0, 0))
drawRect(RACKET_POS['right'][0], RACKET_POS['right'][1], RACKET['width'], RACKET['height'], (0, 0, 1))
# Draw circle
drawRect(BALL['position'][0], BALL['position'][1], BALL['size'], BALL['size'])
glutSwapBuffers()
def handle_arrow_keys(key, x, y):
if KEYBOARD[key] == 'up':
RACKET_POS['right'][1] += RACKET['speed']
elif KEYBOARD[key] == 'down':
RACKET_POS['right'][1] -= RACKET['speed']
elif KEYBOARD[key] == 'right':
RACKET_POS['right'][0] += RACKET['speed']
elif KEYBOARD[key] == 'left':
RACKET_POS['right'][0] -= RACKET['speed']
def handle_char_keys(key, x, y):
if ord(key) == 27: # in case of escape (27 is ESC keycode)
sys.exit(0)
if KEYBOARD[key] == 'up':
RACKET_POS['left'][1] += RACKET['speed']
elif KEYBOARD[key] == 'down':
RACKET_POS['left'][1] -= RACKET['speed']
elif KEYBOARD[key] == 'right':
RACKET_POS['left'][0] += RACKET['speed']
elif KEYBOARD[key] == 'left':
RACKET_POS['left'][0] -= RACKET['speed']
elif KEYBOARD[key] == 'space':
GAME_OBJECT['started'] = ~ GAME_OBJECT['started']
def enable2D(width, height):
glClearColor(0, 0, 0, 1.0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, width, 0, height)
def main():
# init opengl (glut)
glutInit(sys.argv)
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE )
glutInitWindowSize(GAME_OBJECT['width'], GAME_OBJECT['height'])
glutCreateWindow("PONG GAME")
# Callback functions
glutDisplayFunc(draw)
glutTimerFunc(GAME_OBJECT['delay'], update, 0)
glutSpecialFunc(handle_arrow_keys)
glutKeyboardFunc(handle_char_keys)
# Setup scene
enable2D(GAME_OBJECT['width'], GAME_OBJECT['height'])
# let the magic begin
glutMainLoop()
if __name__ == '__main__': main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment