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.
 
 
Pandemic_Pong/pong_player.py

174 lines
7.5 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
pong_player.py
Pandemic Pong Player Logic
"""
import os, fcntl
import libevdev
import pong_constants as pgc # Pong global constants
import pong_globalvars as pgv # Pong global variables
def print_event(e):
"""Sample from libevdev docs, useful for testing ..."""
print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
if e.matches(libevdev.EV_SYN):
if e.matches(libevdev.EV_SYN.SYN_MT_REPORT):
print("++++++++++++++ {} ++++++++++++".format(e.code.name))
elif e.matches(libevdev.EV_SYN.SYN_DROPPED):
print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(e.code.name))
else:
print("-------------- {} ------------".format(e.code.name))
else:
print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))
class PongPlayer:
"""The player consists of gamepad input & variables"""
def __init__(self, path, x, y, w, h):
# Gamepad init.
self.fd = open(path, "rb") # File descriptor to close (later ...)
fcntl.fcntl(self.fd, fcntl.F_SETFL, os.O_NONBLOCK)
self.dev = libevdev.Device(self.fd) # Actual gamepad of this player
self.state = pgc.BTN_STATE_NONE # Button mask (as listed above)
self.x = x # Current position
self.y = y
self.w = w # Dimensions
self.h = h
self.delta_x = 0 # Current delta (speed) settings
self.delta_y = 0
self.color = pgc.COL_WHITE # 'Infection' colour (white = cleared)
self.delay = 0 # 'Infectious' time
self.score = 0 # Current score points of this player
def reinit(self, x, y, delta_x, delta_y):
"""Re-initialize player for next game"""
self.state = 0
self.x = x
self.y = y
self.delta_x = delta_x
self.delta_y = delta_y
self.color = pgc.COL_WHITE
self.delay = 0
def exit(self):
"""To quit gracefully, we should close the event queues ..."""
self.fd.close()
def eval_gamepad(self):
"""Decode gamepad events (if any ...)"""
bChanged = False
try:
for e in self.dev.events():
#print_event(e)
# Event type 1 (EV_KEY)
# Event code 288 (BTN_TRIGGER) <- 1=[Blue/X]
# Event code 289 (BTN_THUMB) <- 1=[Red/A]
# Event code 290 (BTN_THUMB2) <- 1=[Yellow/B]
# Event code 291 (BTN_TOP) <- 1=[Green/Y]
# Event code 292 (BTN_TOP2) <- 1=[Frontal left]
# Event code 293 (BTN_PINKIE) <- 1=[Frontal right]
# Event code 294 (BTN_BASE)
# Event code 295 (BTN_BASE2)
# Event code 296 (BTN_BASE3) <- 1=[Centre left]
# Event code 297 (BTN_BASE4) <- 1=[Centre right]
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
if self.delay <= 0: # As long as we're not infectious ...
self.state = pgc.BTN_TRIGGER # self.state ^ pgc.BTN_TRIGGER
self.color = pgc.COL_BLUE # Infect 'blue'
self.delay = pgc.COLORDELAY # Start infectious time immediately ...
elif e.code.value == 289: # BTN_THUMB
if self.delay <= 0: # As long as we're not infectious ...
self.state = pgc.BTN_THUMB # self.state ^ pgc.BTN_THUMB
self.color = pgc.COL_RED
self.delay = pgc.COLORDELAY
elif e.code.value == 290: # BTN_THUMB2
if self.delay <= 0: # As long as we're not infectious ...
self.state = pgc.BTN_THUMB2 # self.state ^ pgc.BTN_THUMB2
self.color = pgc.COL_YELLOW
self.delay = pgc.COLORDELAY
elif e.code.value == 291: # BTN_TOP
if self.delay <= 0: # As long as we're not infectious ...
self.state = pgc.BTN_TOP # self.state ^ pgc.BTN_TOP
self.color = pgc.COL_GREEN
self.delay = pgc.COLORDELAY
elif e.code.value == 292: # BTN_TOP2
self.state = self.state ^ pgc.BTN_TOP2
elif e.code.value == 293: # BTN_PINKIE
self.state = self.state ^ pgc.BTN_PINKIE
elif e.code.value == 296: # BTN_BASE3
self.state = self.state ^ pgc.BTN_BASE3
elif e.code.value == 297: # BTN_BASE4
self.state = self.state ^ pgc.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:
self.delta_x = self.delta_x - 1
elif e.value == 255:
self.delta_x = self.delta_x + 1
else: # 127/Neutral
self.delta_x = 0
else: # ABS_Y
if e.value == 0:
self.delta_y = self.delta_y - 1
elif e.value == 255:
self.delta_y = self.delta_y + 1
else: # 127/Neutral
self.delta_y = 0
bChanged = True
#if bChanged:
# print("State=",self.state, "X=", self.delta_x, "Y=", self.delta_y)
except libevdev.EventsDroppedException:
print("Dropped!")
for e in self.dev.sync():
print_event(e)
return bChanged
def eval_position(self, min_x, max_x):
"""Player movement w/ area restrictions"""
bChanged = False
# Left/right positioning
sum_x = self.x + self.delta_x * 10
if sum_x < min_x:
sum_x = min_x
elif sum_x + self.w > max_x:
sum_x = max_x - self.w
# Top/bottom positioning
sum_y = self.y + self.delta_y * 10
if sum_y < pgv.GAMEAREA_MIN_Y:
sum_y = pgv.GAMEAREA_MIN_Y
elif sum_y + self.h > pgv.GAMEAREA_MAX_Y:
sum_y = pgv.GAMEAREA_MAX_Y - self.h
# Movement indication (TODO: may be removed later ...)
if (sum_x != self.x) or (sum_y != self.y):
bChanged = True
self.x = sum_x
self.y = sum_y
return bChanged
if __name__ == "__main__":
print("***** pong_player has no function, call 'pandemic_pong.py'!")