Actual sliding in a sliding puzzle

Started by
6 comments, last by Zahlman 14 years, 5 months ago
Hey there fellow (hobbyist) game developers. Problem: I've made a start at a sliding puzzle game* and I like the way I organised my code. But when I "slide" a block in some direction, it just appears on the target spot. What I want it to do is to smoothly slide to the target spot. Now although making things slide across a screen isn't very hard to do, finding an obvious way to fit that into my design is (to me). *: This one: Fifteen Puzzle The design: I have the board split up in three parts: - A model of the board: you can shuffle it, make moves on it etc. - A view of the board: retrieves the status of the model to draw the board - A controller for the board: maps input from computer to actions on the board The board's status is represented internally as a 2-dimensional array of integers:
1 2 3
4 5 6
7 8 0
The empty spot is represented by a 0. To make a move to the right, I simply swap the 0 with the number to the left of the 0 (So in the example block 8 would move to the empty spot). Questions: 1: Is there a way to keep this internal representation of the board's and still implement nicely sliding blocks? 2: Would anyone feel like glancing over my source code (a little over 300 lines of code) and criticise it in any way? 3: Would the board's state be a more appropriate naming instead of the board's status? My English isn't good enough to make a good choice ^^. Source Code: Link: Click! I use Code::Blocks as IDE and SFML to open a window and draw upon it. The 2.4mb size is SFML's doing I guess ^^. To actually play the game, move the .dll files to bin/Debug and run de .exe file. Press enter to shuffle the board and use the arrow keys to put the board back into it's initial state (I really think state is the more appropriate word..). Thank you in advance! Arjan B
Advertisement
I didn't read your source code, but in general it is a very good idea to separate presentation from logic (formally known as model-view-controller pattern).

When you perform a slide, first do the logic in the model context. Then, in response to a successful slide, interpolate the position of the sliding block from the start position to the end position on the view context, by using the slide time as the interpolation parameter. In order to update the interpolation, you need to use a timer- either an OS-supplied one or your own. The responsibilities of the controller context seem clear to you.

This way, your game logic doesn't have to care how the game state is presented, and vice versa.

In general, the current object hierarchy (and its properties) of a game is called a "state".

Niko Suni

What Niko said.

Also, notice that sliding takes some time and you may have to make more changes for that. In particular you should make sure that a fast user can enter more moves before your sliding animation is finished. You can implement that by building a queue of inputs (mouse clicks or key presses) and reading from it only when you are ready to start the next sliding animation.

If the sliding is slow, the user may need some sort of feedback (a brief flashing of the selected tile to move, or a small clicking noise) to know that the input event has been captured.

First off, thank you very much for your replies!

Quote:Original post by Nik02
When you perform a slide, first do the logic in the model context. Then, in response to a successful slide, interpolate the position of the sliding block from the start position to the end position on the view context, by using the slide time as the interpolation parameter. In order to update the interpolation, you need to use a timer- either an OS-supplied one or your own. The responsibilities of the controller context seem clear to you.

This way, your game logic doesn't have to care how the game state is presented, and vice versa.


I was thinking about something like that, but the view doesn't know when a move occurs. The model shouldn't even know about the view so I guess the controller should notify the view in some way? (Suggestion for a way ^^?)

Quote:Original post by alvaro
Also, notice that sliding takes some time and you may have to make more changes for that. In particular you should make sure that a fast user can enter more moves before your sliding animation is finished. You can implement that by building a queue of inputs (mouse clicks or key presses) and reading from it only when you are ready to start the next sliding animation.


That was another problem that popped up in my mind and a queue seems a very nice solution. Thanks!

Quote:Original post by Nik02
In general, the current object hierarchy (and its properties) of a game is called a "state".


Ah okay, thanks!

Quote:Original post by Arjan B
Quote:Original post by Nik02
When you perform a slide, first do the logic in the model context. Then, in response to a successful slide, interpolate the position of the sliding block from the start position to the end position on the view context, by using the slide time as the interpolation parameter. In order to update the interpolation, you need to use a timer- either an OS-supplied one or your own. The responsibilities of the controller context seem clear to you.

This way, your game logic doesn't have to care how the game state is presented, and vice versa.


I was thinking about something like that, but the view doesn't know when a move occurs. The model shouldn't even know about the view so I guess the controller should notify the view in some way? (Suggestion for a way ^^?)


You could raise an event from the model layer, when the slide occurs. You'd listen for this event in the view layer, and respond by running the slide animation. The piece to be animated, as well as its start and end position, could be parameters of the event.

In raw C++, events are usually implemented by using callback functions - you give the event source object a pointer to a function that it should call when something of interest happens. This callback function would be implemented in the view layer, and the model layer would call it.

Niko Suni

Quote:Original post by Arjan B
I was thinking about something like that, but the view doesn't know when a move occurs. The model shouldn't even know about the view so I guess the controller should notify the view in some way? (Suggestion for a way ^^?)


In games, we typically just run a loop such that the view is told to update every so often whether or not we know there's a reason for it to update. :)
Thanks for the reply!

Quote:Original post by Zahlman
Quote:Original post by Arjan B
I was thinking about something like that, but the view doesn't know when a move occurs. The model shouldn't even know about the view so I guess the controller should notify the view in some way? (Suggestion for a way ^^?)


In games, we typically just run a loop such that the view is told to update every so often whether or not we know there's a reason for it to update. :)


That's what I'm doing ^^. Every frame the view retrieves the 2D array from the model and uses only that information to draw. If I would want to keep it that way I would have to let the view keep track of the previous state of the board, so when it retrieves the new state it can check for a change. If there is a change, draw a nice transition over multiple frames (which is another thing I would have to think about).

So an event system would be nicer I think. Which bring me to another question: I always thought the model was to know about nothing but itself, but it's okay to have it generate events to the outside world, even though he doesn't know what's out there?

I'm seeing now how a (at first glance) small extra feature can really make you have to redesign a lot ^^.
Quote:Original post by Arjan B
Which bring me to another question: I always thought the model was to know about nothing but itself, but it's okay to have it generate events to the outside world, even though he doesn't know what's out there?


"Know about" doesn't necessarily mean what you might think. ;) Try reading this.

This topic is closed to new replies.

Advertisement