How to create a sprite

I am trying to create a very simple sprite image.

First I have an existing image (Width = 100px, Height = 100px).

I will scroll this image between 10 and 100 times, each time placing it in the sprite next to the previous one.

The sprite is limited to a width of 3000 pixels.

The images are placed next to each other in order, so I can simply combine them with a simple method, however I need to limit the width of the combined images to 3000 pixels, and then start from a new line.

+7
source share
4 answers

Let me try with some pseudo code

Bitmap originalImage; // that is your image of 100x100 pixels Bitmap bigImage; // this is your 3000x3000 canvas int xPut = 0; int xPut = 0; int maxHeight = 0; while (someExitCondition) { Bitmap imagePiece = GetImagePieceAccordingToSomeParameters(originalImage); if (xPut + imagePiece.Width > 3000) { xPut = 0; yPut += maxHeight; maxHeight = 0; } DrawPieceToCanvas(bigImage, xPut, yPut, imagePiece); xPut += imagePiece.Width; if (imagePiece.Height > maxHeight) maxHeight = imagePiece.Height; // iterate until done } 
+3
source

There is a lot of information about 2D sprites in the following MSDN article: Rendering 2D Sprites

These examples are based on Microsoft XNA , which is a platform that Visual Studio can use to develop games for Windows, Windows Phone, and XBOX 360.

For example, to draw a sprite, you can use the following C # code (example taken from an MSDN article, remote XBOX 360 code removed):

 private Texture2D SpriteTexture; private Rectangle TitleSafe; protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); SpriteTexture = Content.Load<Texture2D>("ship"); TitleSafe = GetTitleSafeArea(.8f); } protected Rectangle GetTitleSafeArea(float percent) { Rectangle retval = new Rectangle( graphics.GraphicsDevice.Viewport.X, graphics.GraphicsDevice.Viewport.Y, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height); return retval; } protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); Vector2 pos = new Vector2(TitleSafe.Left, TitleSafe.Top); spriteBatch.Draw(SpriteTexture, pos, Color.White); spriteBatch.End(); base.Draw(gameTime); } 

To initialize it, you must call LoadContent() , then you need to call GetTitleSafeArea(100) to get a safe drawing area (in this case it is 100 percent), finally you can use the Draw method. It takes a parameter containing an instance of the GameTime class, which is a snapshot of the game’s synchronization state, expressed in values ​​that can be used by games with a variable pitch (in real time) or with a fixed pitch (playing time).

Please let me know if this helps you.

+7
source

declare a variable in 3000, if you insert an image with a width of 250, remove this value from the variable, continue to do this, it also allows you to decide if there is enough free space on this line for the next image, seeing if the remaining number is larger than the width of the next image. every time you start a new line, set the variable back to 3k and run again. resolved

+2
source

An approach that can work is to place the sprite frames anywhere in the bitmap (so you can make them more compact) and accompany each bitmap file (n xml) that describes the location, size and origin of each frame AND has a list of all animations. Something like that:

 <SpriteSheet> <Frames> <Frame id="0" location="20,40" size="64,64" origin="32,32" /> <Frame id="1" location="100,40" size="64,64" origin="32,32" /> <Frame id="2" location="164,40" size="64,64" origin="0,0" /> <Frame id="3" location="20,120" size="64,64" origin="32,32" /> </Frames> <Animations> <Animation name="walk left" > <Keyframes> <Keyframe frameId="0" duration="0:0:0.5" offset="-5,0" /> <Keyframe frameId="1" duration="0:0:0.5" offset="-5,0" /> <Keyframe frameId="2" duration="0:0:0.4" offset="-2,0" /> <Keyframe frameId="1" duration="0:0:0.5" offset="-5,0" /> </Keyframes> </Animation> <Animation name="walk right" > <Keyframes> <Keyframe frameId="5" duration="0:0:0.5" offset="5,0" /> <Keyframe frameId="6" duration="0:0:0.5" offset="5,0" /> <Keyframe frameId="2" duration="0:0:0.4" offset="2,0" /> <Keyframe frameId="6" duration="0:0:0.5" offset="5,0" /> </Keyframes> </Animation> </Animations> </SpriteSheet> 

Thus, you can reuse frames in the animation (and thereby optimize the size of the bitmap images even more) and adjust the animation by simply editing the xml file.

All you have to do is read the XML file, read the bitmap, and when starting the animation: start the timer, which ticks at regular intervals. When it is ticking, you calculate the correct keyframe in the animation, adding the duration of the keyframes one by one and stopping when the sum is greater than the tick time; You must use the current keyframe.

In the xml file above, I added things like an offset, which allows you to change the position of the sprite during the animation (you can even interpolate it so that it moves smoothly)

All that remains is to capture the correct frame from the bitmap. As an optimization, you can pre-process the bitmap when loading the xml file by capturing frames, saving them as tiny bitmaps and discarding a large bitmap. This can optimize memory when the bitmap is large and not fully covered by frames.

In other cases, you do not pre-process and just blit the frame.

For large applications (more raster images / animations / frames), I recommend creating an application for creating and editing an XML file. Another option would be to create a plugin for your favorite painting program (if possible)

+2
source

All Articles