No I won’t be making a snake out of flour, sugar and eggs; More syntax, google queries, visual studio and obviously Unity! This is my experience in making the game Snake.
The first step in any game is getting the field set up, this was a task no more difficult than the Pong game that I made last, simply sprites given 2D Box colliders, and then they were stretched until they made a respectable field size, a note to those who plan ahead, the larger your field in a slow game like snake, the quicker your movement should allow for, otherwise it can get dull.
The most major part of snake, isn’t the movement, but the generation of the tail and making the tail follow the same movement path as the previous link. To do this I consulted a tutorial on the matter, it allowed for a very simple setup, but that was actually transmogrified (lovely word) to better suit my needs later on in the project. Originally there was a “Move()” function that was used through an “InvokeRepeating()” call, this is absolutely fine, however in order for you to increase the speed of the Snake it doesn’t work as you’d have to constantly cancel the Invoke, and start a new one, it is far better to call a “StartCoroutine()” in this case.
To explain the 2 methods above, “InvokeRepeating()” is given a method to call, in this case “Move()”, you then give it a start time e.g. ‘Start in 0.5 seconds’, and then a repeat instruction ‘and do so again every 0.25 seconds’. This is absolutely fine, however what happens is that the Snake will move and stop for those 0.25 seconds, and you can’t alter an InvokeRepeating command, as I said above, it needs to be cancelled and then re-instantiated. This is wasteful, to stop a command, and build a new one, it just didn’t seem to tally with efficiency and allow for later modifications. I was familiar due to my history of projects however with the command “yield return new WaitForSeconds”, there’s a lot going on in that command, “yield” means to stop executing this ‘Coroutine’ (something which runs alongside the rest of the program, it’s a very simple version of concurrency, to a degree), the next really most important bit is the “WaitForSeconds()” part, what happens is that the yield will tell the computer to stop executing the method and to come back after “WaitForSeconds()” has finished. This is better because if we give a variable like “snakeSpeed”, the movement of the snake can be called sooner, or later, this allows for apparently quicker or slower movement of the Snake.
Now the issue is of how to move the Snake, speed has been dealt with now. Well since we don’t want fluid motion, we want this almost stop-motion type visual style, we actually have to use “Translate()”, not “velocity”. Depending on if the player presses a certain key (say left) then the direction should be “Vector2.left” (also remember however, a Snake can’t just turn back on itself, so be sure to check that if it’s going left, it wasn’t already going right, otherwise it’ll collide with itself and die).
The snake now can move, the next issue is it’s tail and knowing where to add the tail, and how to make the tail move like the rest of the snake. Let’s say the snake has collided with a food object, well we want to destroy the food object, increase our score, make the snake faster, but also we need to make a new tail segment. This is done through the “Instantiate()” command, assign a prefab, give a location, and a rotation (usually just “Quaternion.identity”) and a new object will be made on the fly. Now comes the tricky bit however. The Snake can grow and shrink to quite an extent, and all the individual elements need to be stored collectively, this can be done through the use of a List. In my own experience Lists are pretty annoying, but then again I’ve not had much experience with them. When we instantiate a new tail object, we want to insert the tail object. Now this List section is also from the tutorial I worked through, so the tail object is instantiated at the very front of the List, this is because every movement call we either hit food, or we don’t, when we hit food, don’t update the list elements and the new tail segment will just fill in the space left. However should we hit nothing, and there is a tail to move, take the last element of the list, move that element to where the head was, then insert at the top of the List the element we just moved, then pop the duplicate we have at the end off. In this regard the tail acts like a conveyor belt made of of segments that we move, and it stops us having to update every single tail element to move forward X amount of spaces. It can seem backward, but it’s very efficient.
The above is really the majority of the interaction, the rest of the game is just tweaking game logic and structure, like adding in a score, or lives etc. I did add some things into the code here and there, for instance to stop food spawning on top of the Snake or on top of other items of food, I added a “Physics.CheckBox()” command during the instantiation. If a food item would collide with absolutely anything, then re-roll the random values that determine the X & Y coordinates of where the food will be.
Another thing that I did was I hand-coded all the menus. Now Unity has 2 systems, the UI system which is mainly inspector based and was used for the Pong C# game I made last month, however when it came to making a web-build it didn’t like the Menu set-up (I have since tried again and the menu works fine, but now the goal colliders don’t, typical). So I thought as an added challenge, why not hand code all the elements using Unity’s GUI system. Now it’s not as verbose as the UI system, there isn’t a resolution option you’ll notice, I could have perhaps added some odd system of up and down arrows and an apply button, but really I was doing this to:
A) see and feel the difference
B) hope that the GUI setup would work better in the Web-build (it doesn’t).
It took over 100 lines of code to make up the menu system, and it is a very basic one I’ll grant you, however having it all hard-coded means that updating where an element on the Screen appears is maddening annoying and slow. Admittedly with the UI setup I had last time it did mean that when you changed to certain resolutions the UI didn’t behave appropriately and might flip the scores on the screen, but that’s a challenge to face and improve each time I make these little games.
Overall I feel I made an okay mock-up of Snake, I added a new game mode that requires you to play around with speed and the randomness of which food particle will spawn a Blue one that makes you bigger and faster, or a smaller one that makes you smaller and slower (physically they should probably be the other way around but it doesn’t matter too much). The idea is that if too many particles spawn you’ll lose, and if you eat too many good food pieces you’ll get dangerously fast, but if you eat too many bad food pieces you’ll be too slow and may lose the game due to inaction. How you play is up to you really, note that they both score the same amount of points, and also with no tail, if you eat a bad food particle you will lose sadly.
This month I’ll be working with my friend Dave who you may have heard on the Podcast a couple days back. He’ll be making the game logic behind brick-breaker/breakout. I will however be focusing on making a better UI and menu-system, I know what I want to achieve, I want some win/lose screen, volume and resolution options, maybe some animation to go with, over-all just polishing the things around a game and leaving Dave to get used to game logic in Unity. Hopefully we can do it all, and be on the look-out for our next design podcast, we’re set to record this evening or tomorrow so it may be up next week.
Until then thank you very much for reading, have an awesome day, and keep on designing.