XNA UK User Group

A helping hand for bedroom coders throughout the land.
in

RandomChaos

  • Anyone getting sick of clouds yet?

    http://www.youtube.com/v/P-Nw4CANeBc <p><a href="http://www.youtube.com/v/P-Nw4CANeBc">http://www.youtube.com/v/P-Nw4CANeBc</a></p>

    So, here is the system (still not finished) with the skysphere and my infantile physics system. Again footage taken on my poop laptop so bit slow, but on my 360 it's a steady 60FPS.

    I think the flying ship gives a better perspective than the terrain, also I have altered the cloud shader to take into account the time of day, you will see at night fall the clouds are no longer bright white.

    As ever comment and ratings welcome.

  • Speech in you Windows XNA Games

    I found this while messing about with the media player in XNA, just noticed there is some legacy code in the download from it :( Anyway, how to get speech into your games, it's dead easy really, you just need to have .NET Framework 3.0 and you have all you need.

    NOTE: You don't need XNA 3.0 for this just the .NET 3.0 Framework on your system.

    First off you need to add the System.Speech assembly to your project references, then in your Game1.cs add the following:

    using System.Speech.Synthesis;

    and in your Game1 class add:

    SpeechSynthesizer synth = new SpeechSynthesizer();

    Now, all you have to do is call the synth.SpeackAsync() method passing the text you want to have spoken. I used this:

    synth.SpeakAsync("Hello, Welcome to the Random Chaos Generic X N A Speech Sample." +
                                    " This sample is hosted by; the X N A U K User Group. Thanks " +
                                    "to Leaf and Robin for letting me host my blog here and I hope " +
                                    "you find my samples useful.");

    This will use the default voice that is set up on your PC (see Control Panel->Speech). But you can also access the other two voice types that ship with the OS (XP, not sure about Vista). To do this try any one of these:

    synth.SelectVoice("LH Michael");
    synth.SelectVoice("LH Michelle");
    synth.SelectVoice("Microsoft Sam");

    I prefer "LH Michael", reminds me of Stephen Hawking and I think it's a little clearer than the other two.

    I know, not the best chat in the world, but it's free lol

  • Yes, more clouds...

    http://www.youtube.com/v/XlG2nwv9QAA <p><a href="http://www.youtube.com/v/XlG2nwv9QAA">http://www.youtube.com/v/XlG2nwv9QAA</a></p>

    Yes, been playing some more with the clouds. I have had the last clip playing on the 360 and it not drop below 60 fps, on my laptop I get about 7fps, and yes, my laptop sux!!

    So I have now put it with my dynamic sky sphere, and I think it looks pretty good. In the clip I am showing a few large clouds in a huge bounding volume against the sky sphere, then a large cloud field against the sky sphere showing the transfer from day to night and back again. I have not implemented lighting on the clouds but I think it still looks nice, the final bit of the clip is both bits together with an added mushroom cloud in the middle.

    Still much to do and as ever, very little time, but I am getting there I think, all though slowly :)

  • 3D Clouds in XNA - Another Update

    http://www.youtube.com/v/khntLU3v_-s <p><a href="http://www.youtube.com/v/khntLU3v_-s">http://www.youtube.com/v/khntLU3v_-s</a></p>

    Well I have kind of been letting this code sit for a while, not looked at it as of late, then this week decided to have another play with it, kind of hoping I can put it to bed.

    So I have not started to use Ninians sprite sheet, the sheet is full of alphas, so instead of getting them off the sheet and then just sending them to the screen, set the base colour of the sprite then multiply its alpha by the RGB returned from the sprite sheet. This I think gives a more natural cloud look. I still have some performance issues, but have managed to speed up the draw order sort and that has helped a little. I have also put in some terrain so you have a point of reference, was a bit odd just looking at clouds hanging there in the sky..

    I still have tones I want to do with this yet. I think the next thing will be imposters, then an editor so you can create a cloud field or set of clouds and be able to save them to disk and re use them as an when you like. Naturally more optimizations and some lighting in the shader.

    Hop you like the clip, ratings, and comments are welcome as ever.

  • Generic XNA - Threading for Windows

     

    Well I have done some basic threading in my job, basic stuff and thought I would try and put the basic threading I have done into an XNA Game Component. I am not saying this is how you should do your threading, my method is certainly not the only way to thread processes either and more than likely not the best. I think though that if you are new to development and you want to thread part of your game then I think this may be of some use to you.

    What is a thread?

    OK, there are a few links out there that describe what a thread is better than I could, so here are a few links for reference:-

    Research Microsoft Andrew D. Birrel (not read this yet, looks v good though)

    MSDN (Again, I should read this too...)

    ThreadManager

    This is a simple manager, you can pass methods to it that you want to have processed in a thread of there own. You can have as many threads as you like, BUT, it's probably best to keep your threads down to as few as possible, don't go threading processes because you can.

    So, on to the code. The ThreadManager class is derived from (as most my samples) from GameComponent. The threading method I use requires four components, ParameterizedThreadStart if you don't need to pass parameters to your thread start method then you can use ThreadStart; these are how we bind our method to a Thread, Thread this is the actual thread class used to start and stop the thread, ManualResetEvent this class is used to manage the call interval for the thread and the Mutex class which is used to ensure there are no thread clashes. I wanted to be able to add as many threads as I wanted in my ThreadManager so I have put these class instances into Dictionaries. Also in this implementation I wanted to be able to manage how often the thread code was ran and also to be able to kill a thread at will. To do this I added two other dictionaries to hold what threads I want to stop and one for the interval between thread calls.

    /// <summary>
    /// This is the Thread manager.
    /// </summary>
    public class ThreadManager : GameComponent
    {
        /// <summary>
        /// List of ParameterizedThreadStart used to start the treads.
        /// </summary>
        private Dictionary<int, ParameterizedThreadStart> threadStarters = new Dictionary<int, ParameterizedThreadStart>();
        /// <summary>
        /// List of runnign threads.
        /// </summary>
        private Dictionary<int,Thread> threads = new Dictionary<int,Thread>();
        /// <summary>
        /// Used to make the thread wait.
        /// </summary>
        public static Dictionary<int, ManualResetEvent> threadStopEvent = new Dictionary<int, ManualResetEvent>();
        /// <summary>
        /// Mutex's to stop thread clashes.
        /// </summary>
        public static Dictionary<int, Mutex> mutexs = new Dictionary<int, Mutex>();
        /// <summary>
        /// List of bools to control imediate stopping of thread loops.
        /// </summary>
        public static Dictionary<int, bool> stopThreads = new Dictionary<int, bool>();
        /// <summary>
        /// List of intervals threads will wait befoer next cycle.
        /// </summary>
        public static Dictionary<int, int> threadIntervals = new Dictionary<int, int>();
        /// <summary>
        /// Managers GameTime to be passed onto the threads.
        /// </summary>
        static GameTime gameTime;
    
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="game">Calling game class</param>
        public ThreadManager(Game game) : base(game)
        { }
    
        /// <summary>
        /// Overiden Update call, loads manager gameTime varaible.
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            ThreadManager.gameTime = gameTime;
    
            base.Update(gameTime);
        }
    
        /// <summary>
        /// Method to add a thread to the maanger.
        /// </summary>
        /// <param name="threadCode">Code to be executed in the thread.</param>
        /// <param name="threadInterval">Time period between each call in miliseconds</param>
        /// <returns>Index of thread, first one added will be 0 next 1 etc..</returns>
        public int AddThread(ThreadCode threadCode, int threadInterval)
        {
            int retVal = threads.Count;
    
            threadStarters.Add(threadStarters.Count, new ParameterizedThreadStart(ThreadWorker));
            threads.Add(threads.Count, new Thread(threadStarters[threads.Count]));
            threadStopEvent.Add(threadStopEvent.Count, new ManualResetEvent(false));
            mutexs.Add(mutexs.Count, new Mutex());
            threadIntervals.Add(threadIntervals.Count, threadInterval);
            stopThreads.Add(stopThreads.Count, false);
    
            threads[threads.Count-1].Start(new ThreadCodeObj(threadCode,threads.Count-1));
    
            return retVal;
        }
    
        /// <summary>
        /// Method to kill a single thread.
        /// </summary>
        /// <param name="index"></param>
        public void KillThread(int index)
        {
            mutexs[index].WaitOne();
            stopThreads[index] = true;
            threads[index].Join(0);
            mutexs[index].ReleaseMutex();
        }
        
        /// <summary>
        /// Method to start a thread
        /// </summary>
        /// <param name="threadCode"></param>
        /// <param name="threadInterval"></param>
        /// <param name="index"></param>
        public void StartThread(ThreadCode threadCode,int threadInterval,int index)
        {
            if (threads[index].ThreadState == ThreadState.Stopped)
            {
                threads[index] = new Thread(threadStarters[index]);
                threadIntervals[index] =  threadInterval;
                stopThreads[index] = false;
                threads[index].Start(new ThreadCodeObj(threadCode, index));
            }
        }
    
        /// <summary>
        /// This is the method that is called per thread.
        /// </summary>
        /// <param name="ThreadCodeObject">Instance of ThreadCodeObj to execute.</param>
        private static void ThreadWorker(object ThreadCodeObject)
        {
            int index = ((ThreadCodeObj)ThreadCodeObject).threadIndex;
    
            do
            {
                try
                {
                    mutexs[index].WaitOne();
                    if (gameTime != null)
                        ((ThreadCodeObj)ThreadCodeObject).CodeToCall(gameTime);
    
                }
                finally
                {
                    mutexs[index].ReleaseMutex();
                }
            }
            while (!threadStopEvent[index].WaitOne(threadIntervals[index], false) && !stopThreads[index]);
        }
    
        /// <summary>
        /// Method to tidy up unfinished threads.
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            for (int t = 0; t < threads.Count; t++)
                KillThread(t);
    
            base.Dispose(disposing);
        }
    }

    As you can see in the code snippet above, there are 4 methods that are not native to the GameComponent, AddThread, KillThread, StartThread, ThreadWorker.

    AddThread

    Well, guess what this method does...yep, adds a thread to the manager. So each thread needs one of the base thread elements to, I also set the interval and if the thread is stopped. I set the flag to say this thread has been stopped, then call the threads Join method, this stops (blocks) this thread from running until the thread terminates, this won't happen until the threads loop in ThreadWorker exits and is why I set the stop flag for the thread so that it will terminate. You will see in this call I use another class ThreadCodeObj.

    ThreadCodeObj

    /// <summary>
    /// This is the delegate to be used for passing the code to be called in the tread.
    /// </summary>
    /// <param name="gameTime">GameTime</param>
    public delegate void ThreadCode(GameTime gameTime);
    
    /// <summary>
    /// This class holds the required data for the code to be called in the thread.
    /// </summary>
    internal class ThreadCodeObj
    {
        public ThreadCode CodeToCall = null;
        public int threadIndex = -1;
    
        public ThreadCodeObj(ThreadCode code, int index)
        {
            CodeToCall = code;
            threadIndex = index;
        }
    }

    This class stores the code to be called in the thread and the index of the thread it is to be used in.

    KIllThread

    Yep, you got it, kills a running thread. First off the treads mutex calls it's WaitOne method, this method holds this thread up until it's free to do it's work.

    StartThread

    Restarts a killed thread. First check if this thread has been stopped, if it has then re initialise the threads elements.

    ThreadWorker

    Well this I guess is where it all happens, first we get the index of the thread we are in, then we kick off the threads loop, get the mutex for this thread to tell us when it is safe to call the delegate, then we make sure the gameTime instance is not null and call the delegate. We then get the mutex for this thread to signal that we are done and then check if we need to leave the loop and if not wait for the given interval for this thread index.

     Implementation

    So as with most of my samples (I like to think) it's simple to add a method to a thread. First of all set up the ThreadManager and add it to the Game.Components list, now simply call the ThreadManager.AddThread method, passing it the method you want to put in the thread via the ThreadCode delegate along with the interval you want for the thread. I guess most of the threads you will create will have a time span of 0 so they are executed immediately.

    You will also notice I have not bothered with affinity (the ability to request the processor the thread will run on) in this sample, this is because on a PC, you wont know how many CPU's your application will be running on so it's probably best left up to the OS to sort it out.

    My next post on threading will be for the XBox, it will be almost identical with this source but will have affinity included, we know where we stand with the 360, we know what processors, how many cores and which ones we can put threads on.

    The sample code shows this working in a very simplistic manor, I simply add three methods to the thread manager that populate a variable that holds the game time each time it is called. You can kill the thread and then re start them with an interval of 0.

    Source solution can be found here.

  • Generic XNA - Movies in your Windows games

    Well, I started looking into this after a friend of mine asked if it could be done. I remembered the other week on Ziggyware that someone got a web cam to stream in an XNA app and so thought that the principle should be the same, taking the output, rendering it as a texture then applying it as you required. So started to try and do it myself, well I came a cropper as the examples I came across were for the old MDX and not XNA (I am not bright enough to do a full port), having to use unsafe code to get handles to the Game.Graphics device etc... but then I came across this post on codeplex as well as a few others which gives a class in XNA to do just this using DirectShow. Now all the examples I found seem to have originated from this post on CodeProject, as does the class I am using here.

    Now you may be wondering, where is the movie clip for this....well fraps does not seem to play well with the method I am using to do this and so does not generate a nice clip for me to put up, wish it did because I think it's pretty cool.

    Anyway, all I have done is got this lovely class's output image on a 3D surface. This means you can have movies playing in your games in a virtual cinema, have adverts playing on an advertising billboard as you race past in your racer game, have a television like in GTA IV (I love the cartoons!)

    Clip of the Web Cam in XNA done by MirageProject on YouTube, this gives you an idea of what my implementation looks like, but instead of giving it a device to read from you give it a *.wmv, *.mpg or any other supported format. Also, notice in my image above that the clip on the left is in black and white, this is down to the shader effect applied, not the clip.

    http://www.youtube.com/v/1s63YEWwgqI <p><a href="http://www.youtube.com/v/1s63YEWwgqI">http://www.youtube.com/v/1s63YEWwgqI</a></p>

     

    You can get the solution zip here. (You have to supply your own clips or the zip would have been huge!!)

  • RandomChaos Physics

    http://www.youtube.com/v/F8ImehSQ_ow <p><a href="http://www.youtube.com/v/F8ImehSQ_ow">http://www.youtube.com/v/F8ImehSQ_ow</a></p>

    So I have started work on a simple physics engine. I intend to have it serve both 2D and 3D development. I guess it wont have all the lovely bits and bobs that engines like BulletX have, but what the hell, it's going to help me understand how a Physics Engine works. Not sure about all the others, but this will naturally be exclusively for XNA and so written in C#. As ever I will put the full source up here once I have finished it so you can improve or add to it.

    So needless to say, other things may well be held up; Nova Wars and the Volumetric Cloud system being just two of them. As I think I have mentioned before; my goal now with the blog is to take all the samples I have put up and get them into an engine. This will also help me debug the samples as I will know what plays well with others and what does not. So I kind of think a Physics Engine, no matter how basic, will be a great addition.

    The clip in this post just shows where I currently am with the Physics Engine which is basic Force Generators. There is so much to do, not to mention adding 2D Physics too...I really have become an XNA junkie....help.....I don't seem to be able to stop..

  • Generic XNA - Fire 2D & 3D Shaders

    http://www.youtube.com/v/F2RMt7KKpW0 <p><a href="http://www.youtube.com/v/F2RMt7KKpW0">http://www.youtube.com/v/F2RMt7KKpW0</a></p>

    Well, this should be the final post on these flame shaders. As you have seen in the previous posts I have created 2D and 3D flame shaders based on the flame shader that comes with the NVIDIA SDK. When I initially created the 2D shader I found there was an issue with it when drawn with the 3D effect, turns out the issue was in the FireEmitterBase class, it was fixed by me setting the effect save state in the Begin call. Once that was done it all rendered fine.

    The only issue with the 2D flame shader is that you have to make a draw call per flame as an index.offset has to be passed per flame or the flame animations will all look the same.

    I have put them all in the same project, just added a new class for the 2D flame, as well as the shader it's self and a floor class.

    Solution can be found here.

  • Generic XNA - Fire 2D

    http://www.youtube.com/v/0pR_MX3ytuQ <p><a href="http://www.youtube.com/v/0pR_MX3ytuQ">http://www.youtube.com/v/0pR_MX3ytuQ</a></p>  

    Well, just posting my first attempt at getting the flame shader into 2D. It's not perfect, but as it stands at the moment, will give you 2D flames. When played with the 3D flames it does not seem to render well, but on it's own, as you can see it seems to be working. I am going to give it a bit of testing before I put the source out, but think it should be fine for pure 2D implementation, also still need to move the code into it's own solution....

    As ever C&C welcome.

  • Generic XNA - 3D Fire Sample

    Hope the music is acceptable this time...

    http://www.youtube.com/v/y-txtVQ7rUU <p><a href="http://www.youtube.com/v/y-txtVQ7rUU">http://www.youtube.com/v/y-txtVQ7rUU</a></p>

    Sorry about the quality of the clip, it was a 20MB clip, but I think youtube has crunched it up adn so it has lost some quality....

    OK, here is the code sample for the flame shader I have adapted from NVIDIA's Volumetric Flame shader. The emitter class is pretty much the same as the billboard particle samples in my earlier posts, the real work is in the shader. I took the original NVIDIA flame shader and merged it with my billboard shader resulting in the sample you see here.

    Now the emitter given in this sample is very basic, but I am sure you will be able either derive from it or use it as a template for your own flame emitter.

    I have had a few requests regarding a 2D version of the shader so I am going to look at applying it to a 2D context.

    Solution can be located here.

  • SkyBox Shader Fix

    I have found my skybox shader has a bug in it, the shader displays the cubemap as a reflection, the following shader code will give a better result.

    So, if you have used my skybox sample then replace the shader with this code:

    Texture surfaceTexture;
    samplerCUBE TextureSampler = sampler_state 
    { 
        texture = <surfaceTexture> ; 
        magfilter = LINEAR; 
        minfilter = LINEAR; 
        mipfilter = LINEAR; 
        AddressU = Mirror;
        AddressV = Mirror;
    };
    
    float4x4 World : World;
    float4x4 View : View;
    float4x4 Projection : Projection;
    
    float3 EyePosition : CameraPosition;
    
    struct VS_INPUT 
    {
        float4 Position    : POSITION0;
        float3 Normal : NORMAL0;    
    };
    
    struct VS_OUTPUT 
    {
        float4 Position    : POSITION0;
        float3 ViewDirection : TEXCOORD2;
            
    };
    
    float4 CubeMapLookup(float3 CubeTexcoord)
    {    
        return texCUBE(TextureSampler, CubeTexcoord);
    }
    
    VS_OUTPUT Transform(VS_INPUT Input)
    {
        float4x4 WorldViewProjection = mul(mul(World, View), Projection);
        float3 ObjectPosition = mul(Input.Position, World);
        
        VS_OUTPUT Output;
        Output.Position    = mul(Input.Position, WorldViewProjection);
        
        
        Output.ViewDirection = ObjectPosition - EyePosition;    
        
        return Output;
    }
    
    struct PS_INPUT 
    {    
        float3 ViewDirection : TEXCOORD2;
    };
    
    float4 BasicShader(PS_INPUT Input) : COLOR0
    {    
        float3 ViewDirection = normalize(Input.ViewDirection);    
        ViewDirection.x *= -1;
        return CubeMapLookup(ViewDirection);
    }
    
    technique BasicShader 
    {
        pass P0
        {
            VertexShader = compile vs_2_0 Transform();
            PixelShader  = compile ps_2_0 BasicShader();
        }
    }

    Sorry for giving you a crappy shader in the first place :P

  • Generic XNA - Fire

     

    Yes, I have been playing with fire! I have had this flame shader by NVIDIA (from the SDK) for ages now. I tried to implement in my olf RC3D Engine but it was a poor attempt and was of no real use to anyone, but I think I may have the beginnings of a decent implementation now. I have mixed the NVIDIA shader based on Yury Uralsky's "Volumetric Fire" with my billboard shader and billboard particle system and it seems to be playing quite well.

    Take a look at the clip and let me know what you think.

    http://www.youtube.com/v/ywhEuMNF19c <p><a href="http://www.youtube.com/v/ywhEuMNF19c">http://www.youtube.com/v/ywhEuMNF19c</a></p>

  • Generic XNA - Ocean II

    "Water, Water everywhere and not a drop to drink..."

    http://www.youtube.com/v/dp1wC53S4XA <p><a href="http://www.youtube.com/v/dp1wC53S4XA">http://www.youtube.com/v/dp1wC53S4XA</a></p>

    Yes more water. This is the fix to my original Ocean class. I found a fair few errors in the class, the shader was fine, just me as usual. As you can see the performance is better and is comparable with Anirudh S Shastry's shader I posted last time.

    Not much else to add so you can locate the solution here.

  • Generic XNA - Water

    http://www.youtube.com/v/fy8oFZ_3O68 <p><a href="http://www.youtube.com/v/fy8oFZ_3O68">http://www.youtube.com/v/fy8oFZ_3O68</a></p>  

    Yes, I know, I have already put up the NVIDIA ocean shader, but after a member of the community had some issue with it, mostly how it played with the SkySphere sample I found that in my naive XNA days (I know, I am still learning) I made a shed load of errors in the implementation of the class. This I am going to remedy in my next post, so expect the Ocean Shader II post to be next.

    During my investigation of the issues David Reilly was having with the combination of Ocean and SkySphere I came across a water shader that I found ages ago. I cant for the life of me remember where I got it from, but I am glad I found it. It's written by Anirudh S Shastry and it does all the stuff the NVIDIA shader does but I personally think that it has better performance. I guess putting them both up here gives you the choice when it comes to water shaders. I also plan to come up with my own water shader at some point, but for now here are the third party shaders I have.

    As far as the shader goes, I have not changed much, there was a redundant routine or two, but other than that it is pretty much as I found it. As with the NVIDIA shader, all I have done is provided an XNA class that gives access to the shader and it's parameters.

     

    Hope you find it useful. Solution can be found here.

  • Generic XNA - Wiring your own Events

    GenericXNAEvents

    As I mentioned in one of the post responses on this blog here is an examples of how you can wire up events in your game object. As usual I have tried to keep this as simple as I can to try and make it clear whats going on.

    I guess the first thing to do is describe what an event is, well an event can be anything that occurs during the execution of your game, an enemy shoots, a bomb detonates, the player passes the mouse over a game object (as in this example) but rather than checking ALL your objects each loop you just want to be told when this happens so you can do what you need to do to handle the event. I guess this is a pretty basic C# skill, but if you are not a C# developer you may not know how to do this, so here is my example of Events and how I wire them up.

    So off to the code, I created a new project called GenericXNAEvents, off this project I created the object I am going to use in this example, a simple object that will display a coloured rectangle and have events attached to it that tell me when the mouse is passed over it, clicked on it and when the mouse leaves it. The first thing I do is create a delegate that defines my event, I make this public so it is accessible outside of my class as this dictates how the event handler will be written by those "subscribing" to the events. This done I then create my events, these are logical instances of the delegate that are going to be used to "Fire" my events when they occur, "Subscribers" will also be able to attach (wire) them selves to these events.

     

    // Delegate definition of an event.
    public delegate void FiredEvent(object sender);

    // Instances of delegate event.
    public FiredEvent OnMouseOver;
    public FiredEvent OnMouseOut;
    public FiredEvent OnMouseClick;

     

    As you can see I have three events, one for when the mouse is over this object, one for when it moves off this object and one for when this object is clicked.

    Now, I create the conditions that fire my events in the Update method.

    // Is the mouse over me?
    Point mouseCoord = new Point(Mouse.GetState().X,Mouse.GetState().Y);
    Rectangle mouseRec = new Rectangle(mouseCoord.X, mouseCoord.Y, 1, 1);
    
    Rectangle me = new Rectangle(left,top,width,height);
    
    // Check for mouse over and moust out.
    if (me.Intersects(mouseRec))
    {
        moueOver = true;
        
        // If someone has subscribed to this event, tell them it has fired.
        if (OnMouseOver != null)
            OnMouseOver(this);
    }
    else
    {
        if (moueOver)
        {
            moueOver = false;
            // If someone has subscribed to this event, tell them it has fired.
            if (OnMouseOut != null)
                OnMouseOut(this);
        }
    }
    
    // Check for mouse clicked.
    if (moueOver && Mouse.GetState().LeftButton == ButtonState.Pressed)
    {
        // If someone has subscribed to this event, tell them it has fired.
        if (OnMouseClick != null)
            OnMouseClick(this);
    }

    First thing I do is create the rectangles that will be used to check for intersection with the mouse, if the mouse intersects the object then I set my boolean flag marking that the mouse is over me to true, then check to see if anyone has subscribed to my OnMouseOver event, if they have I call there event handlers. If I am not intersecting the mouse and the mouse has been over me, then the mouse must have moved off of me, so I set my flag to false, check to see if anyone has subscribed to my OnMouseOut event, if they have I call there event handlers. Finally, if the mouse is over me and it has been clicked I check if anyone has subscribed to my OnMouseClick event and if they have, call there event handlers.

    So that's the mechanics of it, how do I now subscribe to these events??

    In the constructor of my Game1 Class I create three instances of my EventObjects, placed at different locations on the screen with different names and colours, I then "wire" up my event handlers.

    EventObject obj1 = new EventObject(this, "Obj1", Color.Red, 100, 150, 32, 32);
    EventObject obj2 = new EventObject(this, "Obj2", Color.Gold, 100, 500, 64, 32);
    EventObject obj3 = new EventObject(this, "Obj3", Color.Silver, 400, 200, 64, 64);
    
    // Wire up mouse over events.
    obj1.OnMouseOver += new EventObject.FiredEvent(MouseOver);
    obj2.OnMouseOver += new EventObject.FiredEvent(MouseOver);
    obj3.OnMouseOver += new EventObject.FiredEvent(MouseOver);
    
    // Wire up mouse out events.
    obj1.OnMouseOut += new EventObject.FiredEvent(MouseOut);
    obj2.OnMouseOut += new EventObject.FiredEvent(MouseOut);
    obj3.OnMouseOut += new EventObject.FiredEvent(MouseOut);
    
    // Wire up mouse click events
    obj1.OnMouseClick += new EventObject.FiredEvent(MouseClick);
    obj2.OnMouseClick += new EventObject.FiredEvent(MouseClick);
    obj3.OnMouseClick += new EventObject.FiredEvent(MouseClick);

    I now need to create my event handlers, these handlers MUST have the same pattern (return value and parameters) as the FiredEvent delegate defined earlier or you will get a compile error. Also note that I have appended (+=) the event handlers to the objects events, this means you can have a single event fire more than one event handler, you can associate a single handler if you like (=), and this will replace ALL previously set handlers to the one you specify.

    public void MouseOver(object sender)
    {
        if (sender is EventObject)
        {
            message = string.Format("Mouse is over {0}", ((EventObject)sender).Name);
        }
    }
    
    public void MouseOut(object sender)
    {
        message = "No Message.";
    }
    
    public void MouseClick(object sender)
    {
        if (sender is EventObject)
        {
            message = string.Format("Mouse clicked {0}", ((EventObject)sender).Name);
        }
    }

    As you can see I am checking to see what the sender is before I do anything with it, you could have objects with a similar event definition call this event handler also, but in this case we just have the one.

    So effectively you can have an event call multiple event handlers and have event handler called by multiple objects and object types. Pretty cool eh?! Thanks Microsoft :)

    Full solution example can be found here.

    Any questions, please post them here and I will do my best to answer them.

More Posts Next page »