diff --git a/samples/gamepad/main.py b/samples/gamepad/main.py new file mode 100644 index 0000000000..189c4e0f16 --- /dev/null +++ b/samples/gamepad/main.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +''' +Demonstrate usage of gamepads and other input devices + +In this sample you can use a gamepad type device to control the camera and +show some messages on screen. Using the left stick on the controler will +move the camera where the right stick will rotate the camera. +''' + +from direct.showbase.ShowBase import ShowBase +from panda3d.core import TextNode, InputDevice, loadPrcFileData, Vec3 +from direct.gui.OnscreenText import OnscreenText + +loadPrcFileData("", "notify-level-device debug") + +class App(ShowBase): + def __init__(self): + ShowBase.__init__(self) + # print all events sent through the messenger + self.messenger.toggleVerbose() + + self.lblWarning = OnscreenText( + text = "No devices found", + fg=(1,0,0,1), + scale = .25) + self.lblWarning.hide() + + self.lblAction = OnscreenText( + text = "Action", + fg=(1,1,1,1), + scale = .15) + self.lblAction.hide() + + self.checkDevices() + + # Accept device dis-/connection events + # NOTE: catching the events here will overwrite the accept in showbase, hence + # we need to forward the event in the functions we set here! + self.accept("connect-device", self.connect) + self.accept("disconnect-device", self.disconnect) + + self.accept("escape", exit) + self.accept("gamepad0-start", exit) + self.accept("flight_stick0-start", exit) + + # Accept button events of the first connected gamepad + self.accept("gamepad0-action_a", self.doAction, extraArgs=[True, "Action"]) + self.accept("gamepad0-action_a-up", self.doAction, extraArgs=[False, "Release"]) + self.accept("gamepad0-action_b", self.doAction, extraArgs=[True, "Action 2"]) + self.accept("gamepad0-action_b-up", self.doAction, extraArgs=[False, "Release"]) + + self.environment = loader.loadModel("environment") + self.environment.reparentTo(render) + + # disable pandas default mouse-camera controls so we can handle the camera + # movements by ourself + self.disableMouse() + + self.taskMgr.add(self.moveTask, "movement update task") + + def connect(self, device): + # we need to forward the event to the connectDevice function of showbase + self.connectDevice(device) + # Now we can check for ourself + self.checkDevices() + + def disconnect(self, device): + # we need to forward the event to the disconnectDevice function of showbase + self.disconnectDevice(device) + # Now we can check for ourself + self.checkDevices() + + def checkDevices(self): + # check if we have gamepad devices connected + if self.devices.get_devices(InputDevice.DC_gamepad): + # we have at least one gamepad device + self.lblWarning.hide() + else: + # no devices connected + self.lblWarning.show() + + def doAction(self, showText, text): + if showText and self.lblAction.isHidden(): + self.lblAction.show() + else: + self.lblAction.hide() + + def moveTask(self, task): + dt = globalClock.getDt() + movementVec = Vec3() + + gamepads = base.devices.getDevices(InputDevice.DC_gamepad) + if len(gamepads) == 0: + # savety check + return task.cont + + # we will use the first found gamepad + for i in range(gamepads[0].getNumControls()): + if gamepads[0].getControlMap(i) == InputDevice.C_left_x: + movementVec.setX(gamepads[0].getControlState(i)) + elif gamepads[0].getControlMap(i) == InputDevice.C_left_y: + movementVec.setY(gamepads[0].getControlState(i)) + + if gamepads[0].getControlMap(i) == InputDevice.C_right_x: + base.camera.setH(base.camera, 100 * dt * (gamepads[0].getControlState(i))) + elif gamepads[0].getControlMap(i) == InputDevice.C_right_y: + base.camera.setP(base.camera, 100 * dt * (gamepads[0].getControlState(i))) + + # calculate movement + base.camera.setX(base.camera, 100 * dt * movementVec.getX()) + base.camera.setY(base.camera, 100 * dt * movementVec.getY()) + + return task.cont + +app = App() +app.run()