From 94ac5b33ebc7545a5b02b77e31cdfd891f929dbc Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Thu, 27 Jun 2019 18:19:57 -0400 Subject: [PATCH] NEW Pong program that ONLY uses PySimpleGUI calls. Previously cheated and worked directly with Canvas in tkinter. Not anymore! Also runs on PySimpleGUIWeb and should run on PySimpleGUIQt soon --- DemoPrograms/Demo_Pong_Multiple_Platforms.py | 172 +++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 DemoPrograms/Demo_Pong_Multiple_Platforms.py diff --git a/DemoPrograms/Demo_Pong_Multiple_Platforms.py b/DemoPrograms/Demo_Pong_Multiple_Platforms.py new file mode 100644 index 00000000..2e88127c --- /dev/null +++ b/DemoPrograms/Demo_Pong_Multiple_Platforms.py @@ -0,0 +1,172 @@ +# !/usr/bin/env python +# Based on work by - Siddharth Natamai +# At the moment, this source file runs on TWO of the 4 PySimpleGUI ports with a third one coming soon (Qt). +# import PySimpleGUIQt as sg # not quite working on Qt yet... needs Graph.Relocate fixed first +# import PySimpleGUIWeb as sg +import PySimpleGUI as sg +import random + +GAMEPLAY_SIZE = (700, 400) +BAT_SIZE = (20, 110) +STARTING_BALL_POSITION = (327, 200) +player_1_Starting_Score = 0 +player_2_Starting_Score = 0 +BALL_RADIUS = 12 +# BACKGROUND_COLOR = 'lightblue' # if running on PySimpleGUIWeb +BACKGROUND_COLOR = 'black' +# BALL_COLOR = 'black' # if running on PySimpleGUIWeb +BALL_COLOR = 'green1' +num_rounds = 0 +while num_rounds == 0: + try: + num_rounds = int(sg.PopupGetText('How many rounds would you like to play?')) + except Exception as e: + num_rounds = 0 + + +class Ball: + def __init__(self, graph, bat_1, bat_2, colour): + self.graph = graph # type: sg.Graph + self.bat_1 = bat_1 + self.bat_2 = bat_2 + self.player_1_Score = player_1_Starting_Score + self.player_2_Score = player_2_Starting_Score + self.draw_P1 = None + self.draw_P2 = None + self.id = self.graph.DrawCircle(STARTING_BALL_POSITION, BALL_RADIUS, line_color=colour, fill_color=colour) + self.curx, self.cury = STARTING_BALL_POSITION + # self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1]) + self.x = random.choice([-2.5, 2.5]) + self.y = -2.5 + + def win_loss_check(self): + winner = None + if self.player_1_Score >= num_rounds: + winner = 'Player Right Wins' + if self.player_2_Score >= num_rounds: + winner = 'Player Left Wins' + return winner + + def update_player1_score(self, val): + self.graph.DeleteFigure(self.draw_P1) + self.draw_P1 = self.graph.DrawText(str(val), (170, 50), font=('Courier 60'), color='white') + + def update_player2_score(self, val): + self.graph.DeleteFigure(self.draw_P2) + self.draw_P2 = self.graph.DrawText(str(val), (550, 50), font=('courier 40'), color='white') + + def hit_bat(self, pos): + bat_pos = (self.bat_1.curx, self.bat_1.cury) + if pos[0] >= bat_pos[0] and pos[0] <= bat_pos[0]+BAT_SIZE[0]: + if bat_pos[1] <= pos[1] <= bat_pos[1]+BAT_SIZE[1]: + return True + return False + + def hit_bat2(self, pos): + bat_pos = (self.bat_2.curx, self.bat_2.cury) + if pos[0] >= bat_pos[0] and pos[0] <= bat_pos[0]+BAT_SIZE[0]: + if bat_pos[1] <= pos[1] <= bat_pos[1]+BAT_SIZE[1]: + return True + return False + + + def draw(self): + self.curx += self.x + self.cury += self.y + self.graph.RelocateFigure(self.id, self.curx, self.cury) + if self.cury <= 0: # see if hit top or bottom of play area. If so, reverse y direction + self.y = 4 + self.cury = 0 + if self.cury >= GAMEPLAY_SIZE[1]-BALL_RADIUS/2: + self.y = -4 + self.cury = GAMEPLAY_SIZE[1]-BALL_RADIUS/2 + if self.curx <= 0: # see if beyond player + self.player_1_Score += 1 + self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1]) + self.x = 4 + self.update_player2_score(self.player_1_Score) + self.curx, self.cury = STARTING_BALL_POSITION + if self.curx >= GAMEPLAY_SIZE[0]: + self.player_2_Score += 1 + self.graph.RelocateFigure(self.id, STARTING_BALL_POSITION[0], STARTING_BALL_POSITION[1]) + self.x = -4 + self.update_player1_score(self.player_2_Score) + self.curx, self.cury = STARTING_BALL_POSITION + if self.hit_bat((self.curx, self.cury)): + self.x = 4 + if self.hit_bat2((self.curx, self.cury)): + self.x = -4 + + +class PongBat(): + def __init__(self, graph:sg.Graph, colour, x, width=BAT_SIZE[0], height=BAT_SIZE[1]): + self.graph = graph + self.id = graph.DrawRectangle((x - width / 2, 200), (x + width / 2, 200 + height), fill_color=colour) + self.y = 0 + self.x = x + self.curx = x + self.cury = height/2 + + def up(self, amount): + self.y = -amount + + def down(self, amount): + self.y = amount + + @property + def curr_pos(self): + pos = self.cury + return pos + + def draw(self): + self.graph.RelocateFigure(self.id, self.curx, self.cury) + if self.cury + self.y + BAT_SIZE[1] <= GAMEPLAY_SIZE[1] and self.cury + self.y + BAT_SIZE[1] >= 0: + self.cury += self.y + if self.cury <= 0: + self.cury = 0 + self.y = 0 + if self.cury >= GAMEPLAY_SIZE[1]: + self.cury = GAMEPLAY_SIZE[1] + self.y = 0 + + +def pong(): + layout = [[sg.Graph(GAMEPLAY_SIZE, (0,GAMEPLAY_SIZE[1]), (GAMEPLAY_SIZE[0],0), background_color=BACKGROUND_COLOR, key='_GRAPH_')], + [sg.T(''), sg.Button('Exit'), sg.T('Speed'), sg.Slider((0,20),default_value=10, orientation='h', enable_events=True, key='_SPEED_')]] + + window = sg.Window('Pong', layout, return_keyboard_events=True).Finalize() + + graph_elem = window.FindElement('_GRAPH_') # type: sg.Graph + + bat_1 = PongBat(graph_elem, 'red', 30) + bat_2 = PongBat(graph_elem, 'blue', 670) + + ball_1 = Ball(graph_elem, bat_1, bat_2, 'green1') + sleep_time = 10 + + while True: + ball_1.draw() + bat_1.draw() + bat_2.draw() + + event, values = window.Read(timeout=sleep_time) # type: str, str + if event is None or event == 'Exit': + break + elif event.startswith('Up') or event.endswith('Up'): + bat_2.up(5) + elif event.startswith('Down') or event.endswith('Down'): + bat_2.down(5) + elif event == 'w': + bat_1.up(5) + elif event == 's': + bat_1.down(5) + elif event == '_SPEED_': + sleep_time = int(values['_SPEED_']) + + if ball_1.win_loss_check(): + sg.Popup('Game Over', ball_1.win_loss_check() + ' won!!') + break + window.Close() + +if __name__ == '__main__': + pong()