menuwindow.cpp may not compile. To fix this, change lines 17-19 of menuwindow.cpp from
QPixmap p = ui->label_logo->pixmap(Qt::ReturnByValue);
const int SCALE = 4;
ui->label_logo->setPixmap(p.scaled(p.width() * SCALE, p.height() * SCALE));
to
const QPixmap *p = ui->label_logo->pixmap();
const int SCALE = 4;
ui->label_logo->setPixmap(p->scaled(p->width() * SCALE, p->height() * SCALE));
We value academic integrity very highly. Please read the Honor Code section on our course webpage to make sure you understand what is considered as plagiarism and what the penalties are. The following are some of the highlights:
The objective of this assignment is to provide you with practice on the OOP concepts of Inheritance and Polymorphism, as well as writing code with less reliance on a provided skeleton code. Upon completion of this assignment, you should be able to:
virtual.
In this (last) assignment, you are going to implement the graphical user interface (GUI) for SimpleCity.
Since Qt is not taught in the lectures, you are expected to self-learn Qt. Here are some useful resources:
pa4
├── City.cpp
├── City.h
├── SimpleCity.pro
├── buildings/
│ ├── Apartment.cpp
│ ├── Apartment.h
│ ├── Building.cpp
│ ├── Building.h
│ ├── BuildingInformationFormatString.h
│ ├── Clinic.cpp
│ ├── Clinic.h
│ ├── GoldMine.cpp
│ ├── GoldMine.h
│ ├── Health.cpp
│ ├── Health.h
│ ├── Hospital.cpp
│ ├── Hospital.h
│ ├── House.cpp
│ ├── House.h
│ ├── Residential.cpp
│ ├── Residential.h
│ ├── Revenue.cpp
│ ├── Revenue.h
│ ├── SilverMine.cpp
│ └── SilverMine.h
├── graphics.cpp
├── graphics.h
├── images/
│ ├── apartment.png
│ ├── clinic.png
│ ├── destruct.png
│ ├── gold_mine.png
│ ├── hospital.png
│ ├── house.png
│ ├── navigation.png
│ ├── next.png
│ ├── silver_mine.png
│ └── stripes.png
├── images.qrc
├── main_gui.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── menuwindow.cpp
├── menuwindow.h
├── menuwindow.ui
└── test-city.txt
SimpleCity.pro: The Qt Creator project file for SimpleCity. Open this in Qt Creator.City.cpp, City.h and files in buildings/: Provided files implementing the game logic. These are also the files you worked on in PA3. No need to modify these files.images/ and images.qrc: Image files used in the application and the corresponding Qt Resource Collection Files. No need to modify these files.main_gui.cpp: The main() function. No need to modify this file.mainwindow.cpp, mainwindow.h and mainwindow.ui: Files implementing the main window. You may need to modify mainwindow.cpp and mainwindow.h.menuwindow.cpp, menuwindow.h and menuwindow.ui: Files implementing the menu window. You may need to modify menuwindow.cpp and menuwindow.h.graphics.cpp and graphics.h: Files implementing the game graphics. No need to modify these files.test-city.txt: Save file for testing.However, since this assignment is graded in live demo, you are not constrained to follow our rules. You can do whatever you like to the code, as long as the application produces the expected results. (See Submission & Grading)
When the application is started, the menu window appears. You only need to modify menuwindow.cpp and possibly menuwindow.h.
When the "New Game" button is clicked, the UI is changed to prompt the player for the desired size of the city.
The current map size is shown in the label in the center. By default, the map size is 20. The left arrow button decreases the map size by 2, to a minimum of 10. The right arrow button increases the map size by 2, to a maximum of 30. When the "Start Game" button is clicked, create a new city with the specified map size and start the game. The menu window is closed and the main window is started.
menuwindow.ui to understand the UI elements of the menu window.
MenuWindow::ui->label_grid_size, which is a QLabel.MenuWindow::ui->pages, which is a QStackedWidget.QFileDialog to display the dialog for the player to choose a save file.MenuWindow::start_game(). Either create a new city or load a city from save, then pass the city pointer to this function.
When the game is started, the main window is shown. Most functions regarding the game display has been already implemented in graphics.cpp and graphics.h, and you do not need to modify these files. You only need to modify mainwindow.cpp and possibly mainwindow.h.
At the top, there are 3 buttons that control the display of overlay: "Normal Overlay", "Type Overlay" and "Neighbor Effects Overlay". The display of overlay has already been implemented in graphics.cpp and graphics.h.
By default, "Normal Overlay" is chosen. When "Type Overlay" is chosen, the buildings are highlighted according to their types (Health, Revenue or Residential):
When "Neighbor Effects Overlay" is chosen, lines are shown to indicate neighboring effects between buildings:
You need to configure the behaviors of the overlay buttons:
MainWindow::initialize_overlay_buttons(), which is called in the MainWindow constructor. You should set the style sheet of the overlay buttons, such that the selected overlay type is white, while others are blue. By default, the "Normal Overlay" button is selected.
QButton::setStyleSheet() and make use of the strings BTN_SELECTED_STYLE and BTN_RELEASED_STYLE.MainWindow::on_overlay_button_clicked() with the corresponding value of the enum class OverlayButton. For example,
MainWindow::on_overlay_button_clicked(OverlayButton::NORMAL).MainWindow::on_overlay_button_clicked().
MainWindow::selected_overlay_button to the selected overlay button. This is accessed by the code in graphics.cpp to display the overlay.graphics.cpp, which sets the member variable MainWindow::side_menu_status. You need to complete the code in MainWindow::main_loop(), which is called 50 times per second to perform the animation. In particular, you need to complete two cases in the switch statement (Updated November 10):
HIDDEN_TO_VISIBLE case, decrease the x-coordinate of MainWindow::ui->side_menu_move by fixed steps (e.g. 10), to a minimum of 0. Once 0 (or less) is reached, set MainWindow::side_menu_status to VISIBLE.VISIBLE_TO_HIDDEN case, increase the x-coordinate of MainWindow::ui->side_menu_move by fixed steps (e.g. 10), to a maximum of 400. Once 400 (or greater) is reached, set MainWindow::side_menu_status to HIDDEN, and set the maximum width of MainWindow::ui->side_menu_move to 0.
switch (side_menu_status) {
case SideMenuStatus::HIDDEN:
qDebug("Hidden");
break;
case SideMenuStatus::HIDDEN_TO_VISIBLE:
qDebug("Hidden -> Visible");
break;
case SideMenuStatus::VISIBLE:
qDebug("Visible");
break;
case SideMenuStatus::VISIBLE_TO_HIDDEN:
qDebug("Visible -> Hidden");
break;
}
HIDDEN_TO_VISIBLE state, the side menu should be appearing. When it has appeared, move to the VISIBLE state.VISIBLE_TO_HIDDED state, the side menu should be disappearing. When it has disappeared, move to the HIDDEN state.MainWindow::ui->side_menu is the parent widget for MainWindow::ui->side_menu_move. We set its maximum width to control whether the widget and the side menu can be displayed. If the maximum width is not set, then MainWindow::ui->side_menu always block mouse cursor in front of the grid.MainWindow::initialize_side_menu_buttons(), which is called in the MainWindow constructor. You should set the style sheet of the side menu buttons, such that the selected button is white, while others are blue. By default, the "Navigate" button is selected.
QButton::setStyleSheet() and make use of of the strings BTN_SELECTED_STYLE and BTN_RELEASED_STYLE.MainWindow::on_side_menu_button_clicked() with the corresponding value of the enum class SideMenuButton. For example,
MainWindow::on_side_menu_button_clicked(SideMenuButton::CLINIC).MainWindow::on_side_menu_button_clicked().
MainWindow::selected_side_menu_button to the selected side menu button. This is accessed by the code in graphics.cpp.mainwindow.ui to understand the UI elements of the main window.
QFileDialog to display the dialog for the player to choose a save file.graphics.cpp.
Deadline: 20 November 2021 Saturday HKT 23:59.
You may earn 8% course grade for each PA. Since ZINC does not (yet) support grading assignments with GUI, you need to submit the source files to Canvas, and then perform live demo.
Compress all source code as pa4_[student-id].zip and submit to Canvas.
There will be a penalty of -1 point (out of a maximum 100 points) for every minute you are late. For instance, since the deadline is 23:59:00 on 20 November 2021, if you submit your solution at 1:00:00 on 21 November 2021, there will be a penalty of -61 points for your assignment. However, the lowest grade you may get from an assignment is zero: any negative score after the deduction due to late penalty (and any other penalties) will be reset to zero.
Live demo of your work will be held in Week 12-13. You will be demonstrating your work in a 1-to-1 session with a TA. You will be asked to download your submission from Canvas, compile it in Qt Creator and run it by following a series of steps. The TA will grade you work by checking whether the behavior matches the expected behavior. The schedule of the live demo will be announced later.
In the live demo, the TA will ask you to follow the below steps sequentially. The TA may ask you to do some specific actions in order to check the behavior of your program. If your program crashed in the middle, you are given another two chances to retry. The latest run is graded. No partial credits are given in each step.
In this assignment, we do not check for memory leak.
This assignment was originally proposed and designed by Yu Hei CHAU.
The images of the in-game buildings are created by pixel32 @ opengameart.org.
https://opengameart.org/content/pixel-city-municipal-buildings