mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-26 19:12:07 -05:00
131 lines
No EOL
4 KiB
C#
131 lines
No EOL
4 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
using System;
|
|
using ClassicalSharp.Events;
|
|
using ClassicalSharp.Model;
|
|
using OpenTK;
|
|
|
|
namespace ClassicalSharp.Renderers {
|
|
|
|
internal class HeldBlockAnimation {
|
|
|
|
internal bool doAnim, digAnim, swingAnim;
|
|
internal float angleY = 0;
|
|
internal Vector3 pos;
|
|
|
|
double time, period = 0.25, speed = Math.PI / 0.25;
|
|
byte lastType;
|
|
Game game;
|
|
HeldBlockRenderer held;
|
|
|
|
internal void Init( Game game, HeldBlockRenderer held ) {
|
|
this.game = game;
|
|
this.held = held;
|
|
lastType = game.Inventory.HeldBlock;
|
|
|
|
game.Events.HeldBlockChanged += DoSwitchBlockAnim;
|
|
game.UserEvents.BlockChanged += BlockChanged;
|
|
}
|
|
|
|
internal void Dispose() {
|
|
game.Events.HeldBlockChanged -= DoSwitchBlockAnim;
|
|
game.UserEvents.BlockChanged -= BlockChanged;
|
|
}
|
|
|
|
/// <summary> Sets the current animation state of the held block.<br/>
|
|
/// true = left mouse pressed, false = right mouse pressed. </summary>
|
|
internal void SetClickAnim( bool dig ) {
|
|
ResetAnimationState( true, dig ? 0.3 : 0.25 );
|
|
swingAnim = false;
|
|
digAnim = dig;
|
|
doAnim = true;
|
|
// Start place animation at bottom of cycle
|
|
if( !dig ) time = period / 2;
|
|
}
|
|
|
|
void DoSwitchBlockAnim( object sender, EventArgs e ) {
|
|
if( swingAnim ) {
|
|
// Like graph -sin(x) : x=0.5 and x=2.5 have same y values
|
|
// but increasing x causes y to change in opposite directions
|
|
if( time > period * 0.5 )
|
|
time = period - time;
|
|
} else {
|
|
ResetAnimationState( false, 0.25 );
|
|
doAnim = true;
|
|
swingAnim = true;
|
|
}
|
|
}
|
|
|
|
void BlockChanged( object sender, BlockChangedEventArgs e ) {
|
|
if( e.Block == 0 ) return;
|
|
SetClickAnim( false );
|
|
}
|
|
|
|
internal void Update( double delta, Vector3 last ) {
|
|
if( swingAnim || !digAnim ) {
|
|
pos.Y = -0.4f * (float)Math.Sin( time * speed );
|
|
if( swingAnim ) {
|
|
// i.e. the block has gone to bottom of screen and is now returning back up
|
|
// at this point we switch over to the new held block.
|
|
if( pos.Y > last.Y )
|
|
lastType = held.type;
|
|
held.type = lastType;
|
|
}
|
|
} else {
|
|
if( time >= period * 0.25 ) PlaceSecondCycle();
|
|
else PlaceFirstCycle();
|
|
}
|
|
time += delta;
|
|
if( time > period )
|
|
ResetAnimationState( true, 0.25 );
|
|
}
|
|
|
|
// Based off incredible gifs from (Thanks goodlyay!)
|
|
// https://dl.dropboxusercontent.com/u/12694594/slowBreakTranslate.gif
|
|
// https://dl.dropboxusercontent.com/u/12694594/slowBreakRotate1.gif
|
|
// https://dl.dropboxusercontent.com/u/12694594/slowBreakRotate2.gif
|
|
// https://dl.dropboxusercontent.com/u/12694594/slowBreakFull.gif
|
|
void PlaceFirstCycle() {
|
|
double angle = time * speed;
|
|
pos.X = -0.325f * (float)Math.Sin( angle * 2 );
|
|
pos.Y = 0.20f * (float)Math.Sin( angle * 2 * 2 );
|
|
pos.Z = -0.325f * (float)Math.Sin( angle * 2 );
|
|
|
|
angleY = -90 * (float)Math.Sin( angle * 2 );
|
|
held.block.SwitchOrder = angleY <= -30;
|
|
}
|
|
|
|
void PlaceSecondCycle() {
|
|
// Need to adjust angle so it starts at same point and of first cycle
|
|
// And finishes cycle at original position
|
|
double endFirst = period * 0.25;
|
|
double angle = (endFirst * 2 + (time - endFirst) * 0.66667) * speed;
|
|
|
|
pos.X = -0.325f * (float)Math.Sin( angle );
|
|
pos.Y = 0.25f * (float)Math.Sin( angle * 2 );
|
|
pos.Z = -0.325f * (float)Math.Sin( angle );
|
|
|
|
// For second cycle, rotate the block from 0-->15 then back to 15-->0.
|
|
float rotX = Math.Max( 0, (float)angle - 90 * Utils.Deg2Rad );
|
|
if( rotX >= 45 * Utils.Deg2Rad ) rotX = 90 * Utils.Deg2Rad - rotX;
|
|
held.block.CosX = (float)Math.Cos( rotX * 0.33333 );
|
|
held.block.SinX = (float)Math.Sin( rotX * 0.33333 );
|
|
|
|
angleY = -90 * (float)Math.Sin( angle );
|
|
held.block.SwitchOrder = angleY <= -30;
|
|
}
|
|
|
|
void ResetAnimationState( bool updateLastType, double period ) {
|
|
time = 0;
|
|
doAnim = false;
|
|
swingAnim = false;
|
|
pos = Vector3.Zero;
|
|
angleY = 0;
|
|
this.period = period;
|
|
speed = Math.PI / period;
|
|
|
|
if( updateLastType )
|
|
lastType = game.Inventory.HeldBlock;
|
|
pos = Vector3.Zero;
|
|
}
|
|
}
|
|
} |