- Modifié
I can't display spine animation on my WinForm Project
I have 3 files to use spine animation.
.png, .skel, .atlas
And i write code on visual studio 2017 like this
using System.Windows.Forms;
using System.Drawing;
using System;
using Spine;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private Timer timer;
private Atlas atlas;
private SkeletonBinary skBinary;
private SkeletonData skData;
private Skeleton sk;
private Animation ani;
private AnimationState aniState;
private AnimationStateData aniStateData;
public Form1()
{
InitializeComponent();
Size = new Size(800, 480);
timer = new Timer();
timer.Interval = 500;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
aniState.Update(timer.Interval);
aniState.Apply(sk);
sk.UpdateWorldTransform();
Invalidate();
timer.Start();
}
protected override void OnLoad(EventArgs e)
{
try
{
base.OnLoad(e);
atlas = new Atlas("Alchemist.atlas", new MyTextureLoader());
skBinary = new SkeletonBinary(atlas);
skData = skBinary.ReadSkeletonData("Alchemist.skel");
sk = new Skeleton(skData);
ani = skData.FindAnimation("walk");
aniStateData = new AnimationStateData(skData);
aniState = new AnimationState(aniStateData);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void DrawSkin(Graphics g)
{
foreach (Slot slot in sk.Slots)
{
if (slot.Attachment == null || slot.Attachment.GetType() != typeof(RegionAttachment))
continue;
RegionAttachment attach = (RegionAttachment)slot.Attachment;
AtlasRegion region = (AtlasRegion)attach.RendererObject;
g.ResetTransform();
g.TranslateTransform(400, 100);
g.TranslateTransform(attach.X, attach.Y);
g.RotateTransform(attach.Rotation);
g.TranslateTransform(slot.Bone.WorldX, -slot.Bone.WorldY);
g.RotateTransform(slot.Bone.Rotation);
g.ScaleTransform(slot.Bone.ScaleX, slot.Bone.ScaleY);
Rectangle dstRC = new Rectangle(0, 0, region.width, region.height);
Rectangle srcRC = new Rectangle(region.x, region.y, region.width, region.height);
g.DrawImage((Image)region.page.rendererObject, dstRC, srcRC, GraphicsUnit.Pixel);
g.ResetTransform();
}
}
private void DrawBones(Graphics g)
{
g.ResetTransform();
g.TranslateTransform(400, 100);
Color Color = Color.FromArgb(255, 0, 0, 255);
foreach (Bone bone in sk.Bones)
{
float x = bone.Data.Length + bone.WorldX;
float y = bone.Data.Length + bone.WorldY;
g.DrawLine(Pens.Red, new PointF(bone.WorldX, bone.WorldY), new PointF(x, y));
}
foreach (Bone bone in sk.Bones)
{
g.DrawEllipse(Pens.Blue, bone.WorldX - 2, bone.WorldY - 2, 4, 4);
}
g.ResetTransform();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
DrawSkin(g);
DrawBones(g);
}
public class MyTextureLoader : TextureLoader
{
public void Load(AtlasPage page, string path)
{
Bitmap img = new Bitmap(path);
page.width = img.Width;
page.height = img.Height;
page.rendererObject = img;
}
public void Unload(object texture)
{
((Bitmap)texture).Dispose();
}
}
}
}
And i run this program, i can't see any animation and picture.
please help me...
Cool, you figured out how to write your own Win32 Forms renderer! Your drawing code looks mostly OK, altough I'm not familiar with the API. The translation by (400,100) looks a bit weird. You can take a look at our spine-ts Canvas backend, which also uses a plain old 2D drawing API, much like the one you use. spine-runtimes/SkeletonRenderer.ts at 3.6
I'd also suggest to start with a super simple skeleton: 1 root bone, with 1 slot, housing 1 region attachment, no translation, rotation, scale, sheer etc. You can then work your way up through these features and ensure your transformations set on the Graphics context work correctly.
Try this branch on GitHub : https://github.com/execomrt/spine-runtimes/tree/master/spine-windows-forms
This will allow to render the 'Spine Boy' with only using GDI and Windows Forms.