Woohoo, another massive Mega wall-of-text that is going to be TL;DR'd by the majority of the internet!
The reason I've been offline for a while is twofold, but both sides to the problem lie in the fact that I don't have my own internet connection, I use my dad's. Independance is great, but requires gainful employment first. And I still haven't got the latter. So basically, because of an argument/dispute/I'mRightSoShutUp I had a few days before writing this, I was told:"OK. Sure. You're right, but you can't use the internet now for <x> amount of time." (Where x is an unknown variable that depends on whether my parents decide I'm being condescending enough to deserve my time on the internet).Anyway, it doesn't hurt me. Since I do most of my work offline, I got a lot done. I did kinda just disappear from the Minecraft server, which was annoying (I had just started building a shelter/outhouse when I was 'kicked' by Windows >_>). Anyway… disclaimer:This blog may contain traces of Error, a sprinkling of Length, and just a Dash of Awesome…As the title explains, I'm now working with XNA (Which is made a lot easier now that I understand the ins and outs of the C# language).So I sat down this evening and opened the VC# Express 2010 IDE, and started working on a platformer. As per tradition, I'm using placeholder art, but even so, to my dismay I discovered that there is no built in support for animated sprites. So the first thing I had to do? Make a class that can load and draw animated sprites with all the bells and whistles (Origin, Scaling, Flipping). And I did. The result is as follows:Source codeclass MXSprite
{
private Texture2D spriteData;
private int x;
private int y;
private int width;
private int height;
private int origin_x;
private int origin_y;
private int numframes;
private double speed;
private double scale;
private bool flip_x;
private bool flip_y;
private bool isLoaded;
// Current Frame and Frame Counter
private int c_frame;
private double fcount;
// Status values and properties
private bool isFrameEnd;
private bool IsFrameEnd { get { return this.isFrameEnd; } }
private bool isFrameStart;
private bool IsFrameStart { get { return this.isFrameStart; } }
// A sprite that can handle multiple frames in a single image.
// I'll also make a MXListSprite that uses a container.
public MXSprite()
{
spriteData = null;
x = y = 0;
width = height = 0;
numframes = 0;
scale = speed = 1.0;
flip_x = false;
flip_y = false;
isLoaded = false;
}
public void Load(ContentManager cmanager, string resName)
{
if (isLoaded) return;
spriteData = cmanager.Load<Texture2D>(resName);
isLoaded = true;
}
public void Setup(int width, int height, double speed = 1.0, int origin_x = 0, int origin_y = 0)
{
this.width = width;
this.height = height;
this.speed = speed;
this.origin_x = origin_x;
this.origin_y = origin_y;
this.numframes = spriteData.Width / this.width;
this.c_frame = 0;
this.fcount = 0.0;
}
public void Step()
{
// Perform a frame step. Adjust if necessary
fcount += speed;
if (fcount >= 1.0)
{
fcount = 0.0; // This could be clipped instead of clamped
// while(fcount >= 1.0)fcount -= 1.0; // This will work too, and retain the fractional part.
// But it's a potential bottleneck if somebody accidentally sets
// the Speed property to something stupid like 500.
c_frame += 1;
}
if (c_frame == numframes - 1)
{
isFrameEnd = true;
}
else isFrameEnd = false;
if (c_frame > numframes - 1)
{
c_frame = 0;
}
if (c_frame == 0)
{
isFrameStart = true;
}
else isFrameStart = false;
}
// Methods
public void Draw(SpriteBatch spriteBatch)
{
Rectangle srcRect = new Rectangle(this.c_frame * this.width, 0, this.width, this.height);
SpriteEffects fx = (flip_x ? SpriteEffects.FlipHorizontally : 0) | (flip_y ? SpriteEffects.FlipVertically : 0);
spriteBatch.Draw(spriteData, new Vector2(x, y), srcRect, Color.White, (float)0.0, new Vector2(origin_x, origin_y), new Vector2((float)
scale,(float)scale), SpriteEffects.None, (float)0.0);
}
// Properties
public int X { get { return this.x; } set { this.x = value; } }
public int Y { get { return this.y; } set { this.y = value; } }
public int Width { get { return this.width; } }
public int Height { get { return this.height; } }
public int NumFrames { get { return this.numframes; } }
public int CurrentFrame { get { return this.c_frame; } set { this.c_frame = (value < this.numframes ? value : numframes-1); } }
public double Speed { get { return this.speed; } set { this.speed = value; } }
public double Scale { get { return this.scale; } set { this.scale = value; } }
public bool FlipX { get { return this.flip_x; } set { this.flip_x = value; } }
public bool FlipY { get { return this.flip_y; } set { this.flip_y = value; } }
public bool IsLoaded { get { return this.isLoaded; } }
}
// This array stores the tiles.
Tile[] tiles; // Size varies depending on map size
// This is the absolute view coordinate being 'mapped' to tile-space
// I offset it by (-1,-1) to render the border tiles
int tvx = (view_x / tile_width)-1;
int tvy = (view_y / tile_height)-1;
// Calculate the width and height of the view in tiles
int tvw = view_width/tile_width;
int tvh = view_height/tile_height;
// Calculate the start index
// map_width is the width of the map in tiles, _not the absolute value_
int start_index = tvy * map_width + tvx;
// Number of tiles to process + 2 extra rows|columns
int p_count = (tvw*tvh) + (map_width*2);
// Clamp values
if(start_index < 0)start_index = 0;
if(start_index > tiles.count()-1)break; // Out of bounds
for(int i = start_index; i < start_index + p_count; i++)
{
// Check values for validity and break loop if out of bounds
if(i > tiles.count()-1)break;
// Otherwise process
DrawTile(i);
}
public void Draw(SpriteBatch sb, Rectangle? viewRect = null)
{
int w = 32;
int h = 32;
Rectangle rr;
if (viewRect != null)
{
rr = (Rectangle)viewRect;
}
else rr = new Rectangle(0, 0, 512, 480);
int tvx = (rr.X / w)-1;
int tvy = (rr.Y / h)-1;
int tvw = (rr.Width / w)+2;
int tvh = (rr.Height / h)+2;
for (int iy = tvy; iy < tvy + tvh; iy++)
for (int ix = tvx; ix < tvx + tvw; ix++)
{
int i = iy * width + ix;
if (i > numtiles - 1)
{
i = (i % numtiles);
if (i > numtiles - 1) i = numtiles - 1;
}
if (i < 0)
{
i = -i;
i = numtiles - (i % numtiles);
}
int x = ix * w;
int y = iy * h;
x -= rr.X;
y -= rr.Y;
if (i > numtiles - 1) i = numtiles - 1;
if (backlayer[i].t >= 0) myTileset.Draw(sb, backlayer[i].t, x, y, 1.0);
if (midlayer[i].t >= 0) myTileset.Draw(sb, midlayer[i].t, x, y, 0.9);
if (frontlayer[i].t >= 0) myTileset.Draw(sb, frontlayer[i].t, x, y, 0.1);
}
}
If youre a listed school in microsoft's dreamspark, then you can get visual studio for free.
also, the TL;DR was much easier for me to read than the actual blog.what was with skipping lines half way through sentences? anyway i love the parent excuse lol. parent logic is the best. read about half than realized i was spending too much time on this blog xD
seriously though, i wish i had that kinda time to kill, you seem like you always got something cool going on. i don't even have enough time to read this blog let alone work on anything =\