Commit 06a48b0c authored by 魔大农's avatar 魔大农 🍀

Added mouse click handling

parent 369f0c85
No preview for this file type
<material>
<technique name="Techniques/NoTextureAdd.xml" />
<parameter name="MatDiffColor" value="0 0 0 0" />
</material>
\ No newline at end of file
<technique vs="Unlit" ps="Unlit" vsdefines="NOUV" >
<pass name="alpha" depthwrite="false" blend="add" />
</technique>
......@@ -34,27 +34,32 @@ Board::Board(): Object(MC->GetContext()),
{
rootNode_ = MC->world_.scene_->CreateChild("Board");
model_ = rootNode_->CreateComponent<StaticModel>();
model_->SetModel(MC->cache_->GetResource<Model>("Resources/Models/Board.mdl"));
model_->SetMaterial(MC->cache_->GetResource<Material>("Resources/Materials/Board.xml"));
model_->SetModel(MC->GetModel("Board"));
model_->SetMaterial(MC->GetMaterial("Board"));
model_->SetCastShadows(true);
//Fill board with squares
for (int i{0}; i < BOARD_WIDTH; ++i) for (int j{0}; j < BOARD_HEIGHT; ++j){
//Create base
Square* square{new Square};
square->coords_ = IntVector2(i, j);
square->node_ = rootNode_->CreateChild("Square");
StringVector tag{}; tag.Push(String("Square"));
square->node_->SetTags(tag);
square->node_->SetPosition(CoordsToPosition(square->coords_));
StaticModel* touchPlane{square->node_->CreateComponent<StaticModel>()};
touchPlane->SetModel(MC->GetModel("Plane"));
touchPlane->SetMaterial(MC->GetMaterial("Invisible"));
square->free_ = true;
square->piece_ = nullptr;
//Create slot
Node* slotNode{square->node_->CreateChild("Slot")};
slotNode->SetPosition(Vector3::UP * 0.05f);
square->slot_ = slotNode->CreateComponent<AnimatedModel>();
square->slot_->SetModel(MC->GetModel("Slot"));
square->slot_->SetMaterial(MC->GetMaterial("Glow")->Clone());
square->slot_->GetMaterial()->SetShaderParameter("MatDiffColor", Color(0.0f, 0.0f, 0.0f, 0.0f));
//Create light
Node* lightNode{slotNode->CreateChild("Light")};
lightNode->SetPosition(Vector3::UP * 0.23f);
square->light_ = lightNode->CreateComponent<Light>();
......@@ -101,6 +106,13 @@ bool Board::IsEmpty() const
return true;
}
bool Board::IsFull() const
{
for (Square* s: squares_.Values())
if (s->free_) return false;
return true;
}
Vector3 Board::CoordsToPosition(IntVector2 coords)
{
......@@ -120,6 +132,10 @@ void Board::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
bool Board::PutPiece(Piece* piece, Square* square)
{
if (!square){
return PutPiece(piece);
}
if (piece && square->free_){
MC->DeselectPiece();
......@@ -136,9 +152,13 @@ bool Board::PutPiece(Piece* piece, Square* square)
if (CheckQuatter())
MC->Quatter();
MC->NextPhase();
return true;
} else return false;
} else {
Refuse();
return false;
}
}
bool Board::CheckQuatter()
......@@ -294,6 +314,8 @@ bool Board::SelectLast()
if (lastSelectedSquare_ && lastSelectedSquare_ != selectedSquare_) {
Select(lastSelectedSquare_);
return true;
} else if (!selectedSquare_) {
SelectNearestFreeSquare();
} else return false;
}
......@@ -345,9 +367,5 @@ void Board::Step(IntVector2 step)
if (squares_.Contains(newCoords)){
Select(squares_[newCoords].Get());
}
} else if (lastSelectedSquare_)
SelectLast();
else {
SelectNearestFreeSquare();
}
} else SelectLast();
}
......@@ -20,6 +20,7 @@
#define BOARD_H
#include <Urho3D/Urho3D.h>
#include "mastercontrol.h"
#include "piece.h"
#include "quattercam.h"
......@@ -64,8 +65,16 @@ public:
} else
return PutPiece(piece, selectedSquare_);
}
bool PutPiece(Square* square) {
return PutPiece(MC->GetPickedPiece(), square);
}
bool PutPiece(){
return PutPiece(MC->GetPickedPiece());
}
void Step(IntVector2 step);
Vector<SharedPtr<Square>> GetSquares() const { return squares_.Values(); }
Square* GetNearestSquare(Vector3 pos, bool free = true);
Square* GetSelectedSquare() const { return selectedSquare_; }
Square* GetLastSelectedSquare() const { return lastSelectedSquare_; }
......@@ -80,6 +89,7 @@ public:
void Refuse();
bool IsEmpty() const;
bool IsFull() const;
private:
SharedPtr<Node> rootNode_;
StaticModel* model_;
......
......@@ -78,10 +78,8 @@ void EffectMaster::ArchTo(Node* node, Vector3 pos, Quaternion rot, float archHei
{
ValueAnimation* posAnim{new ValueAnimation(context_)};
posAnim->SetKeyFrame(0.0f, node->GetPosition());
if (delay != 0.0f)
posAnim->SetKeyFrame(0.5f * delay, node->GetPosition());
for (int i{1}; i < WAYPOINTS - 1; ++i){
for (int i{0}; i < WAYPOINTS - 1; ++i){
float t{static_cast<float>(i) / WAYPOINTS};
posAnim->SetKeyFrame(delay + duration * t,
node->GetPosition().Lerp(pos, t) + archHeight * Vector3::UP * Arch(t));
......
......@@ -17,16 +17,22 @@
*/
#include "inputmaster.h"
#include "effectmaster.h"
#include "quattercam.h"
#include "board.h"
#include "piece.h"
InputMaster::InputMaster() : Master(),
input_{GetSubsystem<Input>()},
idleTime_{0.0f},
idle_{false},
mouseIdleTime_{0.0f},
sinceStep_{STEP_INTERVAL},
actionDone_{false}
actionDone_{false},
rayPiece_{},
raySquare_{}
{
SubscribeToEvent(E_MOUSEMOVE, URHO3D_HANDLER(InputMaster, HandleMouseMove));
SubscribeToEvent(E_MOUSEBUTTONDOWN, URHO3D_HANDLER(InputMaster, HandleMouseButtonDown));
SubscribeToEvent(E_MOUSEBUTTONUP, URHO3D_HANDLER(InputMaster, HandleMouseButtonUp));
SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(InputMaster, HandleKeyDown));
......@@ -80,7 +86,10 @@ void InputMaster::HandleKeyDown(StringHash eventType, VariantMap &eventData)
switch (key){
case KEY_ESC:{
if (!BOARD->IsEmpty() || MC->GetSelectedPiece() || MC->GetPickedPiece()){
if (!BOARD->IsEmpty()
|| MC->GetSelectedPiece()
|| MC->GetPickedPiece())
{
MC->Reset();
} else MC->Exit();
} break;
......@@ -108,10 +117,10 @@ void InputMaster::HandleKeyUp(StringHash eventType, VariantMap &eventData)
if (key == KEY_SPACE) actionDone_ = false;
if (key == KEY_UP ||
key == KEY_DOWN ||
key == KEY_LEFT ||
key == KEY_RIGHT)
if (key == KEY_UP
|| key == KEY_DOWN
|| key == KEY_LEFT
|| key == KEY_RIGHT)
{
sinceStep_ = STEP_INTERVAL;
}
......@@ -164,23 +173,47 @@ void InputMaster::Step(Vector3 step)
}
}
void InputMaster::HandleMouseMove(StringHash eventType, VariantMap &eventData){
mouseIdleTime_ = 0.0f;
///Reposition cursor and update selection
}
void InputMaster::HandleMouseButtonDown(StringHash eventType, VariantMap &eventData)
{
mouseIdleTime_ = 0.0f;
ResetIdle();
using namespace MouseButtonDown;
int button{eventData[P_BUTTON].GetInt()};
pressedMouseButtons_.Insert(button);
if (MC->InPickState()){
Piece* piece{RaycastToPiece()};
if (piece){
rayPiece_ = piece;
} else rayPiece_ = nullptr;
} else if (MC->InPutState()){
Square* square{RaycastToSquare()};
if (square){
raySquare_ = square;
} else raySquare_ = nullptr;
}
}
void InputMaster::HandleMouseButtonUp(StringHash eventType, VariantMap &eventData)
{
mouseIdleTime_ = 0.0f;
ResetIdle();
using namespace MouseButtonUp;
int button{eventData[P_BUTTON].GetInt()};
if (pressedMouseButtons_.Contains(button)) pressedMouseButtons_.Erase(button);
if (MC->InPickState()){
if (rayPiece_)
rayPiece_->Pick();
} else if (MC->InPutState()){
if (raySquare_)
BOARD->PutPiece(raySquare_);
}
}
void InputMaster::HandleJoystickButtons()
......@@ -192,8 +225,9 @@ void InputMaster::HandleJoystickButtons()
ResetIdle();
if (buttons.Contains(LucKey::SB_START)){
if (MC->GetGameState() == GameState::QUATTER
|| buttons.Contains(LucKey::SB_SELECT))
if (buttons.Contains(LucKey::SB_SELECT
|| BOARD->IsFull()
|| MC->GetGameState() == GameState::QUATTER))
{
MC->Reset();
}
......@@ -305,7 +339,6 @@ void InputMaster::HandleActionButtonPressed()
if (selectedPiece){
selectedPiece->Pick();
MC->NextPhase();
BOARD->SelectNearestFreeSquare();
} else if (MC->selectionMode_ == SM_STEP)
MC->SelectLastPiece();
......@@ -313,46 +346,10 @@ void InputMaster::HandleActionButtonPressed()
MC->CameraSelectPiece();
} else if (MC->InPutState() ){
if (BOARD->PutPiece(MC->GetPickedPiece())){
MC->NextPhase();
} else BOARD->Refuse();
BOARD->PutPiece(MC->GetPickedPiece());
}
}
void InputMaster::SetIdle()
{
if (!idle_){
idle_ = true;
if (MC->GetSelectedPiece())
MC->DeselectPiece();
Square* selectedSquare{BOARD->GetSelectedSquare()};
if (selectedSquare)
BOARD->Deselect(selectedSquare);
}
}
void InputMaster::ResetIdle()
{
if (idle_) {
idle_ = false;
if (MC->InPutState()){
if (!BOARD->SelectLast())
BOARD->SelectNearestFreeSquare();
} else if (MC->InPickState()){
if (!MC->SelectLastPiece())
MC->CameraSelectPiece();
}
}
idleTime_ = 0.0f;
}
void InputMaster::HandleCameraMovement(float t)
{
Vector2 camRot{};
......@@ -470,3 +467,81 @@ void InputMaster::SmoothCameraMovement(Vector2 camRot, float camZoom)
smoothCamRotate_ = 0.0666f * (camRot + smoothCamRotate_ * 14.0f);
smoothCamZoom_ = 0.05f * (camZoom + smoothCamZoom_ * 19.0f);
}
void InputMaster::SetIdle()
{
if (!idle_){
idle_ = true;
if (MC->GetSelectedPiece())
MC->DeselectPiece();
Square* selectedSquare{BOARD->GetSelectedSquare()};
if (selectedSquare)
BOARD->Deselect(selectedSquare);
}
}
void InputMaster::ResetIdle()
{
if (idle_) {
idle_ = false;
if (MC->InPutState()){
BOARD->SelectLast();
} else if (MC->InPickState()){
if (!MC->SelectLastPiece())
MC->CameraSelectPiece();
}
}
idleTime_ = 0.0f;
}
Piece* InputMaster::RaycastToPiece()
{
Ray cameraRay{MouseRay()};
PODVector<RayQueryResult> results;
RayOctreeQuery query(results, cameraRay, RAY_TRIANGLE, 1000.0f, DRAWABLE_GEOMETRY);
MC->world_.scene_->GetComponent<Octree>()->Raycast(query);
for (RayQueryResult r : results){
for (Piece* p : MC->world_.pieces_)
if (r.node_ == p->GetNode())
return p;
}
return nullptr;
}
Square* InputMaster::RaycastToSquare()
{
Ray cameraRay{MouseRay()};
PODVector<RayQueryResult> results;
RayOctreeQuery query(results, cameraRay, RAY_TRIANGLE, 1000.0f, DRAWABLE_GEOMETRY);
MC->world_.scene_->GetComponent<Octree>()->Raycast(query);
for (RayQueryResult r : results){
for (Square* s : BOARD->GetSquares())
if (r.node_ == s->node_)
return s;
}
return nullptr;
}
Ray InputMaster::MouseRay()
{
IntVector2 mousePos{GetSubsystem<Input>()->GetMousePosition()};
Graphics* graphics{GetSubsystem<Graphics>()};
float screenX{static_cast<float>(mousePos.x_) / graphics->GetWidth()};
float screenY{static_cast<float>(mousePos.y_) / graphics->GetHeight()};
Ray mouseRay{CAMERA->camera_->GetScreenRay(screenX, screenY)};
return mouseRay;
}
......@@ -26,6 +26,8 @@
#define STEP_INTERVAL 0.23f
#define DEADZONE 0.34f
class Square;
class InputMaster : public Master
{
URHO3D_OBJECT(InputMaster, Master);
......@@ -40,6 +42,8 @@ public:
JoystickState* GetActiveJoystick();
bool MultipleJoysticks();
Ray MouseRay();
private:
Input* input_;
......@@ -47,6 +51,8 @@ private:
float idleTime_;
bool idle_;
float mouseIdleTime_;
Vector2 smoothCamRotate_;
float smoothCamZoom_;
......@@ -58,14 +64,19 @@ private:
void HandleKeyDown(StringHash eventType, VariantMap &eventData);
void HandleKeyUp(StringHash eventType, VariantMap &eventData);
void HandleKeys();
void HandleMouseMove(StringHash eventType, VariantMap& eventData);
void HandleMouseButtonDown(StringHash eventType, VariantMap &eventData);
void HandleMouseButtonUp(StringHash eventType, VariantMap &eventData);
void HandleJoystickButtonDown(StringHash eventType, VariantMap &eventData);
void HandleJoystickButtonUp(StringHash eventType, VariantMap &eventData);
void HandleJoystickButtons();
void HandleUpdate(StringHash eventType, VariantMap &eventData);
void SmoothCameraMovement(Vector2 camRot, float camZoom);
void HandleCameraMovement(float t);
void HandleJoystickButtons();
void Screenshot();
void HandleActionButtonPressed();
......@@ -74,7 +85,11 @@ private:
void HandleRightArrowPressed();
void HandleLeftArrowPressed();
bool CorrectJoystickId(int joystickId);
void HandleKeys();
Piece* RaycastToPiece();
Square* RaycastToSquare();
Piece* rayPiece_;
Square* raySquare_;
};
#endif // INPUTMASTER_H
......@@ -75,7 +75,6 @@
#include <Urho3D/UI/UI.h>
#include <Urho3D/Scene/ValueAnimation.h>
#include <Urho3D/DebugNew.h>
namespace Urho3D {
......
......@@ -40,11 +40,10 @@ MasterControl::MasterControl(Context *context):
musicState_{MUSIC_SONG1},
previousMusicState_{MUSIC_OFF},
selectionMode_{SM_CAMERA},
lastReset_{0.0f},
selectedPiece_{nullptr},
lastSelectedPiece_{nullptr},
pickedPiece_{nullptr}
pickedPiece_{nullptr},
lastReset_{0.0f}
{
instance_ = this;
}
......@@ -124,6 +123,7 @@ void MasterControl::CreateScene()
//Create board and pieces
world_.board_ = new Board();
world_.pieces_.Reserve(NUM_PIECES);
for (int p{0}; p < NUM_PIECES; ++p){
Piece* newPiece = new Piece(Piece::Attributes(p));
......@@ -229,9 +229,9 @@ void MasterControl::HandleUpdate(StringHash eventType, VariantMap& eventData)
CameraSelectPiece();
//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));
leafyLightNode_->SetRotation(Quaternion(MC->Sine(MC->Sine(0.1f, 0.05f, 0.23f), -0.23f, 0.23f) + 90.0f, Vector3::RIGHT) *
Quaternion(MC->Sine(0.23f, 178.0f, 182.0f), Vector3::FORWARD));
leafyLight_->SetBrightness(0.34f + MC->Sine(0.011f, 0.05f, 0.23f) + MC->Sine(0.02f, 0.05f, 0.13f));
}
void MasterControl::SelectPiece(Piece* piece)
{
......@@ -243,7 +243,7 @@ void MasterControl::SelectPiece(Piece* piece)
void MasterControl::CameraSelectPiece()
{
if (Lame())
if (IsLame())
return;
Piece* nearest{selectedPiece_};
......@@ -313,6 +313,10 @@ void MasterControl::NextPhase()
if (gameState_ == GameState::QUATTER)
return;
if (selectedPiece_){
selectedPiece_->Deselect();
}
previousGameState_ = gameState_;
switch (gameState_) {
......@@ -354,30 +358,24 @@ void MasterControl::Reset()
void MasterControl::NextMusicState()
{
//Fade out
if (musicState_ == MUSIC_SONG1){
previousMusicState_ = musicState_;
musicState_ = MUSIC_OFF;
FX->FadeOut(musicSource1_);
} else if (musicState_ == MUSIC_SONG2){
FX->FadeOut(musicSource2_);
}
switch (musicState_) {
case MUSIC_SONG1: case MUSIC_SONG2:{
previousMusicState_ = musicState_;
musicState_ = MUSIC_OFF;
} break;
case MUSIC_OFF: {
FX->FadeOut(musicSource2_);
} else if (musicState_ == MUSIC_OFF){
previousMusicState_ = musicState_;
if (previousMusicState_ == MUSIC_SONG1)
musicState_ = MUSIC_SONG2;
else if (previousMusicState_ == MUSIC_SONG2)
musicState_ = MUSIC_SONG1;
previousMusicState_ = MUSIC_OFF;
} break;
default: {
previousMusicState_ = MUSIC_OFF;
musicState_ = MUSIC_SONG1;
} break;
}
//Fade in
if (musicState_ == MUSIC_SONG1){
FX->FadeTo(musicSource1_, musicGain_);
} else if (musicState_ == MUSIC_SONG2){
......@@ -404,6 +402,18 @@ void MasterControl::MusicGainDown(float step)
FX->FadeTo(musicSource2_, musicGain_, 0.23f);
}
void MasterControl::TakeScreenshot()
{
Graphics* graphics{GetSubsystem<Graphics>()};
Image screenshot{context_};
graphics->TakeScreenShot(screenshot);
//Here we save in the Screenshots folder with date and time appended
String fileName{GetSubsystem<FileSystem>()->GetProgramDir() + "Screenshots/Screenshot_" +
Time::GetTimeStamp().Replaced(':', '_').Replaced('.', '_').Replaced(' ', '_')+".png"};
Log::Write(1, fileName);
screenshot.SavePNG(fileName);
}
float MasterControl::Sine(const float freq, const float min, const float max, const float shift)
{
float phase{freq * world_.scene_->GetElapsedTime() + shift};
......@@ -416,15 +426,3 @@ float MasterControl::Cosine(const float freq, const float min, const float max,
float add{0.5f * (min + max)};
return LucKey::Cosine(phase) * 0.5f * (max - min) + add;
}
void MasterControl::TakeScreenshot()
{
Graphics* graphics{GetSubsystem<Graphics>()};
Image screenshot{context_};
graphics->TakeScreenShot(screenshot);
//Here we save in the Screenshots folder with date and time appended
String fileName{GetSubsystem<FileSystem>()->GetProgramDir() + "Screenshots/Screenshot_" +
Time::GetTimeStamp().Replaced(':', '_').Replaced('.', '_').Replaced(' ', '_')+".png"};
Log::Write(1, fileName);
screenshot.SavePNG(fileName);
}
......@@ -23,10 +23,8 @@
#include "luckey.h"
namespace Urho3D {
class Drawable;
class Node;
class Scene;
class Sprite;
}
using namespace Urho3D;
......@@ -105,14 +103,15 @@ public:
Sound* GetMusic(String name) const;
Sound* GetSample(String name) const;
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();
void NextPhase();
void NextMusicState();
void TakeScreenshot();
float Sine(const float freq, const float min = -1.0f, const float max = 1.0f, const float shift = 0.0f);
float Cosine(const float freq, const float min = -1.0f, const float max = 1.0f, const float shift = 0.0f);
private:
static MasterControl* instance_;
InputMaster* inputMaster_;
......@@ -127,16 +126,15 @@ private:
GameState previousGameState_;
MusicState musicState_;
MusicState previousMusicState_;
SelectionMode selectionMode_;
Piece* selectedPiece_;
Piece* lastSelectedPiece_;
Piece* pickedPiece_;
SelectionMode selectionMode_;
void CreateScene();
void Reset();
void HandleUpdate(StringHash eventType, VariantMap& eventData);
void NextPhase();
void CameraSelectPiece();
void StepSelectPiece(bool next);
......@@ -149,7 +147,7 @@ private:
bool SelectLastPiece();
float lastReset_;
bool Lame() { return GetSubsystem<Time>()->GetElapsedTime() - lastReset_ < (RESET_DURATION + 0.23f); }
bool IsLame() { return GetSubsystem<Time>()->GetElapsedTime() - lastReset_ < (RESET_DURATION + 0.23f); }
};
#endif // MASTERCONTROL_H
......@@ -25,8 +25,10 @@ Piece::Piece(Attributes attributes): Object(MC->GetContext()),
attributes_{attributes},
state_{PieceState::FREE }
{
rootNode_ = MC->world_.scene_->CreateChild("Piece"+GetCodon(4));
rootNode_ = MC->world_.scene_->CreateChild("Piece_"+GetCodon(4));
rootNode_->SetRotation(Quaternion(Random(360.0f), Vector3::UP));
StringVector tag{}; tag.Push(String("Piece"));
rootNode_->SetTags(tag);
StaticModel* pieceModel{rootNode_->CreateComponent<StaticModel>()};
pieceModel->SetCastShadows(true);
......@@ -75,13 +77,13 @@ String Piece::GetCodon(int length) const
String codon{};
codon += attributes_[0] ? "T" : "S"; //Tall : Short
codon += !attributes_[0] ? "S" : "T"; //Tall : Short
if (length > 1)
codon += attributes_[1] ? "R" : "S"; //Round : Square
codon += !attributes_[1] ? "S" : "R"; //Round : Square
if (length > 2)
codon += attributes_[2] ? "H" : "S"; //Hole : Solid
codon += !attributes_[2] ? "S" : "H"; //Hole : Solid
if (length == NUM_ATTRIBUTES)
codon += attributes_[3] ? "L" : "D"; //Light : Dark
codon += !attributes_[3] ? "D" : "L"; //Light : Dark
return codon;
}
......@@ -103,6 +105,7 @@ void Piece::Select()
void Piece::Deselect()
{
if (state_ == PieceState::SELECTED){
state_ = PieceState::FREE;
FX->FadeOut(outlineModel_->GetMaterial());
FX->FadeOut(light_);
......@@ -110,7 +113,8 @@ void Piece::Deselect()
}
void Piece::Pick()
{
if (state_ == PieceState::SELECTED){
if (state_ != PieceState::PUT){
state_ = PieceState::PICKED;
if (MC->GetGameState() == GameState::PLAYER1PICKS)
rootNode_->SetParent(CAMERA->GetPocket(false));
......@@ -121,15 +125,20 @@ void Piece::Pick()
FX->FadeOut(outlineModel_->GetMaterial());
FX->FadeOut(light_);
MC->NextPhase();
}
}
void Piece::Put(Vector3 position)
{
if (state_ == PieceState::PICKED){
state_ = PieceState::PUT;
state_ = PieceState::PUT;
rootNode_->SetParent(MC->world_.scene_);
FX->ArchTo(rootNode_, position, Quaternion(Random(-13.0f, 13.0f), Vector3::UP), 2.3f, 0.42f);
}
}
void Piece::Put(Square* square)
{
BOARD->PutPiece(this, square);
}
......@@ -33,6 +33,8 @@ enum class PieceState {FREE, SELECTED, PICKED, PUT};
#define NUM_ATTRIBUTES 4
class Square;
class Piece : public Object
{
URHO3D_OBJECT(Piece, Object);
......@@ -40,6 +42,7 @@ public:
typedef std::bitset<NUM_ATTRIBUTES> Attributes;
Piece(Attributes);
Node* GetNode() const { return rootNode_; }
void SetPosition(Vector3 pos) { rootNode_->SetPosition(pos); }