[Tutorial] Classic 2D Snake in C#

Hi all, recently I was googling around for some old classic games, and i ran across the old classic Snake game and thought, that would be cool to write in Unity, so I did. Then I decided to make a tutorial out of it, so that I can show others some intermediate C# techniques.

Keep in mind the focus of this is purely programming. What you’ll be doing is building the game from 4 sounds and nothing else but code.

Here is the web player: 2D Snake Game

Here is the tutorial documentation: 2D Snake Tutorial

Here are the 4 sounds used in the game: 2D Snake Game Sounds

Although I recommend building everything from the documentation, if your interested in the project files, you can get them here: 2D Snake Game Project Files

The goal is to show you how singletons work, and how you can use programming to build things at run time. The code is clean and well commented, so you shouldn’t have any issues following along, but please let me know if you do have any questions, I’ll be glad to help you as much as I can.

Hope you enjoy!

-Raiden

2 Likes

Thanks for sharing this tutorial. I’ve been trying to nail down my understanding of Singletons and what I can use them for and I believe I do have a fair understanding now. I’ve gotten through most of the tutorial and I really like your code and comment structure and in fact I’m intending to change over to your style from my current style.

Does using Singletons and dynamic instantiation improve performance versus relying on the Update function, if statements, and GameObject.Find? I always try to type as little code as possible but I’m always looking to write more efficient code.

Thank you.

Hi GTGD, thank you for your comments. I’m glad you like my style of coding. I’m constantly striving to write clean, commented and well structured code so that it makes it easy to go back to old projects and know what’s going on. :slight_smile:

Using singletons, I believe do improve performance. Things like: GameObject.Find(), FindWithTag() will give you a performance hit, so it’s important even when your not using singletons to cache objects and/or components in Start() so that Unity doesn’t do routine lookups each time you reference them (for me even if it is once).

There is only 1 drawback to using singletons, and that is as far as I know your allowed only 1 instance of the object you are accessing, so for example in the tutorial if you wanted to have multiple “Food” objects, then the Instance would only be the first stored instance of the any 1 of the multiple Food objects created in scene, therefore giving you a possible incorrect reference.

Let me know if you have any other questions, I’ll be looking at other classic’s to see what I can come up with next.

Thanks again

-Raiden

Thanks for the thorough tutorial. It’s always nice to have some new text based tutorials.

I’ve got some (slightly more ambitious) suggestions :slight_smile:

  • A classic RTS? Remaking the original Red Alert would be fun.
  • Or a hack 'n slash RPG like the original Diablo?
  • Or the original Grand Theft Auto?

Great Tutorial, really helped me understand singletons a bit better.

One thing though - the food.cs and ScreenDeath.cs sections seem to be missing from the pdf!

Otherwise, top notch, thank you!

Is the movement of the snake made on purpose that slow/hard? Haven’t got the chance to look at code to see if is something wrong.

Thank you all for your replies.

Good catch wav, I’m updating the docs, i’ll have them done soon.

The movement style does not mimic the original, it’s just a style i picked. The idea was increment the speed each time you ate a food and grew a tail, so it actually gets a little more difficult the longer you get, well as long as your holding down the key to move :).

-Raiden

Just wanted to let everyone know, the tutorial pdf has been updated to include Food.cs and ScreenDeath.cs, as well as some typo fixes.

Thanks

-Raiden

excellent article ,thank you very much for giving so detail sample.

First of all, thank you so much for making this tutorial. It has helped me tremendously in learning how to use C# and Unity to make this game.

I do have a question. A lot of the code (as you also stated in the PDF) are very similar if not, exactly the same, but just in different script files. To further your stress on good coding, wouldn’t it have been better to create an interface or a parent class with those repeated methods and then create new classes that inherit from them? This way, the Lives script will only have the “UpdateLivesText” method while it inherits all the other methods.

I’m not sure if you purposely left it out because it’s a beginner’s tutorial or Unity doesn’t like polymorphism/inheritance or whatever, so any insights as to why you decided to repeat code (which is considered against the OOP way) would be great.

Thanks,

SChan

Excellent job my friend.

Thanks so much for the great comments.

I agree SChan, repeatable code is not well designed OOP programming, but to be honest, I don’t do much coding around inheritance or polymorphism. I used some repeat code, mainly just to keep the objects methods to themselves only, and well its also a way I consider a simpler style of programming, by having similar functions written out, but keeping them within each objects class.

Somewhere down the road, I’ll step it up, and if I come up with another tutorial similar to this, I’ll add in more intermediate solutions.

@Ramsar

