Baby Steps

Unless someone has amazing godlike talent, or are the product of super secret government experiments, of which I count myself as being in neither, it is safe to assume no one can immediately become an expert on things. Now I'm not going to say I'm new to programming, but to make games, like anything takes a lot of practice.

Therefore, with my amateur programming knowledge, questionable art skills and dubious musical capabilities, I am going to attempt for my first 'project' to build something simple. Really simple. Something I shouldn't be able to feasibly mess up beyond all recognition.

So I'll start with good old Tic Tac Toe, aka Noughts and Crosses. And for extra kicks, try to get it working as a simple App on Android (there's a legitimate reason for that!).
Disclaimer: This is written as a semi-tutorial, documenting my own failures and success at getting this working. Feel free to follow along, but don't expect a miracle, and don't expect to learn anything particularly new, or interesting. And certainly do not take this as a standard by which you should go about doing anything. Do not. Donot. Donut.


Game Plan

Obviously before I do any programming at all, I should take a brief look as to how the game will work, so I have a decent enough idea of what I am actually even doing.

Game starts.
Player 1 and player 2 alternate between placing Os and Xs on a 3x3 grid.
If three Os or Xs  are in a straight line (diagonals included), then the corresponding player wins.
After a win, the game restarts, clearing the grid.

The rules look about right, even if they aren't as abstract as they could be, but that doesn't matter too badly. Alright then, time to hit Unity3D. For those who are not aware, Unity3D is a really cool engine that's picking up pace as a great tool for indie game creation, a bit like GameMaker: Studio except 3D and uses C#/Javascript rather than GML. Plus, you can build that game in unity then port it to loads of platforms, which is another reason why it's pretty popular. And as you probably guessed, it does phones too, so why not try?

TacTicToe.unity


The game board was simple enough, just creating some objects and scaling them correctly. Thing is, it looks a bit lacking in any kind of definitions. I think it needs more colour.



There, some tasteful colours and an extra set of lines for the border. This is done by creating a new material in the assets window and dragging it onto a mesh, for the curious. 
NOTE: I hid the settings for choosing the material colours whilst messing about with it. To show them again click on the light bar that contains the material preview in the inspector, that will toggle it shown again. Also stick to diffuse as a shader for now, no need to go overboard.
Next I'll need some objects to represent noughts and crosses, but as Unity prefabs rather than objects on scene (since I'm going to be spawning them). I think the best way to implement these is to have a block with various meshes parented to it to form the nought and cross shapes, then create a prefab out of the blocks (with the shapes linked as children).
NOTE 1: Dragging an object1 onto object2 in the Hierarchy window makes object1 a child of object2.
NOTE 2: Dragging the object to the assets window makes it a prefab.


Not too pretty but that'll do for asset creation for now. Time to move onto the coding.

Code Structure

This should be simple enough:
  1. Player x selects a space on the grid to place their block.
  2. Game checks to make sure that space is empty.
  3. Game places block on that space, updates the grid in code.
  4. Game checks if a 3-in-a-row has occurred. If true, step 5, else step 6.
  5. Game stops, congratulates Player x on a Win.
  6. Game checks if all spaces are filled, in which case it is a Draw.
  7. Otherwise, Game swaps control to Player y, and moves back to step 1 with x and y reversed.
This will all be controlled by the GameController, which is an effectively empty GameObject that only exists to manage scripts. For good measure I'll also tag it GameController since it's there. Also I'll need a couple of variables, covering some basics such as who's turn it is and to track the board.

For step 1, a handy event already exists that uses an objects collision. Since GameController has no collision this is no good. A "brilliant" solution is to do away with the GameController object, and use something else instead, preferably one that has collision. Now the problem here is to work out how I am going to identify which space the player has chosen. Tracking a mouse in a 3D space is inherently awkward anyway, and since OnMouseDown() uses the collision model, a good alternative would be to set up trigger boxes for each space on the game board. This also has the added advantage of giving me some preset positions to spawn the noughts and crosses onto.


The concept should be simple enough - By configuring each box to an equivalent position on the grid using the editor, I can use the boxes call methods from the main TacTicToe class using the positional parameters.

using UnityEngine;
using System.Collections;

public class TacTicToe : MonoBehaviour {
    private static bool turn;
    private static int[,] grid;

// Use this for initialization
void Start () {
        //true is noughts, false is crosses
        turn = true;
        //the grid is going to be 3x3
        grid = new int[3, 3];
}

// Update is called once per frame
void Update () {

}

    public static void OnGridSelected(int x, int y)
    {
        //code geht hier ja!
    }
}

public class GridBox : MonoBehaviour {
    public int gridX;
    public int gridY;

    void OnMouseDown()
    {
        Debug.Log("I've been clicked!");
        TacTicToe.OnGridSelected(gridX, gridY);
    }
}


NOTE: Debug.Log(string) lets you send debug messages to the console of the Unity Editor when you run the game.

The beauty of Unity's editor is that it lets me set the variables of gridX and gridY as I see fit, so I could fool around and have the centre box have an assigned grid coordinate of (0, 0) for some cheap laughs amongst the confusion of potential playtesters.

From here on I can insert bits of code into the OnGridSelected(x, y) method. First, to check if the space is empty and exit the code early if its already done:

if (grid[x, y] != 0)
{
    //not empty, so ignore it.
    return;
}

Then to actually putting the block down. Unity can instantiate a new object from an original copy, which in my case I'll be using my prefabs for.

Here I come to across the problem, which is using static or not. Because unity can handle all kinds of crazy things, if you set something as a public non-static variable then you can set the reference for it inside the unity editor as demonstrated with the gridX gridY thing. The problem itself is that if I want to be able to set my Nought and Cross prefabs to the GameController's variables (so it can instantiate from them), then it needs to be non static. However, as you can see above, my OnGridSelected is a static method, so I can't reference non-static things in it. If you are still confused as I can sometimes be, read up on static classes.

Anyway, thanks to some handy support over at Unity3D's answer archives, I can alter the code of the GridBox class so it references a nonspecified TacTicToe script which I can set in the editor. From here on I can just connect up the scripts to the game board (which contains a TacTicToe script) through the editor, and set the OnGridSelected method to a non static!



Anyway, that's enough writing for one evening. I'll do the rest in due course (slowly, and tediously).

NEXT

No comments:

Post a Comment