Daybreak motor XNA 3D Engine
Users Online
· Guests Online: 2

· Members Online: 0

· Total Members: 1
· Newest Member: mike
Latest Articles
xna-uk
XNA 4.0 Official

XNA 4.0 was officially announced today at GDC 2010, earlier this week support was announced by Windows Phone 7 Series phones for XNA developed products and to support this new platform XNA 4.0 has been announced. So besides support for Microsoft's new mobile OS, what does XNA 4 change?

Firstly, there is now support for Visual Studio 2010. Next there have been audio improvements with support for dynamic audio output and microphone input. Further to this there have been a number of graphics changes and optimisations, with the addition of new effect classes (like BasicEffect) to support skinned animations, environment mapping, dual textures and alpha testing. 

More details at Michael Klucher's blog and Sgt. Conker's blog



MVP 2010 Summit

Well, what a great week I had a the summit, as ever, can’t tell you much about it due to our NDA’s but here are some pics from my time there, I have also pinched some pics from other MVP’s (well Benjamin’s pics :P)

2010-02-16 17.39.12

Bellevue was really nice, quite, but nice.

2010-02-16 17.39.23

My room mate Vicente Cartas Espinel, was great to meet you Vicente, you were a great roomie :)

2010-02-17 02.23.40

Andy “Z_Man” Dunn and Michael Cummings, just off to the left is Catalin Zima. It was so cool to meet so many XNA community legends, I was quite awestruck I think.. o.O

2010-02-17 02.23.49

Phil Bourke and Vicente in deep conversation, Benjamin Nitschke is to the right.

2010-02-17 04.30.33

MVP’s, beer and XNA talk, a great combination! (well till the morning I found..)

2010-02-17 06.25.44

No idea what Andy was conveying here, I may have had one too many by this time..

2010-02-17 19.36.51

Onto the serious stuff, day 1 of XNA bits..

2010-02-18 03.50.36

Some RockBand madness.

2010-02-19 00.56.52

Got to meet the XNA Team too, I am truly awestruck now…!

2010-02-19 01.45.08

Back to the hotel (this was the view from our window), before off out again.

Next set of pictures are Benjamin’s, can you tell I have had a drink?

BenjaminsPics1

I may have had a pint or so…

BenjaminsPics5

Yep, had a few we did….

BenjaminsPics3

Packing up our stuff, last day of XNA stuff…sad day..

I then got to wander around Seattle before I went home, here are a few pics I took..

DSC00016 DSC00021 DSC00026

All in all I think we all had a great time, I would like to say thanks to the MVP program for looking after us, the XNA Team for all there effort, both on the day’s and the work they must have had to do in the build up. And also to Andy Dunn, for letting me crash at his house for a couple of nights. Thanks all :D



Depth (Z-) Buffers
As with all games, Z-buffering plays an important part when rendering the pixels to the screen. During the development of Britonia I have often run into a problems related to the Z-Buffer, so I thought it would be nice to share what I have learned about them and how to avoid these issues.

What are Depth Buffers?

Depth buffers (commonly referred to as Z- or W- buffers) are a means to check which pixels being rendered will occlude one another. This is achieved by creating a separate surface the same size as the back(colour-) buffer where the depth of each rendered pixel is stored. Then before any other colours competing for the same pixel are rendered, they must first pass the depth function test using the same position within the depth buffer. Typically this check is passed if the new depth is less than or equal to the current depth in the depth buffer, although it is possible to change the pass conditions. Enabling and setting the depth function with the following:
    // enable depth buffer checks
    GraphicsDevice.RenderState.DepthBufferEnable = true;

    // specify the pass criteria for pixels
    GraphicsDevice.RenderState.DepthBufferFunction = CompareFunction.LessEqual;

    // allow writing to the depth buffer
    GraphicsDevice.RenderState.DepthBufferWriteEnable = true;


Z-Buffering or W-Buffering? Z-buffering is when the z component of a transformed pixel is stored as the depth. This differs from W-buffering, which takes the homogeneous W-component as the depth value. Because most of today's hardware has support for Z-buffering it is the more commonly of the two.

