Sunday, October 23, 2011

DDTe3 Hours 19 to 21 A distorted Tile

The distortion puzzle is a game I had created before but have never released on Blazing Games. The idea is that the game is made up of a broken up images where the boxes that make up the image are varying sizes. The part of the image that is shown in each tile is scaled to the size of the tile making for a distorted version of the image. While the game is essentially the original picture puzzle game, the effect of the distortion makes the game much more challenging than a regular picture puzzle game.

The key problem with this game is that the game board is no longer a grid. This means that the tiles will need to be handled differently then the other grid-based games. Likewise, the display is not as simple as the image being displayed in the tile may be distorted. This means that it is a good idea to create a special tile for dealing with the tiles in the distortion puzzle.

Having a hex tile that handled borders was much more convenient then the approach used with the grid games, so I decided to take this approach with the distortionTile. As the rendering and management of the tile is pretty much the same as the hex tile except for the shape I will not go into much detail about that aspect of this class. The focus instead will be on the two key aspects of this class. These are the clip and splitting.

The clip is kind of complex as there are two clips that make up this tile. The first clip is the true clip which is set once all the splitting has been done. If the current clip is the same as the true clip than the tile is in the correct place. The current clip is what gets swapped and is used to determine what is drawn.

Splitting tiles is a special situation as it is what is used to generate the puzzle for the game. To prevent too small of tiles, there are restrictions on how big a tile has to be in order to be split. The split is always done along the longest side, though in hind-site this is probably unnecessary and even more distorted puzzles could be generated by removing this restriction. The split line is then randomly generated but will always be somewhere within the 60% of the middle of the side. The rational for doing this is to prevent super-slim slices within the puzzle as those are hard for the player to deal with both in figuring out what is in the slice and in clicking on the slice.

PuzzleGallery.DistortionTile.prototype.split = function()
{
   var child;
   var temp;
   var tempRect = new BGLayers.Rectangle(this._logicalPosition);
   var childRect = new BGLayers.Rectangle(this._logicalPosition);
   var childClip = new BGLayers.Rectangle(this._clip);
   if (Math.max(this._clip.width, this._clip.height) < (this.thickness*5))
       return null;
   temp = Math.random() * .6 + .2;
   if (this._clip.width >= this._clip.height) {
       this._clip.width = Math.floor(temp * this._clip.width);
       tempRect.width = Math.floor(temp * tempRect.width);
       childRect.x += tempRect.width;
       ++childRect.x;
       childRect.width -= tempRect.width;
       childClip.x += this._clip.width;
       childClip.width -= this._clip.width;
   } else {
       this._clip.height = Math.floor(temp * this._clip.height);
       tempRect.height = Math.floor(temp * tempRect.height);
       childRect.y += tempRect.height;
       ++childRect.y;
       childRect.height -= tempRect.height;
       childClip.y += this._clip.height;
       childClip.height -= this._clip.height;
   }
   this.adjustPosition(tempRect);
   child = new PuzzleGallery.DistortionTile(this.id, this._image, childClip, childRect.width, childRect.height, this.thickness);
   child.setTileListener(this.listener);
   this.parent.addChild(child, childRect);
  
   return child;
}

This leaves us with two things that need to be done to have a full game. We need the actual game manager and we need a class to display the puzzle. Both those will be discussed next time.

Sunday, October 16, 2011

DDTe3 Hour 18 - Hex Sliding Puzzle

I have decided to switch back to posting my entries here on Sunday evenings. I was actually thinking of dropping this blog and just posting to Google+, but figured that this has a bit more permanence then G+ posts do. This article continues my series on Dozen Days of Tiles episode 3, where I created 8 games in 24 hours. This entry covers the creation of my hex sliding puzzle.

Originally, I was not thinking about doing a hex-based sliding puzzle as realistically you can not slide hexes as they form a really nicely locked pattern. Puzzle games do not necessarily have to reflect reality, so after thinking about it for a while, I figured that this would be an interesting game to develop. After playing the finished version of the game, I am quite glad that I did as it is actually a really fun variation of the sliding puzzle.

The hard part to creating this game is in dealing with the sliding. A hex grid can be thought of as a three-axis system, but that is only partially true. While the Z axis does exist, it is dependent on the X axis and  the Y axis. This means that manipulating the Z axis means that you are actually changing the X and Y axis. This got me thinking that if I just move along both the X and Y axis at the same time, things should work. Here is the new version of the sliding code.

PuzzleGallery.HexSlidingPuzzleGame.prototype.moveSlider = function(p)
{
   var tempX,tempY;
   var hp = new PuzzleGallery.HexPoint();
   hp.setPointFromGrid(p.x, p.y);

   while ((this.slider.x != hp.x) || (this.slider.y != hp.y)) {
       tempX = this.slider.getGridX();
       tempY = this.slider.getGridY();
       if (this.slider.x > hp.x) {
           this.slider.translateX(-1);
       } else if (this.slider.x < hp.x) {
           this.slider.translateX(1);
       }
       if (this.slider.y > hp.y) {
           this.slider.translateY(-1);
       } else if (this.slider.y < hp.y) {
           this.slider.translateY(1);
       }

       this.puzzle.swapPuzzlePieces(tempX, tempY, this.slider.getGridX(), this.slider.getGridY());
   };

   this.view.update();   
}

