Added table construction from layout, basic click and tile selection functions are also added

This commit is contained in:
Dmitriy Shishkov 2022-04-28 03:39:51 +03:00
parent cb147f7057
commit a02f88af49
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
9 changed files with 207 additions and 56 deletions

2
App.h
View File

@ -5,7 +5,7 @@
class MyApp : public wxApp
{
public:
public:
virtual bool OnInit() override;
};

View File

@ -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;
}

View File

@ -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

View File

@ -4,16 +4,12 @@
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)
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);
}

View File

@ -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];

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}

View File

@ -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