-
Notifications
You must be signed in to change notification settings - Fork 1
How the NEW Chessboard works
The old chessboard had a lot of parts coming together to make it work, and with a lot of strange logic choices. For example, a BoardPiece object could contain an aPiece object, which could then contain the same BoardPiece object, which would contain the same aPiece object, ad infinitum.
That's just one flaw with the old system, but really the biggest flaw was readability. It was very difficult to actually find what you were looking for when trying to add something to the game because everything was nested in a bunch of different function calls. This new chessboard logic is designed to completely simplify that.
These are the objects used for the new chessboard logic:
- NewBoardSpawner
- obj_piece
- obj_tile
The first step is to actually create the board, which means generating the tiles and the pieces.
It uses two for-loops to create the tiles on each column, and then move to the next row. The "chr" function and "ord" function are used in tandem to increase the tile letter based on the character's ASCII value. As it's looping, if a tile is in a position that has been designated to have a piece on it by default, it will run the spawn_piece function.
First, the piece is created on the same x and y position as the tile it's on. Second, it's set to be either the opponent's piece or the player's piece. Third, it's decided what piece it actually is. Fourth, its positional values are updated. Lastly, the tile is updated to actually contain the piece.
This is the object the new board uses for the chess pieces used during gameplay. Each variable is pretty self-explanatory:
- belongs_to: Does the piece belong to the player or the opponent
- piece_name: What piece is it
- row_number: The row number the piece is on
- col_letter: The column letter the piece is on
- image_speed: Built in GameMaker variable, used to set animation speed, with 0 meaning no movement
- image_index: Built in GameMaker variable, used to set a specific frame of an animation
The Draw event of the object updates the sprite depending on which piece it is, and then also increases the image_index value if the piece should be white instead of black.
This is where the bulk of the code for this update is contained. It has a VERY long function, called "mark_valid_tiles," which is what's used for movement logic, but what it lacks in brevity it makes up for in legibility.
Similar to obj_piece, the variables for this object are fairly obvious:
- row_number: The row number the piece is on
- col_letter: The column letter the piece is on
- piece_contained: The piece that is currently on the tile instance, set to noone if there is no piece
- valid_tile: Used to determine if the game should draw the sprite for a valid movement on a tile
- global.selected_piece: Tracks whatever piece the player selected
The Draw event for the tile is really simple. It draws the tile itself first, then it draws the tile's position label, and then if the tile is marked as valid it draws the sprite for a valid tile on top of itself.
The Mouse Left Pressed event already has comments in the code, so I won't add much detail. It first checks if the tile that was clicked was marked as a valid tile, and then if it wasn't it checks if it instead was a tile with a piece on it.
Now I'll explain the two functions that the object has currently, which are "clear_valid_tiles" and "mark_valid_tiles."
The clear_valid_tiles function simply loops through all instances of obj_tile that exists in the room, and sets their valid_tile variable to false.
The mark_valid_tiles function contains the movement and piece-taking logic for all of the different types of pieces in the game. Due to the length of the function, I won't explain everything it contains, but I will still walk through the logic for the Pawn, since the logic for all of the pieces is relatively similar.
The comments explain what the function does at the beginning. Afterwards, a switch-statement is used to determine what type of piece is being viewed.
The value of the row_number_search variable is set to one row above the piece (or below it, if the piece belongs to an opponent), using the size of the tile's sprite as the offset. The value of col_letter_search is set to the same column as the piece. Then, the game sets tile_inst to whatever tile instance it finds at the position values we just set. If the position actually holds a tile, and that tile doesn't have a piece on it, the tile is marked as a valid move.
This is a special condition if the pawn is on its starting row. It works the exact same way as the previous Basic movement, but an extra row above/below the last one.
The last check for the pawn is the two tiles it can "attack" when it moves. It works just like the previous two tile checks, but instead of making sure the tile is empty, this time checks to make sure the tile is NOT empty AND it has an opponent piece on it. After all of that, the case for the pawn is done, and global.selected_piece is set to the piece the player selected.
Although the mark_valid_tiles function may appear daunting at first, its purpose is to make debugging easier by having a straightforward path one can look at when trying to fix any issues or keep track of any variables they may need.
Wiki
User Stories
Design
Requirements
Architecture
Considerations & Issues
Documentation
- How to Add a Card to the Game
- How the Music Controller & Script work
- Card Paging & Search System (CardManager)
- How to Spawn Cards in a Room
- How the Chessboard works
- How to Add a New Board Color
- How to use Alert System
- Chess Logic
- Cheat Mode
- Timer
- How the new card system works
- How the NEW Chessboard works