Trying to keep things going as and when I can. This is a super quick-update just to display the correct buttons for the current puzzle. I know I'll be swamped for the next few days so grabbing 15 mins just to get another little piece done is going to be vital.
Nonoku- Selecting Things
Nonoku - Something Familiar
A quick recreation of the first puzzle from Nonoku’s original release. Underpinning it is a simple struct that holds the board layout and colours (I didn’t update the button handling to show them yet).
The actual tiles are hardcoded as a string that gets parsed into a 2D array. I’ll need something a bit more flexible in future but this will suffice for getting content on screen.
I’m now testing it on actual hardware, instead of just running in the simulator. The signing process seems to have been improved a lot in Xcode 8 which is nice.
About as basic as it gets...
Nonoku - Coloured Buttons
The eternal question when writing from a coder’s perspective, UK English, or US English, spelling. Context seems important to me. Mostly I will spell using US English standards since that’s the environment I’m coding in (Color, Center, Synthesize). When writing documentation, except when specifically referencing code, I’ll default to UK English (Colour, Centre, Synthesise). In an IDE it’s hard to type the UK English variant, in a document editor, it’s hard to type the US English spelling. Maybe it’s purely contextual and if I was updating a document that was in US English I’d automatically switch. I certainly find that with the minor differences between Windows and OS X keyboard layouts when I switch between them.
Anyway… More buttons. These ones are in the game itself and allow the selection of different colours to fill in the puzzle. It automatically scales to allow different numbers of colours. Eight seems to be the upper practical limit for fitting them into the UI.
More PaintCode shenanigans. I’ve also got Telekinesis working. I’m not really doing anything fancy enough to warrant it but it’s fun to play with a little. These buttons are two separate elements. One rounded rectangle that I can scale whilst maintaining the aspect ratio, and the circular ‘button’ part which has an inner shadow (as a highlight) and an outer shadow to give it a little depth. The highlight and the shadow are set according to the colour of the button. Not being familiar with PaintCode, I tried doing it as a single element. Since I needed different scaling that proved tricky. I got close with the Frames and Constraints but it wasn’t quite right. In the end, it was faster (and more logical) to split it out into separate pieces.
And yes, I am procrastinating on the next part. I need to add the game part of this game. I mostly have the shape of it in my head and I’ve messed with a couple of implementations but I’m waiting for it to feel right before I commit to something.
Nonoku - Buttons
Real life caught up so only a little progress. Started experimenting with some graphics tools just to change things up. Nothing final yet but this was quick enough to implement. I used PaintCode to draw out the button and add a gradient fill I could swap with the flat background by setting a flag. Then all I had to do was create a custom UIControl
to draw the button.
The text is defined at run-time so could be localised in future if I stick with this style.
override func draw(_ rect: CGRect) {
NonokuKit.drawMenuButton(frame: bounds, tapped: tapped, text: text)
}
So simple it's barely even worth including.
Nonoku - Adding Some Color
Just a small update this time. Added some placeholder tiles to the board. A little bit of tidying as well. Mostly moving some values into constants for re-use elsewhere. The only thing of note is using an SKCropNode
with a rounded rect, set to the same size as the board, so that the tiles always fit within the same space.
private func addTiles(parent: SKNode) {
let tileColor: [UIColor] = [SKColor(colorLiteralRed: 200/255, green: 182/255, blue: 240/255, alpha: 1),
SKColor(colorLiteralRed: 164/255, green: 134/255, blue: 222/255, alpha: 1),
SKColor(colorLiteralRed: 131/255, green: 95/255, blue: 200/255, alpha: 1)]
let tileSize = boardWidth / 10
for col in 0..<10 {
for row in 0..<10 {
let xValue = CGFloat(col)
let yValue = CGFloat(row)
let rect = CGRect(x: tileSize * xValue, y: tileSize * yValue, width: tileSize, height: tileSize)
let tile = SKShapeNode(rect: rect)
tile.fillColor = tileColor[((row * 10) + col) % tileColor.count]
tile.strokeColor = tile.fillColor
parent.addChild(tile)
}
}
}
Nonoku - First Steps With SpriteKit
I’ve not had an excuse, up to now, to play with SpriteKit
. Initially I was going to re-write Nonoku following the same basic implementation as I did before with custom UIView
elements. Whilst walking back from lunch, I wondered if I could come up with something that wouldn’t stretch my limited artistic abilities but still look nice. Adding a little more motion to it would be good but that wouldn’t really fit with UIView
and autolayout
. So, I decided to give SpriteKit
another look.
I’d taken a glance at it before but not in any real depth and I was pretty sure I’d missed some stuff in just following tutorials.
So, first step, get an SKView
in my GameViewController
class. Easy enough, I’m using a storyboard so just change the class of the View belonging to the UIViewController
to an SKView
. It’s still a UIView
when referencing it in code so I need to remember to cast it when using it: view as! SKView
.
override func viewDidLoad() {
super.viewDidLoad()
let spriteView = view as! SKView
spriteView.showsFPS = true
spriteView.showsDrawCount = true
spriteView.showsNodeCount = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let gameScene = GameScene(size: view.bounds.size)
let spriteView = view as! SKView
spriteView.presentScene(gameScene)
}
Easy enough. I also need something to show so I included a GameScene
object. This is just a starting point so I’ll start with drawing the board the tiles will be displayed on.
The board is a rounded rectangle, divided into a 10x10 grid by dashed lines. Since I don’t expect this to change I added the board outline, and the lines, to an SKEffectNode
with shouldRasterize
set to true
. This means it will render itself to a cached bitmap so it can be re-rendered quickly, instead of re-drawing each node every frame. The number of draw calls dropped from 20, to 1, with this change. Whilst optimising upfront is normally to be avoided, this is a small change and easily reversed. More importantly, it’s something to be remembered later. Considering how multiple items can be grouped together can bring noticeable performance improvements.
Nonoku - The Rewrite
Trying to spend a little bit more time working on my own projects. Here's the first commit. A quick storyboard sketch of the all the principle screens in the app - splash screen, menu, options, level select, game. Navigation is by buttons. I didn't hook up segues so instead control navigation by instantiating my views from the storyboard and calling show
to transition between them.
Each ViewController
in the storyboard has a unique identifier that maps to a value in an enum. I’ve added a helper that includes an extension to UIViewController
to handle the crossDissolve. All I need to do is pass a valid identifier to it and I’m done. To go back, I can call dismiss
(e.g. dismiss(animated: true, completion: nil)
).
An Evening of Code: Elevator
A distraction. Took a few minutes just to implement a basic mechanic. Not sure what this is to do with anything but into the Experiments/ dir it goes.
The elevator has a collision box and, when the player touches it we can activate the 'elevator' functionality on a keypress. The system allows up and down movement so you could have multiple floors.
An Evening of Code: Generating Roads 2
Fixed a couple of bugs which was keeping the generation from truly finishing which makes increasing the frequency of the branches more feasible. I tweaked the previous generation to increase how often it branched as it approaches the centre. It's still way to messy and chaotic to be a workable solution but for something so basic and naive it actually does better than I expected.
An Evening of Code: Sierpinski Triangle
An extension of yesterday's work with L-Systems. The Sierpinski Triangle.
Firstly, I updated the implementation to draw the shape over a number of frames. This is not the end goal of this work so I'm doing it in Unity by drawing to a texture which is easy to implement but far from the most efficient ;) In this case it was best to limit the texture size to 512x512 to avoid a severe performance hit when redrawing the texture. If I needed to, I could simulate a larger texture by mapping it to multiple smaller ones but that's out of scope for the moment.
Next I updated the rules implementation to support multiple rules. Previously I used a single string and a regular expression. This no longer worked because the rules have to be applied simultaneously. Instead, I used a Dictionary to store the rules and, since the rules I need at the moment are only applied to a single character I could simply enumerate the axiom and use the character as the key to the dictionary. If there's a match I append the rule to a new string. If not I append the character.
There is one additional change that is not described in the notation - after each iteration the angle gets flipped so that it goes from 60 to -60, and back again. This is required to keep the triangle facing the same way at each iteration.
A= Step forward
B = Step forward
+ = +60 degrees
- = -60 degrees
A → B-A-B
B → A+B+A
Axiom: A
After 9 iterations the string has gone from 1 to 39,365 characters.
string Iterate(string axiom) { string newAxiom = ""; foreach (char c in axiom) { string ch = c.ToString(); string replace = null; rules.TryGetValue(ch, out replace); if (replace != null) { newAxiom += replace; } else { newAxiom += ch; } } angle = -angle; Debug.Log ("Axiom Length: " + newAxiom.Length); return newAxiom; } void FixedUpdate() { int length = axiom.Length; for (int i = 0; i < 200; i++) { if (index < axiom.Length) { char c = axiom[index]; if (c == 'F' || c == 'A' || c == 'B') { Vector2 newPoint = NewPoint(currentPoint, stepLength, angle); DrawLine (new Line(currentPoint, newPoint), colors[colIndex % 3]); colIndex++; currentPoint = newPoint; } else if (c == '-') { angle -= angleStep; } else if (c == '+') { angle += angleStep; } index++; } } texture2D.Apply(); }
An Evening of Code: Koch Snowflake
The Koch Snowflake is the one of the first, and simplest, of the fractals.
Starting with an equilateral triangle:
- Start at the first line and remove it.
- Set the step length by dividing the line length by 3.
- Set the angle to that of the line.
- Step forward.
- Rotate 60 degrees left.
- Step forward.
- Rotate 120 degrees right.
- Step forward.
- Rotate 60 degrees left.
- Step forward.
In total, we've added four new lines and increased the total length of the shape by 1/3. Repeat for the remaining lines and we have completed an iteration. Starting again on the new shape we can repeat the same steps for each of the new lines. As can be seen from the above animation, which only iterates 5 times, the complexity rapidly increases.
Technically this is not actually a Koch Snowflake as that is the shape we approach as we iterate. However, we would need to iterate an infinite number of times to generate a true Snowflake.
Iterating on a single line generates a Koch Curve. The Snowflake, starting from a triangle, is made of three curves.
The Koch Curve can be described by a Lindenmayer (L-) System. This is where we create a string and, each iteration, run a set of rules to replace characters in the string with others. Each character defines a drawing rule which we can follow to draw the shape after the iterations have completed.
F = Step Forward
+ = Rotate 60 degrees right
- = Rotate 60 degrees left
Rules
F → F-F++F-F
Starting with: F++F++F++
Our drawing instructions give us our starting triangle. Iterating, we increase the size of the string and generate more rules. Following them generate the animation above.
float stepLength = 256; string rule = "F-F++F-F"; Vector2 start = new Vector2(128, 128); protected override void Draw () { string axiom = "F++F++F++"; for (int i = 0; i < 5; i++) { axiom = Iterate(axiom); } int index = 0; Color[] colors = new Color[3]{Color.black, Color.red, Color.blue}; int length = axiom.Length; Vector2 currentPoint = start; float angle = 0; int colIndex = 0; while(index < axiom.Length) { char c = axiom[index]; if (c == 'F') { Vector2 newPoint = NewPoint(currentPoint, stepLength, angle); DrawLine (new Line(currentPoint, newPoint), colors[colIndex % 3]); colIndex++; currentPoint = newPoint; } else if (c == '-') { angle -= 60; } else if (c == '+') { angle += 60; } index++; } } string Iterate(string axiom) { Regex regex = new Regex("F"); stepLength /= 3; return regex.Replace(axiom, rule); } Vector2 NewPoint(Vector2 point, float step, float angle) { float radAngle = angle * Mathf.Deg2Rad; float x1 = (point.x + (step * Mathf.Cos(radAngle))); float y1 = (point.y + (step * Mathf.Sin(radAngle))); return new Vector2(x1, y1); }
Try modifying the above to generate new shapes. For example, replacing the '+' with '-' symbols in the starting axiom will create the equilateral triangle facing in the other direction and which starts a different pattern which will never exceed the bounds of the initial equilateral triangle.
An Evening of Code: Drawing a Line
Not hugely exciting but I did also spend a little time cleaning up an old project. Didn't end up doing as much as I thought was needed so instead I started looking at ways to start learning L-systems. To begin, I'll need a way to get them on the screen. For the first go I figured being able to draw lines to a texture would be sufficient. This is a quick and dirty implementation of Bresenham's line algorithm. I don't need it to be fast so substituted floats for the bit shifting just to make it easy. Nothing to be proud of here but it does get me what I need for tonight.
public void DrawLine(int x0, int y0, int x1, int y1, Color color) { int dy = y1 - y0; int dx = x1 - x0; float error = 0; float deltaError = 0; if (dx != 0 && dy != 0) { deltaError = Mathf.Abs((float)dy / (float)dx); } int y = y0; int x = x0; for (int i = 0; i < Mathf.Abs(dx); i++) { texture2D.SetPixel(x, y, color); error = error + deltaError; while (error >= 0.5f) { texture2D.SetPixel (x, y, color); y += Mathf.RoundToInt(Mathf.Sign(dy)); error = error - 1.0f; } x += Mathf.RoundToInt(Mathf.Sign(dx)); } }
An Evening of Code: Simplex Noise and Mesh Building
On advice from the tutorials out there I've moved to using Simplex noise. It also now creates two layers of noise so that we can have dirt on top of the stone.
Probably the biggest single change is that chunks now generate a mesh, rather than instantiating a cube for each voxel. This is (unsurprisingly) a lot faster and actually allows me to have stacks of blocks.
Creating a mesh in Unity is pretty straightforward. Specify four Vector3s and define as two triangles to form a square face. Use 6 square faces to form a cube.
// Top Face Vector3[] vertices = new Vector3[4]; vertices[0] = new Vector3 (x, y, z + 1); vertices[1] = new Vector3 (x + 1, y, z + 1); vertices[2] = new Vector3 (x + 1, y, z ); vertices[3] new Vector3 (x, y, z ); // Triangles int[] triangles = new int[6]; // Two triangles, 3 points each, 2 verts are shared triangles[0] = 0; triangles[1] = 1; triangles[2] = 2; triangles[3] = 0; triangles[4] = 2; triangles[5] = 3; mesh.Clear(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.Optimize(); mesh.RecalculateNormals(); col.sharedMesh = mesh; // Use render mesh for collisions
A simple optimisation then is to check if there is another cube adjacent. Since there is no gap we don't need to include the face on that side.
Lastly, track the block type and assign the appropriate texture.
It's lacking a lot of features that would make it a game. I might look into some basic changes like supporting just because it's straightforward. Really though, this was to serve as a refresher in how to think about 3D and procedural content. In that, it's served its purpose.
An Evening of Code: Voxels and Terrain
Because sometimes you just have to rip off Minecraft.
Naive voxel based terrain generated using Perlin noise. Nothing too special, I just wanted to get a feeling for how it works. Quite satisfying to jump about and simple to implement. Terrain is generated in chunks and has colliders. It's not particularly fast to instantiate the chunks but this was just a 'getting things on the screen' type of experiment. There are plenty of tutorials on this and I'm sure I'll have a look before going much further but doing a bit upfront was a good learning process and a nice way to get thinking about 3D again. No particular plans for this but a fun change of pace.
An Evening of Code
Wherein the author spends an evening writing a small project or feature.
My New Year's resolution to myself was to write more code and write more. As a full time developer that was hard. Motivation was thin on the ground after a day down the code mines. With last year's hellish release out of the way at the start of January things have changed.
To start, my role at work has changed and I'm not writing so much code. Now I get home, not having scratched that itch I've had for the last ten years, and I find it much easier to spend a couple of hours working on something else. I've also got a standing desk at work and sitting for an evening at home doesn't leave me feeling guilty.
So far I've focused on creating small pieces. There's few things I like more than a new project. Creating something from nothing is incredibly satisfying and not something that can be experienced in many jobs.
Anyway. I was in a rut, creatively speaking. For the New Year I decided to make a(nother) go of it. Write more code and write more in general. I don't know if I'll stick with it. Historically my interest tends to tail off over time. Having a few different projects helps. But, also, giving myself permission to work on something else if the current task doesn't interest me today. Having a space to just take one mechanic and work it through is very liberating. Sometimes just knowing that I don't have to do something is motivation to do it.
Rebellious.
An Evening of Code: Nonoku
Just took a few hours to recreate the first puzzle from my iOS game, Nonoku, in Unity. Good timing as it was almost one year ago since it launched. You can play this version in your web browser here (opens in new window).
Nonoku is a tile based game where you have to reveal tiles by working out what colour they are. When you select a revealed tile it will show you how many unrevealed tiles of that colour there are in each direction. Games play out on a 10x10 grid and there can be up to four colours in a puzzle. Some of the later ones get quite tricky. The one here is from the tutorial.
Didn't encounter any major issues in getting the core game play implemented. In fact, it went even quicker than I'd hoped to get to this point. There would be plenty more to do in order to finish it out as a game but as I'd already solved most of the problems a year or two ago it felt like coming back to a really familiar project. Even though the original version was written in Objective-C in Xcode having a solution already in my head meant I could focus on getting it to a playable state.
I nearly didn't bother with the draggable cursor. I started with just being able to select a single tile but it becomes a huge pain to play. Adding it in meant a small re-write and a little more time spent than I was planning, but not by much. It's a little glitchy still but generally reliable and much better than only being able to fill one tile at a time.
The launch trailer for the original iOS version is below and you can find it in the app store here.
An Evening of Code: Scoring
Added a basic scoring implementation to the runner so you can see how far you get and compare it to a previous run. Does not persist between sessions for now. Cleaned up a few implementation details but nothing major.
Play it here (opens new window). Let me know how far you get ;)
Evening of Code: Endless Runner
Play it here (opens new window).
A little more than an evening since I also wanted to experiment with animating a 2D sprite from pieces rather than separately drawn animation frames. A simple run loop lent itself to an Endless Runner style game. A quick jaunt to photoshop and I had a building and background. I'm no artist so I checked out Game Art Guppy and picked up the free Ninja sprite which was handily broken into separate elements already. Ideal for what I needed.
In terms of implementation, this is about as simple as it gets. A Game Object for the Ninja, Sky, and another to hold a script for loading in buildings. The building prefab is just a Sprite and will draw in 2 - 6 instances in a row before adding a gap and creating the next set. There's a small y-offset just to add a little challenge. Would be nice to separate it and add a little parallax but that wasn't the purpose of the exercise. To move the player, the buildings scroll to the left and wrap to create an endless play field.
Most of the tweaking was then on finding a good speed and jump height for the player. The main complication here was when I accidentally attached the player to the camera, instead of the other way round, and suddenly saw speeds increasing massively as the player was moving, and then the camera was moved to keep up which moved the player again.
The hierarchy looks like this. The "~Ground~" is an empty game object with an icon attached so I could visualise roughly where the ground would be whilst animating the sprite. It's laid out as a tree. 'Ninja' is the parent object for convenience. SpritePelvis acts as the anchor for the rest of the sprite. Technically it could be the parent but that felt a little confusing for naming. Everything follows from there. The arms and head attach to the torso, the legs to the pelvis. The top and bottom of the body can move independently.
This is the animation curve for the RightArmUpper sprite rotation during the run. A full run loop runs for 15 frames so for every piece I wanted to animate I positioned them were they needed to be and created key frames at the start and end so it loops seamlessly. Setting the curves to be flat at those points ensures a smooth transition (if needed). At the mid-point (not quite) I added another key frame and rotated to the correct place. This particular curve takes the right arm from back behind the character to in front and back again.
In addition to the run, I also added an idle animation just to have something to start from as a little refresher. As an extra touch, I set the animation speed to be a percentage of the player's current velocity relative to the maximum velocity so that the animation starts slow and speeds up with the movement.
Finally, the only way to fail is to miss a jump and fall. I added a check to the player's y position and if it exceeded a value I knew would cause it to drop off the page I reload the level. Instant restart.
An Evening of Code: On Patrol
Refactored the player code into a parent class so I can use it with NPCs. Added a new sprite, a recoloured version of the player to serve as the enemy. Gave it a basic left/right patrol path to confirm that the navigation works correctly.
Cleaning up the code after a mad rush of feature adding is always beneficial and, in this case, let me get a new character up and running very quickly. It also allowed me to clear out a lot of code from the player character. There's more that can be done but it's sufficient for the moment.