전으로 돌아 왔습니다. 다시. : 3 지금 당장 RPG 프로젝트를 진행하고 있습니다. 재미있을 뿐이므로 쉽게 이해할 수 있습니다. 기본 프레임 워크를 작성한 지점으로 이동했습니다. 이제 스프라이트 맵에서 스프라이트를 그릴 우아한 방법을 쓰고 싶습니다.스프라이트, XNA, C# 및 우아함
포켓 몬스터 다이아몬드의 스프라이트 맵을 사용하고 있습니다 (쉽게 테스트 할 수 있기 때문에 테스트 할 수 있습니다. 다음 포켓몬 게임을 만들지는 않습니다). 메인 영웅이 세 방향으로 모두 걷고 있습니다. 하나의 행, 37px x 37px 스프라이트, 이미지의 12 스프라이트.
이미지는 여기에 있습니다 : http://spriters-resource.com/ds/pkmndiamondpearl/lucas.png (현재 "Walking"하위 세트로 작업 중입니다).
나는 아래에 나열되어 모두와 SpriteManager 클래스 (spritesheets의 수집에 대한 XML 파일의 표현 인 SpriteSheetData 클래스와 함께) SpriteSheet 클래스를 만들었습니다
SpriteSheet.cs
을namespace RPG.Utils.Graphics
{
/// <summary>
/// Represents a Sprite Sheet. A Sprite Sheet is a graphic that contains a number of frames for animations.
/// These are laid out a set distance apart.
/// </summary>
public struct SpriteSheet
{
/// <summary>
/// The name for the texture. Used internally to reference the texture.
/// </summary>
[ContentSerializer]
public string TextureName
{
get;
private set;
}
/// <summary>
/// The file name of the texture.
/// </summary>
[ContentSerializer]
public string TextureFile
{
get;
private set;
}
/// <summary>
/// The width of each sprite in the sprite sheet.
/// </summary>
[ContentSerializer]
public int SpriteWidth
{
get;
private set;
}
/// <summary>
/// The height of each sprite in the sprite sheet.
/// </summary>
[ContentSerializer]
public int SpriteHeight
{
get;
private set;
}
/// <summary>
/// The interval between each frame of animation.
/// This should be (by default) 100f or 100ms.
/// </summary>
[ContentSerializer]
public float AnimationInterval
{
get;
set;
}
/// <summary>
/// The number of frames per each individual animation.
/// </summary>
[ContentSerializer]
public int AnimationLength
{
get;
set;
}
/// <summary>
/// The texture for this sprite sheet.
/// </summary>
[ContentSerializerIgnore]
public Texture2D Texture
{
get;
set;
}
}
SpriteManager.cs
/// <summary>
/// A sprite manager. Just loads sprites from a file and then stores them.
/// </summary>
public static class SpriteManager
{
private static Dictionary<string, SpriteSheetData> m_spriteSheets;
public static Dictionary<string, SpriteSheetData> SpriteSheets
{
get
{
if (m_spriteSheets == null)
m_spriteSheets = new Dictionary<string, SpriteSheetData>();
return m_spriteSheets;
}
}
/// <summary>
/// Loads all the sprites from the given directory using the content manager.
/// Sprites are loaded by iterating SpriteSheetData (.xml) files inside the /Sprites/ directory.
/// </summary>
/// <param name="mgr">Content Manager.</param>
/// <param name="subdir">Directory to load.</param>
public static void LoadAllSprites(ContentManager mgr, string subdir)
{
// Get the files in the subdirectory.
IEnumerable<string> files = Directory.EnumerateFiles(mgr.RootDirectory+"/"+subdir);
foreach (string f in files)
{
// Microsoft, why do you insist on not letting us load stuff with file extensions?
string fname = f.Replace("Content/", "").Replace(".xnb", "");
SpriteSheetData data = mgr.Load<SpriteSheetData>(fname);
string spriteSheetDir = subdir +"/" + data.SpriteSheetName + "/";
int loaded = 0;
for (int i = 0; i < data.SpriteSheets.Length; i++)
{
loaded++;
SpriteSheet current = data.SpriteSheets[i];
current.Texture = mgr.Load<Texture2D>(spriteSheetDir + current.TextureFile);
data.SpriteSheetMap[current.TextureName] = current;
}
Console.WriteLine("Loaded SpriteSheetData file \"{0}\".xml ({1} sprite sheet(s) loaded).", data.SpriteSheetName, loaded);
SpriteSheets[data.SpriteSheetName] = data;
}
}
/// <summary>
/// Query if a given Sprite definition file is loaded.
/// </summary>
/// <param name="spriteName">
/// The sprite definition file name (ie, "Hero"). This should correspond with the XML file
/// that contains the definition for the sprite sheets. It should NOT be the name OF a spritesheet.
/// </param>
/// <returns>True if the sprite definition file is loaded.</returns>
public static bool IsLoaded(string spriteName)
{
return SpriteSheets.ContainsKey(spriteName);
}
}
SpriteSheetData.cs
/// <summary>
/// Represents data for a SpriteSheet. These are stored in XML files.
/// </summary>
public struct SpriteSheetData
{
/// <summary>
/// The collective name for the sprite sheets.
/// </summary>
[ContentSerializer]
public string SpriteSheetName
{
get;
set;
}
/// <summary>
/// The SpriteSheets in this data file.
/// </summary>
[ContentSerializer]
internal SpriteSheet[] SpriteSheets
{
get;
set;
}
[ContentSerializerIgnore]
private Dictionary<string, SpriteSheet> m_map;
/// <summary>
/// The sprite sheet map.
/// </summary>
[ContentSerializerIgnore]
public Dictionary<string, SpriteSheet> SpriteSheetMap
{
get
{
if (m_map == null)
m_map = new Dictionary<string, SpriteSheet>();
return m_map;
}
}
}
그리고 나는 스프라이트를 "읽어"을 사용하고있는 파일은 다음과 같습니다 스프라이트/Hero.xml
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
<Asset Type="RPG.Utils.Graphics.SpriteSheetData">
<SpriteSheetName>Hero</SpriteSheetName>
<SpriteSheets>
<Item Type="RPG.Utils.Graphics.SpriteSheet">
<TextureName>HeroWalking</TextureName>
<TextureFile>hero_walk</TextureFile>
<SpriteWidth>37</SpriteWidth>
<SpriteHeight>37</SpriteHeight>
<AnimationInterval>400</AnimationInterval>
<AnimationLength>3</AnimationLength>
</Item>
</SpriteSheets>
</Asset>
</XnaContent>
오전 데 문제는 내가 우아하게 구성 할 수있는 방법이 확실하지 오전입니다 1) 스프라이트 로딩과 2) 스프라이트 시트의 페어링 (이것은 게임의 "일반적인"부분입니다. 다시 사용하고자하는 비트이므로 생성 할 수있는 엔티티의 인스턴스가 얼마나 많은지 모르겠습니다.)를 엔티티/인게임 오브젝트, 특히 플레이어로 가져와야합니다 (지금부터 시도하고 있기 때문에). 나는 계속하는 방법에 대해 확신하지 못하므로 어떤 도움이라도 대단히 감사합니다. 당신은 더 이상 코드가 필요하면
요청 (하나님의 금지) 및 당신에게 주어져야한다 : 3
제쳐두고 제가 일반적으로 관리자와 같이하고 싶은 점은 그리기 방법을 사용할 수 있도록 허용 한 것입니다. 이 메서드는 SpriteBatch 또는 GraphicsDevice를 가져 와서 데이터를 렌더링 한 다음 렌더링합니다. 매우 우아하게 메인 로직 루프에서 업데이트 로직과 드로를 분리 할 수 있습니다. 이렇게하면 클래스를 다른 게임 논리 및 관리자에 대해 너무 많이 알지 못하게 할 수 있습니다. 오류가 넘쳐나지 않도록 가능한 한 클래스를 독립적으로 유지하려고합니다. 도움이 되길 바랍니다! 건배! –