Depth buffer Formats and Resolution:

The precision that you will get from the depth buffer depends greatly on the format of the surface you choose to use as well as the near and far clip plane distances. Depth buffers are non linear, and the depth stored in the depth buffer is relative to the z coordinate. The maths can be a little confusing but put basically, you get more precision closer to the near plane as you do the further away you get. There is a Z-buffer calculator on this site here so you can test it out for yourself.

In that article he talks about the resolution of z, so instead of covering the same equation, I thought I'd do a little picture representation of the resolution of Z:
Photobucket
The depths are calculated using : depth value = (1 _lbitshift_ depth_format) * ( zFar / (zFar - zNear) + zFar * zNear / (zNear - zFar) / distance_of_object )

The graph above shows a 16-bit depth buffer. The closest depth (1.0f) has a value of 0, while the furthest depth (1000.0f) has a depth value of 65536 in the buffer. As you can see on the left of the x-axis although the increments in distance are only relatively small (1.1, 1.2 etc.), we actually have a huge difference in the depth values assigned to these positions, whilst towards the furthest distances, the differences in depth value is very small. Hopefully you can see form this graph the importance of selecting as high a value as possible for the zNear distance. This is a pretty common mistake when starting out with directx/xna whereby the programmer defines a point extremely close to the camera for the zNear like 0.1f, but you can see from above that this wastes a lot of depth needlessly - especially considering that not many objects will actually be that close to the camera. Similarly, you should also pick sensible values for the zFar distance.

Planet Rendering

Of course when rendering planets, the distances involved mean you would very quickly have problems considering the depths distances involved if you were to use constant values as the near and far plane distances. As you can imagine, this isn't that difficult to overcome, but I wanted to mention it so you have a reference. For each individual planet in Britonia, I dynamically adjust the near and far clip plane distances based on the closest point on the planet sphere and the furthest point. Even using 16-bit depth buffers and realistic planet sizes there are no visible artifacts (anymore).
Photobucket
Creating, Caching and Restoring the DepthBuffers


Creating a depth buffer is very straight forward. In XNA the depth buffer is created and on the graphics device like so:
Graphics.GraphicsDevice.DepthStencilBuffer = new DepthStencilBuffer(Graphics.GraphicsDevice, width, height, DepthFormat.Depth16);
It is worth noting that if you wish to use a stencil buffer when rendering your scene, then this shares the same surface as the depthbuffer, and you will have to sacrifice some bits per pixel for this stencil buffer. As example would be:
Graphics.GraphicsDevice.DepthStencilBuffer = new DepthStencilBuffer(Graphics.GraphicsDevice, width, height, DepthFormat.Depth15Stencil1);

The last thing I'd like to mention is the ability to store the depth buffer for your scenes, which can be restored and used again later. Again this is quite easy to do:
// Cache the current depth buffer
DepthStencilBuffer old = GraphicsDevice.DepthStencilBuffer;

// Set our custom depth buffer
GraphicsDevice.DepthStencilBuffer = shadowDepthBuffer;

As an example of how this may be benefical: In britonia I store the depth buffer for each planet during the planet rendering phase. This is then later restored when rendering the ground objects on the closest planet. This is required because of the swapping of depth buffers with multiple planets as mentioned above.

If you feel like reading up some more, you can find the MSDN article here.

You can find the same article on my website, hince the watermarks on the images :)

XNA and Windows 7 Multi-touch

I am pretty sure, that like me you are more than capable of scanning the web for snippets of info on how to do this, well I thought, to save you the time and effort I’ll put up a simple how-to here.

As ever I am standing on the shoulder of giants, the first thing I do to get multi-touch into my XNA project is to use a regular windows form to render to. I dare say there it a much better way to do this with WPF, which I am sure I’ll have a look at when I have time, but for now,  I am using the good old 2.0 Windows Form.  Now for this I have used a great post by another XNA MVP Pedro Guida aka “Ultrahead” showing how to get XNA to render to a panel control. I can’t for the life of me find his original post, it may have even been on The Code Project and also used the MS Multitouch code samples.

