A gamepad usage example
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

161 lines
7.7 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
pandemic_pong.py
Pandemic python/Qt5 pong clone
History:
--------
21.11.20/KQ Initial version
25.11.20/KQ Class based version w/ scaling ;)
27.11.20/KQ Client/server variant started
02.12.20/KQ Streamlined version published
"""
import sys, os, fcntl, time, random
from glob import glob
from playsound import playsound
import game_objects.pong_constants as pgc # Pong global constants
import game_objects.pong_globalvars as pgv # Pong global variables
from game_objects.pong_player import PongPlayer, pickEventQueues
from game_objects.pong_object import PongObject
from game_objects.pong_game import PongGame
import game_objects.pong_viewserver as vs # Pong TCP view server (threads)
if __name__ == '__main__':
pgv.bSizeable = False
pgv.bIsServer = False
pgv.bIsViewer = False
pgv.bIsLocal = True # by default
player_index = 0 # Illegal, local
player_server = ""
debug_x = 0 # Debug window positions
debug_y = 0
bIsBot1 = False
bIsBot2 = False
sMsg = "usage: ./pandemic_pong.py --[--sizeable|fullscreen] --[server | [viewer | player <1|2>] <ip_adress> [--bot]]"
if len(sys.argv) > 1:
if sys.argv[1] == "--sizeable": # else=default=fullscreen assumed ...
pgv.bSizeable = True
if len(sys.argv) > 2:
if sys.argv[2] == "--server":
pgv.bIsServer = True
pgv.bIsLocal = False
print("*** PANDEMIC PONG (server) ***")
if pgc.DEVLOCAL == True:
debug_x = int(pgc.GAMEAREA_MAX_X / 2.5) # Top centered window
debug_y = int(pgc.GAMEAREA_MAX_Y / 40)
elif len(sys.argv) == 4:
if sys.argv[2] == "--viewer":
pgv.bIsViewer = True
pgv.bIsLocal = False
player_server = sys.argv[3]
print("*** PANDEMIC PONG (viewer talking to game server @{}) ***".format(player_server))
if pgc.DEVLOCAL == True:
debug_x = int(pgc.GAMEAREA_MAX_X / 2.5) # Bottom centered window
debug_y = int(pgc.GAMEAREA_MAX_Y / 2)
elif len(sys.argv) >= 5:
if sys.argv[2] == "--player":
pgv.bIsLocal = False
player_index = int(sys.argv[3])
player_server = sys.argv[4]
bot_msg = ""
if len(sys.argv) == 6: # Bot option?
if sys.argv[5] == "--bot":
bot_msg = "bot"
pgv.bBotDemo = False
elif sys.argv[5] == "--botdemo":
bot_msg = "botdemo"
pgv.bBotDemo = True
if player_index == 2:
bIsBot2 = True
else: # Player 1 bot assumed
bIsBot1 = True
print("*** PANDEMIC PONG (player #{} {} talking to game server @{}) ***".format(player_index, bot_msg, player_server))
if pgc.DEVLOCAL == True:
debug_x = int(pgc.GAMEAREA_MAX_X / 3 * 4 * (player_index-1)) # Left(0) or right top window
debug_y = int(pgc.GAMEAREA_MAX_Y / 40)
else:
print(sMsg)
exit(1)
else:
print(sMsg)
exit(1)
else: # Local version
print("*** PANDEMIC PONG (local) ***")
sEventQueue1, sEventQueue2 = pickEventQueues() # Search 'GAMEPAD ' entries (1 or 2 connected?)
if (sEventQueue1 == None) or (sEventQueue2 == None):
if pgv.bIsLocal == True:
print("Local game requires 2 gamepads connected!")
exit(-1)
if pgc.DEVLOCAL == False:
print("I'm a slow starter, please be patient!") # Caching actually ...
try:
# Initialize
random.seed()
game = PongGame(pgv.bIsServer)
ball = PongObject(pgc.GAMEAREA_MAX_X/2, pgc.GAMEAREA_MAX_Y/2, 20, 20, 8.0, 2.5)
if player_index == 0: # Local or viewer or server?
if pgv.bIsServer == True: # Server, no gamepads locally avail.
player1 = PongPlayer(None, 1, "", 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
player2 = PongPlayer(None, 2, "", pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot2)
elif pgv.bIsViewer == True: # Viewer, no gamepads locally avail.
player1 = PongPlayer(None, 1, "", 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
player2 = PongPlayer(None, 2, "", pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot2)
else: # Local version (both gamepads assumed locally connected)
player1 = PongPlayer(sEventQueue1, 1, "", 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
player2 = PongPlayer(sEventQueue2, 2, "", pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot2)
elif player_index == 1: # Client/server version, player #1, only one queue (the last one!) avail. ...
if pgc.DEVLOCAL == True:
player1 = PongPlayer(sEventQueue1, player_index, player_server, 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
else:
player1 = PongPlayer(sEventQueue2, player_index, player_server, 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
player2 = PongPlayer(None, 2, "", pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot2)
elif player_index == 2: # Client/server version, player #2, only one queue (the last one!) avail. anyway ...
player1 = PongPlayer(None, 1, "", 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot1)
player2 = PongPlayer(sEventQueue2, player_index, player_server, pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160, bIsBot2)
# TODO: Pretty ugly patch for handler data access ... (better: separate sender class)
vs.init_send_structures(game, player1, player2, ball)
# 3 View clients permissible
if (player_index > 0) or (pgv.bIsViewer == True): # i.e. NOT local only
viewserver = vs.ViewServer(player_server) # Create a view server
else: # Local
viewserver = None
except IOError as e:
import errno
if e.errno == errno.EACCES:
print("Insufficient permissions to access, maybe USB gamepad not plugged in?")
elif e.errno == errno.ENOENT:
print("Device not found?")
else:
raise e
sys.exit(-1)
rc = 0
if pgv.bIsServer == False: # This is NOT the headless server!
from game_objects.pong_viewer import run_Qt5_viewer
rc = run_Qt5_viewer(debug_x, debug_y, player_index, viewserver, game, ball, player1, player2, bIsBot1 or bIsBot2)
else: # Headless server-side game loop
while True:
try:
if game.pong_game(ball, player1, player2) == False: # Player game ended
game.reinit() # Re-init on server
time.sleep(pgc.SLEEPSERVERMAINLOOP) # Yield to other threads ...
except KeyboardInterrupt:
print("\rPandemic Pong Server stopped by user.")
break
# Quit gracefully
player2.exit()
player1.exit()
sys.exit(rc)