Tuesday 6 March 2012

Programming and SpriteSheets

Been working on a Class to handle spritesheets and textures for a side project. It holds all textures required for the game to save loading and passing them around all over the place. At the moment it doesnt have a simple load class for a single image, e.g. a background or gui, but its not too hard to add that, which is the next step.

As it stands, it holds textures as Texture2d[], taking a spritesheet and chopping it up into smaller images, defined by the int w, h parameters, and can then be used from anywhere else through the Art instance i. E.g sprites[4](below) would return the 5th 'chopped' image on the sheet. The 4 can be incremented for animations, or cycle through a list of ints for custom animations.

(1, 2, 3, 2), which would draw boxes 0,1,2,1... etc rather than 1, 2, 3, 1, 2, 3....

Personally I find it a lot easier to use this method rather than source rects, due to the fact of collision boxes, origins having to be readjusted (Collision box would use the whole texture width when using a source, although an easy fix).

Also saves from passing in textures to each class, or having them need their own Load methods.

May be worth returning a Texture[,] rather than a Texture[], however, it seems to work fine as it currently is.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace NameSpace
{
    public class Art
    {        
        //instance
        public static Art i;
        private static ContentManager c;

        public static void Init(ContentManager content)
        {           
            c = content;
            i = new Art(); 
        }

        //Texture Arrays

        public Texture2D[] sprites = LoadAndSplit(@"Sprites\SpriteSheet", 48, 48);
        public Texture2D[] tiles = LoadAndSplit(@"TileSets/Tileset1", 48, 48);

        //Loads and Splits the texture into a Texture array
        public static Texture2D[] LoadAndSplit(string name, int w, int h)
        {
            Texture2D image = c.Load (name);

            int xSplit = image.Width / w;
            int ySplit = image.Height / h;

            Texture2D[] r = new Texture2D[xSplit * ySplit];
            int datePerSplit = w * h;

            Color[] originalPixels = new Color[image.Width * image.Height];
            image.GetData(originalPixels);

            int index = 0;

            for (int y = 0; y < ySplit * h; y+= h)
                for (int x = 0; x < xSplit * w; x+= w)
                {
                    Texture2D split = new Texture2D(image.GraphicsDevice, w, h);
                    Color[] splitPixels = new Color[datePerSplit];

                    for (int sy = 0; sy < h; sy++)
                        for (int sx = 0; sx < w; sx++)
                        {
                            int splitIndex = sx + sy * w;

                            if (y + sy >= image.Height || x + sx >= image.Width)
                                splitPixels[splitIndex] = Color.Transparent;
                            else
                                splitPixels[splitIndex] = originalPixels[(x + sx) + (y + sy) * image.Width];
                        }

                    split.SetData(splitPixels);

                    r[index++] = split;                   
                }                     
                        
            return r;            
            
        }       
       
    }
}

Friday 2 March 2012

Animations

Added the Animation class (animated by frame using spriteSheets). The Character class holds the animations by Dictionary (animations and string name), so it can be changed according to the playerstate.