The spawn of these two resources has  given me my own Panel control that XNA can render to AND the Windows 7 Multi-touch API can be hooked up to.

So, how does all this hang together first off we open up a new XNA Windows Project, then Add a Windows Form to the project, we then need to create our own Panel object so that it can interact with multi-touch.

The code for the new Panel class is 99% taken from the MS Multitouch samples and it involves hooking into the WndProc method on the control.

XNAWindowsMTPanel

    public class XNAWindowsMTPanel : Panel
    {
        ///////////////////////////////////////////////////////////////////////
        // Protected members, for derived classes.

        // Touch event handlers
        public event EventHandler<WMTouchEventArgs> Touchdown;   // touch down event handler
        public event EventHandler<WMTouchEventArgs> Touchup;     // touch up event handler
        public event EventHandler<WMTouchEventArgs> TouchMove;   // touch move event handler

        // EventArgs passed to Touch handlers
        public class WMTouchEventArgs : System.EventArgs
        {
            // Private data members
            private int x;                  // touch x client coordinate in pixels
            private int y;                  // touch y client coordinate in pixels
            private int id;                 // contact ID
            private int mask;               // mask which fields in the structure are valid
            private int flags;              // flags
            private int time;               // touch event time
            private int contactX;           // x size of the contact area in pixels
            private int contactY;           // y size of the contact area in pixels

            // Access to data members
            public int LocationX
            {
                get { return x; }
                set { x = value; }
            }
            public int LocationY
            {
                get { return y; }
                set { y = value; }
            }
            public int Id
            {
                get { return id; }
                set { id = value; }
            }
            public int Flags
            {
                get { return flags; }
                set { flags = value; }
            }
            public int Mask
            {
                get { return mask; }
                set { mask = value; }
            }
            public int Time
            {
                get { return time; }
                set { time = value; }
            }
            public int ContactX
            {
                get { return contactX; }
                set { contactX = value; }
            }
            public int ContactY
            {
                get { return contactY; }
                set { contactY = value; }
            }
            public bool IsPrimaryContact
            {
                get { return (flags & TOUCHEVENTF_PRIMARY) != 0; }
            }

            // Constructor
            public WMTouchEventArgs()
            {
            }
        }

        ///////////////////////////////////////////////////////////////////////
        // Private class definitions, structures, attributes and native fn's
        //Exercise1-Task2-Step2

        // Touch event window message constants [winuser.h]
        private const int WM_TOUCHMOVE = 0x0240;
        private const int WM_TOUCHDOWN = 0x0241;
        private const int WM_TOUCHUP = 0x0242;

        private const int WM_MOUSEMOVE = 0x0200;
        private const int WM_LBUTTONDOWN = 0x0202;
        private const int WM_LBUTTONUP = 0x0208;
        private const int WM_MBUTTONDBLCLK = 0x0209;

        // Touch event flags ((TOUCHINPUT.dwFlags) [winuser.h]
        private const int TOUCHEVENTF_MOVE = 0x0001;
        private const int TOUCHEVENTF_DOWN = 0x0002;
        private const int TOUCHEVENTF_UP = 0x0004;
        private const int TOUCHEVENTF_INRANGE = 0x0008;
        private const int TOUCHEVENTF_PRIMARY = 0x0010;
        private const int TOUCHEVENTF_NOCOALESCE = 0x0020;
        private const int TOUCHEVENTF_PEN = 0x0040;

        // Touch input mask values (TOUCHINPUT.dwMask) [winuser.h]
        private const int TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001; // the dwTime field contains a system generated value
        private const int TOUCHINPUTMASKF_EXTRAINFO = 0x0002; // the dwExtraInfo field is valid
        private const int TOUCHINPUTMASKF_CONTACTAREA = 0x0004; // the cxContact and cyContact fields are valid

        // Touch API defined structures [winuser.h]
        //Exercise1-Task2-Step4
        [StructLayout(LayoutKind.Sequential)]
        private struct TOUCHINPUT
        {
            public int x;
            public int y;
            public System.IntPtr hSource;
            public int dwID;
            public int dwFlags;
            public int dwMask;
            public int dwTime;
            public System.IntPtr dwExtraInfo;
            public int cxContact;
            public int cyContact;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINTS
        {
            public short x;
            public short y;
        }

        // Currently touch/multitouch access is done through unmanaged code
        // We must p/invoke into user32 [winuser.h]
        //Exercise1-Task2-Step3
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool RegisterTouchWindow(System.IntPtr hWnd, ulong ulFlags);

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetTouchInputInfo(System.IntPtr hTouchInput, int cInputs, [In, Out] TOUCHINPUT[] pInputs, int cbSize);

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern void CloseTouchInputHandle(System.IntPtr lParam);

        // Attributes
        private int touchInputSize;        // size of TOUCHINPUT structure

        [SecurityPermission(SecurityAction.Demand)]
        public XNAWindowsMTPanel()
        {
            Dock = DockStyle.Fill;
            // GetTouchInputInfo need to be
            // passed the size of the structure it will be filling
            // we get the sizes upfront so they can be used later.
            touchInputSize = Marshal.SizeOf(new TOUCHINPUT());
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams createParams = base.CreateParams;
                createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
                return createParams;
            }
        }

        protected override void CreateHandle()
        {
            base.CreateHandle();
            ulong ulFlags = 0;
            RegisterTouchWindow(this.Handle, ulFlags);
        }

        ///////////////////////////////////////////////////////////////////////
        // Private methods

        // Window procedure. Receives WM_ messages.
        // Translates WM_TOUCH window messages to touch events.
        // Normally, touch events are sufficient for a derived class,
        // but the window procedure can be overriden, if needed.
        // in:
        //      m       message
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected override void WndProc(ref Message m)
        {
            // Decode and handle WM_TOUCH* message.
            bool handled;
            switch (m.Msg)
            {
                case WM_TOUCHDOWN:
                case WM_TOUCHMOVE:
                case WM_TOUCHUP:
                    handled = DecodeTouch(ref m);
                    break;
                default:
                    handled = false;
                    break;
            }

            // Call parent WndProc for default message processing.
            base.WndProc(ref m);

            if (handled)
            {
                // Acknowledge event if handled.
                try
                {
                    m.Result = new System.IntPtr(1);
                }
                catch (Exception exception)
                {
                    Debug.Print("ERROR: Could not allocate result ptr");
                    Debug.Print(exception.ToString());
                }
            }
        }

        // Extracts lower 16-bit word from an 32-bit int.
        // in:
        //      number      int
        // returns:
        //      lower word
        private static int LoWord(int number)
        {
            return number & 0xffff;
        }

        // Decodes and handles WM_TOUCH* messages.
        // Unpacks message arguments and invokes appropriate touch events.
        // in:
        //      m           window message
        // returns:
        //      flag whether the message has been handled
        private bool DecodeTouch(ref Message m)
        {
            // More than one touchinput may be associated with a touch message,
            // so an array is needed to get all event information.
            int inputCount = LoWord(m.WParam.ToInt32()); // Number of touch inputs, actual per-contact messages

            TOUCHINPUT[] inputs; // Array of TOUCHINPUT structures
            try
            {
                inputs = new TOUCHINPUT[inputCount]; // Allocate the storage for the parameters of the per-contact messages
            }
            catch (Exception exception)
            {
                Debug.Print("ERROR: Could not allocate inputs array");
                Debug.Print(exception.ToString());
                return false;
            }

            // Unpack message parameters into the array of TOUCHINPUT structures, each
            // representing a message for one single contact.
            //Exercise2-Task1-Step3
            if (!GetTouchInputInfo(m.LParam, inputCount, inputs, touchInputSize))
            {
                // Get touch info failed.
                return false;
            }

            // For each contact, dispatch the message to the appropriate message
            // handler.
            // Note that for WM_TOUCHDOWN you can get down & move notifications
            // and for WM_TOUCHUP you can get up & move notifications
            // WM_TOUCHMOVE will only contain move notifications
            // and up & down notifications will never come in the same message
            bool handled = false; // // Flag, is message handled
            //Exercise2-Task1-Step4
            for (int i = 0; i < inputCount; i++)
            {
                TOUCHINPUT ti = inputs[i];

                // Assign a handler to this message.
                EventHandler<WMTouchEventArgs> handler = null;     // Touch event handler
                if ((ti.dwFlags & TOUCHEVENTF_DOWN) != 0)
                {
                    handler = Touchdown;
                }
                else if ((ti.dwFlags & TOUCHEVENTF_UP) != 0)
                {
                    handler = Touchup;
                }
                else if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0)
                {
                    handler = TouchMove;
                }

                // Convert message parameters into touch event arguments and handle the event.
                if (handler != null)
                {
                    // Convert the raw touchinput message into a touchevent.
                    WMTouchEventArgs te; // Touch event arguments

                    try
                    {
                        te = new WMTouchEventArgs();
                    }
                    catch (Exception excep)
                    {
                        Debug.Print("Could not allocate WMTouchEventArgs");
                        Debug.Print(excep.ToString());
                        continue;
                    }

                    // TOUCHINFO point coordinates and contact size is in 1/100 of a pixel; convert it to pixels.
                    // Also convert screen to client coordinates.
                    te.ContactY = ti.cyContact / 100;
                    te.ContactX = ti.cxContact / 100;
                    te.Id = ti.dwID;
                    {
                        Point pt = PointToClient(new Point(ti.x / 100, ti.y / 100));
                        te.LocationX = pt.X;
                        te.LocationY = pt.Y;
                    }
                    te.Time = ti.dwTime;
                    te.Mask = ti.dwMask;
                    te.Flags = ti.dwFlags;

                    // Invoke the event handler.
                    handler(this, te);

                    // Mark this event as handled.
                    handled = true;
                }
            }

            CloseTouchInputHandle(m.LParam);

            return handled;
        }
    }

