1st game loop for pong

pull/2/head
kaqu 2 years ago
parent 94c4d04b20
commit eb28d884d0
  1. 239
      evalgamepad.py

@ -2,7 +2,7 @@
#
# evalgamepad.py
# Reading two USB gamepads & making sense of it ...
# Reading two USB gamepads & making sense of it (try pong)...
#
#-----------------------------------------------------------------------
# 'lsusb' ouput: Bus 002 Device 003: ID 0079:0011 DragonRise Inc. Gamepad
@ -12,7 +12,7 @@
# /dev/input/event7
#
import sys, os, fcntl
import sys, os, fcntl, time
import libevdev
# Buttons in 'state<n>'
@ -25,6 +25,42 @@ BTN_PINKIE = 32 # [Frontal right]
BTN_BASE3 = 64 # [Centre left]
BTN_BASE4 = 128 # [Centre right]
GAMEAREA_MIN_X = 0 # Game area definition
GAMEAREA_MAX_X = 1920 # Assume FHD resolution
GAMEAREA_MIN_Y = 0
GAMEAREA_MAX_Y = 1080
def init_player(path):
# Gamepad init.
fd = open(path, "rb")
fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
dev = libevdev.Device(fd)
return {
"fd" : fd, # File descriptor to close (later ...)
"dev" : dev, # Actual gamepad of this player
"state" : 0, # Button mask (as above)
"delta_x" : 0, # Current delta setting
"delta_y" : 0,
"x" : GAMEAREA_MAX_X/2, # Current actual position
"y" : GAMEAREA_MAX_Y/2, # Start at center
"w" : 10,
"h" : 100
}
def exit_player(player):
player["fd"].close()
def init_object(x, y, w, h, delta_x, delta_y):
return {
"delta_x" : delta_x, # Current movement
"delta_y" : delta_y,
"x" : x, # Current position
"y" : y,
"w" : w, # Size of object
"h" : h,
}
def print_event(e):
print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
if e.matches(libevdev.EV_SYN):
@ -37,11 +73,11 @@ def print_event(e):
else:
print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))
def evalgamepad(dev, state, x, y):
def eval_gamepad(player):
bChanged = False
try:
for e in dev.events():
bChanged = True
try:
for e in player["dev"].events():
#print_event(e)
# Event type 1 (EV_KEY)
@ -58,105 +94,158 @@ def evalgamepad(dev, state, x, y):
if e.type.value == 1: # Non-Cross events
if e.value == 1: # Simple buttons may act as toggles
if e.code.value == 288: # BTN_TRIGGER
state = state ^ BTN_TRIGGER
player["state"] = player["state"] ^ BTN_TRIGGER
elif e.code.value == 289: # BTN_THUMB
state = state ^ BTN_THUMB
player["state"] = player["state"] ^ BTN_THUMB
elif e.code.value == 290: # BTN_THUMB2
state = state ^ BTN_THUMB2
player["state"] = player["state"] ^ BTN_THUMB2
elif e.code.value == 291: # BTN_TOP
state = state ^ BTN_TOP
player["state"] = player["state"] ^ BTN_TOP
elif e.code.value == 292: # BTN_TOP2
state = state ^ BTN_TOP2
player["state"] = player["state"] ^ BTN_TOP2
elif e.code.value == 293: # BTN_PINKIE
state = state ^ BTN_PINKIE
player["state"] = player["state"] ^ BTN_PINKIE
elif e.code.value == 296: # BTN_BASE3
state = state ^ BTN_BASE3
player["state"] = player["state"] ^ BTN_BASE3
elif e.code.value == 297: # BTN_BASE4
state = state ^ BTN_BASE4
player["state"] = player["state"] ^ BTN_BASE4
bChanged = True
# Event type 3 (EV_ABS)
# Event code 0 (ABS_X) <- Cross: 127=Neutral, 0=[Left], 255=[Right]
# Event code 1 (ABS_Y) <- Cross: 127=Neutral, 0=[Top], 255=[Down]
elif e.type.value == 3: # EV_ABS
if e.code.value == 0: # ABS_X
if e.value == 0:
x = x - 1
player["delta_x"] = player["delta_x"] - 1
elif e.value == 255:
x = x + 1
player["delta_x"] = player["delta_x"] + 1
else: # 127/Neutral
x = 0
player["delta_x"] = 0
else: # ABS_Y
if e.value == 0:
y = y + 1
player["delta_y"] = player["delta_y"] + 1
elif e.value == 255:
y = y - 1
player["delta_y"] = player["delta_y"] - 1
else: # 127/Neutral
y = 0
print("State=",state, "X=", x, "Y=", y)
player["delta_y"] = 0
bChanged = True
#if bChanged:
# print("State=",player["state"], "X=", player["delta_x"], "Y=", player["delta_y"])
except libevdev.EventsDroppedException:
print("Dropped!")
for e in dev.sync():
for e in player["dev"].sync():
print_event(e)
return bChanged, state, x, y
def evalposition(sum_x, sum_y, delta_x, delta_y):
sum_x = sum_x + delta_x
sum_y = sum_y + delta_y
if sum_x < 0:
sum_x = 0
elif sum_x > 16384:
sum_x = 16384
if sum_y < 0:
sum_y = 0
elif sum_y > 8192:
sum_y = 8192
return sum_x, sum_y
def gameloop(dev1, dev2):
state1 = 0
state2 = 0
x1 = 0
x2 = 0
y1 = 0
y2 = 0
player1_x = 0
player2_x = 0
player1_y = 0
player2_y = 0
return bChanged
def eval_position(player):
bChanged = False
sum_x = player["x"] + player["delta_x"]/255
sum_y = player["y"] + player["delta_y"]/255
if sum_x < GAMEAREA_MIN_X:
sum_x = GAMEAREA_MIN_X
elif sum_x + player["w"] > GAMEAREA_MAX_X:
sum_x = GAMEAREA_MAX_X - player["w"]
if sum_y < GAMEAREA_MIN_Y:
sum_y = GAMEAREA_MIN_Y
elif sum_y + player["h"] > GAMEAREA_MAX_Y:
sum_y = GAMEAREA_MAX_Y - player["h"]
if (sum_x != player["x"]) or (sum_y != player["y"]):
bChanged = True
player["x"] = sum_x
player["y"] = sum_y
return bChanged
def eval_object(obj):
sum_x = obj["x"] + obj["delta_x"]
sum_y = obj["y"] + obj["delta_y"]
if sum_x < GAMEAREA_MIN_X:
sum_x = GAMEAREA_MIN_X
obj["delta_x"] = -obj["delta_x"]
elif sum_x + obj["w"] > GAMEAREA_MAX_X:
sum_x = GAMEAREA_MAX_X - obj["w"]
obj["delta_x"] = -obj["delta_x"]
if sum_y < GAMEAREA_MIN_Y:
sum_y = GAMEAREA_MIN_Y
obj["delta_y"] = -obj["delta_y"]
elif sum_y + obj["h"] > GAMEAREA_MAX_Y:
sum_y = GAMEAREA_MAX_Y - obj["h"]
obj["delta_y"] = -obj["delta_y"]
obj["x"] = sum_x
obj["y"] = sum_y
def draw_objects(ball, player1, player2): # Update objects on playground
print("\rB: ", ball["x"], "/", ball["y"], end="")
print(" P1: ", player1["x"], "/", player1["y"], " S:", hex(player1["state"]), " ", end="")
print(" P2: ", player2["x"], "/", player2["y"], " S:", hex(player2["state"]), " ", end="")
def gameloop(ball, player1, player2):
while True:
bChanged, state1, x1, y1 = evalgamepad(dev1, state1, x1, y1)
if (state1 & BTN_BASE4) > 0: # Exit?
print("Player #1 aborted game")
break
bChanged, state2, x2, y2 = evalgamepad(dev2, state2, x2, y2) # Exit?
if (state2 & BTN_BASE4) > 0:
print("Player #2 aborted game")
break
player1_x, player1_y = evalposition(player1_x, player1_y, x1, y1)
print("Player #1: ", player1_x," / ",player1_y)
player2_x, player2_y = evalposition(player2_x, player2_y, x2, y2)
print("Player #2: ", player2_x," / ",player2_y)
# 1. Retrieve user entries
bChanged = eval_gamepad(player1)
if bChanged:
if (player1["state"] & BTN_BASE4) > 0: # Exit?
print("Player #1 aborted game")
break
else:
print("Player #1: {}h".format(hex(player1["state"])))
bChanged = eval_gamepad(player2) # Exit?
if bChanged:
if (player2["state"] & BTN_BASE4) > 0:
print("Player #2 aborted game")
break
else:
print("Player #2: {}h".format(hex(player2["state"])))
# 2. Adjust player positions
bChanged = eval_position(player1)
if bChanged:
print("Player #1: ", player1["x"], " / ", player1["y"])
bChanged = eval_position(player2)
if bChanged:
print("Player #2: ", player2["x"], " / ", player2["y"])
# 3. Adjust object positions
eval_object(ball)
# 4. Refresh game area drawing
draw_objects(ball, player1, player2)
# 5. Little delay for testing
time.sleep(0.1)
def init_gamearea(): # Create base playground
pass
def main(args):
path1 = args[1]
path2 = args[2]
try:
# Gamepad #1 init.
fd1 = open(path1, "rb")
fcntl.fcntl(fd1, fcntl.F_SETFL, os.O_NONBLOCK)
dev1 = libevdev.Device(fd1)
# Gamepad #2 init.
fd2 = open(path2, "rb")
fcntl.fcntl(fd2, fcntl.F_SETFL, os.O_NONBLOCK)
dev2 = libevdev.Device(fd2)
# Initialize
init_gamearea()
ball = init_object(10, 10, 15, 15, 2.0, 1.5)
player1 = init_player(args[1])
player2 = init_player(args[2])
# Work ...
gameloop(dev1, dev2)
gameloop(ball, player1, player2)
# Quit gracefully
fd2.close()
fd1.close()
exit_player(player2)
exit_player(player1)
except KeyboardInterrupt: # Never comes ... (?!)
pass

Loading…
Cancel
Save