Add animation as blocks are broken
This commit is contained in:
parent
53987d2d52
commit
069e80469c
@ -66,7 +66,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
|
|
||||||
void UnloadChunk(ReadOnlyChunk chunk)
|
void UnloadChunk(ReadOnlyChunk chunk)
|
||||||
{
|
{
|
||||||
Game.PendingMainThreadActions.Add(() =>
|
Game.Invoke(() =>
|
||||||
{
|
{
|
||||||
ActiveMeshes.Remove(chunk.Coordinates);
|
ActiveMeshes.Remove(chunk.Coordinates);
|
||||||
ChunkMeshes.RemoveAll(m => m.Chunk.Coordinates == chunk.Coordinates);
|
ChunkMeshes.RemoveAll(m => m.Chunk.Coordinates == chunk.Coordinates);
|
||||||
@ -80,7 +80,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
case "Position":
|
case "Position":
|
||||||
var sorter = new ChunkRenderer.ChunkSorter(new Coordinates3D(
|
var sorter = new ChunkRenderer.ChunkSorter(new Coordinates3D(
|
||||||
(int)Game.Client.Position.X, 0, (int)Game.Client.Position.Z));
|
(int)Game.Client.Position.X, 0, (int)Game.Client.Position.Z));
|
||||||
Game.PendingMainThreadActions.Add(() => ChunkMeshes.Sort(sorter));
|
Game.Invoke(() => ChunkMeshes.Sort(sorter));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using Microsoft.Xna.Framework;
|
|||||||
using XVector3 = Microsoft.Xna.Framework.Vector3;
|
using XVector3 = Microsoft.Xna.Framework.Vector3;
|
||||||
using TVector3 = TrueCraft.API.Vector3;
|
using TVector3 = TrueCraft.API.Vector3;
|
||||||
using TRay = TrueCraft.API.Ray;
|
using TRay = TrueCraft.API.Ray;
|
||||||
|
using TrueCraft.Core.Logic.Blocks;
|
||||||
|
|
||||||
namespace TrueCraft.Client.Modules
|
namespace TrueCraft.Client.Modules
|
||||||
{
|
{
|
||||||
@ -14,8 +15,13 @@ namespace TrueCraft.Client.Modules
|
|||||||
public TrueCraftGame Game { get; set; }
|
public TrueCraftGame Game { get; set; }
|
||||||
|
|
||||||
private BasicEffect HighlightEffect { get; set; }
|
private BasicEffect HighlightEffect { get; set; }
|
||||||
|
private AlphaTestEffect DestructionEffect { get; set; }
|
||||||
|
private Mesh ProgressMesh { get; set; }
|
||||||
|
private int Progress { get; set; }
|
||||||
|
private static readonly RasterizerState RasterizerState;
|
||||||
private static readonly VertexPositionColor[] CubeVerticies;
|
private static readonly VertexPositionColor[] CubeVerticies;
|
||||||
private static readonly short[] CubeIndicies;
|
private static readonly short[] CubeIndicies;
|
||||||
|
private static readonly BlendState DestructionBlendState;
|
||||||
|
|
||||||
static HighlightModule()
|
static HighlightModule()
|
||||||
{
|
{
|
||||||
@ -37,6 +43,18 @@ namespace TrueCraft.Client.Modules
|
|||||||
0, 4, 4, 7, 7, 6, 6, 2,
|
0, 4, 4, 7, 7, 6, 6, 2,
|
||||||
1, 5, 5, 4, 3, 7, 6, 5
|
1, 5, 5, 4, 3, 7, 6, 5
|
||||||
};
|
};
|
||||||
|
DestructionBlendState = new BlendState
|
||||||
|
{
|
||||||
|
ColorSourceBlend = Blend.DestinationColor,
|
||||||
|
ColorDestinationBlend = Blend.SourceColor,
|
||||||
|
AlphaSourceBlend = Blend.DestinationAlpha,
|
||||||
|
AlphaDestinationBlend = Blend.SourceAlpha
|
||||||
|
};
|
||||||
|
RasterizerState = new RasterizerState
|
||||||
|
{
|
||||||
|
DepthBias = -3,
|
||||||
|
SlopeScaleDepthBias = -3
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public HighlightModule(TrueCraftGame game)
|
public HighlightModule(TrueCraftGame game)
|
||||||
@ -44,6 +62,29 @@ namespace TrueCraft.Client.Modules
|
|||||||
Game = game;
|
Game = game;
|
||||||
HighlightEffect = new BasicEffect(Game.GraphicsDevice);
|
HighlightEffect = new BasicEffect(Game.GraphicsDevice);
|
||||||
HighlightEffect.VertexColorEnabled = true;
|
HighlightEffect.VertexColorEnabled = true;
|
||||||
|
DestructionEffect = new AlphaTestEffect(Game.GraphicsDevice);
|
||||||
|
DestructionEffect.Texture = game.TextureMapper.GetTexture("terrain.png");
|
||||||
|
DestructionEffect.ReferenceAlpha = 1;
|
||||||
|
|
||||||
|
GenerateProgressMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateProgressMesh()
|
||||||
|
{
|
||||||
|
int[] indicies;
|
||||||
|
var texCoords = new Vector2(Progress, 15);
|
||||||
|
var texture = new[]
|
||||||
|
{
|
||||||
|
texCoords + Vector2.UnitX + Vector2.UnitY,
|
||||||
|
texCoords + Vector2.UnitY,
|
||||||
|
texCoords,
|
||||||
|
texCoords + Vector2.UnitX
|
||||||
|
};
|
||||||
|
for (int i = 0; i < texture.Length; i++)
|
||||||
|
texture[i] *= new Vector2(16f / 256f);
|
||||||
|
var verticies = BlockRenderer.CreateUniformCube(XVector3.Zero,
|
||||||
|
texture, VisibleFaces.All, 0, out indicies, Color.White);
|
||||||
|
ProgressMesh = new Mesh(Game, verticies, indicies);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(GameTime gameTime)
|
public void Update(GameTime gameTime)
|
||||||
@ -62,10 +103,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
{
|
{
|
||||||
Game.HighlightedBlock = cast.Item1;
|
Game.HighlightedBlock = cast.Item1;
|
||||||
Game.HighlightedBlockFace = cast.Item2;
|
Game.HighlightedBlockFace = cast.Item2;
|
||||||
HighlightEffect.World =
|
HighlightEffect.World = DestructionEffect.World =
|
||||||
Matrix.CreateTranslation(new XVector3(-0.5f)) *
|
|
||||||
Matrix.CreateScale(1.01f) *
|
|
||||||
Matrix.CreateTranslation(new XVector3(0.5f)) *
|
|
||||||
Matrix.CreateTranslation(new XVector3(cast.Item1.X, cast.Item1.Y, cast.Item1.Z));
|
Matrix.CreateTranslation(new XVector3(cast.Item1.X, cast.Item1.Y, cast.Item1.Z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,9 +111,11 @@ namespace TrueCraft.Client.Modules
|
|||||||
public void Draw(GameTime gameTime)
|
public void Draw(GameTime gameTime)
|
||||||
{
|
{
|
||||||
Game.Camera.ApplyTo(HighlightEffect);
|
Game.Camera.ApplyTo(HighlightEffect);
|
||||||
|
Game.Camera.ApplyTo(DestructionEffect);
|
||||||
|
|
||||||
if (Game.HighlightedBlock != -Coordinates3D.One)
|
if (Game.HighlightedBlock != -Coordinates3D.One)
|
||||||
{
|
{
|
||||||
|
Game.GraphicsDevice.RasterizerState = RasterizerState;
|
||||||
foreach (var pass in HighlightEffect.CurrentTechnique.Passes)
|
foreach (var pass in HighlightEffect.CurrentTechnique.Passes)
|
||||||
{
|
{
|
||||||
pass.Apply();
|
pass.Apply();
|
||||||
@ -84,6 +124,26 @@ namespace TrueCraft.Client.Modules
|
|||||||
CubeVerticies.Length, CubeIndicies, 0, CubeIndicies.Length / 2);
|
CubeVerticies.Length, CubeIndicies, 0, CubeIndicies.Length / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Game.EndDigging != DateTime.MaxValue)
|
||||||
|
{
|
||||||
|
var diff = Game.EndDigging - DateTime.UtcNow;
|
||||||
|
var total = Game.EndDigging - Game.StartDigging;
|
||||||
|
var progress = (int)(diff.TotalMilliseconds / total.TotalMilliseconds * 10);
|
||||||
|
progress = -(progress - 5) + 5;
|
||||||
|
if (progress > 9)
|
||||||
|
progress = 9;
|
||||||
|
|
||||||
|
if (progress != Progress)
|
||||||
|
{
|
||||||
|
Progress = progress;
|
||||||
|
GenerateProgressMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Game.GraphicsDevice.BlendState = DestructionBlendState;
|
||||||
|
ProgressMesh.Draw(DestructionEffect);
|
||||||
|
Game.GraphicsDevice.BlendState = BlendState.AlphaBlend;
|
||||||
|
Game.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
public class PlayerControlModule : IInputModule
|
public class PlayerControlModule : IInputModule
|
||||||
{
|
{
|
||||||
private TrueCraftGame Game { get; set; }
|
private TrueCraftGame Game { get; set; }
|
||||||
private DateTime StartDigging { get; set; }
|
|
||||||
private DateTime NextAnimation { get; set; }
|
private DateTime NextAnimation { get; set; }
|
||||||
private DateTime EndDigging { get; set; }
|
|
||||||
private Coordinates3D TargetBlock { get; set; }
|
|
||||||
private XVector3 Delta { get; set; }
|
private XVector3 Delta { get; set; }
|
||||||
private bool Capture { get; set; }
|
private bool Capture { get; set; }
|
||||||
|
|
||||||
@ -25,9 +22,9 @@ namespace TrueCraft.Client.Modules
|
|||||||
{
|
{
|
||||||
Game = game;
|
Game = game;
|
||||||
Capture = true;
|
Capture = true;
|
||||||
StartDigging = DateTime.MinValue;
|
Game.StartDigging = DateTime.MinValue;
|
||||||
EndDigging = DateTime.MaxValue;
|
Game.EndDigging = DateTime.MaxValue;
|
||||||
TargetBlock = -Coordinates3D.One;
|
Game.TargetBlock = -Coordinates3D.One;
|
||||||
NextAnimation = DateTime.MaxValue;
|
NextAnimation = DateTime.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +135,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
switch (e.Button)
|
switch (e.Button)
|
||||||
{
|
{
|
||||||
case MouseButton.Left:
|
case MouseButton.Left:
|
||||||
if (StartDigging == DateTime.MinValue) // Would like to start digging a block
|
if (Game.StartDigging == DateTime.MinValue) // Would like to start digging a block
|
||||||
{
|
{
|
||||||
var target = Game.HighlightedBlock;
|
var target = Game.HighlightedBlock;
|
||||||
if (target != -Coordinates3D.One)
|
if (target != -Coordinates3D.One)
|
||||||
@ -149,11 +146,11 @@ namespace TrueCraft.Client.Modules
|
|||||||
var target = Game.HighlightedBlock;
|
var target = Game.HighlightedBlock;
|
||||||
if (target == -Coordinates3D.One) // Cancel
|
if (target == -Coordinates3D.One) // Cancel
|
||||||
{
|
{
|
||||||
StartDigging = DateTime.MinValue;
|
Game.StartDigging = DateTime.MinValue;
|
||||||
EndDigging = DateTime.MaxValue;
|
Game.EndDigging = DateTime.MaxValue;
|
||||||
TargetBlock = -Coordinates3D.One;
|
Game.TargetBlock = -Coordinates3D.One;
|
||||||
}
|
}
|
||||||
else if (target != TargetBlock) // Change target
|
else if (target != Game.TargetBlock) // Change target
|
||||||
BeginDigging(target);
|
BeginDigging(target);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -163,15 +160,16 @@ namespace TrueCraft.Client.Modules
|
|||||||
|
|
||||||
private void BeginDigging(Coordinates3D target)
|
private void BeginDigging(Coordinates3D target)
|
||||||
{
|
{
|
||||||
|
// TODO: Adjust digging time to compensate for latency
|
||||||
var block = Game.Client.World.GetBlockID(target);
|
var block = Game.Client.World.GetBlockID(target);
|
||||||
TargetBlock = target;
|
Game.TargetBlock = target;
|
||||||
StartDigging = DateTime.UtcNow;
|
Game.StartDigging = DateTime.UtcNow;
|
||||||
short damage;
|
short damage;
|
||||||
EndDigging = StartDigging.AddMilliseconds(
|
Game.EndDigging = Game.StartDigging.AddMilliseconds(
|
||||||
BlockProvider.GetHarvestTime(block, 0, out damage));
|
BlockProvider.GetHarvestTime(block, 0, out damage));
|
||||||
Game.Client.QueuePacket(new PlayerDiggingPacket(
|
Game.Client.QueuePacket(new PlayerDiggingPacket(
|
||||||
PlayerDiggingPacket.Action.StartDigging,
|
PlayerDiggingPacket.Action.StartDigging,
|
||||||
TargetBlock.X, (sbyte)TargetBlock.Y, TargetBlock.Z,
|
Game.TargetBlock.X, (sbyte)Game.TargetBlock.Y, Game.TargetBlock.Z,
|
||||||
Game.HighlightedBlockFace));
|
Game.HighlightedBlockFace));
|
||||||
NextAnimation = DateTime.UtcNow.AddSeconds(0.25);
|
NextAnimation = DateTime.UtcNow.AddSeconds(0.25);
|
||||||
}
|
}
|
||||||
@ -181,9 +179,9 @@ namespace TrueCraft.Client.Modules
|
|||||||
switch (e.Button)
|
switch (e.Button)
|
||||||
{
|
{
|
||||||
case MouseButton.Left:
|
case MouseButton.Left:
|
||||||
StartDigging = DateTime.MinValue;
|
Game.StartDigging = DateTime.MinValue;
|
||||||
EndDigging = DateTime.MaxValue;
|
Game.EndDigging = DateTime.MaxValue;
|
||||||
TargetBlock = -Coordinates3D.One;
|
Game.TargetBlock = -Coordinates3D.One;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -205,7 +203,7 @@ namespace TrueCraft.Client.Modules
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
Game.Client.Velocity *= new TVector3(0, 1, 0);
|
Game.Client.Velocity *= new TVector3(0, 1, 0);
|
||||||
if (EndDigging != DateTime.MaxValue)
|
if (Game.EndDigging != DateTime.MaxValue)
|
||||||
{
|
{
|
||||||
if (NextAnimation < DateTime.UtcNow)
|
if (NextAnimation < DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
@ -213,12 +211,13 @@ namespace TrueCraft.Client.Modules
|
|||||||
Game.Client.QueuePacket(new AnimationPacket(Game.Client.EntityID,
|
Game.Client.QueuePacket(new AnimationPacket(Game.Client.EntityID,
|
||||||
AnimationPacket.PlayerAnimation.SwingArm));
|
AnimationPacket.PlayerAnimation.SwingArm));
|
||||||
}
|
}
|
||||||
if (DateTime.UtcNow > EndDigging && Game.HighlightedBlock == TargetBlock)
|
if (DateTime.UtcNow > Game.EndDigging && Game.HighlightedBlock == Game.TargetBlock)
|
||||||
{
|
{
|
||||||
Game.Client.QueuePacket(new PlayerDiggingPacket(
|
Game.Client.QueuePacket(new PlayerDiggingPacket(
|
||||||
PlayerDiggingPacket.Action.StopDigging,
|
PlayerDiggingPacket.Action.StopDigging,
|
||||||
TargetBlock.X, (sbyte)TargetBlock.Y, TargetBlock.Z,
|
Game.TargetBlock.X, (sbyte)Game.TargetBlock.Y, Game.TargetBlock.Z,
|
||||||
Game.HighlightedBlockFace));
|
Game.HighlightedBlockFace));
|
||||||
|
Game.EndDigging = DateTime.MaxValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace TrueCraft.Client.Rendering
|
|||||||
if (_vertices != null)
|
if (_vertices != null)
|
||||||
_vertices.Dispose();
|
_vertices.Dispose();
|
||||||
|
|
||||||
_game.PendingMainThreadActions.Add(() =>
|
_game.Invoke(() =>
|
||||||
{
|
{
|
||||||
_vertices = new VertexBuffer(_graphicsDevice, VertexPositionNormalColorTexture.VertexDeclaration,
|
_vertices = new VertexBuffer(_graphicsDevice, VertexPositionNormalColorTexture.VertexDeclaration,
|
||||||
(value.Length + 1), BufferUsage.WriteOnly);
|
(value.Length + 1), BufferUsage.WriteOnly);
|
||||||
@ -132,7 +132,7 @@ namespace TrueCraft.Client.Rendering
|
|||||||
if (_indices[index] != null)
|
if (_indices[index] != null)
|
||||||
_indices[index].Dispose();
|
_indices[index].Dispose();
|
||||||
|
|
||||||
_game.PendingMainThreadActions.Add(() =>
|
_game.Invoke(() =>
|
||||||
{
|
{
|
||||||
_indices[index] = new IndexBuffer(_graphicsDevice, typeof(int),
|
_indices[index] = new IndexBuffer(_graphicsDevice, typeof(int),
|
||||||
(indices.Length + 1), BufferUsage.WriteOnly);
|
(indices.Length + 1), BufferUsage.WriteOnly);
|
||||||
|
@ -19,6 +19,7 @@ using TrueCraft.Client.Rendering;
|
|||||||
using TVector3 = TrueCraft.API.Vector3;
|
using TVector3 = TrueCraft.API.Vector3;
|
||||||
using XVector3 = Microsoft.Xna.Framework.Vector3;
|
using XVector3 = Microsoft.Xna.Framework.Vector3;
|
||||||
using TrueCraft.Core.Logic;
|
using TrueCraft.Core.Logic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace TrueCraft.Client
|
namespace TrueCraft.Client
|
||||||
{
|
{
|
||||||
@ -34,12 +35,16 @@ namespace TrueCraft.Client
|
|||||||
public float ScaleFactor { get; set; }
|
public float ScaleFactor { get; set; }
|
||||||
public Coordinates3D HighlightedBlock { get; set; }
|
public Coordinates3D HighlightedBlock { get; set; }
|
||||||
public BlockFace HighlightedBlockFace { get; set; }
|
public BlockFace HighlightedBlockFace { get; set; }
|
||||||
|
public DateTime StartDigging { get; set; }
|
||||||
|
public DateTime EndDigging { get; set; }
|
||||||
|
public Coordinates3D TargetBlock { get; set; }
|
||||||
|
|
||||||
private List<IGameplayModule> Modules { get; set; }
|
private List<IGameplayModule> Modules { get; set; }
|
||||||
private SpriteBatch SpriteBatch { get; set; }
|
private SpriteBatch SpriteBatch { get; set; }
|
||||||
private KeyboardHandler KeyboardComponent { get; set; }
|
private KeyboardHandler KeyboardComponent { get; set; }
|
||||||
private MouseHandler MouseComponent { get; set; }
|
private MouseHandler MouseComponent { get; set; }
|
||||||
private RenderTarget2D RenderTarget { get; set; }
|
private RenderTarget2D RenderTarget { get; set; }
|
||||||
|
private int ThreadID { get; set; }
|
||||||
|
|
||||||
private FontRenderer Pixel { get; set; }
|
private FontRenderer Pixel { get; set; }
|
||||||
private IPEndPoint EndPoint { get; set; }
|
private IPEndPoint EndPoint { get; set; }
|
||||||
@ -139,6 +144,15 @@ namespace TrueCraft.Client
|
|||||||
SpriteBatch = new SpriteBatch(GraphicsDevice);
|
SpriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
|
||||||
Window_ClientSizeChanged(null, null);
|
Window_ClientSizeChanged(null, null);
|
||||||
|
ThreadID = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Invoke(Action action)
|
||||||
|
{
|
||||||
|
if (ThreadID == Thread.CurrentThread.ManagedThreadId)
|
||||||
|
action();
|
||||||
|
else
|
||||||
|
PendingMainThreadActions.Add(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateRenderTarget()
|
private void CreateRenderTarget()
|
||||||
|
Reference in New Issue
Block a user