This third blog post presents the User Interface that I designed for my 2048 video game (you can check the first blog post of this series out if you haven’t read it yet).
I chose to rely on the very good tkinter
package, which is the standard Python interface to the Tk
GUI toolkit. Both Tk
and tkinter
are available on most Unix platforms, as well as on Windows systems. More details are available on the official documentation website.
This third post will mainly describe the TkConstants
and Window
classes. If you want more details, the source code of the project is also available on Github.
TkConstants class
This class is actually pretty simple and only contains the required text options (font types, police sizes) and the required colors for the tile backgrounds/borders.
Each tile number has been associated to a tuple (background color, foreground color) where foreground color is the color of the text:
colors = {
'0':("#cdc0b4", "#cdc0b4"),
'2':("#eee4da", "#776e65"),
'4':("#ede0c8", "#776e65"),
'8':("#f2b179", "#f9f6f2"),
'16':("#f59563", "#f9f6f2"),
'32':("#f67c5f", "#f9f6f2"),
'64':("#f65e3b", "#f9f6f2"),
'128':("#edcf72", "#f9f6f2"),
'256':("#edcc61", "#f9f6f2"),
'512': ("#edc850", "#f9f6f2"),
'1024':("#edc53f", "#f9f6f2"),
'2048':("#edc22e", "#f9f6f2")
}
Window class
The Window
class contains 5 main methods, that have quite self-explanatory names:
def start_new_game(self)
def replay_game(self)
def display_grid(self)
def update_grid(self)
def update(self, event)
The update
method is the general callback for any key release event:
self.window.bind('<KeyRelease>', self.update)
The update_grid method is called by the update method when a grid displayed need to be re-drawn:
if event.keysym in [v.value for v in Directions]:
if not self.game.ended_game:
# ...
self.update_grid()
Finally, the start_new_game
and replay_game
methods are called in response to the click event on options of the File
menu. The final rendering is shown below:
Finally, from a main entry-point file (e.g., Application.py
), the GUI is created and started as follow:
# No need to create grid or game objects when we launch GUI
app = Window(nb_rows_columns=Constants.GRID_NB_ROWS_COLUMNS, base_path=replay_dir)
app.start_new_game()
As a reminder, I do not guarantee that my solution is the best or the most optimized one. Feel free to propose yours or any suggestion you may have by commenting this series of blog posts.
I hope you enjoyed reading this blog post and that you are impatient for the next blog posts. 🙂