[GROS EDIT]
j'etais tout content, j'ai posté ça, mais a l'usage, je me suis rendu compte que ça ne fonctionnait pas, et donc que ça servait un peu a rien . J'ai donc réécrit en partie le bidule, pour qu'il se substitue aux Event irrlicht. Et qu'il serve un peu a quelque chose du coup
NB : J'ai mis en commentaire les fonctions booléennes, mais je les ai enlevées du post parce que je devais dépasser la limite de carateres autorisés . A la place j'ai préféré utiliser les propriétés C# (get et set dans un seul truc). En gros, j'expose seulement l'etat du event.keyCode courant.
le code source est dispo ici
[/GROS EDIT]
ok, c'etait pas grand chose, mais comme j'avais besoin de gerer plus finement mes evenements claviers et sours, j'ai décidé de porter le MastEventReceiver pour le .NetCP le code dispo sur le wiki de Irrlicht.
Meme si le.NetCP utilise les event delegate pour gérer les evenements, je pense que ce code peut servir a quelque chose, etant donné qu'il apporte une granularité plus fine dans la gestion des controles, en portant les etats de 2 a 4 (Up / Down / Pressed / Released). Donc dans l'ordre, la classe que vous pouvez recuperer pour vos projets, et plus bas, quelques exemples pour s'en servir.
Si vous avez des suggestions, des questions, si vous remarquez des trucs pas clean, hésitez pas a poster.
/// ================================================================================================== /// MastEventReceiver code is ø (Copyright) Robert E. Demarest, AKA Mastiff or Mastiff Odit /// This file may be used in any non-commercial or commercial project as long as the following conditions are met: /// You may not claim this code as being your own. /// You may not use this code for any harmful, malicious or otherwise damaging programs. /// /// This is version 1.2a of the class. /// This class is designed for use with the Irrlicht Engine, it was written for version 1.3 of the engine. /// ================================================================================================== /// ////////////////////////////////////////////////////////////////////////////////////////////////////// // // To use this Class just add #include "MastEventReceiver.cpp" to the end of your includes list. (or add the class in-line into your program) // Then create an instance of it like so: MastEventReceiver eventReceiver; // Then call the initialization fucntion like so: eventReceiver.init(); // Then inside your Main Game Loop place "eventReceiver.endEventProcess();" in the beginning of your game loop, before anything - // that would require input, then put "eventReceiver.startEventProcess();" at the very end of your Main Game Loop. // yeah I know it's confusing, but it makes alot more sense in the internals of the class. // ////////////////////////////////////////////////////////////////////////////////////////////////////// // // Ravine's port of MastEventReceiver, for use in Irrlicht.NetCP // // Changes : // // > No more getXxxx functions. I moved all that in the mouseData structure, whith properties (both get{} and set {} ) // > Moving the init() function to the constructor. Since this code does not inherit the event receiver (cause of event design of .NetCP) // i wrote a constructor for the class which do the same as the init(). That function is still here, deactivated by comments (see end of page) // > Changed the function names to fix with C# language specs : LikeThis() instead of likeThis() // > Changed the KeyPressed / KeyDown / KeyUp / KeyReleased functions parameter "keyCode" from char type to IrrlichtNETCP.KeyCode type. // Felt confused by the "char" type, and prefere stick with KeyCode type. Anyway, it's cast to (int) within the function. // > Commented the whole set of functions which returned boolean if the key was in a determinated state. // Use the properties instead LeftMouseButton, MiddleMouseButton, RightMouseButton, and KeyState, which returns // the current state of the concerned keys (the KeyState event refers to the current keyState of the current KeyBoard Event // If you try to read it when it's not a keyboard event, it will throw an "index out of array exception".) // // Bugs corrected : // // > the keystate array was created with KeyCode.CODES_COUNT (basically, its value is 255). // this created an Out-of-Bound exception in the init() function, because of the "for" test (i <= KeyCode.CODES_COUNT) reaches 255 at the end, which is above the last index (254) // > The mouseButtonState array was originally created as an array of 2, which causes that the right button index (2) can't be used (Out-of-Bound exception again) // Now it's created with 3 and all references in tests which involves the mouseButtonState were change from "<= 2" to "< 3" for clarification purpose (purely personnal point of view) // using System; using System.Collections.Generic; using System.Text; using IrrlichtNETCP; using IrrlichtNETCP.Inheritable; namespace YourNameSpace { /// ============================== /// MastEventReceiver /// ============================== public class MastEventReceiver : Event { // the Event properties are read only, so time to set up some similar fields. protected GUIElement caller; protected GUIEventType guiEvent; protected char key; protected KeyCode keyCode; protected bool keyControl; protected bool keyPressedDown; protected bool keyShift; protected string logText; protected MouseInputEvent mouseInputEvent; protected Position2D mousePosition; protected float mouseWheelDelta; protected EventType type; #region Properties public GUIElement Caller { get { return (this.caller); } } public GUIEventType GUIEvent { get { return (this.guiEvent); } } public char Key { get { return (this.key); } } public KeyCode KeyCode { get { return (this.keyCode); } } public bool KeyControl { get { return (this.keyControl); } } public bool KeyPressedDown { get { return (this.keyPressedDown); } } public bool KeyShift { get { return (this.keyShift); } } public string LogText { get { return (this.logText); } } public MouseInputEvent MouseInputEvent { get { return (this.mouseInputEvent); } } public Position2D MousePosition { get { return (this.mousePosition); } } public float MouseWheelDelta { get { return (this.mouseWheelDelta); } } public EventType Type { get { return (this.type); } } #endregion // Enumeration for keyStatesEnum.Up, keyStatesEnum.Down, keyStatesEnum.Pressed and keyStatesEnum.Released key states. Also used for mouse button states. public enum keyStatesEnum { Up, Down, Pressed, Released } // Enumeration for Event Handling State. protected enum processStateEnum { Started, Ended } // Mouse button states. protected keyStatesEnum[] mouseButtonState = new keyStatesEnum[3]; //Left(0), Middle(1) and Right(2) Buttons. // Keyboard key states. protected keyStatesEnum[] keyState = new keyStatesEnum[(int)KeyCode.CODES_COUNT]; // Mouse X/Y coordinates and Wheel data. protected struct mouseData { private int x; private int y; private float wheel; //wheel is how far the wheel has moved public float Wheel { get { return(this.wheel); } set { this.wheel = value; } } public int X { get { return (this.x); } set { this.x = value; } } public int Y { get { return (this.y); } set { this.y = value; } } } protected mouseData mouse; protected processStateEnum processState; // STARTED = handling events, ENDED = not handling events public MastEventReceiver() { //KeyBoard States. for (int i = 0; i < (int)KeyCode.CODES_COUNT; i++) { keyState[i] = keyStatesEnum.Up; } //Mouse states for (int i = 0; i < 3; i++) { mouseButtonState[i] = keyStatesEnum.Up; } caller = null; guiEvent = GUIEventType.ButtonClicked; key = ' '; keyCode = KeyCode.Scroll; keyControl = false; keyPressedDown = false; keyShift = false; logText = null; mouseInputEvent = MouseInputEvent.LMouseLeftUp; mousePosition = new Position2D(); mouseWheelDelta = 0.0f; type = EventType.UserEvent; } ////////////////////// // Public functions ////////////////////// public bool OnEvent(Event ev) { #region copy event's info caller = ev.Caller; guiEvent = ev.GUIEvent; key = ev.Key; keyCode = ev.KeyCode; keyControl = ev.KeyControl; keyPressedDown = ev.KeyPressedDown; keyShift = ev.KeyShift; mouseInputEvent = ev.MouseInputEvent; mousePosition = ev.MousePosition; mouseWheelDelta = ev.MouseWheelDelta; type = ev.Type; try{ logText = ev.LogText; } catch (System.AccessViolationException ex) { } #endregion bool eventprocessed = false; ////////////////////////////// // Keyboard Input Event ////////////////////////////// if (ev.Type == EventType.KeyInputEvent) { if (processState == processStateEnum.Started) { // if key is Pressed Down if (ev.KeyPressedDown == true) { // If key was not down before if (keyState[(int)ev.KeyCode] != keyStatesEnum.Down) { keyState[(int)ev.KeyCode] = keyStatesEnum.Pressed; // Set to Pressed } else { // if key was down before keyState[(int)ev.KeyCode] = keyStatesEnum.Down; // Set to Down } } else { // if the key is down if (keyState[(int)ev.KeyCode] != keyStatesEnum.Up) { keyState[(int)ev.KeyCode] = keyStatesEnum.Released; // Set to Released } } } eventprocessed = true; } ////////////////////////////// // Mouse Input Event ////////////////////////////// if (ev.Type == EventType.MouseInputEvent) { if (processState == processStateEnum.Started) { //Mouse changed position if (ev.MouseInputEvent == MouseInputEvent.MouseMoved) { mouse.Y = ev.MousePosition.Y; mouse.X = ev.MousePosition.X; } //Wheel moved. if (ev.MouseInputEvent == MouseInputEvent.MouseWheel) { // original Cpp : mouse.wheel += ev.MouseInput.Wheel; mouse.Wheel += ev.MouseWheelDelta; } //Left Mouse Button Pressed if (ev.MouseInputEvent == MouseInputEvent.LMousePressedDown) { // if (mouseButtonState[0] == keyStatesEnum.Up || mouseButtonState[0] == keyStatesEnum.Released) { mouseButtonState[0] = keyStatesEnum.Pressed; } else { mouseButtonState[0] = keyStatesEnum.Down; } } //Left Mouse Button Rleased if (ev.MouseInputEvent == MouseInputEvent.LMouseLeftUp) { // if (mouseButtonState[0] != keyStatesEnum.Up) { mouseButtonState[0] = keyStatesEnum.Released; } } //Middle Mouse Button Pressed if (ev.MouseInputEvent == MouseInputEvent.MMousePressedDown) { // if (mouseButtonState[1] == keyStatesEnum.Up || mouseButtonState[1] == keyStatesEnum.Released) { mouseButtonState[1] = keyStatesEnum.Pressed; } else { mouseButtonState[1] = keyStatesEnum.Down; } } //Middle Mouse Button Rleased if (ev.MouseInputEvent == MouseInputEvent.MMouseLeftUp) { // if (mouseButtonState[1] != keyStatesEnum.Up) { mouseButtonState[1] = keyStatesEnum.Released; } } //Right Mouse Button Pressed if (ev.MouseInputEvent == MouseInputEvent.RMousePressedDown) { // if (mouseButtonState[2] == keyStatesEnum.Up || mouseButtonState[2] == keyStatesEnum.Released) { mouseButtonState[2] = keyStatesEnum.Pressed; } else { mouseButtonState[2] = keyStatesEnum.Down; } } //Right Mouse Button Rleased if (ev.MouseInputEvent == MouseInputEvent.RMouseLeftUp) { // if (mouseButtonState[2] != keyStatesEnum.Up) { mouseButtonState[2] = keyStatesEnum.Released; } } } eventprocessed = true; } return eventprocessed; } #region properties public keyStatesEnum LeftMouseButton { get { return mouseButtonState[0]; } } public keyStatesEnum MiddleMouseButton { get { return mouseButtonState[1]; } } public keyStatesEnum RightMouseButton { get { return mouseButtonState[2]; } } public keyStatesEnum KeyState { get { return this.keyState[(int)keyCode]; } } #endregion // This is used so that the Key States will not be changed during execution of your Main game loop. // Place this at the very START of your Main Loop public void EndEventProcess() { processState = processStateEnum.Ended; } // This is used so that the Key States will not be changed during execution of your Main game loop. // Place this function at the END of your Main Loop. public void StartEventProcess() { processState = processStateEnum.Started; //Keyboard Key States for (int i = 0; i < (int)KeyCode.CODES_COUNT; i++) { if (keyState[i] == keyStatesEnum.Released) { keyState[i] = keyStatesEnum.Up; } if (keyState[i] == keyStatesEnum.Pressed) { keyState[i] = keyStatesEnum.Down; } } //Mouse Button States for (int i = 0; i < 3; i++) { if (mouseButtonState[i] == keyStatesEnum.Released) { mouseButtonState[i] = keyStatesEnum.Up; } if (mouseButtonState[i] == keyStatesEnum.Pressed) { mouseButtonState[i] = keyStatesEnum.Down; } } //Mouse Wheel state mouse.Wheel = 0.0f; } } /// ========================================== /// END OF MastEventReceiver /// ========================================== }
Je l'ai commenté avant de poster sur le forum du .NetCP, et j'en ai profité pour relire. A priori c'est sans bug (a priori). Comme toujours, si vous voyez des trucs pas catholiques, hésitez pas a le signaler
Comment ça marche.
//create some MastEventReceiver instance. private MastEventReceiver mastEventReceiver = new MastEventReceiver(); [...other declarations...]
// sticking with his specs, put the EndEventProcess() and StartEventProcess() at beginning and end of the while(device.Run() )
while (device.Run())
{
// CARE he says that you must put the End() at the begining of the scene
mastEventReceiver.EndEventProcess();
driver.BeginScene(true, true, new IrrlichtNETCP.Color());
smgr.DrawAll();
driver.EndScene();
// AND the Start() at the end. If he says so :)
mastEventReceiver.StartEventProcess();
}
Ensuite, il faut se palucher une surcharge du OnEvent qu'on vise ( et déclarer donc un OnEvent(MastEventReceiver e) ) pour pouvoir traiter evenements clavier avec le nouveau comportement.
// within the OnEvent delegate that we all love to use, add some ref to it private bool device_OnEvent(Event e) { mastEventReceiver.OnEvent(e) cam.OnEvent(mastEventReceiver); } return (true); }
J'espere que ce bout de code vous sera utile. J'ai pas enormément eu de soucis pour le transcrire, le code etant clair a la base. j'en ai juste profité pour corriger 2/3 bugs (cf mon paragraphe en dessous du disclaimer de Mastiff).
Enjoy
Dernière modification par Ravine (07-08-2007 15:16:29)
Hors ligne
Un petit bump pour signaler que j'ai mis a jour mon message ainsi que le code, pour qu'il soit un peu plus utile que précédemment.
Modifs :
> Héritage de Event.
> Récupération des infos de Event.
> Utilisation des Properties (get {} ) a la place des fonctions booléennes (toujours présentes cela dit, mais commentées, donc inactives) pour avoir un acces aux etats.
Note : Le KeyState en l'état ne me plait pas. Si quelqu'un chercher a faire une lecture sans avoir vérifié qu'on etait bien en présence d'un keyboardEvent, on risque d'avoir une exception de type "index en dehors du tableau". Si vous avez une idée pour contourner ce genre de souci ( un try catch finally serait pas mal, mais dans ce cas, que renvoyer comme valeur par défaut ?).
Hors ligne