Skip to content

Commit

Permalink
MapRender: support particles.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kagamia committed Mar 15, 2018
1 parent 1b3560f commit 3bea67b
Show file tree
Hide file tree
Showing 16 changed files with 961 additions and 9 deletions.
2 changes: 1 addition & 1 deletion WzComparerR2.MapRender/FrmMapRender2.SceneManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private async Task LoadMap()
this.resLoader.BeginCounting();

//加载地图数据
var mapData = new MapData();
var mapData = new MapData(this.Services.GetService<IRandom>());
mapData.Load(mapImg.Node, resLoader);

//处理bgm
Expand Down
33 changes: 32 additions & 1 deletion WzComparerR2.MapRender/FrmMapRender2.SceneRendering.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ private void UpdateAllItems(SceneNode node, TimeSpan elapsed)
}
}
}
else if (item is ParticleItem)
{
var particle = (ParticleItem)item;
var pSystem = particle.View?.ParticleSystem;
if (pSystem != null)
{
pSystem.Update(elapsed);
}
}
}
}
else
Expand Down Expand Up @@ -557,7 +566,10 @@ private MeshItem GetMesh(SceneItem item)
return GetMeshReactor((ReactorItem)item);
}
}

else if (item is ParticleItem)
{
return GetMeshParticle((ParticleItem)item);
}
return null;
}

Expand Down Expand Up @@ -749,6 +761,25 @@ private MeshItem GetMeshReactor(ReactorItem reactor)
return mesh;
}

private MeshItem GetMeshParticle(ParticleItem particle)
{
var pSystem = particle.View?.ParticleSystem;
if (pSystem == null)
{
return null;
}

Vector2 position;
position.X = renderEnv.Camera.Center.X * (100 + particle.Rx) / 100;
position.Y = renderEnv.Camera.Center.Y * (100 + particle.Ry) / 100;

var mesh = batcher.MeshPop();
mesh.RenderObject = pSystem;
mesh.Position = position;
mesh.Z0 = particle.Z;
return mesh;
}

