# Filename: A10_2D_baseline_client.py
# Written by: James D. Miller
# 6:42 PM Wed January 20, 2016
import sys, os, time
import pygame
# PyGame Constants
from pygame.locals import *
from pygame.color import THECOLORS
# Network stuff. Note "connection" is a single instantiation.
from PodSixNet.Connection import connection, ConnectionListener
# Argument parsing...
import argparse
#=======================================================================
# Classes
#=======================================================================
class NetworkListener( ConnectionListener):
def __init__(self, (host, port)):
self.Connect((host, port))
self.client_colors = {'C1': THECOLORS["orangered1"],'C2': THECOLORS["tan"],'C3': THECOLORS["cyan"],'C4': THECOLORS["blue"],
'C5': THECOLORS["pink"], 'C6': THECOLORS["red"],'C7': THECOLORS["coral"],'C8': THECOLORS["green"],
'C9': THECOLORS["grey80"],'C10': THECOLORS["rosybrown3"]}
self.background_color = THECOLORS["white"]
self.client_name = 'C0'
self.client_color = THECOLORS["black"]
def Network(self, data):
#print 'network data:', data
pass
# def Network_connected(self, data):
# print "connected to the server", data
def Network_hello(self, data):
global client_ID, client_state
print "Network_hello:", data
client_ID = data['P_ID']
if client_ID == 0:
print "The server new-client count exceeds the limit. Restart the server."
signoff(client_state)
self.client_name = 'C' + str(client_ID)
self.background_color = THECOLORS["black"]
self.client_color = self.client_colors[self.client_name]
# Initialize user state dictionary.
client_state = {'action': 'CN',
'ID': client_ID,
'mXY':(0,0), 'mBd':False, 'mB':1,
'a':'U', 's':'U', 'd':'U', 'w':'U',
'j':'U', 'k':'U', 'l':'U', 'i':'U', ' ':'U',
'm':'U',
'f':'U',
't':'U', 'ls':'U'}
pygame.display.set_caption("Air Table GamePad V.3: Player C" + str(client_ID))
# def Network_error(self, data):
# print "error:", data['error'][1]
# def Network_disconnected(self, data):
# print "Disconnected from the server."
def Network_badhealth(self, data):
global start_shutdown
start_shutdown = True
print "The message I'm getting from the server is: " + data['message'] + "."
print "I'm really not feeling very well."
self.background_color = THECOLORS["white"]
#signoff(client_state)
# def Network_myaction(self, data):
# print "myaction:", data
#=======================================================================
# Functions
#=======================================================================
def signoff(client_state):
sys.exit()
def checkforUserInput(client_state):
# Get all the events since the last call to get().
for event in pygame.event.get():
if (event.type == pygame.QUIT):
signoff(client_state)
elif (event.type == pygame.KEYDOWN):
if (event.key == K_ESCAPE):
signoff(client_state)
elif (event.key==K_c):
mydisplay.fill(THECOLORS["yellow"])
elif (event.key==K_1):
return 1
elif (event.key==K_2):
return 2
elif (event.key==K_3):
return 3
elif (event.key==K_a):
client_state['a'] = 'D'
elif (event.key==K_s):
client_state['s'] = 'D'
elif (event.key==K_d):
client_state['d'] = 'D'
elif (event.key==K_w):
client_state['w'] = 'D'
elif (event.key==K_j):
client_state['j'] = 'D'
elif (event.key==K_k):
client_state['k'] = 'D'
elif (event.key==K_l):
client_state['l'] = 'D'
elif (event.key==K_i):
client_state['i'] = 'D'
elif (event.key==K_SPACE):
client_state[' '] = 'D'
elif (event.key==K_LSHIFT):
client_state['ls'] = 'D'
elif (event.key==K_t):
client_state['t'] = 'D'
elif (event.key==K_BACKSLASH):
print "Trying to start a new connection."
connection.DoConnect((args.serverIP, 4330))
#network_listener = NetworkListener((args.serverIP, 4330))
elif (event.type == pygame.KEYUP):
if (event.key==K_a):
client_state['a'] = 'U'
elif (event.key==K_s):
client_state['s'] = 'U'
elif (event.key==K_d):
client_state['d'] = 'U'
elif (event.key==K_w):
client_state['w'] = 'U'
elif (event.key==K_j):
client_state['j'] = 'U'
elif (event.key==K_k):
client_state['k'] = 'U'
elif (event.key==K_l):
client_state['l'] = 'U'
elif (event.key==K_i):
client_state['i'] = 'U'
elif (event.key==K_SPACE):
client_state[' '] = 'U'
elif (event.key==K_LSHIFT):
client_state['ls'] = 'U'
elif (event.key==K_t):
client_state['t'] = 'U'
elif event.type == pygame.MOUSEBUTTONDOWN:
client_state['mBd'] = True
# Check the button status.
(button1, button2, button3) = pygame.mouse.get_pressed()
if button1:
client_state['mB'] = 1
elif button2:
client_state['mB'] = 2
elif button3:
client_state['mB'] = 3
else:
client_state['mB'] = 0
elif event.type == pygame.MOUSEBUTTONUP:
client_state['mBd'] = False
client_state['mB'] = 0
# cursor x,y
client_state['mXY'] = pygame.mouse.get_pos()
#=======================================================================
# Main program statements
#=======================================================================
# Parse parameters provided in the command line.
# This description string (and parameter help) gets displayed if help is requested (-h added after the filename).
parser = argparse.ArgumentParser(description='Please add optional client parameters after the file name. For example: \n' +
'A10_2D_baseline_client.py 111.222.22.22')
# A required positional argument.
parser.add_argument('serverIP', type=str, help='Use the IP address that is reported by the server when it starts.')
# An optional positional argument.
#parser.add_argument('someString', type=str, nargs='?', default='string1', help='Just enter a string value in the second position.')
# An optional argument.
#parser.add_argument('--test', '-t', type=str, help='Example: -t teststring OR --test teststring')
args = parser.parse_args()
print "Server IP Address:", args.serverIP
#print "someString:", args.someString
#print "test:", args.test
pygame.init()
mydisplay = pygame.display.set_mode((800, 700))
# Instantiate clock to help control the framerate.
myclock = pygame.time.Clock()
# Font object for rendering text onto display surface.
fnt = pygame.font.SysFont("Arial", 14)
client_ID = 0
# Initialize the state dictionary
client_state = {}
# Note, the connection can take place in the NetworkListener or here.
# This "connection" is an instantiation of the EndPoint class that is done in the Connection.py file.
# Note, if you do this here, you have to call the "DoConnect" method, not the "Connect" method that
# is indicated on the web site.
#connection.DoConnect((args.serverIP, 4330))
network_listener = NetworkListener((args.serverIP, 4330))
framerate_limit = 120
flip_timer = 0.0
start_shutdown = False
shutdown_timer = 0.0
while True:
dt_s = float(myclock.tick(framerate_limit) * 1e-3)
#myclock.tick(framerate_limit)
try:
connection.Pump()
except:
signoff(client_state)
network_listener.Pump()
checkforUserInput(client_state)
if client_ID != 0:
#print "client_state", client_state
connection.Send(client_state)
if start_shutdown:
shutdown_timer += dt_s
if shutdown_timer > 0.5:
network_listener.background_color = THECOLORS["red"]
if shutdown_timer > 1.0:
signoff(client_state)
flip_timer += dt_s
if (flip_timer > 0.2):
# Background
mydisplay.fill( network_listener.background_color)
# Small rectangle to illustrate the client color that will appear on the server screen.
pygame.draw.rect(mydisplay, network_listener.client_color, pygame.Rect(50, 50, 60, 20), 3)
# Small background rectangle for text
pygame.draw.rect(mydisplay, THECOLORS["white"], pygame.Rect(150, 50, 35, 20))
# Text
fps_string = "%.0f" % myclock.get_fps()
txt_surface = fnt.render(fps_string, True, THECOLORS["black"])
mydisplay.blit(txt_surface, [158, 51])
pygame.display.flip()
flip_timer = 0.0