In this sequence of tutorial pages we will be creating a game similar to the Blocks Mania iOS game.
Game Introduction (VIDEO)
The game consists of a tiled game board like the one shown below:
We will begin with a very simple game board that consists of blank tiles ( / ), the player ( / @), and the end point ( / X):
Tile and Position Classes (VIDEO)
We will represent each spot on the gameboard with a tile. Each tile is a button that can be pressed by clicking with the mouse. Each tile keeps track of a position (column and row) and a type. What follows is a first attempt at these classes.
public class Position { public final int col; public final int row; public Position(int col, int row) { this.col = col; this.row = row; } }
Since the Position
class just describes the pairing of integers, I've made the attributes public
. Note also that I've declared the attributes as final
.
public class Tile extends JButton { private final Position position; private final char type; public Tile(Position position) { this(position, ' '); } public Tile(Position position, char type) { super("" + type); this.position = position; this.type = type; } }
The type
attribute is used to distinguish between different types of game tiles. In the beginning stages of our development, this type will just be a character that will be displayed as the label for the button.
QUESTIONS/EXERCISES
- What are the advantages of declaring the
Position
attributes aspublic
? - What are the disadvantages of declaring the
Position
attributes aspublic
? - Since the type will be the same for every object from the
Tile
class, can you think of a better way to store this information?
Game Movement (VIDEO)
The video describes the intended behavior when the player makes a move. If the tile at row: 1, col: 3 is clicked, the tile at row: 1, col: 8 should determine what should happen next. If this tile is a blank tile, then the Player should be moved to position row: 1, col: 8, and the next move should be moved based on the tile at position row: 1, col: 7.
Therefore, we add the following method to the Tile
class:
public class Tile extends JButton { // ... public Move processMove(Move move) { return move; } }
The Move
class keeps track of the current position and direction that the Player is moving. The direction is defined as one of a number of class constants:
public class Move { public final static int DIRECTION_NORTH = 0; public final static int DIRECTION_SOUTH = 1; public final static int DIRECTION_WEST = 2; public final static int DIRECTION_EAST = 3; public final static int DIRECTION_STOP = 4; public final static int DIRECTION_WIN = 5; public final static int DIRECTION_LOSE = 6; private final int direction; private final Position position; public Move(int direction, Position position) { this.direction = direction; this.position = position; } public int getDirection() { return direction; } public Position getPosition() { return position; } }
QUESTIONS/EXERCISES
- Which class constant directions are not required to implement the
Tile.processMove()
method? - Implement the
processMove()
method for theTile
class that represents a blank tile. - The
position
anddirection
attributes are declaredfinal
. What implications does this have on how objects from theMove
class can be used?
Gameboard Class (VIDEO)
A GameBoard
class is used to manage the GUI of each level of the game. The GameBoard
is a JPanel
that contains a grid of buttons.
public class GameBoard extends JPanel { private Tile[][] gameboard; public GameBoard(String filename) { loadGame(filename); createGUI(); } private void createGUI() { // Use GridLayout // Add tiles to JPanel } private void loadLevel(String filename) { // Read in characters from file // Allocate space for gameboard 2D array // Create tiles from characters // Add tiles to gameboard // Connect action listener to each tile } }
QUESTIONS/EXERCISES
- Implement the
loadLevel()
method for theGameBoard
class. - Implement the
createGUI()
method for theGameBoard
class.
Game and WinTile Classes (VIDEO)
For now, the Game
class will just create a game using the first level of the game. Eventually it will need to manage multiple levels and the transition between levels.
public class Game extends JFrame { public static void main(String[] ignored) { JFrame game = new Game(); game.setVisible(true); } public Game() { super("Maniacal Blocks"); this.setSize(300, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); add(new GameBoard("levels/level1.txt")); } }
public class WinTile extends Tile { public WinTile(Position position) { super(position, 'X'); } @Override public Move processMove(Move move) { return move; } }
QUESTIONS/EXERCISES
- The
EndTile
class in the video has been renamedWinTile
here. Why? - Implement the
processMove()
method for theWinTile
class. - Modify the
Game
class to add a panel that shows the number of moves made and contains a RESTART button.
Last modified: Monday, 29-Jul-2024 06:54:47 EDT