private object GetRenderObject(object animator, bool flip = false, int alpha = 255)
{
if (animator is FrameAnimator)
Expand Down
5 changes: 5 additions & 0 deletions WzComparerR2.MapRender/FrmMapRender2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ private void Graphics_DeviceCreated(object sender, EventArgs e)

protected override void Initialize()
{
//init services
this.Services.AddService<Random>(new Random());
this.Services.AddService<IRandom>(new ParticleRandom(this.Services.GetService<Random>()));

//init components
this.renderEnv = new RenderEnv(this, this.graphics);
this.batcher = new MeshBatcher(this.GraphicsDevice) { CullingEnabled = true };
this.resLoader = new ResourceLoader(this.Services);
Expand Down
19 changes: 19 additions & 0 deletions WzComparerR2.MapRender/IRandom.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;

namespace WzComparerR2.MapRender
{
public interface IRandom
{
float NextVar(float baseValue, float varRange, bool nonNegative = false);
int NextVar(int baseValue, int varRange, bool nonNegative = false);
Vector2 NextVar(Vector2 baseValue, Vector2 varRange);
Color NextVar(Color baseValue, Color varRange);
int Next(int maxValue);
bool NextPercent(float percent);
}
}
56 changes: 53 additions & 3 deletions WzComparerR2.MapRender/MapData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ namespace WzComparerR2.MapRender
{
public class MapData
{
public MapData()
public MapData(IRandom random)
{
this.Scene = new MapScene();
this.MiniMap = new MiniMap();
this.Tooltips = new List<TooltipItem>();

this.random = random;
}

#region 基本信息
Expand All @@ -44,6 +46,8 @@ public MapData()
public MapScene Scene { get; private set; }
public IList<TooltipItem> Tooltips { get; private set; }

private readonly IRandom random;

public void Load(Wz_Node mapImgNode, ResourceLoader resLoader)
{
var infoNode = mapImgNode.Nodes["info"];
Expand Down Expand Up @@ -124,6 +128,10 @@ public void Load(Wz_Node mapImgNode, ResourceLoader resLoader)
{
LoadTooltip(node);
}
if ((node = mapImgNode.Nodes["particle"]) != null)
{
LoadParticle(node);
}

//计算地图大小
CalcMapSize();
Expand Down Expand Up @@ -388,6 +396,16 @@ private void LoadTooltip(Wz_Node tooltipNode)
}
}

private void LoadParticle(Wz_Node node)
{
foreach(var particleNode in node.Nodes)
{
var item = ParticleItem.LoadFromNode(particleNode);
item.Name = node.Text;
Scene.Effect.Slots.Add(item);
}
}

private void CalcMapSize()
{
if (!this.VRect.IsEmpty)
Expand Down Expand Up @@ -489,6 +507,10 @@ public void PreloadResource(ResourceLoader resLoader)
{
PreloadResource(resLoader, (ReactorItem)item);
}
else if (item is ParticleItem)
{
PreloadResource(resLoader, (ParticleItem)item);
}
}
}

Expand Down Expand Up @@ -722,6 +744,35 @@ private void PreloadResource(ResourceLoader resLoader, ReactorItem reactor)
reactor.View = view;
}

private void PreloadResource(ResourceLoader resLoader, ParticleItem particle)
{
string path = $@"Effect\particle.img\{particle.ParticleName}";
var particleNode = PluginManager.FindWz(path);

if (particleNode == null)
{
return;
}

var desc = resLoader.LoadParticleDesc(particleNode);
var pSystem = new ParticleSystem(this.random);
pSystem.LoadDescription(desc);

for (int i = 0; i < particle.SubItems.Length; i++)
{
var subItem = particle.SubItems[i];
var pGroup = pSystem.CreateGroup(i.ToString());
pGroup.Position = new Vector2(subItem.X, subItem.Y);
pGroup.Active();
pSystem.Groups.Add(pGroup);
}

particle.View = new ParticleItem.ItemView()
{
ParticleSystem = pSystem
};
}

private StateMachineAnimator CreateSMAnimator(Wz_Node node, ResourceLoader resLoader)
{
var aniData = new Dictionary<string, RepeatableFrameAnimationData>();
Expand Down Expand Up @@ -787,14 +838,13 @@ private void AddMobAI(StateMachineAnimator ani)

private void AddNpcAI(StateMachineAnimator ani)
{
Random r = new Random();
var actions = new[] { "stand", "say", "mouse", "move", "hand", "laugh", "eye" };
var availActions = ani.Data.States.Where(act => actions.Contains(act)).ToArray();
if (availActions.Length > 0)
{
ani.AnimationEnd += (o, e) =>
{
e.NextState = availActions[r.Next(availActions.Length)];
e.NextState = availActions[this.random.Next(availActions.Length)];
};
}
}
Expand Down
3 changes: 2 additions & 1 deletion WzComparerR2.MapRender/MapScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public MapScene()
Layers = new SceneNode(),
Fly = new FlyLayerNode(),
Front = new ContainerNode(),
Effect = new ContainerNode()
});

for (int i = 0; i <= 7; i++)
Expand All @@ -27,7 +28,7 @@ public MapScene()
public SceneNode Layers { get; private set; }
public FlyLayerNode Fly { get; private set; }
public ContainerNode Front { get; private set; }

public ContainerNode Effect { get; private set; }

public IEnumerable<PortalItem> Portals => this.Fly.Portal.Slots.OfType<PortalItem>();

Expand Down
53 changes: 50 additions & 3 deletions WzComparerR2.MapRender/MeshBatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public void Draw(MeshItem mesh)
{
this.DrawItem((LineListMesh)mesh.RenderObject);
}
else if (mesh.RenderObject is ParticleSystem)
{
this.DrawItem(mesh, (ParticleSystem)mesh.RenderObject);
}
}

