Joystick

From SDL.NET

Table of contents

Introduction

SDL.NET supports joystick input. This tutorial will show how to move a custom cursor around the screen using a joystick. Also, pressing the joystick button will print to the console.

Initialization

To intialize the joystick subsystem just instantiate a Joystick object.

Joystick joystick = Joysticks.OpenJoystick(0);

This creates a joystick object that is represents the first joystick found on the system.

Events

The Events class contains several Joystick-related events.

JoystickAxisMotion // Movement
JoystickButtonDown // Button pressed
JoystickButtonUp   // Button released
JoystickHatMotion  // Hat motion
JoystickBallMotion // Ball motion

Each event can be bound to an event handler which will fire off an appropriate method such as:

// This method will set the position of the cursor accroding to the movement of the joystick.
private void JoystickAxisChanged(object sender, JoystickAxisEventArgs e)
{
	if (e.AxisIndex == 0)
	{
		position.X = (int)(joystick.GetAxisPosition(JoystickAxis.Horizontal)  * width);
	} 
	else if (e.AxisIndex == 1)
	{
		position.Y = (int)(joystick.GetAxisPosition(JoystickAxis.Vertical) * height);
	}
}

// This method will simply print to the console when the button is pressed.
private void JoystickButtonDown(object sender, JoystickButtonEventArgs e)
{
	Console.WriteLine("Joystick button was pressed");
}

Data Files

The tutorial uses this graphic file (cursor.png) as a custom cursor that responds to joystick movement. Image:cursor.png

Full Source Code

using System;
using System.Drawing;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;

using SdlDotNet.Graphics;
using SdlDotNet.Input;
using SdlDotNet.Audio;
using SdlDotNet.Core;

namespace SdlDotNetExamples.SmallDemos
{
    public class JoystickExample : IDisposable
    {
        Point position = new Point(100, 100);
        int width = 640;
        int height = 480;
        Joystick joystick;
        Surface screen;
        Surface cursor;

        /// <summary>
        /// 
        /// </summary>
        public JoystickExample()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        public void Go()
        {
            string filePath = Path.Combine("..", "..");
            string fileDirectory = "Data";
            string fileName = "cursor.png";
            if (File.Exists(fileName))
            {
                filePath = "";
                fileDirectory = "";
            }
            else if (File.Exists(Path.Combine(fileDirectory, fileName)))
            {
                filePath = "";
            }

            string file = Path.Combine(Path.Combine(filePath, fileDirectory), fileName);

            Events.Tick += new EventHandler<TickEventArgs>(Tick);
            Events.KeyboardDown +=
                new EventHandler<KeyboardEventArgs>(this.KeyboardDown);
            Events.Quit += new EventHandler<QuitEventArgs>(this.Quit);
            Events.JoystickAxisMotion +=
                             new EventHandler<JoystickAxisEventArgs>(this.JoystickAxisChanged);
            Events.JoystickButtonDown += new EventHandler<JoystickButtonEventArgs>(this.JoystickButtonDown);
            joystick = Joysticks.OpenJoystick(0);

            try
            {
                Video.WindowIcon();
                Video.WindowCaption = "SdlDotNet - Joystick Example";
                screen = Video.SetVideoMode(width, height, true);
                Mouse.ShowCursor = false; // hide the cursor

                Surface surf =
                    screen.CreateCompatibleSurface(width, height, true);
                surf.Fill(new Rectangle(new Point(0, 0),
                    surf.Size), System.Drawing.Color.Black);

                cursor = new Surface(file);

                Events.Run();
            }
            catch
            {
                throw;
            }
        }

        private void Tick(object sender, TickEventArgs e)
        {
            screen.Fill(Color.Black);
            screen.Blit(cursor, new Rectangle(position, screen.Size));
            screen.Update();
        }

        private void KeyboardDown(object sender, KeyboardEventArgs e)
        {
            if (e.Key == Key.Escape ||
                e.Key == Key.Q)
            {
                Events.QuitApplication();
            }
        }

        private void Quit(object sender, QuitEventArgs e)
        {
            Events.QuitApplication();
        }

        private void JoystickAxisChanged(object sender, JoystickAxisEventArgs e)
        {
            if (e.AxisIndex == 0)
            {
                position.X = (int)(joystick.GetAxisPosition(JoystickAxis.Horizontal) * width);
            }
            else if (e.AxisIndex == 1)
            {
                position.Y = (int)(joystick.GetAxisPosition(JoystickAxis.Vertical) * height);
            }
        }

        private void JoystickButtonDown(object sender, JoystickButtonEventArgs e)
        {
            Console.WriteLine("Joystick button was pressed");
        }

        /// <summary>
        /// Application EntryPoint.
        /// </summary>
        [STAThread]
        public static void Main()
        {
            JoystickExample joystickExample = new JoystickExample();
            joystickExample.Go();
        }

        /// <summary>
        /// Lesson Title
        /// </summary>
        public static string Title
        {
            get
            {
                return "JoystickExample: Move the cursor with a joystick";
            }
        }

        #region IDisposable Members

        private bool disposed;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (this.screen != null)
                    {
                        this.screen.Dispose();
                        this.screen = null;
                    }
                    if (this.cursor != null)
                    {
                        this.cursor.Dispose();
                        this.cursor = null;
                    }
                    if (this.joystick != null)
                    {
                        this.joystick.Dispose();
                        this.joystick = null;
                    }
                }
                this.disposed = true;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 
        /// </summary>
        public void Close()
        {
            Dispose();
        }

        /// <summary>
        /// 
        /// </summary>
        ~JoystickExample()
        {
            Dispose(false);
        }

        #endregion
    }
}

See Also