# How to code sprite sheets?

First of all, the XNA Framework works on my computer, but I do not wish to use it for reasons. I am set with the task of coding my own sprite sheet class. I do not know if a class is the best way to do it, but I have tried my best. I am not an advanced C# user, but I know enough to have got this far with the class:

class Spritesheet
{
//w: 50px h: 96px
Bitmap sheet;
int fWidth, fHeight;
int framesPerRow, framesPerCol;
int x, y;
public Bitmap curState;

public Spritesheet(string path, int width, int height)
{
sheet = new Bitmap(path);
fWidth = width;
fHeight = height;
framesPerRow = sheet.Width / fWidth;
framesPerCol = sheet.Height / fHeight;
curState = new Bitmap(path);
}

public void playSprite(int frameSpeed, int endFrame, int row)
{
int curFrame = 0;
int count = 0;
bool play = true;

while (play)
{
if (count == (frameSpeed - 1))
{
curFrame = curFrame++ % endFrame;
Rectangle cloneRect = new Rectangle(row * fWidth, curFrame * fHeight, fWidth, fHeight);
System.Drawing.Imaging.PixelFormat pFormat = sheet.PixelFormat;
Bitmap curState = sheet.Clone(cloneRect, pFormat);
}

count = (count + 1) % frameSpeed;
}
}
}


I am aware that class variables should never be public, but this is just until I get it working. My Form1 looks like this:

public partial class Form1 : Form
{
Spritesheet player = new Spritesheet("Content/Sprite/charzera.png", 700, 270);

public Form1()
{
InitializeComponent();
pb_char.Image = player.curState;
}

private void timer1_Tick(object sender, EventArgs e)
{
player.playSprite(5, 13, 0);
pb_char.Image = player.curState;
}

}


The form builds but doesn't launch now. I am just lost on where to go with this now. I want a spritesheet to be created for the main character, and from there I want to be able to pick a row based on what action is happening and then the game to run along the row animating the PictureBox that I am using for the character.

I've never done this before, so its probably completely wrong.

• Reasons? It might be helpful if you elaborated exactly why you won't use XNA. – Sturlen Nov 29 '15 at 18:32
• From your posted code, it looks like you have many gaps in your knowledge and are taking too many steps at once. SE is not a good platform for walking people through complex procedures like this, so I think you should break this up into smaller tasks, like: how to display an image, how to show a basic animation (e.g. single image flickering), how to display different frames in a multi-frame spritesheet, how to show a spritesheet as an animation, and finally how to show different animations in a spritesheet. – congusbongus Nov 30 '15 at 1:11
• As a matter of a fact, the entire code logic for deciding what sprite to draw on a spritesheet can be developed without using XNA or other graphics library. You just develop a system to obtain some coordinates and pass that to you graphics subsystem, whatever it is. – rlam12 Nov 30 '15 at 2:29
• Thanks for the help. I got it eventually. Yeah it might have been too big a jump. – Tiernan Watson Nov 30 '15 at 18:50

I'm not sure how to do this in C# as I haven't used it but the basic idea is to cut out each section of the sprite sheet when you need it and crop the rest. I have C++/SFML code for it but I will try to generalize it

enum Direction {Down, Left, Right, Up};

int source_x = 1;
int source_y = Down;

int loop = 0;

float frameCounter = 0, switchframe = 100, frameSpeed = 500;

Clock clock;

Sprite PlayerImage;
Texture PlayerT;

bool updateFrame = false;

{
std::cout << "Error Image could not load" << std::endl;
}

PlayerImage.setTexture(PlayerT);
while (window.isOpen())
{
if (Keyboard::isKeyPressed(sf::Keyboard::W))
{
source_y = Up;
PlayerImage.move(0, -0.05);
updateFrame = true;
}
else if (Keyboard::isKeyPressed(sf::Keyboard::S))
{
source_y = Down;
PlayerImage.move(0, 0.05);
updateFrame = true;
}
else if (Keyboard::isKeyPressed(sf::Keyboard::D))
{
source_y = Right;
PlayerImage.move(0.05, 0);
updateFrame = true;
}
else if (Keyboard::isKeyPressed(sf::Keyboard::A))
{
source_y = Left;
PlayerImage.move(-0.05, 0);
updateFrame = true;
}

loop++;
if (loop >= 3000)
{
loop = 0;
updateFrame = false;
}

if (updateFrame)
{
frameCounter += frameSpeed * clock.restart().asSeconds();
}
else
{
frameCounter = 0;
}

if (frameCounter >= switchframe)
{
frameCounter = 0;
source_x++;
if (source_x * 32 >= PlayerT.getSize().x)
source_x = 0;
}

window.clear();
PlayerImage.setTextureRect(sf::IntRect(source_x * 32, source_y * 32, 32, 32));

window.draw(PlayerImage);
window.display();
}


I hope that this helps however it is for another language.

Also I found this thread over on Stack Overflow which could help: https://stackoverflow.com/questions/16112622/2d-sprite-animations-without-using-xna-or-other-third-party-libraries