Added table construction from layout, basic click and tile selection functions are also added
This commit is contained in:
parent
cb147f7057
commit
a02f88af49
114
Controller.cpp
114
Controller.cpp
@ -5,25 +5,121 @@
|
||||
Controller::Controller(Drawer& drawer): drawer(drawer) {};
|
||||
|
||||
void Controller::resize(const wxSize& tableSize) {
|
||||
drawer.setBG(tableSize);
|
||||
drawer.initScreen(tableSize);
|
||||
wxSize& resolution = drawer.resolution;
|
||||
wxSize& gridSize = drawer.gridSize;
|
||||
wxRect& tablePixelRect = drawer.tablePixelRect;
|
||||
|
||||
resolution = tableSize;
|
||||
|
||||
wxLogDebug("Resize");
|
||||
int gridPoint = min(resolution.x / (gridSize.x * TILE_WIDTH),
|
||||
resolution.y / (gridSize.y * TILE_HEIGHT));
|
||||
|
||||
if (gridPoint > 2) {
|
||||
tablePixelRect.SetSize({gridPoint * TILE_WIDTH * gridSize.x, gridPoint * TILE_HEIGHT * gridSize.y});
|
||||
|
||||
drawer.tilePixelSize.Set(gridPoint * TILE_WIDTH, gridPoint * TILE_HEIGHT);
|
||||
}
|
||||
|
||||
tablePixelRect.SetPosition({(resolution.x - tablePixelRect.width) / 2,
|
||||
(resolution.y - tablePixelRect.height) / 2});
|
||||
|
||||
drawer.setBG(tableSize);
|
||||
drawer.initScreen(tableSize, table);
|
||||
}
|
||||
|
||||
wxPoint Controller::toGrid(const wxPoint& point) {
|
||||
wxPoint out(-1, -1);
|
||||
|
||||
if (point.x >= pixelTableRect.x &&
|
||||
point.x <= pixelTableRect.x + pixelTableRect.width &&
|
||||
point.y >= pixelTableRect.y &&
|
||||
point.y <= pixelTableRect.y + pixelTableRect.height)
|
||||
wxRect& tablePixelRect = drawer.tablePixelRect;
|
||||
|
||||
if (point.x >= tablePixelRect.x &&
|
||||
point.x <= tablePixelRect.x + tablePixelRect.width &&
|
||||
point.y >= tablePixelRect.y &&
|
||||
point.y <= tablePixelRect.y + tablePixelRect.height)
|
||||
{
|
||||
out.x = upDiv(point.x - pixelTableRect.x, tileSize.x);
|
||||
out.y = upDiv(point.y - pixelTableRect.y, tileSize.y);
|
||||
out.x = (point.x - tablePixelRect.x) / drawer.tilePixelSize.x;
|
||||
out.y = (point.y - tablePixelRect.y) / drawer.tilePixelSize.y;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
wxPoint Controller::fromGrid(const wxPoint& point) {
|
||||
return { drawer.tablePixelRect.x + point.x * drawer.tilePixelSize.x,
|
||||
drawer.tablePixelRect.y + point.y * drawer.tilePixelSize.y };
|
||||
}
|
||||
|
||||
void Controller::loadLayout(const wxString& path) {
|
||||
layout.openFile(path);
|
||||
|
||||
drawer.gridSize = layout.getDimensions();
|
||||
|
||||
table = TLVec(drawer.gridSize.x, wxVector<wxVector<TLSquare>>(drawer.gridSize.y, wxVector<TLSquare>()));
|
||||
|
||||
layout.readLayout(table);
|
||||
}
|
||||
|
||||
TLVec* Controller::getTable() {
|
||||
return &table;
|
||||
}
|
||||
|
||||
TLSquare* Controller::getCardByPosition(const wxPoint& point) {
|
||||
int8_t topIndex = -1;
|
||||
auto res = table[0][0].rend();
|
||||
|
||||
for (auto el = table[point.x][point.y].rbegin(); el != table[point.x][point.y].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.x > 0)
|
||||
for (auto el = table[point.x-1][point.y].rbegin(); el != table[point.x-1][point.y].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.y > 0)
|
||||
for (auto el = table[point.x][point.y-1].rbegin(); el != table[point.x][point.y-1].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (point.x > 0 && point.y > 0)
|
||||
for (auto el = table[point.x-1][point.y-1].rbegin(); el != table[point.x-1][point.y-1].rend(); ++el)
|
||||
if (el->second != (uint8_t)-1) {
|
||||
auto d = el->first;
|
||||
if (d > topIndex) {
|
||||
topIndex = d;
|
||||
res = el;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return &(*res);
|
||||
}
|
||||
|
||||
void Controller::select(TLSquare* card) {
|
||||
if (selected != nullptr && selected->second == card->second && selected != card) {
|
||||
selected->second = -1;
|
||||
card->second = -1;
|
||||
selected = nullptr;
|
||||
|
||||
drawer.initScreen(drawer.tableSize, table);
|
||||
} else
|
||||
selected = card;
|
||||
}
|
||||
|
18
Controller.h
18
Controller.h
@ -4,6 +4,7 @@
|
||||
#include "wxw.h"
|
||||
|
||||
#include "Drawer.h"
|
||||
#include "XmlLayout.h"
|
||||
|
||||
class Controller {
|
||||
public:
|
||||
@ -13,14 +14,23 @@ public:
|
||||
|
||||
void resize(const wxSize& tableSize);
|
||||
|
||||
void loadLayout(const wxString& path);
|
||||
|
||||
wxPoint toGrid(const wxPoint& point);
|
||||
wxPoint fromGrid(const wxPoint& point);
|
||||
|
||||
void select(TLSquare* card);
|
||||
|
||||
TLVec* getTable();
|
||||
|
||||
TLSquare* getCardByPosition(const wxPoint& point);
|
||||
private:
|
||||
Drawer& drawer;
|
||||
XmlLayout layout;
|
||||
|
||||
wxSize tileSize;
|
||||
wxSize resolution;
|
||||
wxSize gridSize;
|
||||
wxRect pixelTableRect;
|
||||
TLVec table;
|
||||
|
||||
TLSquare* selected = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
46
Drawer.cpp
46
Drawer.cpp
@ -4,15 +4,11 @@
|
||||
static const char* tileImageNames[] = { "Back", "Blank", "Chun", "Front", "Haku", "Hatsu", "Man1", "Man2", "Man3", "Man4", "Man5", "Man6", "Man7", "Man8", "Man9", "Nan", "Pei", "Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin6", "Pin7", "Pin8", "Pin9", "Shaa", "Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou6", "Sou7", "Sou8", "Sou9", "Ton" };
|
||||
|
||||
Drawer::Drawer() {
|
||||
for (int i = 0; i < 37; i++) {
|
||||
for (int i = 0; i < 37; i++)
|
||||
tileImages[i].LoadFile(_("./resources/tiles/") + _(tileImageNames[i]) + _(".png"), wxBITMAP_TYPE_PNG);
|
||||
tileImages[i].Rescale(60, 80);
|
||||
}
|
||||
}
|
||||
|
||||
void Drawer::drawTable(wxDC& dc) {
|
||||
wxLogDebug("Redraw");
|
||||
|
||||
if (isScreenReady)
|
||||
dc.DrawBitmap(screenBitmap, 0, 0, false);
|
||||
}
|
||||
@ -22,8 +18,6 @@ wxBitmap copyBitmap(const wxBitmap& old) {
|
||||
}
|
||||
|
||||
void Drawer::setBG(const wxSize& tableSize) {
|
||||
wxLogDebug("Recreate background");
|
||||
|
||||
bgBitmap = wxBitmap(tableSize);
|
||||
|
||||
wxMemoryDC dc;
|
||||
@ -34,15 +28,43 @@ void Drawer::setBG(const wxSize& tableSize) {
|
||||
isBgReady = true;
|
||||
}
|
||||
|
||||
void Drawer::initScreen(const wxSize& tableSize) {
|
||||
wxLogDebug("Recreate screen");
|
||||
void Drawer::initScreen(const wxSize& tableSize, const TLVec& layout) {
|
||||
if (isBgReady) {
|
||||
screenBitmap = copyBitmap(bgBitmap);
|
||||
|
||||
wxMemoryDC dc;
|
||||
dc.SelectObject(screenBitmap);
|
||||
|
||||
int cards_set = -1;
|
||||
uint8_t layer = -1;
|
||||
|
||||
while (cards_set) {
|
||||
layer++;
|
||||
cards_set = 0;
|
||||
|
||||
for (int i = 0; i < layout.size(); i++)
|
||||
for (int j = 0; j < layout[i].size(); j++) {
|
||||
int k = layout[i][j].size() - 1;
|
||||
while (k > -1 && layout[i][j][k].second == (uint8_t)-1)
|
||||
k--;
|
||||
|
||||
if (k > -1)
|
||||
if (layout[i][j][k].first == layer) {
|
||||
drawTile(dc, layout[i][j][k].second, {tablePixelRect.x + tilePixelSize.x*i, tablePixelRect.y + tilePixelSize.y*j});
|
||||
cards_set++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isScreenReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Drawer::drawTile(wxDC& dc, const char index) {
|
||||
dc.DrawBitmap(tileImages[3], wxPoint(10, 10));
|
||||
dc.DrawBitmap(tileImages[index], wxPoint(10, 10));
|
||||
void Drawer::drawTile (wxDC& dc, int8_t index, const wxPoint& position) {
|
||||
dc.DrawRoundedRectangle(position, tilePixelSize * 2, 10);
|
||||
|
||||
if (tileImages[index].GetWidth() != tilePixelSize.x * 2)
|
||||
dc.DrawBitmap(tileImages[index].Scale(tilePixelSize.x * 2 - 20, tilePixelSize.y * 2 - 20), {position.x + 10, position.y + 10});
|
||||
else
|
||||
dc.DrawBitmap(tileImages[index], position);
|
||||
}
|
||||
|
14
Drawer.h
14
Drawer.h
@ -3,6 +3,11 @@
|
||||
|
||||
#include "wxw.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define TILE_HEIGHT 8
|
||||
#define TILE_WIDTH 6
|
||||
|
||||
class Drawer {
|
||||
public:
|
||||
Drawer();
|
||||
@ -11,12 +16,17 @@ public:
|
||||
|
||||
wxSize tableSize;
|
||||
|
||||
wxSize tilePixelSize; // 600x800
|
||||
wxSize resolution;
|
||||
wxSize gridSize;
|
||||
wxRect tablePixelRect;
|
||||
|
||||
void setBG(const wxSize& tableSize);
|
||||
void initScreen(const wxSize& tableSize);
|
||||
void initScreen(const wxSize& tableSize, const TLVec& layout);
|
||||
|
||||
private:
|
||||
void drawScreen(wxDC& dc);
|
||||
void drawTile(wxDC& dc, const char index);
|
||||
void drawTile(wxDC& dc, int8_t index, const wxPoint& position);
|
||||
|
||||
wxImage tileImages[40];
|
||||
|
||||
|
@ -18,8 +18,9 @@ GamePanel::GamePanel(wxFrame* parent) : wxPanel(parent), controller(drawer), sb(
|
||||
Bind(wxEVT_LEFT_DOWN, &GamePanel::OnClick, this);
|
||||
}
|
||||
|
||||
void GamePanel::Start() {
|
||||
void GamePanel::Start(const wxString& path) {
|
||||
controller.stopwatch = 0;
|
||||
controller.loadLayout(path);
|
||||
|
||||
timer->Start(1000, wxTIMER_CONTINUOUS);
|
||||
sb->SetStatusText(LTimeToStr(controller.stopwatch));
|
||||
@ -37,6 +38,14 @@ void GamePanel::OnTimer(wxTimerEvent& _) {
|
||||
}
|
||||
|
||||
void GamePanel::OnClick(wxMouseEvent& _) {
|
||||
wxPoint res = controller.toGrid(wxGetMousePosition());
|
||||
sb->PushStatusText(itowxS(res.x) + _("x") + itowxS(res.y));
|
||||
wxPoint res = controller.toGrid(ScreenToClient(wxGetMousePosition()));
|
||||
|
||||
if (res.x > -1) {
|
||||
auto card = controller.getCardByPosition(res);
|
||||
if (card != nullptr) {
|
||||
controller.select(card);
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
@ -12,7 +12,7 @@ class GamePanel : public wxPanel {
|
||||
public:
|
||||
GamePanel(wxFrame* parent);
|
||||
|
||||
void Start();
|
||||
void Start(const wxString& path);
|
||||
|
||||
private:
|
||||
Drawer drawer;
|
||||
@ -22,8 +22,8 @@ private:
|
||||
void OnTimer(wxTimerEvent& _);
|
||||
void OnClick(wxMouseEvent& _);
|
||||
|
||||
wxStatusBar* sb;
|
||||
wxTimer* timer;
|
||||
wxStatusBar* sb = nullptr;
|
||||
wxTimer* timer = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -5,24 +5,21 @@
|
||||
#include "AboutDlg.h"
|
||||
|
||||
MainFrame::MainFrame()
|
||||
: wxFrame(nullptr, wxID_ANY, _("Маджонг (пасьянс)")),
|
||||
: wxFrame(nullptr, wxID_ANY, _("Маджонг (пасьянс)"), wxDefaultPosition, wxSize(800, 600)),
|
||||
dataDirPath(wxStandardPaths::Get().GetUserDataDir())
|
||||
{
|
||||
InitMenu();
|
||||
BindMenu();
|
||||
initMenu();
|
||||
bindMenu();
|
||||
|
||||
CreateStatusBar();
|
||||
|
||||
panel = new GamePanel(this);
|
||||
panel->SetFocus();
|
||||
panel->Start();
|
||||
|
||||
openLayout();
|
||||
}
|
||||
|
||||
MainFrame::~MainFrame() {
|
||||
delete panel;
|
||||
}
|
||||
|
||||
void MainFrame::InitMenu() {
|
||||
void MainFrame::initMenu() {
|
||||
wxMenu *menuGame = new wxMenu;
|
||||
menuGame->Append(IDM_New_Game, _("Начать сначала"));
|
||||
menuGame->Append(IDM_Open, _("Открыть карту"));
|
||||
@ -41,12 +38,14 @@ void MainFrame::InitMenu() {
|
||||
SetMenuBar(menuBar);
|
||||
}
|
||||
|
||||
void MainFrame::BindMenu() {
|
||||
void MainFrame::bindMenu() {
|
||||
Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void {
|
||||
Close();
|
||||
}, IDM_Exit);
|
||||
|
||||
Bind(wxEVT_MENU, &MainFrame::OnOpen, this, IDM_Open);
|
||||
Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void {
|
||||
openLayout();
|
||||
}, IDM_Open);
|
||||
|
||||
Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void {
|
||||
(new HelpDlg(this, -1))->Show();
|
||||
@ -61,15 +60,20 @@ void MainFrame::BindMenu() {
|
||||
}, IDM_Rules);
|
||||
|
||||
Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void {
|
||||
panel->Start();
|
||||
if (layoutPath.IsEmpty())
|
||||
openLayout();
|
||||
else
|
||||
panel->Start(layoutPath);
|
||||
}, IDM_New_Game);
|
||||
}
|
||||
|
||||
void MainFrame::OnOpen(wxCommandEvent& _) {
|
||||
void MainFrame::openLayout() {
|
||||
wxFileDialog openFileDlg(this, "Открыть карту", dataDirPath + wxFileName::GetPathSeparator() + _("layouts"), "Turtle.smlf", "Файлы Mahjong карт (*.smlf)|*.smlf", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
|
||||
if (openFileDlg.ShowModal() == wxID_CANCEL)
|
||||
return;
|
||||
|
||||
GetStatusBar()->PushStatusText(openFileDlg.GetPath());
|
||||
layoutPath = openFileDlg.GetPath();
|
||||
|
||||
panel->Start(layoutPath);
|
||||
}
|
@ -13,17 +13,17 @@ class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
|
||||
private:
|
||||
void InitMenu();
|
||||
void BindMenu();
|
||||
void initMenu();
|
||||
void bindMenu();
|
||||
|
||||
void OnOpen(wxCommandEvent& _);
|
||||
void openLayout();
|
||||
|
||||
GamePanel *panel;
|
||||
|
||||
const wxString dataDirPath;
|
||||
wxString layoutPath;
|
||||
};
|
||||
|
||||
enum
|
||||
|
Loading…
x
Reference in New Issue
Block a user