Sunday, July 17, 2011

DDTe3 Hours 5 to 6 The Picture Puzzle Game

My mother is still in the hospital, which is at least part of the reason I missed posting this last week. I am thinking about updating this blog the same time that I update the Blazing Games site, but kind of want to keep them separate to emphasis the fact that they are separate things. The few people who actually read this probably already realize this and combining the posting dates may make things easier so don't be surprised if the blog starts being updated late Thursday nights (PST). This is continuing the development of Dozen Days of Tiles episode 3 which is a how many games can I develop in 24 hours challenge instead of the usual developing a game in under 24 hours challenge.

With the puzzle displaying, we are most of the way to a playable picture puzzle game. The only issue remaining that must be solved is input. The mouse input is handled by the BasePuzzleView  class by calling a listener function. As this listener function can be set by any of the games, it is not game dependent. Instead, the function that gets called is what holds the game-play logic.

The information that the game needs to know is what tile was selected. There are a number of ways this information can be passed, but the most universally useful way is simply to indicate the row and column that was selected as any other information can be derived from that knowledge. Determining this is a bit more problematic as BGLayers passes real mouse positions not logical ones. This conversion from real to logical coordinates is something that BGLayers probably should have functions to handle but it does not. Still, this is very easy to calculate as it is essentially just a scaling calculation.

    var rp = this.findRealPosition();
    var lx = (x - rp.x) * (this._logicalSize.width / rp.width);
    var ly = (y - rp.y) * (this._logicalSize.height / rp.height);
    var p = new BGLayers.Point(Math.floor((lx - this.tileLeft) / this.tileWidth),
    Math.floor((ly - this.tileTop) / this.tileHeight));

The game logic to handle the click simply stores the first tile clicked on as the selector and the second click swaps the two tiles. At this point we have a playable game but three problems immediately come to mind. First, there is no visible way of knowing what tile was selected. Second, it isn't always obvious where the tiles are. Third, there is no indication about which tiles are correct or not. The second and third problems can be solved by adding a border that has an optional hint capability. But instead of just having a border, why not add a highlight feature to the border as well and get a hat-trick. For those of you not familiar with Hockey, a hat-trick is when a player scores three goals in a single game.

The TileBorder class simply consists of the four borders and the highlight. The class holds 3  colors one highlight color, one correct color and one incorrect color. The correctness is handled by a setCorrect(b) function that sets the border colors to the correct color if passed true and to the error color if passed false. The highlight is set to the highlight color and is initially invisible but can be turned on (or off again) by calling the setHighlight function.

In my first attempt of implementing this, the borders were just layer classes but I discovered that the rgba colors were not working. This was obviously because the layers by default are solid. Unfortunately, setting them to transparent has the side effect of not drawing the background color making them invisible. This makes sense as the layers are placeholders that draw a background color if necessary and if the layer isn't solid then no background is needed. A new class, the HightlightBlock, was quickly created to draw a solid block. Instead of using rgba colors for transparency, I instead opted for a separate alpha channel. While not utilized yet, it opens the possibility of alternating the transparency without having to worry about the color.

The tile borders are then added to the BasePuzzleView class after the tiles are created so that the borders will always be above the tiles. The update method then adds a single line to it's update loop:

this.tileBorders[indx].setCorrect(tile == indx);

This line sets the correctness color of the border. With that we have a fully playable game. One game down and at least another 3 to go.

No comments: