Skip to content

Commit 7d2eaf6

Browse files
author
XenGi
committed
no osc but my own udp based protocol
1 parent 8222618 commit 7d2eaf6

File tree

5 files changed

+317
-126
lines changed

5 files changed

+317
-126
lines changed

controller_example.py

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
pymlgame - controller example
66
=============================
77
8-
This example shows how you can use a controller connected to a laptop or any
9-
other machine capable of pygame to connect to a pymlgame instance.
8+
This example shows how you can use a xbox 360 controller connected to a noteboook or any other machine capable of
9+
running pygame to connect to a pymlgame instance.
1010
"""
1111

1212
__author__ = 'Ricardo Band'
@@ -19,28 +19,26 @@
1919
__status__ = 'Development'
2020

2121
import sys
22+
import socket
2223

2324
import pygame
24-
import jsonrpclib
2525

2626

2727
class Controller(object):
2828
def __init__(self, host, port):
2929
self.host = host
3030
self.port = port
3131
pygame.init()
32-
self.joysticks = [[pygame.joystick.Joystick(j), None, None]
33-
for j in range(pygame.joystick.get_count())]
32+
self.joysticks = [[pygame.joystick.Joystick(j), None, None] for j in range(pygame.joystick.get_count())]
3433
self.screen = pygame.display.set_mode((100, 10))
3534
pygame.display.set_caption("pymlgame_ctlr")
3635
self.clock = pygame.time.Clock()
37-
self.server = jsonrpclib.Server('http://' + self.host + ':' +
38-
str(self.port))
36+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
37+
#joy[1].sendto(json.dumps(joy[3]), (self.host, self.port))
3938
for joy in self.joysticks:
4039
joy[0].init()
41-
joy[1] = self.server.init()
4240
if joy[0].get_name() == 'Xbox 360 Wireless Receiver':
43-
joy[2] = {0: 'A',
41+
joy[1] = {0: 'A',
4442
1: 'B',
4543
2: 'X',
4644
3: 'Y',
@@ -52,6 +50,20 @@ def __init__(self, host, port):
5250
12: 'Right',
5351
13: 'Up',
5452
14: 'Down'}
53+
joy[2] = {'A': False,
54+
'B': False,
55+
'X': False,
56+
'Y': False,
57+
'L1': False,
58+
'L2': False,
59+
'R1': False,
60+
'R2': False,
61+
'Select': False,
62+
'Start': False,
63+
'Left': False,
64+
'Right': False,
65+
'Up': False,
66+
'Down': False}
5567

5668
def handle_events(self):
5769
for event in pygame.event.get():
@@ -63,21 +75,17 @@ def handle_events(self):
6375
if event.key == pygame.K_ESCAPE:
6476
pygame.event.post(pygame.event.Event(pygame.QUIT))
6577
if event.type == pygame.JOYBUTTONDOWN:
66-
print('joy', self.joysticks[event.joy][0].get_name(),
67-
'(uid:', self.joysticks[event.joy][1], ')button pressed:',
68-
event.button)
69-
self.server.trigger_button(self.joysticks[event.joy][1],
70-
'KeyDown',
71-
self.joysticks[event.joy][2][event.button])
78+
print('joy', self.joysticks[event.joy][0].get_name(), 'button pressed:', event.button)
79+
button = self.joysticks[event.joy][1][event.button]
80+
self.joysticks[event.joy][2][button] = True
7281
if event.type == pygame.JOYBUTTONUP:
73-
print('joy', self.joysticks[event.joy][0].get_name(),
74-
'(uid:', self.joysticks[event.joy][1], ')button released:',
75-
event.button)
76-
self.server.trigger_button(self.joysticks[event.joy][1],
77-
'KeyUp',
78-
self.joysticks[event.joy][2][event.button])
82+
print('joy', self.joysticks[event.joy][0].get_name(), 'button released:', event.button)
83+
button = self.joysticks[event.joy][1][event.button]
84+
self.joysticks[event.joy][2][button] = False
7985

8086
def update(self):
87+
#for joy in self.joysticks:
88+
# joy[1].sendto(bytes(json.dumps(joy[2])), (self.host, self.port))
8189
pass
8290

8391
def render(self):
@@ -96,4 +104,4 @@ def gameloop(self):
96104

97105
if __name__ == '__main__':
98106
CTLR = Controller('127.0.0.1', 1338)
99-
CTLR.gameloop()
107+
CTLR.gameloop()

controller_example2.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#!/usr/bin/env python2.7
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
pymlgame - controller example
6+
=============================
7+
8+
This example shows how you can use your notebooks keyboard to connect to a pymlgame instance.
9+
"""
10+
11+
__author__ = 'Ricardo Band'
12+
__copyright__ = 'Copyright 2014, Ricardo Band'
13+
__credits__ = ['Ricardo Band']
14+
__license__ = 'MIT'
15+
__version__ = '0.1.1'
16+
__maintainer__ = 'Ricardo Band'
17+
__email__ = '[email protected]'
18+
__status__ = 'Development'
19+
20+
import sys
21+
import time
22+
import socket
23+
from threading import Thread, Timer
24+
25+
import pygame
26+
27+
# define some constants
28+
E_UID = pygame.USEREVENT + 1
29+
E_PLAY = pygame.USEREVENT + 2
30+
E_RUMBLE = pygame.USEREVENT + 3
31+
32+
33+
class ReceiverThread(Thread):
34+
"""
35+
This thread listen on a UDP port for packets from a pymlgame instance.
36+
"""
37+
def __init__(self, host='127.0.0.1', port=11338):
38+
"""
39+
Creates the socket and binds it to the given host and port.
40+
"""
41+
super(ReceiverThread, self).__init__()
42+
self.host = host
43+
self.port = port
44+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
45+
self.sock.bind((self.host, self.port))
46+
47+
def run(self):
48+
while True:
49+
data, addr = self.sock.recvfrom(1024)
50+
data = data.decode('utf-8')
51+
52+
if data.startswith('/uid/'):
53+
ev = pygame.event.Event(E_UID, {'uid': int(data[5:])})
54+
pygame.event.post(ev)
55+
elif data.startswith('/play/'):
56+
ev = pygame.event.Event(E_PLAY, {'filename': str(data[6:])})
57+
pygame.event.post(ev)
58+
elif data.startswith('/rumble/'):
59+
ev = pygame.event.Event(E_RUMBLE, {'duration': float(data[8:].replace(',', '.'))})
60+
pygame.event.post(ev)
61+
62+
63+
class Controller(object):
64+
def __init__(self, host='127.0.0.1', port=1337):
65+
self.host = host
66+
self.port = port
67+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
68+
69+
pygame.init()
70+
self.screen = pygame.display.set_mode((128, 113), pygame.DOUBLEBUF, 32)
71+
bg = pygame.image.load('kbd.png')
72+
self.screen.blit(bg, pygame.rect.Rect(0, 0, 128, 113))
73+
pygame.display.flip()
74+
75+
self.keys = [0 for _ in range(14)]
76+
self.mapping = {pygame.K_UP: 0, # Up
77+
pygame.K_DOWN: 1, # Down
78+
pygame.K_LEFT: 2, # Left
79+
pygame.K_RIGHT: 3, # Right
80+
pygame.K_a: 4, # A
81+
pygame.K_w: 5, # B
82+
pygame.K_s: 6, # X
83+
pygame.K_d: 7, # Y
84+
pygame.K_RETURN: 8, # Start
85+
pygame.K_SPACE: 9, # Select
86+
pygame.K_q: 10, # L1
87+
pygame.K_1: 11, # L2
88+
pygame.K_e: 12, # R1
89+
pygame.K_3: 13} # R2
90+
91+
self.timeout = 0
92+
self.rumble_active = False
93+
self.uid = None
94+
95+
receiver = ReceiverThread()
96+
receiver.setDaemon(True)
97+
receiver.start()
98+
99+
def ping(self):
100+
self.sock.sendto(bytes('/ping/{}'.format(self.uid).encode('utf-8')), (self.host, self.port))
101+
102+
def send_keys(self):
103+
# alternative states creation: [1 if k else 0 for k in self.keys]
104+
states = '/states/{}/{}'.format(self.uid, ''.join([str(k) for k in self.keys]))
105+
self.sock.sendto(states.encode('utf-8'), (self.host, self.port))
106+
self.timeout = time.time()
107+
108+
def rumble(self, stop=False):
109+
if stop:
110+
# stop the rumble
111+
pass
112+
else:
113+
# start the rumble
114+
pass
115+
116+
def play_sound(self, filename):
117+
pass
118+
119+
def handle_inputs(self):
120+
while True:
121+
if time.time() > self.timeout + 30:
122+
self.ping()
123+
124+
events = pygame.event.get()
125+
for event in events:
126+
if event.type == pygame.QUIT:
127+
pygame.quit()
128+
sys.exit(0)
129+
elif event.type == pygame.MOUSEBUTTONUP:
130+
pygame.event.post(pygame.event.Event(pygame.QUIT))
131+
elif event.type == E_UID:
132+
self.uid = event.uid
133+
if self.uid:
134+
if event.type == E_PLAY:
135+
self.play_sound(event.filename)
136+
elif event.type == E_RUMBLE:
137+
self.rumble()
138+
#TODO: check if the timers get killed when they are stopped. no zombies allowed here!
139+
t = Timer(event.duration, self.rumble, args=[True, ])
140+
t.setDaemon(True)
141+
t.start()
142+
elif event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
143+
try:
144+
button = self.mapping[event.key]
145+
if event.type == pygame.KEYDOWN:
146+
print('{}({}) key down'.format(event.key, button))
147+
self.keys[button] = 1
148+
elif event.type == pygame.KEYUP:
149+
print('{}({}) key up'.format(event.key, button))
150+
self.keys[button] = 0
151+
self.send_keys()
152+
except KeyError:
153+
break
154+
155+
156+
if __name__ == '__main__':
157+
ctlr = Controller()
158+
try:
159+
while True:
160+
ctlr.handle_inputs()
161+
except KeyboardInterrupt:
162+
pass