So now we have a control we can use to get MT input for, we now need to hook this control up to our form and in turn to our XNA Game class. In the form we need to give our Game class access to the handle it is going to render to. To do this we define XNAWindowsMTPanel object, create a Property on the form so that it can be accessed and then instantiate the XNAWindowsMTPanel object. This leaves our form source code looking like this:

    public partial class frmMain : Form
    {
        public XNAWindowsMTPanel panel1;

        public IntPtr DisplayHandle
        {
            get
            {
                return this.panel1.IsHandleCreated ?
                       this.panel1.Handle : IntPtr.Zero;
            }
        }

        public frmMain(Game1 game)
        {
            InitializeComponent();

            panel1 = new XNAWindowsMTPanel();

            

            this.Controls.Add(panel1);
        }
        
    }

Now in our game class we need to set up the Windows form to be the form we will be rendering to, we create a From object, in the constructor, instantiate, bind to the forms HandleDestroyed event so when the form closes we can tidy up and then show the form. We also need to be able to ‘hide’ our XNA game window to so to do this we need to bind to the XNA game windows Shown event and then hide the window. To help us do this we will need to reference System.Windows.Forms in our Game1 class and to stop any name space conflicts we will alias it with ‘SysWinForms’. We also need to set our view port so that it matches the area we are rendering to and this also needs to be done if the form is resized.

