This tutorial builds on example 04.Movement which showed how to handle keyboard events in Irrlicht. Here we'll handle mouse events and joystick events, if you have a joystick connected and a device that supports joysticks. These are currently Windows, Linux and SDL devices.
Just as we did in example 04.Movement, we'll store the latest state of the mouse and the first joystick, updating them as we receive events.
{
public:
struct SMouseState
{
bool LeftButtonDown;
SMouseState() : LeftButtonDown(false) { }
} MouseState;
virtual bool OnEvent(
const SEvent& event)
{
{
{
MouseState.LeftButtonDown = true;
break;
MouseState.LeftButtonDown = false;
break;
MouseState.Position.X = event.MouseInput.X;
MouseState.Position.Y = event.MouseInput.Y;
break;
default:
break;
}
}
{
JoystickState = event.JoystickEvent;
}
return false;
}
{
return JoystickState;
}
const SMouseState & GetMouseState(void) const
{
return MouseState;
}
MyEventReceiver()
{
}
private:
};
Interface of an object which can receive events.
Axis aligned bounding box in 3d dimensional space.
@ EMIE_LMOUSE_LEFT_UP
Left mouse button was left up.
@ EMIE_LMOUSE_PRESSED_DOWN
Left mouse button was pressed down.
@ EMIE_MOUSE_MOVED
The mouse cursor changed its position.
@ EET_MOUSE_INPUT_EVENT
A mouse input event.
@ EET_JOYSTICK_INPUT_EVENT
A joystick (joypad, gamepad) input event.
u8 Joystick
The ID of the joystick which generated this event.
SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
struct SJoystickEvent JoystickEvent
struct SMouseInput MouseInput
The event receiver for keeping the pressed keys is ready, the actual responses will be made inside the render loop, right before drawing the scene. So lets just create an irr::IrrlichtDevice and the scene node we want to move. We also create some other additional scene nodes, to show that there are also some different possibilities to move and animate scene nodes.
int main()
{
if (driverType==video::EDT_COUNT)
return 1;
MyEventReceiver receiver;
if (device == 0)
return 1;
{
std::cout <<
"Joystick support is enabled and " << joystickInfo.
size() <<
" joystick(s) are present." << std::endl;
for(
u32 joystick = 0; joystick < joystickInfo.
size(); ++joystick)
{
std::cout << "Joystick " << joystick << ":" << std::endl;
std::cout << "\tName: '" << joystickInfo[joystick].Name.c_str() << "'" << std::endl;
std::cout << "\tAxes: " << joystickInfo[joystick].Axes << std::endl;
std::cout << "\tButtons: " << joystickInfo[joystick].Buttons << std::endl;
std::cout << "\tHat is: ";
switch(joystickInfo[joystick].PovHat)
{
case SJoystickInfo::POV_HAT_PRESENT:
std::cout << "present" << std::endl;
break;
case SJoystickInfo::POV_HAT_ABSENT:
std::cout << "absent" << std::endl;
break;
case SJoystickInfo::POV_HAT_UNKNOWN:
default:
std::cout << "unknown" << std::endl;
break;
}
}
}
else
{
std::cout << "Joystick support is not enabled." << std::endl;
}
tmp += joystickInfo.
size();
tmp += " joysticks)";
The Irrlicht device. You can create it with createDevice() or createDeviceEx().
virtual void setWindowCaption(const wchar_t *text)=0
Sets the caption of the window.
virtual scene::ISceneManager * getSceneManager()=0
Provides access to the scene manager.
virtual video::IVideoDriver * getVideoDriver()=0
Provides access to the video driver for drawing 3d and 2d geometry.
virtual bool activateJoysticks(core::array< SJoystickInfo > &joystickInfo)=0
Activate any joysticks, and generate events for them.
u32 size() const
Get number of occupied elements of the array.
The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.
Interface to driver which is able to perform 2d and 3d graphics functions.
E_DRIVER_TYPE
An enum for all types of drivers the Irrlicht Engine supports.
unsigned int u32
32 bit unsigned variable.
We'll create an arrow mesh and move it around either with the joystick axis/hat, or make it follow the mouse pointer.
16,16,
2.f, 1.3f,
0.1f, 0.6f
)
);
const f32 MOVEMENT_SPEED = 5.f;
{
const f32 frameDeltaTime = (
f32)(now - then) / 1000.f;
then = now;
bool movedWithJoystick = false;
if(joystickInfo.
size() > 0)
{
f32 moveHorizontal = 0.f;
const f32 DEAD_ZONE = 0.05f;
moveHorizontal =
(
f32)joystickData.
Axis[SEvent::SJoystickEvent::AXIS_X] / 32767.f;
if(fabs(moveHorizontal) < DEAD_ZONE)
moveHorizontal = 0.f;
moveVertical =
(
f32)joystickData.
Axis[SEvent::SJoystickEvent::AXIS_Y] / -32767.f;
if(fabs(moveVertical) < DEAD_ZONE)
moveVertical = 0.f;
const u16 povDegrees = joystickData.
POV / 100;
if(povDegrees < 360)
{
if(povDegrees > 0 && povDegrees < 180)
moveHorizontal = 1.f;
else if(povDegrees > 180)
moveHorizontal = -1.f;
if(povDegrees > 90 && povDegrees < 270)
moveVertical = -1.f;
else if(povDegrees > 270 || povDegrees < 90)
moveVertical = +1.f;
}
if(!core::equals(moveHorizontal, 0.f) || !core::equals(moveVertical, 0.f))
{
nodePosition.
X += MOVEMENT_SPEED * frameDeltaTime * moveHorizontal;
nodePosition.
Y += MOVEMENT_SPEED * frameDeltaTime * moveVertical;
movedWithJoystick = true;
}
}
if(!movedWithJoystick)
{
receiver.GetMouseState().Position, camera);
if(plane.getIntersectionWithLine(ray.start, ray.getVector(), mousePosition))
{
const f32 availableMovement = MOVEMENT_SPEED * frameDeltaTime;
if(toMousePosition.getLength() <= availableMovement)
nodePosition = mousePosition;
else
nodePosition += toMousePosition.
normalize() * availableMovement;
}
}
node->
setMaterialFlag(video::EMF_LIGHTING, receiver.GetMouseState().LeftButtonDown);
}
virtual u32 getTime() const =0
Returns current virtual time in milliseconds.
virtual bool run()=0
Runs the device.
virtual ITimer * getTimer()=0
Provides access to the engine's timer.
T X
X coordinate of the vector.
vector3d< T > & normalize()
Normalizes the vector.
T Y
Y coordinate of the vector.
Scene Node which is a (controlable) camera.
virtual core::line3d< f32 > getRayFromScreenCoordinates(const core::position2d< s32 > &pos, ICameraSceneNode *camera=0)=0
Returns a 3d ray which would go through the 2d screen coodinates.
virtual void drawAll()=0
Draws all the scene nodes.
virtual ISceneCollisionManager * getSceneCollisionManager()=0
Get pointer to the scene collision manager.
virtual IMeshSceneNode * addMeshSceneNode(IMesh *mesh, ISceneNode *parent=0, s32 id=-1, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &rotation=core::vector3df(0, 0, 0), const core::vector3df &scale=core::vector3df(1.0f, 1.0f, 1.0f), bool alsoAddIfMeshPointerZero=false)=0
Adds a scene node for rendering a static mesh.
virtual ICameraSceneNode * addCameraSceneNode(ISceneNode *parent=0, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &lookat=core::vector3df(0, 0, 100), s32 id=-1, bool makeActive=true)=0
Adds a camera scene node to the scene graph and sets it as active camera.
virtual IAnimatedMesh * addArrowMesh(const io::path &name, video::SColor vtxColorCylinder=0xFFFFFFFF, video::SColor vtxColorCone=0xFFFFFFFF, u32 tesselationCylinder=4, u32 tesselationCone=8, f32 height=1.f, f32 cylinderHeight=0.6f, f32 widthCylinder=0.05f, f32 widthCone=0.3f)=0
add a static arrow mesh to the meshpool
virtual void setPosition(const core::vector3df &newpos)
Sets the position of the node relative to its parent.
void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
Sets all material flags at once to a new value.
virtual const core::vector3df & getPosition() const
Gets the position of the node relative to its parent.
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, SColor color=SColor(255, 0, 0, 0), const SExposedVideoData &videoData=SExposedVideoData(), core::rect< s32 > *sourceRect=0)=0
Applications must call this method before performing any rendering.
virtual bool endScene()=0
Presents the rendered image to the screen.
Class representing a 32 bit ARGB color.
float f32
32 bit floating point variable.
unsigned short u16
16 bit unsigned variable.
In the end, delete the Irrlicht device.