2012-05-04 20 views
7

Estoy tratando de crear una imagen de sprite muy básica.Cómo crear una imagen de sprite

En primer lugar tengo una imagen existente (Ancho = 100 px, Altura = 100 px).

Voy a estar recorriendo esta imagen entre 10 y 100 veces, cada vez colocándola en el sprite junto al anterior.

El sprite está limitado a 3000 píxeles de ancho.

Colocar las imágenes una al lado de la otra está bien, porque puedo combinarlas con un método simple, sin embargo, debo limitar el ancho de las imágenes combinadas a 3000px, luego comenzar en una nueva línea.

+0

Suena bastante simple; coloca la imagen anexa mientras la longitud de la imagen total es inferior a 3000 px. – KeithS

+1

http://stylemeltdown.com/image-sprite-navigation-with-css/ –

+0

eso es lo que pensé, pero como puedes ver, tengo que comenzar con una "nueva línea" cuando el sprite tiene un total de 3000px de ancho . –

Respuesta

3

Vamos a tratar con un poco de pseudocódigo

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 
} 
+0

esto sin duda me puso en el camino correcto, gracias –

+0

contento de estar de ayuda :) –

2

declare una variable en 3000, si coloca una imagen de ancho 250 quítelo de la variable, siga haciendo esto, esto también le permite decidir si queda suficiente espacio en esa línea para su próxima imagen viendo si el número que queda es más grande que el ancho de la siguiente imagen. cada vez que comienzas en una nueva línea, establece la variable nuevamente en 3k y comienza de nuevo. Resuelto

7

Hay una gran cantidad de información acerca de 2D sprites en el siguiente artículo de MSDN: Rendering 2D sprites

Esos ejemplos se basan en Microsoft's XNA, que es una plataforma que se puede usar en Visual Studio para desarrollar juegos para Windows, Windows Phone y XBOX 360.

Por ejemplo, para dibujar un sprite, puede usar el siguiente código C# (ejemplo tomado del artículo de MSDN, XBOX 360 código específico eliminado):

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); 
    } 

Es necesario llamar LoadContent() para inicializar, entonces es necesario llamar a GetTitleSafeArea(100) para obtener la zona de dibujo segura (en este caso wich 100 por ciento), finalmente se puede utilizar la Draw método. Acepta un parámetro que contiene una instancia de la clase GameTime, que es una instantánea del estado de sincronización del juego expresada en valores que pueden ser utilizados por juegos de paso variable (tiempo real) o paso fijo (tiempo de juego).

Háganme saber si eso le sirve.

+2

Hola Matt, es habitual en StackOverflow respuestas para incluir un resumen de los contenidos de un enlace o los aspectos más destacados que responden específicamente a la pregunta. El objetivo de los sitios SE es convertirse en un recurso de conocimiento, de respuestas, en los próximos años. Con una respuesta de solo enlace, el operador debe buscar otro recurso para encontrar una respuesta de la que no esté seguro. Lo que es más importante, si su enlace se rompiera alguna vez (a menudo los de Microsoft lo hacen a lo largo del tiempo), su respuesta es inútil para cualquier persona que visite esta página en el futuro. Considere hacer y editar su respuesta para agregar más detalles. ¡Buena suerte! –

+3

Hola Jeremy, estoy de acuerdo y así he agregado más detalles. Saludos, Matt – Matt

2

Un enfoque que puede funcionar es permitir colocar los marcos del sprite en cualquier lugar del mapa de bits (de esa manera puedes hacerlos más compactos) y acompañar cada mapa de bits con un archivo (n xml) que describa la ubicación, tamaño y origen de cada cuadro Y tiene una lista de todas las animaciones. Algo como esto:

<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> 

esta manera se puede reutilizar los marcos a través de animaciones (y así optimizar el tamaño de mapa de bits incluso más) y personalizar las animaciones simplemente editando el archivo XML.

Todo lo que tiene que hacer es leer el archivo XML, leer el mapa de bits y al iniciar una animación: inicie un temporizador que funcione a intervalos regulares. Cuando funciona, calcule el fotograma clave correcto en la animación agregando las duraciones de los fotogramas clave uno por uno y deteniéndolo cuando la suma sea mayor que la hora de marcación; el Keyframe actual debe ser utilizado.

en el archivo XML anterior he añadido cosas tales como un desplazamiento que le permite modificar la posición del sprite durante la animación (incluso se podría interpolar que lo que se mueve sin problemas)

Todo lo que queda es agarrar el marco correcto fuera del mapa de bits. Como optimización, puede preprocesar el mapa de bits al cargar el archivo xml al tomar los marcos, mantenerlos como pequeños mapas de bits y descartar el mapa de bits grande. Esto podría optimizar la memoria cuando el mapa de bits es grande y no está completamente cubierto en marcos.

En otros casos, no preprocesa y solo ajusta el marco.

Para aplicaciones más grandes (más mapas de bits/animaciones/marcos) Recomiendo crear una aplicación para crear y editar el archivo xml. Otra opción podría ser crear un complemento para su programa de pintura favorito (si es posible)

Cuestiones relacionadas