Probably won’t be a tutorial to that degree, but I like your ideas. :slight_smile:

Thanks again everyone.

-Raiden

Awesome. I’ll be looking forward to your tutorials. Thanks again for all that you do for everyone.

Thanks for this code - it helped me out with learning how to program games in Unity only using code. That being said there is a TON of repeat code that could be moved to methods and/or base classes. Especially with items like Lives Scores, ScreenBorder ScreenField, also with the movement of the snake. Using singletons for things like that instead of objects makes programming more difficult in the long run.

In a previous post you said: “used some repeat code, mainly just to keep the objects methods to themselves only, and well its also a way I consider a simpler style of programming, by having similar functions written out, but keeping them within each objects class.”

I agree that it makes it easier to read but not when it comes to maintaining code. Anytime you find yourself cutting and pasting code you should be asking: Could I create a base-class or a method to do this?

It would be really good for you, and future reader of this tutorial, if you were to go back and create this using good OO deign principles. Either way though thanks for this tutorial as it did help me out a lot on the Unity end of things.

I agree completely Noctys, so I have gone back through, looked at some areas you mentioned and re-programmed them in a much more logical manner.

To All: The pdf and project file links have been updated at the start of this thread

I would really be interested in everyone’s thoughts as to how I have removed duplicate code and made it more useful. I like my results, because not only have I made reusable code with the helper scripts, but it allowed me to reduce the overall number of scripts for the game. I have also introduced Method Overloading, you’ll see how it is used in the helper scripts.

One thing I would like to point out, is I am not using Inheritance in any of my code, the reason being is that there are no relationships with any of the games objects, Inheritance should be used on a “is a” basis, and all of my objects are on a “has a” basis. Example: SnakeGame is simply the container for the games items, so to me it wouldn’t make sense for SnakeGame to Inherit because all of the objects used in SnakeGame are simply what it “has”, and not what it “is”.

I hope that makes sense, but I am definitely open for suggestions or improvements. I’m not an advanced programmer, i just like to think i can halfway code :smile:

Hope everyone enjoys the updates and learns a few things.

-Raiden

1 Like

how can you make the snake starts by itself? ex you dont have to press forward, but the snake it should go by itself forward, and you just controll the left right, up down arrows…and maybe a bit smaller the design… Thanks a lot for this game, im beginner, but just asked about how can the snake go forward by itself :slight_smile: thanks a lot again man, we appreciate this help.

Hi paffy, I’m glad you like the tutorial.

We can achieve auto movement for the snake very easy and it only requires some minor changes in 1 script. Open up Snake.cs and look at lines: 19-26 for this:

// direction enum for clarification
public enum Direction
{
	UP,
	DOWN,
	LEFT,
	RIGHT
}

Now we want to create a new field of type Direction, so add this underneath the above code in your Snake.cs:

public Direction mState = Direction.LEFT

Ok, so next thing we need to do is make some changes in our UpdateSnake method, scroll down, starting at line 99, and make the following changes:

// are we moving up								
if (InputHelper.GetStandardMoveUpDirection())
{
	//yield return StartCoroutine(MoveSnake(Direction.UP));
	mState = Direction.UP;
	//Debug.Log ("We are moving UP");
}
	
// are we moving left
if (InputHelper.GetStandardMoveLeftDirection())
{
	//yield return StartCoroutine(MoveSnake(Direction.LEFT));
	mState = Direction.LEFT;
	//Debug.Log ("We are moving LEFT");
}
			
// are we moving down
if (InputHelper.GetStandardMoveDownDirection())
{
	//yield return StartCoroutine(MoveSnake(Direction.DOWN));
	mState = Direction.DOWN;
	//Debug.Log ("We are moving DOWN");
}
			
if (InputHelper.GetStandardMoveRightDirection())
{
	//yield return StartCoroutine(MoveSnake(Direction.RIGHT));
	mState = Direction.RIGHT;
	//Debug.Log ("We are moving RIGHT");
}

Notice we commented out directly moving the snake and we are simply setting the mState Direction field. Now we code in moving the snake based on Direction. Right below the above lines of code, add this:

// run the snake movement constant based on Direction
yield return StartCoroutine(MoveSnake(mState));

Save your script, and there you go, your snake should be off and running by itself, and will keep moving based on your keyboard input. If you have any issues, or questions, please let me know.

-Raiden

The article mentioned overloading, does unity support default parameters C#?

Hi Aoi cyou, could you provide some more details? You can use any type of field as a parameter (float, int, List<>, etc.). I’m not quite sure what your asking.

-Raiden

Excellent.