When trying to see if this method works, sliding along the proper axis works fine but if a shift is not axis-aligned, the results were a bit strange. The quick solution to this problem is to simply limit sliding to axis-aligned slides, which is what the game is going to do anyways. I do not like stop-gap solutions but prefer when possible to know why things are not working.  This problem actually was simple enough to figure out, as the strange results come from moves that are positive or negative along both the X and Y axis. Movement along the proper Z axis always results in opposite mathematical operations being applied to X and Y.

While I could probably special case the sliding of positive or negative X/Y combos, I really wanted to get this game finished in under an hour so I would have more time for the next game as it is a fairly complex game. As I would not be able to rely on sliding to random points as I did with the original sliding puzzle, my quick and dirty solution was to simply increase the amount of random slides five-fold calling the sliding through the axis-checking onTileClicked method.

The next (and as it turned out final) game in this series is still not the rotation puzzle but something never released on the Blazing Games site. The development on that game will start being covered next week.

Friday, October 7, 2011

DDTe3 Hour 17 - Hex Spin Puzzle

This is a continuation of my series on the creation of Dozen Days of Tiles episode 3 games on the Blazing Games site. While the other episodes in the Dozen Days series were about the creation of a game in under 24 hours, this episode is a challenge to see how many simple games can be created in under 24 hours. While this article covers the creation of the hex spin game, it is heavily dependent on the material covered in previous posts.

The next game to create this “day” is the hex-based variation of the spin puzzle. Because of the nature of the hex grid, the spin is a fairly natural operation. The spin, when looked at from a hex map perspective as figure 1 shows, is a very simple operation. Of course, using the grid coordinates that we are storing the hex in would make doing this procedure very tricky to code but by using the hex coordinate system that was discussed in an earlier article this can be a very easy piece of code to write.

figure 1 - Hex Spin

Converting between the two coordinate systems is easy enough to do and could be done right in the spinning code, I have a third hex game in mind so it might be better off to put the conversion and translation of hex coordinates into it’s own class, which I called HexPoint. This class has methods for converting between the two coordinate systems as well as for translating (moving) the hex point along the x, y and z axis. The z axis is tied to the other two so manipulating the z axis actually adjusts both the x and y axis as the following code snippet shows.

PuzzleGallery.HexPoint.prototype.translateZ = function(adj)
{
   this.y = this.y + adj;
   this.x = this.x - adj;
}

The HexSpinPuzzle game is essentially the SpinPuzzle game but with a hex grid so the only code that really needs to be written to create this game is a spin methods. Because I am “borrowing” code from SpinPuzzle which itself was borrowed from TwistPuzzle, the method to perform the spin action is called performTwist. While the logic behind the spin is the same as with the two grid games, the implementation is a bit more complex due to the need to work with two different coordinate systems. While at first glance the code may seem complex, it is remarkably simple and took very little time to write. Essentially, all we are doing is defining a pair of hex coordinates which represent the tiles that are to be manipulated. We start by finding the coordinates of the starting point. I am using the y-1 hex coordinate, though any hex that circles the hex tile that was clicked on could have been chosen for the starting point. As with the regular twist and spin puzzles, we need to save this to a temporary variable as this tile is going to be replaced. The coordinate is saved in a second HexPoint and the original point is translated to the position of the tile that will be shifted into the original point. Becuse of the point chosen to start at, the order of the translations are x+1, y+1, z+1, x-1, and y-1. The final z-1 translation would take us back to the start so instead of doing that translation we instead use the temp value. After each translation, the tile at that location is copied to the previous position.

PuzzleGallery.HexSpinPuzzleGame.prototype.performTwist = function(p)
{
   var hp1 = new PuzzleGallery.HexPoint();
   var hp2 = new PuzzleGallery.HexPoint();
  
   hp1.setPointFromGrid(p.x, p.y);
   hp1.translateY(-1);
   hp2.moveTo(hp1.x, hp1.y);
   var temp = this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY());
   hp1.translateX(1);
   this.puzzle.setPuzzlePiece(
           hp2.getGridX(), hp2.getGridY(),
           this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY()));
   hp2.moveTo(hp1.x, hp1.y);

   hp1.translateY(1);
   this.puzzle.setPuzzlePiece(
           hp2.getGridX(), hp2.getGridY(),
           this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY()));
   hp2.moveTo(hp1.x, hp1.y);

   hp1.translateZ(1);
   this.puzzle.setPuzzlePiece(
           hp2.getGridX(), hp2.getGridY(),
           this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY()));
   hp2.moveTo(hp1.x, hp1.y);

   hp1.translateX(-1);
   this.puzzle.setPuzzlePiece(
           hp2.getGridX(), hp2.getGridY(),
           this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY()));
   hp2.moveTo(hp1.x, hp1.y);

   hp1.translateY(-1);
   this.puzzle.setPuzzlePiece(
           hp2.getGridX(), hp2.getGridY(),
           this.puzzle.getPuzzlePiece(hp1.getGridX(), hp1.getGridY()));
   hp2.moveTo(hp1.x, hp1.y);

//    hp1.translateZ(-1);
   this.puzzle.setPuzzlePiece(hp2.getGridX(), hp2.getGridY(), temp);

   this.view.update();   
}


With this done the game is ready. The next hex game should be fairly simple to write and will probably leave me with enough time to create an eighth game.