game_example.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
pymlgame - example game
66
=======================
77
8-
This example shows how a simple pymlgame could be written. You also need a
9-
connected controller to actually see something happening. You can use the
10-
controller example for this.
8+
This example shows how a simple pymlgame could be written. You also need a connected controller to actually see
9+
something happening. You can use the controller example for this.
1110
"""
1211

1312
__author__ = 'Ricardo Band'
@@ -34,6 +33,8 @@ def __init__(self, host, port, width, height):
3433
self.port = port
3534
self.width = width
3635
self.height = height
36+
37+
pymlgame.init(self.host, self.port)
3738
self.screen = pymlgame.Screen(self.host, self.port,
3839
self.width, self.height)
3940
self.clock = pymlgame.Clock()
@@ -57,8 +58,6 @@ def __init__(self, host, port, width, height):
5758
self.filled = pymlgame.Surface(int(self.screen.width / 2) - 2,
5859
int(self.screen.height / 2) - 2)
5960

60-
self.ctlr = pymlgame.Controller(self.host, self.port + 1)
61-
6261
def update(self):
6362
"""
6463
Update the screens contents in every loop.
@@ -109,22 +108,25 @@ def render(self):
109108
int(self.screen.height / 2) + 1))
110109

111110
self.screen.update()
112-
self.clock.tick(2)
111+
self.clock.tick(15)
113112