The top of our Game1.cs file now looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using SysWinForms = System.Windows.Forms;

namespace GenericXNAMultiTouch
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        frmMain frmMain;

        

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            SysWinForms.Form gameWindow = (SysWinForms.Form)SysWinForms.Form.FromHandle(this.Window.Handle);
            gameWindow.Shown += new EventHandler(gameWindow_Shown);

            frmMain = new frmMain(this);
            frmMain.HandleDestroyed += new EventHandler(frmMain_HandleDestroyed);
            frmMain.Resize += new EventHandler(frmMain_Resize);
            frmMain.Show();

            graphics.PreferredBackBufferHeight = frmMain.panel1.Height;
            graphics.PreferredBackBufferWidth = frmMain.panel1.Width;
        }

        void frmMain_Resize(object sender, EventArgs e)
        {
            if (GraphicsDevice.Viewport.Width != frmMain.panel1.Width || GraphicsDevice.Viewport.Height != frmMain.panel1.Height)
            {
                GraphicsDevice.Viewport = new Viewport
                {
                    X = 0,
                    Y = 0,
                    Height = frmMain.panel1.Height,
                    Width = frmMain.panel1.Width,
                    MaxDepth = GraphicsDevice.Viewport.MaxDepth,
                    MinDepth = GraphicsDevice.Viewport.MinDepth,
                };
            }
        }

        void frmMain_HandleDestroyed(object sender, EventArgs e)
        {
            Exit();
        }

        void gameWindow_Shown(object sender, EventArgs e)
        {
            ((SysWinForms.Form)sender).Hide();
        }