private void DrawItem(MeshItem mesh, Frame frame)
Expand Down Expand Up @@ -277,6 +281,26 @@ private void DrawItem(LineListMesh lineList)
}
}

private void DrawItem(MeshItem mesh, ParticleSystem particleSystem)
{
if (particleSystem.Texture?.Texture != null)
{
ItemType itemType = ItemType.Unknown;
if (particleSystem.BlendFuncSrc == ParticleBlendFunc.SRC_ALPHA)
{
if (particleSystem.BlendFuncDst == ParticleBlendFunc.ONE) //5,2
itemType = ItemType.Sprite_BlendAdditive;
else if (particleSystem.BlendFuncDst == ParticleBlendFunc.INV_SRC_ALPHA) //5,6
itemType = ItemType.Sprite_BlendNonPremultiplied;
}
if (itemType == ItemType.Unknown)
{
throw new Exception($"Unknown particle blendfunc: {particleSystem.BlendFuncSrc}, {particleSystem.BlendFuncDst}");
}
Prepare(itemType);
particleSystem.Draw(this.sprite, mesh.Position);
}
}

public Rectangle[] Measure(MeshItem mesh)
{
Expand Down Expand Up @@ -393,6 +417,8 @@ private void Prepare(ItemType itemType)
case ItemType.Sprite:
case ItemType.Skeleton:
case ItemType.D2DObject:
case ItemType.Sprite_BlendAdditive:
case ItemType.Sprite_BlendNonPremultiplied:
InnerFlush();
lastItem = itemType;
InnerBegin();
Expand Down Expand Up @@ -435,6 +461,22 @@ private void InnerBegin()
this.d2dRender.Begin(this.matrix.Value);
}
break;

case ItemType.Sprite_BlendAdditive:
if (this.sprite == null)
{
this.sprite = new SpriteBatchEx(this.GraphicsDevice);
}
this.sprite.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: this.matrix);
break;

case ItemType.Sprite_BlendNonPremultiplied:
if (this.sprite == null)
{
this.sprite = new SpriteBatchEx(this.GraphicsDevice);
}
this.sprite.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: this.matrix);
break;
}
}

Expand All @@ -443,6 +485,8 @@ private void InnerFlush()
switch (lastItem)
{
case ItemType.Sprite:
case ItemType.Sprite_BlendAdditive:
case ItemType.Sprite_BlendNonPremultiplied:
this.sprite.End();
break;

Expand Down Expand Up @@ -524,9 +568,12 @@ public void Dispose()
private enum ItemType
{
Unknown = 0,
Sprite,
Skeleton,
D2DObject
Sprite = 1,
Skeleton = 2,
D2DObject = 3,
Sprite_AlphaBlend = Sprite,
Sprite_BlendAdditive = 4,
Sprite_BlendNonPremultiplied = 5
}

}
Expand Down
49 changes: 49 additions & 0 deletions WzComparerR2.MapRender/Particle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;

namespace WzComparerR2.MapRender
{
public class Particle
{
public Vector2 Pos;
public Color StartColor;
public Color EndColor;
public float StartSize;
public float EndSize;
public float StartSpin;
public float EndSpin;
public float Life;

//gravity
public Vector2 Dir;
public float RadialAcc;
public float TangentialAcc;

//lifecycle
public float Time;
public float NormalizedTime;

public void Reset()
{
this.Pos = Vector2.Zero;
this.StartColor = new Color();
this.EndColor = new Color();
this.StartSize = 0;
this.EndSize = 0;
this.StartSpin = 0;
this.EndSpin = 0;
this.Life = 0;

this.Dir = Vector2.Zero;
this.RadialAcc = 0;
this.TangentialAcc = 0;

this.Time = 0;
this.NormalizedTime = 0;
}
}
}
Loading

0 comments on commit 3bea67b

Please sign in to comment.