114113
def handle_events(self):
115114
"""
116115
Loop through all events.
117116
"""
118-
for event in self.ctlr.get_events():
119-
if event.type == pymlgame.NEWCTLR:
120-
print('new ctlr with uid:', event.uid)
121-
elif event.type == pymlgame.KEYDOWN:
117+
for event in pymlgame.get_events():
118+
print('event received', event.type)
119+
if event.type == pymlgame.E_NEWCTLR:
120+
print('new ctlr with ip:', event.uid)
121+
elif event.type == pymlgame.E_DISCONNECT:
122+
print()
123+
elif event.type == pymlgame.E_KEYDOWN:
122124
print('key', event.button, 'down on', event.uid)
123125
self.colors.append(self.colors.pop(0))
124-
elif event.type == pymlgame.KEYUP:
126+
elif event.type == pymlgame.E_KEYUP:
125127
print('key', event.button, 'up on', event.uid)
126128
self.colors.append(self.colors.pop(0))
127-
elif event.type == pymlgame.PING:
129+
elif event.type == pymlgame.E_PING:
128130
print('ping from', event.uid)
129131

130132
def gameloop(self):
@@ -138,11 +140,9 @@ def gameloop(self):
138140
self.render()
139141
except KeyboardInterrupt:
140142
pass
141-
# don't forget to quit the controller process if your game ends.
142-
# In future releases this will be done automatically.
143-
self.ctlr.quit()
144143

145144

146145
if __name__ == '__main__':
147-
GAME = Game('127.0.0.1', 1337, 50, 28)
146+
GAME = Game('127.0.0.1', 1337, 40, 16)
147+
#GAME = Game('matelight.cbrp3.c-base.org', 1337, 40, 16)
148148
GAME.gameloop()

kbd.png

3.53 KB
Loading

0 commit comments

Comments
 (0)