不使用XNA或其他第三方库的2d Sprite动画

时间:2013-04-19 19:58:55

标签: c# animation 2d sprite

我想创建一个简单的游戏,类似于RPG Maker可以创建的游戏。我目前主要关注的是一个教程,它可以指导我如何在不使用XNA或任何其他特定库的情况下完成它。

理想的是一步一步的教程或一个易于理解的好例子。

我的目标是独立完成,并了解整个过程如何与彼此相关的动画元素相关。

我过去已经使用一个简单的教程构建了一个简单的蛇游戏,但是它没有动画动画,这是我接下来要学习的主要内容。

修改

到目前为止,我发现的所有教程都使用第三方库。我确实遇到过this link,但我正在寻找一些不包含XNA的东西。

3 个答案:

答案 0 :(得分:15)

有许多方法可以解决您所描述的主题。我将给出一些概述,然后希望提供一些资源,这些资源可以为您提供示例以帮助您入门。

基本上,基于精灵的动画围绕着一系列相似的图像,当按顺序显示时,会产生动作的外观,类似于翻书。

诀窍是要了解你的精灵何时移动(因此应该是动画的) - 以及它何时静止不动(因此不应该动画)。换句话说 - 假设您的游戏的角色仅在您按住时移动或者,您需要检测其中一个键的开始和停止时间,以便您可以相应地开始/停止动画。

想象一下,为简单起见,你只有2个精灵。第一个(左下方)代表你的角色静止不动,第二个代表你的角色中间步骤(右下方):

Mario

如果未按下按钮,则只需连续显示第一张图像。当按钮时,您每隔x毫秒切换两次(取决于您希望动画显示的速度)。

animated .gif是一种格式,您可以在其中包含一系列简单的图像帧,这些图像帧旨在显示为一系列(因此创建了动画的幻觉)。如果你使用这种格式创建你的精灵,你可以使用类似于in this SO discussion的代码,它提供了一些示例代码,用于如何使用C#为动画.gif设置动画并控制它的开始/停止。

或者,如果你想使用精灵文件(就像我上面提到的那样),你可以使用类似于this CodeProject code的东西,它专注于与Windows环境的GDI交互,以便提取和绘制一个精灵的一部分到目标画布上。通过重新绘制每x毫秒(如上所述),这可以提供相同的效果。

要记住的一些事项:

你需要处理精灵的透明度(上面的Mario精灵,例如,具有透明背景) - 这样你的游戏环境的背景就会显示出来。如果使用GDI - 这一切都与你如何调用绘画方法有关。如果使用动画.gif文件 - 要使用的方法取决于您在窗口中的显示方式。

对于其他一些资源/示例/参考,请查看以下资源:

对于Sprite开发:

答案 1 :(得分:4)

我把我所认为的你所追求的例子扔到了一起。此示例可应用于按钮或图片框。我选择了这种简单的方式。

动画的每个实例都包含一个计时器和一个图像列表。每当计时器触发其事件时,都会更新目标控件的图像。

我在这里上传了我的项目文件。 http://mcspazzy.com/code/ParTest.zip

希望它足以提供帮助。只要问你是否需要更多解释。

班级

public class Animation
{
    readonly Timer _animtimer = new Timer();

    public List<Image> Frames;

    public int FrameIndex;

    private Button _target;
    private PictureBox _ptarget;

    public void Target(PictureBox target)
    {
        _ptarget = target;
    }

    public void Target(Button target)
    {
        _target = target;
    }

    public int FrameSpeed
    {
        get { return _animtimer.Interval; }
        set { _animtimer.Interval = value; }
    }

    public Animation()
    {
        Frames  = new List<Image>();
        _animtimer.Interval = 100;
        _animtimer.Tick += Update;
    }

    public void Play()
    {
        _animtimer.Start();
    }

    public void AddFrame(string file)
    {
        Frames.Add(Image.FromFile(file));
    }

    public void Stop()
    {
        _animtimer.Stop();
    }

    private void Update(object sender, EventArgs eventArgs)
    {
        FrameIndex++;

        if (FrameIndex == Frames.Count)
        {
            FrameIndex = 0;
        }
        _target.Image = Frames[FrameIndex];
        _ptarget.Image = Frames[FrameIndex];
    }

    public static implicit operator Image(Animation a)
    {
        return a.Frames[a.FrameIndex];
    }
}

这是我的表单加载。真的可以去任何东西初始化。

    private void Form1Load(object sender, EventArgs e)
    {

        _testAnim.AddFrame(@"F:\Im\Black.png");
        _testAnim.AddFrame(@"F:\Im\Blue.png");
        _testAnim.AddFrame(@"F:\Im\Green.png");
        _testAnim.AddFrame(@"F:\Im\Orange.png");
        _testAnim.AddFrame(@"F:\Im\Red.png");



        _testAnim.Target(ButtonTest);
        _testAnim.Target(PicBox);


        _testAnim.Play();


    }

答案 2 :(得分:1)

在快速搜索中,我找到了this example。 我在c#图形方面不是很有经验,但是我学习使用非图形化语言的几点很少:

  • 声明你想要绘制的地方
  • 创建一个循环运行,直到abort / event结束循环(就像物体碰撞某物)
  • 在循环中:等待,清除旧绘图区域,重新计算新位置,绘制新位置
  • 如果需要,您也可以更改图像以进行绘制,但是您需要为每个“框架”设置单独的图像
  • 多线程是一个好主意,因此您可以将图形与其他游戏逻辑分开运行
  • 尽量保持清除绘图区域的时间并尽可能缩短重绘时间以防止闪烁
  • 跟踪您绘制的对象的大小,更容易检查碰撞(如精灵的中心+半径,然后您可以轻松计算它周围的圆形区域,以检查两个精灵是否彼此太靠近)