Running this now will just give us a blank Windows Form, we need to now tell our Game1 class to render to our XNAWindowsMTPanel and this is very simple to do, simply at the end of the Draw call do this:

            GraphicsDevice.Present(frmMain.DisplayHandle);

You will now have your XNA code rendering on the windows form!! How cool is that!

Now to add the MT functionality. You can see on the XNAWindowsMTPanel class that we have some events we can bind to:

        // Touch event handlers
        public event EventHandler<WMTouchEventArgs> Touchdown;   // touch down event handler
        public event EventHandler<WMTouchEventArgs> Touchup;     // touch up event handler
        public event EventHandler<WMTouchEventArgs> TouchMove;   // touch move event handler

So we we will get some code stubs in our Game1 class then wire these up in Windows Form (again taken from the MS MT samples)

        #region Multi-Touch
        // Touch Stuff
        // Touch down event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchDownHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            
        }

        // Touch up event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchUpHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            
        }

        // Touch move event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchMoveHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            
        }
        #endregion

And now to wire them up in the form:

        public frmMain(Game1 game)
        {
            InitializeComponent();

            panel1 = new XNAWindowsMTPanel();

            // Touch stuff
            // Setup handlers
            panel1.Touchdown += game.OnTouchDownHandler;
            panel1.Touchup += game.OnTouchUpHandler;
            panel1.TouchMove += game.OnTouchMoveHandler;

            this.Controls.Add(panel1);
        }

So, we now have our XNA project rendering on a windows form that is also able to accept munti touch commands, so how can we demonstrate this?

First of all we are going to create an object that we can use to store the touch events in, this will also hold some data to help us represent the touch on the screen.

    public class MTObject
    {
        public XNAWindowsMTPanel.WMTouchEventArgs Event;
        public Point[] spritePositions;
        public Color Color;
        public float Rotation = 0;
        public int Size;

        public MTObject(XNAWindowsMTPanel.WMTouchEventArgs e,int size,Color color)
        {
            Event = e;
            spritePositions = new Point[100];
            Color = color;
            Size = size;
        }        
    }

We then create a Dictionary to store these items in, I am also going to add a Texture2D to render the touch objects and give an audio que with a SoundEffect Object. This is hoe I have defined them in the Game1 class:

        Dictionary<int, MTObject> touchList = new Dictionary<int, MTObject>();

        Texture2D sprite;
        SoundEffect touchWav;

 

 

 

 

Now all we need to do is record when we have a touch contact, when one is removed and when one is moved. Our touch event handlers now look like this:

        #region Multi-Touch
        // Touch Stuff
        // Touch down event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchDownHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            // Is this a new touch or an old one?
            if (!touchList.Keys.Contains(e.Id))
            {
                if (e.IsPrimaryContact)
                    touchList.Add(e.Id, new MTObject(e, 32,Color.Red));
                else
                    touchList.Add(e.Id, new MTObject(e, 16, Color.Gold));
            }

            touchWav.Play();

        }

        // Touch up event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchUpHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            if (touchList.Keys.Contains(e.Id))
                touchList.Remove(e.Id);
        }

        // Touch move event handler.
        // in:
        //      sender      object that has sent the event
        //      e           touch event arguments
        public void OnTouchMoveHandler(object sender, XNAWindowsMTPanel.WMTouchEventArgs e)
        {
            touchList[e.Id].Event.LocationX = e.LocationX;
            touchList[e.Id].Event.LocationY = e.LocationY;
        }
        #endregion

