Skip to content

Latest commit

 

History

History
17 lines (8 loc) · 4.45 KB

DOC.md

File metadata and controls

17 lines (8 loc) · 4.45 KB

Documentation on our project design

Our basic philosophy of design is to make a modular, easy-to-use, and flexible hardware game engine for FPGA gaming development. In order to achieve it, we broke it into a clear file structure with different functionality for each part: ROMs, basic helper modules, display modules, keyboard, object control, game control, and seven-segment display. Unfortunately, our final simple Flappy Bird demo still has some bugs, but we did several small demos and a lot of unit tests and we think our modules perform each of their own functions perfectly well.

ROMs are a very important part for our flexibility, which allows us to change the layout, background or bitmaps for the scenario, maps or objects. We tried hard but didn’t manage to use the QSPI Flash memory in which we can change our data without re-synthesizing other parts. As a result, we chose block memories, which unfortunately caused the synthesis process to become longer, and used the concatenation of row and column to index data. In order to store color data in the memory easily, we also made a python-based program to convert BMP pictures into our ROM modules. We also considered to use ROMs to store transformation information for object movements such that transformations can be dynamically loaded, but given the time restraint, we haven’t finished it.

For display modules, we have a standard VGA sync and game-over/game-logo displaying modules, as well as a display-top module functioning as a connector of objects and a compositor of the display. With the same method as in game-over/game-logo displaying modules, we can modify modules to display any game stages readily. With the support of background ROM, changing background can also be done without modify any displaying module, and we gave the functionality to repeat a small background picture to cover the whole screen.

Our keyboard module is a essential part of basic IO. Outputting a 32-wide bus of key pressing signals, it can handle multi-pressing events and doesn’t cause any blocking and stalling.

Seven segment display is also an important IO module for displaying scores. Based on the standard 7-segment module, we also finished a simple score displaying module which can support two modes: single player mode and two players mode. For further polishing, it could be better to receive the reset signal in order to support refreshing scores in a new round of game.

For game control, we created a game Finite State Machine to provide the functionality of deciding game stages, which can be easily extended, and resetting the game after game-over.

The most powerful part is our object control modules. We’d like to provide as much flexibility as we can to the users, so we decided to use a comprehensive protocol for object movements. We used the object_engine module to provide movement control for the objects controlled by players, and the module can receive four keys from the keyboard and control objects’ movements in X and Y directions independently. It may be worth mentioning that the movements in four directions can be set to display different animations. We used signals such as gravity and grounded to handle different situations where the object is in the air/on the ground and with/without gravity, and signals such as jump_in_air to let developers decide the jump behavior of the object in the air. Furthermore, we used timing registers to simulate the natural accelerating and terminating behaviors of movements, such as the terminal speed when falling in the air. We also used no-boundary signals to change the behavior of the object with respect to boundaries. To maximize flexibility, we used parameters to instantiate an object so that the default value of the attributes like velocity, starting point, boundaries, etc. can be easily modified. On top of these movements, we also provided the interface/signals to accept customized transformations/translations, which ideally can be read from the memory, based on the communications regarding the objects’ current attributes/behaviors. We used it to provide the translation and random-heights of the tubes in our demo. We also finished a collision judging module that can check whether a collision occurs between any two objects. With these object control modules, in collaboration with our IO modules, the engine ideally can create complex behaviors and responses. For example, the player’s object can respond to some key pressings such that it spits small ‘weapons’ to hit the ghosts.