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
This commit is contained in:
parent
4601d62f47
commit
94ac5b33eb
|
@ -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()
|
Loading…
Reference in New Issue