I then make sure that the array of points I am using to represent the touch contacts is updated, effectively giving a string of particles after the touch contact point, giving us the following Update and Draw methods:

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            foreach (int key in touchList.Keys)
            {
                for (int s = touchList[key].spritePositions.Length - 1; s > 0; s--)
                {
                    touchList[key].spritePositions[s] = touchList[key].spritePositions[s - 1];
                }
                touchList[key].spritePositions[0] = new Point(touchList[key].Event.LocationX, touchList[key].Event.LocationY);
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);

            Color alphaColor;

            spriteBatch.Begin();
            foreach (int key in touchList.Keys)
            {
                for (int s = touchList[key].spritePositions.Length - 1; s > 0; s--)
                {
                    touchList[key].spritePositions[s] = touchList[key].spritePositions[s - 1];
                    alphaColor = new Color(touchList[key].Color.R, touchList[key].Color.G, touchList[key].Color.B, (1 - (s / (float)touchList[key].spritePositions.Length)));
                    spriteBatch.Draw(sprite, new Rectangle(touchList[key].spritePositions[s].X, touchList[key].spritePositions[s].Y, touchList[key].Size, touchList[key].Size), new Rectangle(0, 0, sprite.Width, sprite.Height), alphaColor, touchList[key].Rotation++, new Vector2(sprite.Width / 2, sprite.Height / 2), SpriteEffects.None, 1);
                }
                
                alphaColor = touchList[key].Color;
                spriteBatch.Draw(sprite, new Rectangle(touchList[key].spritePositions[0].X, touchList[key].spritePositions[0].Y, touchList[key].Size, touchList[key].Size), new Rectangle(0, 0, sprite.Width, sprite.Height), alphaColor, touchList[key].Rotation++, new Vector2(sprite.Width / 2, sprite.Height / 2), SpriteEffects.None, 1);
                

            }
            spriteBatch.End();

            GraphicsDevice.Present(frmMain.DisplayHandle);
        }

[Go to the site to view embedded media] 

And that’s about it, hope you find it useful. The solution for this post can be found here. As ever C&C welcome.



ZuneRay

[Go to the site to view embedded media]

So, I have this ZuneHD and have been playing about with it for abit now, so looked into what I can do with it. Turns out quite a bit after finding some great samples from the likes of Nick Gravelyn.

So as you can see in the clip, with these samples under my belt I started writing my own Raycaster for the Zune. It is still early days yet, need to do afair bit more (just like all my other unfinished projects I hear you shout!!) and I think it will make for a nice base for creating raycasting games on the Zune.

I don't know about you (or even if you are old enough to remember), but I loved Wolfenstine3D, so this sort of engine will enable you to make games just like that :)

As ever C&C welcome.



XNA Community
Los Indiespensables de Xbox Live Indie Games II parte
En Anaitgames han publicado aquí la continuación del articulo sobre juegos Indie, muy recomendado como ejemplos de juegos que están al mismo nivel incluso más que algunos juegos profesionales de Live Arcade. Saludos,...(read more)

Los Indiespensables de Xbox Live Indie Games
En Anaitgames una página que todo buen amante de juegos debería visitar, Nae dedica un post a los juegos Indie Games que piensa que son indispensables, por lo que se puede apreciar por el titulo del post vamos a tener más como este en los que se enseñan...(read more)

Copa del mundo 2010
Si si como lo habéis leído, los juegos Indie de fútbol que usen avatares, podrían entrar en una promoción para la Copa del Mundo de 2010 de Sudáfrica. Esta oportunidad termina el 1 de Mayo y se decidirá entre los mas descargados y mejor puntuados por...(read more)

XBLA & XBLIG Ratings
En la página xblaratings podéis encontrar un listado muy completo de los juegos de Xbox LIVE Indie Games, con vídeos, screenshots, una breve descripción de cada uno, precio, fecha de salida, países en los que ha salido, idiomas que soporta, y comentarios...(read more)

Foreign feeds
Login
Username

Password



Not a member yet?
Click here to register.

Forgotten your password?
Request a new one here.
RSS Feeds at the site
RSS - Programs
Foreign feeds