From 4d0c579ea7bb8d7d6f8f117a44b6fb9a0e496205 Mon Sep 17 00:00:00 2001 From: dm1sh Date: Fri, 25 Mar 2022 03:48:33 +0300 Subject: [PATCH] Added Drawer and Controller classes for game graphics and logic, refactoring --- AboutDlg.h | 1 - App.cpp | 7 ++++-- App.h | 2 +- Controller.cpp | 3 +++ Controller.h | 15 ++++++++++++ Drawer.cpp | 45 ++++++++++++++++++++++++++++++++++ Drawer.h | 23 ++++++++++++++++++ GameFrame.cpp | 65 -------------------------------------------------- GameFrame.h | 38 ----------------------------- GamePanel.cpp | 38 +++++++++++++++++++++++++++++ GamePanel.h | 27 +++++++++++++++++++++ Graphics.cpp | 9 ------- Graphics.h | 15 ------------ HelpDlg.h | 1 - MainFrame.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ MainFrame.h | 30 +++++++++++++++++++++++ RulesDlg.h | 1 - 17 files changed, 243 insertions(+), 133 deletions(-) create mode 100644 Controller.cpp create mode 100644 Controller.h create mode 100644 Drawer.cpp create mode 100644 Drawer.h delete mode 100644 GameFrame.cpp delete mode 100644 GameFrame.h create mode 100644 GamePanel.cpp create mode 100644 GamePanel.h delete mode 100644 Graphics.cpp delete mode 100644 Graphics.h create mode 100644 MainFrame.cpp create mode 100644 MainFrame.h diff --git a/AboutDlg.h b/AboutDlg.h index 5cfd4f3..99d5b5d 100644 --- a/AboutDlg.h +++ b/AboutDlg.h @@ -7,7 +7,6 @@ class AboutDlg : public wxDialog { public: AboutDlg(wxWindow *parent, wxWindowID id); - ~AboutDlg() {}; }; #endif diff --git a/App.cpp b/App.cpp index 12c8577..16dd507 100644 --- a/App.cpp +++ b/App.cpp @@ -1,12 +1,15 @@ #include "./App.h" -#include "./GameFrame.h" +#include "./MainFrame.h" wxIMPLEMENT_APP(MyApp); bool MyApp::OnInit() { - GameFrame *frame = new GameFrame(); + wxImage::AddHandler(new wxPNGHandler()); + + MainFrame *frame = new MainFrame(); frame->Show(true); SetTopWindow(frame); + return true; } diff --git a/App.h b/App.h index 04bab87..a9a45a7 100644 --- a/App.h +++ b/App.h @@ -6,7 +6,7 @@ class MyApp : public wxApp { public: - virtual bool OnInit(); + virtual bool OnInit() override; }; #endif diff --git a/Controller.cpp b/Controller.cpp new file mode 100644 index 0000000..9a6b42d --- /dev/null +++ b/Controller.cpp @@ -0,0 +1,3 @@ +#include "./Controller.h" + +Controller::Controller() {}; \ No newline at end of file diff --git a/Controller.h b/Controller.h new file mode 100644 index 0000000..dbeeff4 --- /dev/null +++ b/Controller.h @@ -0,0 +1,15 @@ +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#include "./wxw.h" + +class Controller { +public: + Controller(); + + int stopwatch; + +private: +}; + +#endif diff --git a/Drawer.cpp b/Drawer.cpp new file mode 100644 index 0000000..440a5b0 --- /dev/null +++ b/Drawer.cpp @@ -0,0 +1,45 @@ +#include "./Drawer.h" + +static const char* tileImageNames[] = { "Back", "Blank", "Chun", "Front", "Haku", "Hatsu", "Man1", "Man2", "Man3", "Man4", "Man5", "Man5-Dora", "Man6", "Man7", "Man8", "Man9", "Nan", "Pei", "Pin1", "Pin2", "Pin3", "Pin4", "Pin5", "Pin5-Dora", "Pin6", "Pin7", "Pin8", "Pin9", "Shaa", "Sou1", "Sou2", "Sou3", "Sou4", "Sou5", "Sou5-Dora", "Sou6", "Sou7", "Sou8", "Sou9", "Ton" }; + +Drawer::Drawer() { + for (int i = 0; i < 40; i++) { + tileImages[i].LoadFile(_("./resources/tiles/") + _(tileImageNames[i]) + _(".png"), wxBITMAP_TYPE_PNG); + tileImages[i].Rescale(60, 80); + } +} + +void Drawer::drawTable(wxDC& dc) { + drawBG(dc); + drawTiles(dc); +} + +void Drawer::drawBG(wxDC& dc) { + dc.GradientFillConcentric(wxRect(wxPoint(0, 0), tableSize), wxColor(7, 85, 45), wxColor(1, 45, 22)); +} + +void Drawer::drawTiles(wxDC& dc) { + dc.DrawBitmap(tileImages[3], wxPoint(10, 10)); + dc.DrawBitmap(tileImages[10], wxPoint(10, 10)); + + dc.DrawBitmap(tileImages[3], wxPoint(80, 10)); + dc.DrawBitmap(tileImages[10], wxPoint(80, 10)); +} + +wxString LTimeToStr(int time) { + return wxString::Format(_("%d:%02d:%02d"), time / 3600, (time / 60) % 60, time % 60); +} + +void Drawer::drawTimer(wxStaticText* timerText, int time) { + wxString timeStr = LTimeToStr(time); + timerText->SetPosition(wxPoint(tableSize.x / 2, 10)); + timerText->SetLabel(timeStr); +} + +wxStaticText* Drawer::initTimer(wxWindow* parent) { + auto timerText = new wxStaticText(parent, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL); + timerText->SetForegroundColour(wxColor(255, 255, 255)); + timerText->SetFont(wxFont(wxFontInfo(20))); + + return timerText; +} diff --git a/Drawer.h b/Drawer.h new file mode 100644 index 0000000..e7849d4 --- /dev/null +++ b/Drawer.h @@ -0,0 +1,23 @@ +#ifndef DRAWER_H +#define DRAWER_H + +#include "./wxw.h" + +class Drawer { +public: + Drawer(); + + void drawTable(wxDC& dc); + void drawTimer(wxStaticText* timerText, int time); + wxStaticText* initTimer(wxWindow* parent); + + wxSize tableSize; + +private: + void drawBG(wxDC& dc); + void drawTiles(wxDC& dc); + + wxImage tileImages[40]; +}; + +#endif diff --git a/GameFrame.cpp b/GameFrame.cpp deleted file mode 100644 index 767dbcd..0000000 --- a/GameFrame.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "./GameFrame.h" - -#include "./HelpDlg.h" -#include "./RulesDlg.h" -#include "./AboutDlg.h" - -BEGIN_EVENT_TABLE(GameFrame, wxFrame) - EVT_MENU(IDM_Exit, GameFrame::OnExit) - EVT_MENU(IDM_Help, GameFrame::OnHelp) - EVT_MENU(IDM_Rules, GameFrame::OnRules) - EVT_MENU(IDM_About, GameFrame::OnHelp) - EVT_PAINT(GameFrame::OnPaint) -END_EVENT_TABLE() - -GameFrame::GameFrame() - : wxFrame(nullptr, wxID_ANY, _("Маджонг (пасьянс)")) -{ - InitMenu(); -} - -void GameFrame::InitMenu() { - wxMenu *menuGame = new wxMenu; - menuGame->Append(IDM_New_Game, _("Начать сначала")); - menuGame->AppendSeparator(); - menuGame->Append(IDM_Exit, _("Выход")); - - wxMenu *menuHelp = new wxMenu; - menuHelp->Append(IDM_Help, _("Инструкция")); - menuHelp->Append(IDM_Rules, _("Правила игры")); - menuHelp->Append(IDM_About, _("О программе")); - - wxMenuBar *menuBar = new wxMenuBar; - menuBar->Append(menuGame, _("Игра")); - menuBar->Append(menuHelp, _("Помощь")); - - SetMenuBar(menuBar); -} - -void GameFrame::OnExit(wxCommandEvent &event) { - Close(); -} - -void GameFrame::OnHelp(wxCommandEvent &event) { - HelpDlg *dlg = new HelpDlg(this, -1); - - dlg->Show(); -} - -void GameFrame::OnRules(wxCommandEvent &event) { - RulesDlg *dlg = new RulesDlg(this, -1); - - dlg->Show(); -} - -void GameFrame::OnAbout(wxCommandEvent &event) { - AboutDlg *dlg = new AboutDlg(this, -1); - - dlg->Show(); -} - -void GameFrame::OnPaint(wxPaintEvent& event) { - wxPaintDC dc(this); - - paint.drawTable(dc, GetSize()); -} diff --git a/GameFrame.h b/GameFrame.h deleted file mode 100644 index ab26234..0000000 --- a/GameFrame.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef GAMEFRAME_H_ -#define GAMEFRAME_H_ - -#include "./wxw.h" - -#include "./Graphics.h" - -/// @uml{style[#line.dotted:blue]} -class GameFrame : public wxFrame -{ -public: - GameFrame(); - -private: - Graphics paint; - - void InitMenu(); - - void OnExit(wxCommandEvent &event); - void OnHelp(wxCommandEvent &event); - void OnRules(wxCommandEvent &event); - void OnAbout(wxCommandEvent &event); - - void OnPaint(wxPaintEvent& event); - - DECLARE_EVENT_TABLE() -}; - -enum -{ - IDM_Exit = wxID_EXIT, - IDM_Help = wxID_HELP, - IDM_About = wxID_ABOUT, - IDM_New_Game = 1, - IDM_Rules -}; - -#endif diff --git a/GamePanel.cpp b/GamePanel.cpp new file mode 100644 index 0000000..b6c5731 --- /dev/null +++ b/GamePanel.cpp @@ -0,0 +1,38 @@ +#include "./GamePanel.h" + +#include + +GamePanel::GamePanel(wxFrame* parent) : wxPanel(parent) { + SetBackgroundStyle(wxBG_STYLE_PAINT); + + Bind(wxEVT_PAINT, &GamePanel::OnPaint, this); + Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) -> void { + this->drawer.tableSize = evt.GetSize(); + }); + + timer = new wxTimer(this); + timerText = drawer.initTimer(this); + + Bind(wxEVT_TIMER, [this](wxTimerEvent& _) -> void { + controller.stopwatch += 1; + drawer.drawTimer(timerText, controller.stopwatch); + }, timer->GetId()); +} + +void GamePanel::Start() { + wxLogDebug(_("Started game")); + + controller.stopwatch = 0; + timer->Start(1000, wxTIMER_CONTINUOUS); + + Refresh(); +} + +void GamePanel::OnPaint(wxPaintEvent& _) { + wxAutoBufferedPaintDC dc(this); + + drawer.drawTable(dc); + drawer.drawTimer(timerText, controller.stopwatch); + + wxLogDebug("Rerender"); +} diff --git a/GamePanel.h b/GamePanel.h new file mode 100644 index 0000000..8695c09 --- /dev/null +++ b/GamePanel.h @@ -0,0 +1,27 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include "./wxw.h" + +#include + +#include "./Drawer.h" +#include "./Controller.h" + +class GamePanel : public wxPanel { +public: + GamePanel(wxFrame* parent); + + void Start(); + +private: + Drawer drawer; + Controller controller; + + void OnPaint(wxPaintEvent& _); + + wxStaticText* timerText; + wxTimer* timer; +}; + +#endif diff --git a/Graphics.cpp b/Graphics.cpp deleted file mode 100644 index b6f843e..0000000 --- a/Graphics.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "./Graphics.h" - -void Graphics::drawTable(wxDC& dc, wxSize wndSize) { - drawBG(dc, wndSize); -} - -void Graphics::drawBG(wxDC& dc, wxSize wndSize) { - dc.GradientFillConcentric(wxRect(wxPoint(0, 0), wndSize), wxColor(7, 85, 45), wxColor(1, 45, 22)); -} diff --git a/Graphics.h b/Graphics.h deleted file mode 100644 index c30aad0..0000000 --- a/Graphics.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef GRAPHICS_H -#define GRAPHICS_H - -#include "./wxw.h" - -class Graphics { -public: - Graphics() {}; - ~Graphics() {}; - - void drawTable(wxDC& dc, wxSize wndSize); - void drawBG(wxDC& dc, wxSize wndSize); -}; - -#endif diff --git a/HelpDlg.h b/HelpDlg.h index 398f47a..46ca873 100644 --- a/HelpDlg.h +++ b/HelpDlg.h @@ -7,7 +7,6 @@ class HelpDlg : public wxDialog { public: HelpDlg(wxWindow *parent, wxWindowID id); - ~HelpDlg() {}; }; #endif diff --git a/MainFrame.cpp b/MainFrame.cpp new file mode 100644 index 0000000..e907f2d --- /dev/null +++ b/MainFrame.cpp @@ -0,0 +1,56 @@ +#include "./MainFrame.h" + +#include "./HelpDlg.h" +#include "./RulesDlg.h" +#include "./AboutDlg.h" + +MainFrame::MainFrame() + : wxFrame(nullptr, wxID_ANY, _("Маджонг (пасьянс)")) +{ + InitMenu(); + BindMenu(); + + panel = new GamePanel(this); + panel->SetFocus(); + panel->Start(); +} + +void MainFrame::InitMenu() { + wxMenu *menuGame = new wxMenu; + menuGame->Append(IDM_New_Game, _("Начать сначала")); + menuGame->AppendSeparator(); + menuGame->Append(IDM_Exit, _("Выход")); + + wxMenu *menuHelp = new wxMenu; + menuHelp->Append(IDM_Help, _("Инструкция")); + menuHelp->Append(IDM_Rules, _("Правила игры")); + menuHelp->Append(IDM_About, _("О программе")); + + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(menuGame, _("Игра")); + menuBar->Append(menuHelp, _("Помощь")); + + SetMenuBar(menuBar); +} + +void MainFrame::BindMenu() { + Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void { + Close(); + }, IDM_Exit); + + Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void { + (new HelpDlg(this, -1))->Show(); + }, IDM_Help); + + Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void { + (new AboutDlg(this, -1))->Show(); + }, IDM_About); + + Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void { + (new RulesDlg(this, -1))->Show(); + }, IDM_Rules); + + Bind(wxEVT_MENU, [this](wxCommandEvent& _) -> void { + panel->Start(); + }, IDM_New_Game); +} diff --git a/MainFrame.h b/MainFrame.h new file mode 100644 index 0000000..dbed839 --- /dev/null +++ b/MainFrame.h @@ -0,0 +1,30 @@ +#ifndef MainFrame_H_ +#define MainFrame_H_ + +#include "./wxw.h" + +#include "./GamePanel.h" + +/// @uml{style[#line.dotted:blue]} +class MainFrame : public wxFrame +{ +public: + MainFrame(); + +private: + void InitMenu(); + void BindMenu(); + + GamePanel *panel; +}; + +enum +{ + IDM_Exit = wxID_EXIT, + IDM_Help = wxID_HELP, + IDM_About = wxID_ABOUT, + IDM_Rules = wxID_HIGHEST + 1, + IDM_New_Game +}; + +#endif diff --git a/RulesDlg.h b/RulesDlg.h index cc1f718..e296baf 100644 --- a/RulesDlg.h +++ b/RulesDlg.h @@ -7,7 +7,6 @@ class RulesDlg : public wxDialog { public: RulesDlg(wxWindow *parent, wxWindowID id); - ~RulesDlg() {}; }; #endif