Created
December 7, 2016 04:31
-
-
Save ramytamer/f7f374fa8efe464f244e2dcfed49952d to your computer and use it in GitHub Desktop.
OpenGL Pong
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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