Saturday, November 5, 2016

architecture - Separating physics and game logic from UI code


I'm working on a simple block-based puzzle game.


The game play consists pretty much of moving blocks around in the game area, so it's a trivial physics simulation. My implementation, however, is in my opinion far from ideal and I'm wondering if you can give me any pointers on how to do it better.


I've split the code up into two areas: Game logic and UI, as I did with a lot of puzzle games:



  • The game logic is responsible for the general rules of the game (e.g. the formal rule system in chess)

  • The UI displays the game area and pieces (e.g. chess board and pieces) and is responsible for animations (e.g. animated movement of chess pieces)



The game logic represents the game state as a logical grid, where each unit is one cell's width/height on the grid. So for a grid of width 6, you can move a block of width 2 four times until it collides with the boundary.


The UI takes this grid, and draws it by converting logical sizes into pixel sizes (that is, multiplies it by a constant). However, since the game has hardly any game logic, my game logic layer [1] doesn't have much to do except collision detection. Here's how it works:



  1. Player starts to drag a piece

  2. UI asks game logic for the legal movement area of that piece and lets the player drag it within that area

  3. Player lets go of a piece

  4. UI snaps the piece to the grid (so that it is at a valid logical position)

  5. UI tells game logic the new logical position (via mutator methods, which I'd rather avoid)



I'm not quite happy with that:



  • I'm writing unit tests for my game logic layer, but not the UI, and it turned out all the tricky code is in the UI: Stopping the piece from colliding with others or the boundary and snapping it to the grid.

  • I don't like the fact that the UI tells the game logic about the new state, I would rather have it call a movePieceLeft() method or something like that, as in my other games, but I didn't get far with that approach, because the game logic knows nothing about the dragging and snapping that's possible in the UI.


I think the best thing to do would be to get rid of my game logic layer and implement a physics layer instead. I've got a few questions regarding that:



  1. Is such a physics layer common, or is it more typical to have the game logic layer do this?

  2. Would the snapping to grid and piece dragging code belong to the UI or the physics layer?

  3. Would such a physics layer typically work with pixel sizes or with some kind of logical unit, like my game logic layer?


  4. I've seen event-based collision detection in a game's code base once, that is, the player would just drag the piece, the UI would render that obediently and notify the physics system, and the physics system would call a onCollision() method on the piece once a collision is detected. What is more common? This approach or asking for the legal movement area first?


[1] layer is probably not the right word for what I mean, but subsystem sounds overblown and class is misguiding, because each layer can consist of several classes.



Answer



I'll try an attempt to answer this question as I can understand what you're asking, though I don't have much game development experience since I'm still only learning.


As I see it, you to to separate the GUI code from your game logic and domain objects, that is, the puzzle pieces. These are indeed three separate layers - and yes, layer is an appropriate term in my opinion. It is often used to explain the concepts of separating each objects level of a system into subsystems that are independent from each other.


In regards of object-oriented programming, each object shall be a class. So, each piece of your puzzle shall consist of a class per itself, and so the game board. The game board should contains X pieces of puzzle depending on its size and movement capacity that you want to give to the player.


So, here are my thoughts on the topic - I hope that it will help:



  1. The GUI layer: This layer shall contain methods only to display the pieces on the game board to allow the interaction between the the game itself and the player;


  2. The Game Controller layer: Is responsible for the player's inputs. That is the layer that should tell a piece to move in the different directions, and ask the game board whether there will be collisions upon movement and so on;

  3. The Business layer: This layer shall contains all of your business classes, that is, the pieces of your game and the game board object that contains the puzzle pieces.


In this architecture, you would have the GUI layer show the player of the game state, the location of each pieces of puzzle. The GUI layer would then be responsible for getting the player inputs and pass it to an underlying Game Controller layer, which would then be responsible for collision detection. If there's none, then the piece can be ordered to move into that input direction. To do so, you would simply have to call this piece's MoveLeft, MoveRight, etc. methods to make the piece move. You might as well let the game board know what piece you want to move, and then it orders by itself the piece's movement, and piece then moves into the demanded direction. This architecture makes it easy for testing each piece of code into the different layers, and then allows you for unit testing, integration testing and functional testing.


I know this might seem a little confusing at for sight, and thank god if it isn't! Should you require further details and help, please feel free to ask, I'll be glad to help the best I can though I'm a beginner into game development.


Thanks for reading! =)


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...