CanadianMachines / MachineLib / Cymbal.cpp
Cymbal.cpp
Raw
/**
 * @file Cymbal.cpp
 * @author sriram
 */

#include "pch.h"
#include "Cymbal.h"

/// File name for the cymbal stand
const std::wstring CymbalStandFilename = L"/images/cymbal-stand.png";

/// File name for the cymbal image
const std::wstring CymbalFileName = L"/images/cymbal.png";

/// X Location to place the cymbal relative to the stand
const int CymbalPlaceX = 0;

/// Y location to place the cymbal relative to the stand
const double CymbalPlaceY = -205;

/// Offset to the center of the cymbal from the left in pixels
const int CymbalCenterX = 57;

/// Offset to the center of the cymbal from the bottom in pixels
const int CymbalCenterY = 36;

/// How long the rocking lasts in seconds
const double RockingTime = 2.0;

/// Maximum amount to rock in unit rotations
const double RockAmount = 0.03;

/// How quickly to rock in radians per second
const double RockRate = M_PI * 4;

/**
 * constructor
 * @param resourcesDir
 * @param audioEngine
 * @param sound
 */
Cymbal::Cymbal(std::wstring resourcesDir, ma_engine *audioEngine, std::wstring sound) : StruckInstrument(resourcesDir,
																										 audioEngine,
																										 sound)
{
	mStand.SetImage(resourcesDir + CymbalStandFilename);
	mStand.Rectangle(-mStand.GetImageWidth()/2, 0);

	mCymbal.SetImage(resourcesDir +CymbalFileName);
	mCymbal.Rectangle(-mCymbal.GetImageWidth()/2, 0);
}

/**
 * draws cymbal
 * @param graphics
 * @param x
 * @param y
 */
void Cymbal::Draw(std::shared_ptr<wxGraphicsContext> graphics, double x, double y)
{
	mStand.DrawPolygon(graphics, x + GetComponentLocation().x, y + GetComponentLocation().y);

	auto xLoc = (x ) + GetComponentLocation().x ;
	auto yLoc = (y +CymbalCenterY) + GetComponentLocation().y + CymbalPlaceY;

	graphics->PushState();
	// Translate to pivot point
	graphics->Translate(xLoc, yLoc);

	// Rotate by current angle
	graphics->Rotate(M_PI*mRockAngle);

	// Draw cymbal at pivot point
	mCymbal.DrawPolygon(graphics, 0, 0);

	graphics->PopState();
}

/**
 * cymbal was hit
 */
void Cymbal::Hit()
{
	// Start rocking animation
	mRockStartTime = -1;
	mRockAngle = RockAmount;
}

/**
 * virtual setter for time , cymbal is animated
 * @param time
 */
void Cymbal::SetTime(double time)
{
	//if cymbal is hit
	if (mRockStartTime==-1)
	{
		mRockStartTime=time;
	}

	double elapsed = time-mRockStartTime;

	if (mRockStartTime>0 && abs(elapsed)<=RockingTime)
	{
		// Calculate rocking angle based on elapsed time
		mRockAngle = RockAmount * sin(-elapsed * RockRate);
	}

	// Decay rocking over time
	else
	{
		mRockAngle = 0;
		mRockStartTime = 0;
	}

}