Commit e6c51290 authored by 魔大农's avatar 魔大农 🍀

It is playable

parent 98f1256f
No preview for this file type
This diff is collapsed.
#include "board.h"
#include "effectmaster.h"
#include "quattercam.h"
namespace Urho3D {
template <> unsigned MakeHash(const IntVector2& value)
......@@ -39,17 +40,26 @@ Board::Board(): Object(MC->GetContext()),
lightNode->SetPosition(Vector3::UP * 0.23f);
square->light_ = square->node_->CreateComponent<Light>();
square->light_->SetColor(Color(0.0f, 0.8f, 0.5f));
square->light_->SetBrightness(0.0f);
square->light_->SetBrightness(0.1f);
square->light_->SetRange(2.0f);
square->light_->SetCastShadows(true);
squares_[square->coords_] = square;
square->node_->SetEnabledRecursive(false);
// square->node_->SetEnabledRecursive(false);
}
SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(Board, HandleSceneUpdate));
}
void Board::Reset()
{
for (Square* s: squares_.Values()){
s->free_ = true;
s->piece_ = nullptr;
s->light_->SetEnabled(true);
}
DeselectAll();
}
Vector3 Board::SquarePosition(IntVector2 coords)
{
......@@ -67,6 +77,8 @@ void Board::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
bool Board::CheckQuatter()
{
bool checkBlocks{true};
//Check rows
for (int i{0}; i < BOARD_WIDTH; ++i){
Piece::Attributes matching{};
......@@ -153,32 +165,34 @@ bool Board::CheckQuatter()
}
}
//Check 2x2 blocks
for (int k{0}; k < BOARD_WIDTH - 1; ++k){
for (int l{0}; l < BOARD_HEIGHT - 1; ++l){
Piece::Attributes matching{};
matching.flip();
Piece::Attributes first{};
for (int m : {0, 1}) for (int n : {0, 1}){
IntVector2 coords(k + m, l + n);
Piece* piece{squares_[coords].Get()->piece_};
if (piece){
Piece::Attributes attributes(piece->GetAttributes());
if (m == 0 && n == 0) {
first = attributes;
if (checkBlocks){
for (int k{0}; k < BOARD_WIDTH - 1; ++k){
for (int l{0}; l < BOARD_HEIGHT - 1; ++l){
Piece::Attributes matching{};
matching.flip();
Piece::Attributes first{};
for (int m : {0, 1}) for (int n : {0, 1}){
IntVector2 coords(k + m, l + n);
Piece* piece{squares_[coords].Get()->piece_};
if (piece){
Piece::Attributes attributes(piece->GetAttributes());
if (m == 0 && n == 0) {
first = attributes;
} else {
for (int a{0}; a < NUM_ATTRIBUTES; ++a)
if (first[a] != attributes[a])
matching[a] = false;
}
//Full block required
} else {
for (int a{0}; a < NUM_ATTRIBUTES; ++a)
if (first[a] != attributes[a])
matching[a] = false;
matching.reset();
break;
}
//Full block required
} else {
matching.reset();
break;
}
}
//Quatter!
if (matching.any()){
return true;
//Quatter!
if (matching.any()){
return true;
}
}
}
}
......@@ -191,6 +205,7 @@ void Board::PutPiece(Piece* piece, Square* square)
{
square->piece_ = piece;
square->free_ = false;
square->light_->SetEnabled(false);
piece->Put(square->node_->GetWorldPosition()
+ Vector3(Random(-0.05f, 0.05f),
......@@ -200,21 +215,26 @@ void Board::PutPiece(Piece* piece, Square* square)
if (CheckQuatter())
MC->Quatter();
}
Square* Board::GetNearestFreeSquare(Vector3 pos)
Square* Board::GetNearestSquare(Vector3 pos, bool free)
{
Square* nearest{};
for (Square* s : squares_.Values()){
if (!nearest ||
LucKey::Distance(s->node_->GetWorldPosition(), pos) <
LucKey::Distance(nearest->node_->GetWorldPosition(), pos))
if (s->free_)
if (s->free_ || !free)
nearest = s;
}
return nearest;
}
void Board::SelectNearestFreeSquare(Vector3 pos)
{
Square* square{GetNearestFreeSquare(pos)};
Square* square{GetNearestSquare(pos, true)};
if (square) Select(square);
}
void Board::SelectNearestSquare(Vector3 pos)
{
Square* square{GetNearestSquare(pos, false)};
if (square) Select(square);
}
void Board::Select(Square* square)
......@@ -223,25 +243,10 @@ void Board::Select(Square* square)
Deselect(selectedSquare_);
selectedSquare_ = square;
square->selected_ = true;
square->node_->SetEnabledRecursive(true);
// Material* glow{square->slot_->GetMaterial()};
// Color glowColor{glow->GetShaderParameter("MatDiffColor").GetColor()};
// Material* originalGlow{MC->GetMaterial("Glow")};
// Color originalGlowColor{originalGlow->GetShaderParameter("MatDiffColor").GetColor()};
// ValueAnimation* diffFadeIn{new ValueAnimation(context_)};
// diffFadeIn->SetKeyFrame(0.0f, glowColor);
// diffFadeIn->SetKeyFrame(0.23f, originalGlowColor);
// glow->SetShaderParameterAnimation("MatDiffColor", diffFadeIn, WM_ONCE);
// ValueAnimation* lightFadeIn{new ValueAnimation(context_)};
// lightFadeIn->SetKeyFrame(0.0f, square->light_->GetBrightness());
// lightFadeIn->SetKeyFrame(0.23f, 0.5f);
// square->light_->SetAttributeAnimation("Brightness Multiplier", lightFadeIn, WM_ONCE);
MC->effectMaster_->FadeTo(square->slot_->GetMaterial(),
MC->GetMaterial("Glow")->GetShaderParameter("MatDiffColor").GetColor());
MC->effectMaster_->FadeTo(square->light_, 0.42f);
......@@ -256,19 +261,7 @@ void Board::Deselect(Square* square)
square->selected_ = false;
MC->effectMaster_->FadeOut(square->slot_->GetMaterial());
MC->effectMaster_->FadeOut(square->light_);
// Material* glow{square->slot_->GetMaterial()};
// Color glowColor{glow->GetShaderParameter("MatDiffColor").GetColor()};
// ValueAnimation* diffFadeOut{new ValueAnimation(context_)};
// diffFadeOut->SetKeyFrame(0.0f, glowColor);
// diffFadeOut->SetKeyFrame(0.23f, glowColor * 0.0f);
// glow->SetShaderParameterAnimation("MatDiffColor", diffFadeOut, WM_ONCE);
// ValueAnimation* lightFadeOut{new ValueAnimation(context_)};
// lightFadeOut->SetKeyFrame(0.0f, square->light_->GetBrightness());
// lightFadeOut->SetKeyFrame(0.23f, 0.0f);
// square->light_->SetAttributeAnimation("Brightness Multiplier", lightFadeOut, WM_ONCE);
MC->effectMaster_->FadeTo(square->light_, 0.1f);
}
void Board::DeselectAll()
{
......@@ -276,3 +269,15 @@ void Board::DeselectAll()
Deselect(s);
}
}
void Board::Step(IntVector2 step)
{
if (selectedSquare_){
IntVector2 newCoords{selectedSquare_->coords_ + step};
if (squares_.Contains(newCoords)){
Select(squares_[newCoords].Get());
}
} else {
SelectNearestFreeSquare(CAMERA->GetPosition());
}
}
......@@ -40,11 +40,15 @@ public:
void PutPiece(Piece* piece, Square* square);
void PutPiece(Piece* piece) { PutPiece(piece, GetSelectedSquare()); }
Square*GetNearestFreeSquare(Vector3 pos);
void Step(IntVector2 step);
Square*GetNearestSquare(Vector3 pos, bool free = true);
Square* GetSelectedSquare() const { return selectedSquare_; }
void Select(Square* square);
void Deselect(Square* square);
void SelectNearestSquare(Vector3 pos);
void SelectNearestFreeSquare(Vector3 pos);
void DeselectAll();
void Reset();
private:
SharedPtr<Node> rootNode_;
StaticModel* model_;
......@@ -52,7 +56,6 @@ private:
HashMap<IntVector2, SharedPtr<Square>> squares_;
Square* selectedSquare_;
Vector3 SquarePosition(IntVector2 coords);
void Deselect(Square* square);
void HandleSceneUpdate(StringHash eventType, VariantMap& eventData);
};
......
......@@ -24,6 +24,19 @@ void EffectMaster::FadeTo(Light* light, float brightness, float duration)
light->SetAttributeAnimation("Brightness Multiplier", fade, WM_ONCE);
}
void EffectMaster::TransformTo(Node* node, Vector3 pos, Quaternion rot, float duration)
{
ValueAnimation* posAnim{new ValueAnimation(context_)};
posAnim->SetKeyFrame(0.0f, node->GetPosition());
posAnim->SetKeyFrame(duration, pos);
node->SetAttributeAnimation("Position", posAnim, WM_ONCE);
ValueAnimation* rotAnim{new ValueAnimation(context_)};
rotAnim->SetKeyFrame(0.0f, node->GetRotation());
rotAnim->SetKeyFrame(duration, rot);
node->SetAttributeAnimation("Rotation", rotAnim, WM_ONCE);
}
......
......@@ -16,6 +16,7 @@ public:
void FadeTo(Material* material, Color color, float duration = 0.23f);
void FadeTo(Light* light, float brightness, float duration = 0.23f);
void TransformTo(Node* node, Vector3 pos, Quaternion rot = Quaternion::IDENTITY, float duration = 1.0f);
};
#endif // EFFECTMASTER_H
......@@ -18,6 +18,8 @@ InputMaster::InputMaster() : Master(),
void InputMaster::HandleKeyDown(StringHash eventType, VariantMap &eventData)
{
ResetIdle();
int key{eventData[KeyDown::P_KEY].GetInt()};
pressedKeys_.Insert(key);
......@@ -27,9 +29,19 @@ void InputMaster::HandleKeyDown(StringHash eventType, VariantMap &eventData)
case KEY_SPACE:{
HandleActionButtonPressed();
} break;
case KEY_UP:{ Step(Vector3::FORWARD);
} break;
case KEY_DOWN:{ Step(Vector3::BACK);
} break;
case KEY_RIGHT:{ Step(Vector3::RIGHT);
} break;
case KEY_LEFT:{ Step(Vector3::LEFT);
} break;
//Exit when ESC is pressed
case KEY_ESC:{
MC->Exit();
if (MC->GetGameState() == GameState::QUATTER){
MC->Reset();
} else MC->Exit();
} break;
//Take screenshot when 9 is pressed
case KEY_9:{
......@@ -47,8 +59,30 @@ void InputMaster::HandleKeyDown(StringHash eventType, VariantMap &eventData)
default: break;
}
}
void InputMaster::Step(Vector3 step)
{
if (MC->InPutState()){
float quadrant{0.0f};
for (float angle: {90.0f, 180.0f, 270.0f}){
if (LucKey::Delta(CAMERA->GetYaw(), angle, true) <
LucKey::Delta(CAMERA->GetYaw(), quadrant, true))
{
quadrant = angle;
}
}
Vector3 finalStep{Quaternion(quadrant, Vector3::UP) * step};
Board* board{MC->world.board_};
Square* selectedSquare{board->GetSelectedSquare()};
if (selectedSquare)
board->SelectNearestSquare(selectedSquare->node_->GetPosition() + finalStep);
else board->SelectNearestFreeSquare(CAMERA->GetPosition());
}
}
void InputMaster::HandleKeyUp(StringHash eventType, VariantMap &eventData)
{
ResetIdle();
using namespace KeyUp;
int key{eventData[P_KEY].GetInt()};
if (pressedKeys_.Contains(key)) pressedKeys_.Erase(key);
......@@ -56,6 +90,8 @@ void InputMaster::HandleKeyUp(StringHash eventType, VariantMap &eventData)
void InputMaster::HandleMouseButtonDown(StringHash eventType, VariantMap &eventData)
{
ResetIdle();
using namespace MouseButtonDown;
int button{eventData[P_BUTTON].GetInt()};
pressedMouseButtons_.Insert(button);
......@@ -64,6 +100,8 @@ void InputMaster::HandleMouseButtonDown(StringHash eventType, VariantMap &eventD
void InputMaster::HandleMouseButtonUp(StringHash eventType, VariantMap &eventData)
{
ResetIdle();
using namespace MouseButtonUp;
int button{eventData[P_BUTTON].GetInt()};
if (pressedMouseButtons_.Contains(button)) pressedMouseButtons_.Erase(button);
......@@ -71,12 +109,28 @@ void InputMaster::HandleMouseButtonUp(StringHash eventType, VariantMap &eventDat
void InputMaster::HandleJoystickButtonDown(StringHash eventType, VariantMap &eventData)
{
ResetIdle();
using namespace JoystickButtonDown;
int joystickId{eventData[P_JOYSTICKID].GetInt()};
int button{eventData[P_BUTTON].GetInt()};
switch (button){
case 14: HandleActionButtonPressed();
break;
case JB_CROSS:{
HandleActionButtonPressed();
} break;
case JB_DPAD_UP:{ Step(Vector3::FORWARD);
} break;
case JB_DPAD_DOWN:{ Step(Vector3::BACK);
} break;
case JB_DPAD_RIGHT:{ Step(Vector3::RIGHT);
} break;
case JB_DPAD_LEFT:{ Step(Vector3::LEFT);
} break;
case JB_START:{ if (MC->GetGameState() == GameState::QUATTER)
MC->Reset();
} break;
default: break;
}
......@@ -93,8 +147,7 @@ void InputMaster::HandleJoystickButtonUp(StringHash eventType, VariantMap &event
void InputMaster::HandleActionButtonPressed()
{
if (MC->GetGamePhase() == GamePhase::PLAYER1PICKS ||
MC->GetGamePhase() == GamePhase::PLAYER2PICKS )
if (MC->InPickState())
{
Piece* selectedPiece{MC->GetSelectedPiece()};
if (selectedPiece){
......@@ -102,13 +155,12 @@ void InputMaster::HandleActionButtonPressed()
MC->NextPhase();
MC->world.board_->SelectNearestFreeSquare(CAMERA->GetPosition());
}
} else if (MC->GetGamePhase() == GamePhase::PLAYER1PUTS ||
MC->GetGamePhase() == GamePhase::PLAYER2PUTS )
} else if (MC->InPutState() )
{
Square* selectedSquare{MC->world.board_->GetSelectedSquare()};
if (selectedSquare && selectedSquare->free_){
MC->world.board_->PutPiece(MC->GetPickedPiece());
if (MC->GetGamePhase() != GamePhase::QUATTER)
if (MC->GetGameState() != GameState::QUATTER)
MC->NextPhase();
}
}
......@@ -119,9 +171,37 @@ void InputMaster::HandleUpdate(StringHash eventType, VariantMap &eventData)
float t{eventData[Update::P_TIMESTEP].GetFloat()};
idleTime_ += t;
if (idleTime_ > IDLE_THRESHOLD){
SetIdle();
}
HandleCameraMovement(t);
}
void InputMaster::SetIdle()
{
if (!idle_) {
idle_ = true;
if (MC->GetSelectedPiece())
MC->DeselectPiece();
Square* selectedSquare{MC->world.board_->GetSelectedSquare()};
if (selectedSquare)
MC->world.board_->Deselect(selectedSquare);
}
}
void InputMaster::ResetIdle()
{
if (idle_) {
idle_ = false;
if (MC->InPutState())
MC->world.board_->SelectNearestFreeSquare(CAMERA->GetPosition());
}
idleTime_ = 0.0f;
}
void InputMaster::HandleCameraMovement(float t)
{
Vector2 camRot{};
......@@ -131,7 +211,7 @@ void InputMaster::HandleCameraMovement(float t)
float keyZoomSpeed{0.1f};
float joyRotMultiplier{80.0f};
float joyZoomSpeed{3.4f};
float joyZoomSpeed{7.0f};
if (pressedKeys_.Size()) idleTime_ = 0.0f;
for (int key : pressedKeys_){
......@@ -153,7 +233,7 @@ void InputMaster::HandleCameraMovement(float t)
}
if (pressedMouseButtons_.Contains(MOUSEB_RIGHT)){
idleTime_ = 0.0f;
ResetIdle();
IntVector2 mouseMove = input_->GetMouseMove();
camRot += Vector2(mouseMove.x_, mouseMove.y_) * 0.1f;
}
......@@ -163,25 +243,17 @@ void InputMaster::HandleCameraMovement(float t)
Vector2 rotation{-Vector2(joy0->GetAxisPosition(0), joy0->GetAxisPosition(1))
-Vector2(joy0->GetAxisPosition(2), joy0->GetAxisPosition(3))};
if (rotation.Length()){
idleTime_ = 0.0f;
ResetIdle();
camRot += rotation * t * joyRotMultiplier;
}
camZoom += t * joyZoomSpeed * (joy0->GetAxisPosition(13) - joy0->GetAxisPosition(12));
}
float idleThreshold{5.0f};
float idleStartup{Min(0.5f * (idleTime_ - idleThreshold), 1.0f)};
if (idleTime_ > idleThreshold){
if (!idle_) {
idle_ = true;
for (Piece* p: MC->world.pieces_){
p->Deselect();
}
}
//Slowly spin camera when there hasn't been any input for a while
if (idle_){
float idleStartup{Min(0.5f * (idleTime_ - IDLE_THRESHOLD), 1.0f)};
camRot += Vector2(t * idleStartup * -0.5f,
t * idleStartup * MC->Sine(0.23f, -0.042f, 0.042f));
} else {
if (idle_) idle_ = false;
}
//Speed up camera movement when shift key is held down
if (pressedKeys_.Contains(KEY_SHIFT)){
......@@ -208,7 +280,6 @@ void InputMaster::SmoothCameraMovement(float camZoom, Vector2 camRot)
pitchBrake = pitchLeft / PITCH_EDGE;
}
camRot.y_ *= pitchBrake * pitchBrake;
// smoothCamRotate_.y_ *= pitchBrake;
//Slow down zooming when nearing extremes
float zoomBrake{1.0f};
if (Sign(camZoom) < 0.0f){
......@@ -221,7 +292,6 @@ void InputMaster::SmoothCameraMovement(float camZoom, Vector2 camRot)
zoomBrake = zoomLeft / ZOOM_EDGE;
}
camZoom *= zoomBrake;
// smoothCamZoom_ *= zoomBrake;
smoothCamRotate_ = 0.0666f * (camRot + smoothCamRotate_ * 14.0f);
smoothCamZoom_ = 0.05f * (camZoom + smoothCamZoom_ * 19.0f);
......
......@@ -3,7 +3,9 @@
#include "master.h"
enum class JoystickButton {SELECT, LEFTSTICK, RIGHTSTICK, START, DPAD_UP, DPAD_RIGHT, DPAD_DOWN, DPAD_LEFT, L2, R2, L1, R1, TRIANGLE, CIRCLE, CROSS, SQUARE};
enum JoystickButton {SELECT, LEFTSTICK, RIGHTSTICK, JB_START, JB_DPAD_UP, JB_DPAD_RIGHT, JB_DPAD_DOWN, JB_DPAD_LEFT, L2, R2, L1, R1, TRIANGLE, CIRCLE, JB_CROSS, SQUARE};
#define IDLE_THRESHOLD 5.0f
class InputMaster : public Master
{
......@@ -13,8 +15,10 @@ public:
WeakPtr<Node> firstHit_;
bool IsIdle() const noexcept { return idle_; }
void ResetIdle();
void SetIdle();
void HandleActionButtonPressed();
private:
Input* input_;
......@@ -38,6 +42,11 @@ private:
void HandleCameraMovement(float t);
void Screenshot();
void HandleActionButtonPressed();
void Step(Vector3 step);
void HandleDownArrowPressed();
void HandleRightArrowPressed();
void HandleLeftArrowPressed();
};
#endif // INPUTMASTER_H
......@@ -17,7 +17,7 @@ MasterControl* MasterControl::GetInstance()
MasterControl::MasterControl(Context *context):
Application(context),
musicGain_{1.0f},
gamePhase_{GamePhase::PLAYER1PICKS}
gameState_{GameState::PLAYER1PICKS}
{
instance_ = this;
}
......@@ -31,7 +31,7 @@ void MasterControl::Setup()
engineParameters_["ResourcePaths"] = "Data;CoreData;Resources";
engineParameters_["WindowIcon"] = "icon.png";
engineParameters_["FullScreen"] = false;
// engineParameters_["FullScreen"] = false;
// engineParameters_["WindowWidth"] = 960;
// engineParameters_["WindowHeight"] = 540;
}
......@@ -181,37 +181,73 @@ int MasterControl::CountFreePieces()
void MasterControl::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
// float t{eventData[Update::P_TIMESTEP].GetFloat()};
UpdateSelectedPiece();
//Wave leafy light
leafyLightNode_->SetRotation(Quaternion(Sine(Sine(0.1f, 0.05f, 0.23f), -0.23f, 0.23f) + 90.0f, Vector3::RIGHT) *
Quaternion(Sine(0.23f, 178.0f, 182.0f), Vector3::FORWARD));
leafyLight_->SetBrightness(0.34f + Sine(0.011f, 0.05f, 0.23f) + Sine(0.02f, 0.05f, 0.13f));
}
void MasterControl::UpdateSelectedPiece()
{
if (!inputMaster_->IsIdle()){
Piece* nearest{selectedPiece_};
for (Piece* p: world.pieces_){
if (LucKey::Delta(CAMERA->GetYaw(), p->GetAngle(), true) < 180.0f / NUM_PIECES){
p->Select();
} else if (p->GetState() != PieceState::PICKED){
p->Deselect();
if (!nearest) {
nearest = p;
} else if (LucKey::Distance(CAMERA->GetPosition(), p->GetPosition()) <
LucKey::Distance(CAMERA->GetPosition(), nearest->GetPosition())
&& (p->GetState() == PieceState::FREE || p->GetState() == PieceState::SELECTED))
{
nearest = p;
}
}
if (nearest != selectedPiece_ || nearest->GetState() != PieceState::SELECTED){
if (selectedPiece_)
selectedPiece_->Deselect();
selectedPiece_ = nearest;
nearest->Select();
}
}
//Wave leafy light
leafyLightNode_->SetRotation(Quaternion(Sine(Sine(0.1f, 0.05f, 0.23f), -0.23f, 0.23f) + 90.0f, Vector3::RIGHT) *
Quaternion(Sine(0.23f, 178.0f, 182.0f), Vector3::FORWARD));
leafyLight_->SetBrightness(0.34f + Sine(0.011f, 0.05f, 0.23f) + Sine(0.02f, 0.05f, 0.13f));
}
void MasterControl::DeselectPiece()
{
if (selectedPiece_){
selectedPiece_->Deselect();
}
selectedPiece_ = nullptr;
}
void MasterControl::NextPhase()
{
switch (gamePhase_) {
case GamePhase::PLAYER1PICKS: gamePhase_ = GamePhase::PLAYER2PUTS;
DeselectPiece();
switch (gameState_) {
case GameState::PLAYER1PICKS: gameState_ = GameState::PLAYER2PUTS;
break;
case GamePhase::PLAYER2PUTS: gamePhase_ = GamePhase::PLAYER2PICKS;
case GameState::PLAYER2PUTS: gameState_ = GameState::PLAYER2PICKS;
break;
case GamePhase::PLAYER2PICKS: gamePhase_ = GamePhase::PLAYER1PUTS;
case GameState::PLAYER2PICKS: gameState_ = GameState::PLAYER1PUTS;
break;
case GamePhase::PLAYER1PUTS: gamePhase_ = GamePhase::PLAYER1PICKS;
case GameState::PLAYER1PUTS: gameState_ = GameState::PLAYER1PICKS;
break;
default: break;
}
}
void MasterControl::Quatter()
{
gamePhase_ = GamePhase::QUATTER;
gameState_ = GameState::QUATTER;
}
void MasterControl::Reset()
{
for (Piece* p: world.pieces_){
p->Reset();
}
world.board_->Reset();
gameState_ = GameState::PLAYER1PICKS;
}
void MasterControl::ToggleMusic()
......
......@@ -19,7 +19,7 @@ class EffectMaster;
class Board;
class Piece;
enum class GamePhase{PLAYER1PICKS, PLAYER2PUTS, PLAYER2PICKS, PLAYER1PUTS, QUATTER};
enum class GameState{PLAYER1PICKS, PLAYER2PUTS, PLAYER2PICKS, PLAYER1PUTS, QUATTER};
typedef struct GameWorld
{
......@@ -51,20 +51,19 @@ public:
SharedPtr<ResourceCache> cache_;
SharedPtr<Graphics> graphics_;
/// Setup before engine initialization. Modifies the engine paramaters.
virtual void Setup();
/// Setup after engine initialization.
virtual void Start();
/// Cleanup after the main loop. Called by Application.
virtual void Stop();
void Exit();
void CreateLights();
inline GamePhase GetGamePhase() const noexcept { return gamePhase_; }
inline GameState GetGameState() const noexcept { return gameState_; }
inline bool InPickState() const noexcept { return gameState_ == GameState::PLAYER1PICKS || gameState_ == GameState::PLAYER2PICKS; }
inline bool InPutState() const noexcept { return gameState_ == GameState::PLAYER1PUTS || gameState_ == GameState::PLAYER2PUTS; }
float AttributesToAngle(int attributes) const { return (360.0f/NUM_PIECES * attributes) + 180.0f/NUM_PIECES + 23.5f; }
Vector3 AttributesToPosition(int attributes) const {
return Quaternion(AttributesToAngle(attributes), Vector3::UP) * Vector3::FORWARD * 7.0f
return Quaternion(AttributesToAngle(attributes), Vector3::UP) * Vector3::BACK * 7.0f
+ Vector3::DOWN * 0.21f;
}
Piece* GetSelectedPiece() const;
......@@ -75,11 +74,12 @@ public:
Model* GetModel(String name) const { return cache_->GetResource<Model>("Models/"+name+".mdl"); }
Texture* GetTexture(String name) const { return cache_->GetResource<Texture>("Textures/"+name+".png"); }
float Sine(const float freq, const float min, const float max, const float shift = 0.0f);
float Cosine(const float freq, const float min, const float max, const float shift = 0.0f);
void Quatter();
void DeselectPiece();
private:
static MasterControl* instance_;
InputMaster* inputMaster_;
......@@ -89,8 +89,10 @@ private:
SharedPtr<SoundSource> musicSource_;
float musicGain_;
GamePhase gamePhase_;
Node* movingLightNode_;
GameState gameState_;
Piece* selectedPiece_;
Piece* pickedPiece_;
void CreateScene();
void NextPhase();
......@@ -99,6 +101,8 @@ private:
void MusicGainDown(float step);
void HandleUpdate(StringHash eventType, VariantMap& eventData);
void Reset();
void UpdateSelectedPiece();
};
#endif // MASTERCONTROL_H
......@@ -32,6 +32,19 @@ Piece::Piece(Attributes attributes): Object(MC->GetContext()),
light_->SetBrightness(0.0f);
light_->SetRange(3.0f);
}
void Piece::Reset()
{
if (MC->GetSelectedPiece() == this){
MC->DeselectPiece();
}else Deselect();
if (state_ != PieceState::FREE){
state_ = PieceState::FREE;
MC->effectMaster_->TransformTo(rootNode_,
MC->AttributesToPosition(static_cast<int>(attributes_.to_ulong())),
Quaternion(Random(360.0f), Vector3::UP));
}
}
String Piece::GetCodon(int length) const
{
......@@ -53,8 +66,8 @@ String Piece::GetCodon(int length) const
void Piece::Select()
{
if (MC->GetGamePhase() == GamePhase::PLAYER1PICKS ||
MC->GetGamePhase() == GamePhase::PLAYER2PICKS )
if (MC->GetGameState() == GameState::PLAYER1PICKS ||
MC->GetGameState() == GameState::PLAYER2PICKS )
{
outlineModel_->SetEnabled(true);
if (state_ == PieceState::FREE){
......@@ -77,20 +90,12 @@ void Piece::Pick()
{
if (state_ == PieceState::SELECTED){
state_ = PieceState::PICKED;
if (MC->GetGamePhase() == GamePhase::PLAYER1PICKS)
if (MC->GetGameState() == GameState