Skip to content

Instantly share code, notes, and snippets.

@dov
Created November 30, 2020 21:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dov/696db3faa1cc702b5362fd0bbb201cad to your computer and use it in GitHub Desktop.
Save dov/696db3faa1cc702b5362fd0bbb201cad to your computer and use it in GitHub Desktop.
Example of how to move two circles on a goocanvas with a gamepad
#!/usr/bin/python
######################################################################
#
# An example of how to use the gamepad as an input device for
# python.
#
# The example shows two dots that can be controlled by the
# left and the right joystick on a gamepad.
#
# This may be used as the basis for any analog output. E.g. to
# control a camera tilt focus and zoom.
#
# Note! To get this to work, input needs to be patched as follows:
#
# self._character_file = io.open(
# self._character_device_path, 'rb')
# fd = self._character_file.fileno()
# flag = fcntl.fcntl(fd, fcntl.F_GETFL)
# fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK)
#
# See: https://github.com/zeth/inputs/issues/7
#
# License: This code is released under the MIT license.
#
# 2020-11-30 Mon
# Dov Grobgeld <dov.grobgeld@gmail.com>
######################################################################
import pdb
import inputs
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GooCanvas', '2.0')
from gi.repository import Gtk, GLib, GooCanvas
import time
class MainWindow(Gtk.Window):
def __init__(self):
super(MainWindow, self).__init__()
self.connect("destroy", Gtk.main_quit)
width,height = 800,800
self.set_size_request(800, 800)
# Create the GooCanvas widget
cv = GooCanvas.Canvas()
# And ask for access to the root layer
root = cv.get_root_item()
rect = GooCanvas.CanvasRect(
parent = root,
x = 0, y = 0,
width = width, height = height,
fill_color = "#e0ffe0")
self.lball = GooCanvas.CanvasEllipse(
parent = root,
x = width/2,
y = height/2,
radius_x = width/50, radius_y = width/50,
line_width = 3.0,
fill_color = "#ff0000")
self.rball = GooCanvas.CanvasEllipse(
parent = root,
x = width/2,
y = height/2,
radius_x = width/50, radius_y = width/50,
line_width = 3.0,
fill_color = "#00ff00")
self.add(cv)
self.show_all()
# Current speed motion speed for the left and the right ball.
self.dxl = 0
self.dyl = 0
self.dxr = 0
self.dyr = 0
self.gamepad = inputs.devices.gamepads[0]
# Refresh the ball position 100 times a second
GLib.timeout_add(10, self.update_ball_pos)
def update_ball_pos(self):
# Current ball positions
xl = self.lball.get_property('x')
yl = self.lball.get_property('y')
xr = self.rball.get_property('x')
yr = self.rball.get_property('y')
# Consume all pending events
while True:
events = self.gamepad._do_iter()
if events is None or len(events)==0:
break
for event in events:
# Here are the four joystick axes that we
# map to the left and the right ball
if event.code == 'ABS_X':
self.dxl = (event.state-128)/50
elif event.code == 'ABS_Y':
self.dyl = (event.state-128)/50
elif event.code == 'ABS_Z':
self.dxr = (event.state-128)/50
elif event.code == 'ABS_RZ':
self.dyr = (event.state-128)/50
# Update the ball positions
self.lball.set_property('x', xl+self.dxl)
self.lball.set_property('y', yl+self.dyl)
self.rball.set_property('x', xr+self.dxr)
self.rball.set_property('y', yr+self.dyr)
return True
if __name__ == '__main__':
mainwdw = MainWindow()
Gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment