Coding Challenge #3: The Snake Game


Hello and welcome to what today will be a 15 minute coding challenge! I am going to attempt to program, from scratch, in JavaScript, the snake game. I don’t think I’ve ever done this before, perhaps I have I’ve certainly made stuff that resembles it. But if you’re not familiar with the Snake game, pause this video, Google it, play it – I think you’ll find it. Okay, so let’s just get started. I kinda want to spend some time getting to know you But I can’t because I only have fourteen minutes and thirty seconds right now. So the first thing I want to do is—and I’m in a JavaScript framework called p5js— And p5js requires a setup function and a draw function. And the first thing I’m going to do is just make a canvas. That is, I dunno, 600 by 600 pixels. And we’re going to go over here to look at this page There we go, there’s a canvas there. It’s empty. Boy, I’ve got to move faster than this. And, now we’re going to give it a background. I just want to make sure things are up and running. So, I’ve got a canvas. Maybe I need to move this over, it’s kind of under the timer but whatever, you get the point: There’s a canvas. My timer is in the way. Okay, that’s fine, it’ll get better next time. So, Uhm— So, let’s see what we want to do here. So, I want to do this with some object-oriented programming. kAnd I’m going to write something called a constructor function I have some tutorials about constructor functions if you don’t know what that is. And what I’m going to do is make an object that has an x and a y And I’m also going to keep track of an xspeed and a yspeed. Because, what I want— and let’s just make this one What I want is for this snake object to have some functions Like an update function And what happens in that update function is that x value simply changes by the xspeed value And the y value simply changes by the yspeed value Now, I want another function And I’m going to call it show Because what I want is for… Uhhh, I’m going to draw—
I know, I’m going to draw a rectangle A rectangle at this dot x, this dot y that’s, I don’t know, 10 by 10. And, I’m going to make that rectangle white. So, the point of this is, I want to have this simple object. It’s a Snake object, it has an x and a y, an xspeed and a yspeed it’s going to move around the window And its x and y move based on that x- and y-speed At the beginning of the program I can create a variable, I’m just going to name it s Maybe I would want to name it snake in a more normal day of my life But this is a— a little bit of a rushed little project here, so I’m just going to call it “var s” And I’m going to say s is a new Snake And… Uhmm… Then I’m going to say s dot update And s dot show And I might want to move this Snake object to another file, JavaScript file, at some point But I’m not going to worry about that too much. So, I’m sure we got some stuff wrong Well, you can see— Hey, look! There it is; there’s my snake. It’s moving across the window. Bye Snake! No, come back! No, go away! Okay, whatever So, now— So, that’s pretty good. Okay, what happens in the Snake game? I think if you press the up arrow it goes up, if you press the down arrow it goes down left arrow— so we can add something in p5 We can add a function that’s just sort of like a global event. called “keyPressed” And I can say I think it’s key equals UP_ARROW Oh boy, I hope that’s right. Oh, “keyCode” I think with these you want to check a built in variable in p5 called keyCode Then I want to say to my snake— I’m going to set a direction like move Zero along the x axis but negative one is up So you can see kind of this idea that I’m doing here, which is— Boy, I hope these are right. —which is this idea that the snake is going to have a new function That’s going to allow me to set its direction And if I press up, I want to set its direction to zero, negative one Down: zero, one And then, I also want to do right and left. So let me quickly copy and paste this two more times. And I need a RIGHT_ARROW and a LEFT_ARROW And, if it’s moving to the right its x is one and its y is zero. If it’s moving to the left its x is negative one and its y is zero. So, of course, this isn’t going to work now. We can run this, and I can start hitting keys, but it’s going to say “s dot dir is not a function” So, I made up this idea of a function called dir for direction But I need to actually add it to my object And you know, let’s be ambitious here Let’s take this object and let’s make a— This is a little bit dangerous what I’m doing here Let’s make a seperate file. I’m going to call it snake.js And paste it back in there. And in my index.html I am also going to add a reference to snake.js This just allows me to organize my code a little bit differently. So, I can have sketch.js that just has setup, draw, and keyPressed And, I can have snake.js which is just the Snake object Oh, my timer thing is in the way of my code a little bit! I’ve got to work on this more. Okay, that’s a little bit better. So, you can see, this is all the code—the constructor function—for making this kind of object. But, what was the point of doing that? I need to add another function called this dot dir And the point of that function was to receive two values: An x and a y And to use those two values to actually set this object’s direction. So now, if I receive an x and a y, that’s what the xspeed and yspeed become And if I go back to sketch.js, I can see here— There we go That’s what I’m doing here. Okay, I got worried that my audio stopped working. But it seems to still be working. I feel like I’m a little bit loud today, let me turn this down. I shouldn’t be doing this live in the middle of a video But, whatever. Okay, so now if I do this, we should see— Press down, press to the right, press down, press to the left You can see— now let’s do something here Let’s think about this for a second We want the snake— One thing we need to think about here and there’s lots of different ways to implement this but the canvas, we really want to think of it as a grid Because the snake is actually going to be a large rectangle and as it moves it’s going to move to the next spot in the grid, the next spot, then it moves down to the next spot I want some sort of variable to keep track of the size of this grid. I don’t know what to call it, I could call it r Let’s just call it r, let’s call it scl to stand for scale I don’t want to call it scale because scale is a built in function in p5 So, I’m going to come back over here And I’m going to add a variable, I’m going to call it scl for scale And I’m going to make it 20. And then, actually that’s— it could be— it’s a global variable And in the snake, I want to have everything based on that So, I want to move by the xspeed— xspeed and yspeed are really just the direction And then I want to draw the sname at that scale And now, if we go back to the browser And I hit refresh— woah it’s so fast So— a couple things, let’s just add some code really briefly to constrain it this dot x equals— in p5 there’s a functon called constrain Where I can say “Hey, take this value x and constrain it between zero and the width.” And, you know what, the width minus scale Because, I don’t want it to actually go off It’s a rectange drawn from the top left. And, uh, this dot y I want to constrain it to the height minus scale. How’re we doing? We’ve got seven minutes left, we’re getting somewhere. Okay, so now, we can see that, this is kind of working This is ultimately going to be my snake You know, I might not like what I’m about to do next in most cases but I think it’s going to be fine to just really reduce the framerate. Because the snake game is kind of this low-res throwback thing So, I’m just going to globally in p5 in my setup I’m just going to say frameRate, and I’m going to say ten And, now I’m going to refresh it again And, you can see, this looks sort of like what the snake game might be Okay, so, we’ve got that I can now press the arrow keys and move it around What are the things that are missing now? In the snake game random bits of food appear When a bit of food appears, the snake tries to eat that food. When the snake eats that food, it gets a little bit longer And if the snake ever runs into itself, it dies Oh boy, that’s a lot of stuff to do in six minutes Let’s get started! Okay, so the first thing I want to do it, let’s add a piece of food. So uhm, I want to— oh boy this’ll— fine. fine! It’s fine! It’s fine! No problem, no problem, no problem. I kind of want to make a food object, but we don’t have a lot of time maybe I’ll refactor that in later let’s make a uh— Let’s make it a vector. So, I’m going to use createVector which is a quick and easy way to store both an x and a y Of course, I didn’t use the vector in the snake, but whatever, it’s fine We can be a little messy for fun today createVector, and I’m going to give it a random spot… in the window. And I’m going to, in draw, I’m going to— I’m going to make my food a nice purple or pink color. I’m going to draw food dot x food dot y and I’m going to make it the same size And now we can run it, we can see there’s my food. I want to come and get my food now It’s not exactly on the grid So, I should probably deal— let’s make this correct. So, what I actually want to do in terms of its location is— I’m going to make a function called pickLocation And what that function is going to do is— First we need to know: what are the number of columns? So, it’s the width of the window divided by that scale. Then the number of rows. Which is the height of the window divided by scale And then now, I want to create a piece of food that is [in] a random column and a random row And I also want to use floor with both of these. Oh, boy. This is getting to be a very long line of code here. But— so what did I just do? I wrote a function that picks a location because I want it to have— I want it to be only one of these spots in the grid So, I have to divide— this is zero, one, two, three, four Zero, one, two So I need to divide by how big that scale is to pick on of those integers And then, I actually need its actual location I want to multiply it by that scale to expand it back out. And the floor function is everywhere because I need these things to be whole numbers for this to work well So now, you can see, this should— the food— Well, that didn’t seem to work! Are we sure I did that correctly‽ Ah, that’s right— Eh, it’s a little bit off I’m not going to worry about that right now Somebody will, uh, uhm— Somebody will correct me— correct this later. It’s close enough, I’ll fix that later because I only have four minutes left So, what I want to do now is figure out, uh I want to write a function s dot eat the food I want to do something— I expanded myself by five minutes today. Clearly that’s not enough time. I want the snake to eat the food So, uhm, in the Snake object I need to add another function called eat Technical difficulties, but I’m back! And what I’m doing right now is I’m writing the function where the snake eats the food So, I need to check if the snake is at the same location as the food. And, okay, while I was having technical difficulties I realised I’m missing something important Which is, we have this whole pickLocation function but I didn’t actually call it up here I need— the food’s location to be at this thing that I spent all the time doing to make sure it’s on the grid So, now that should solve the problem where the food isn’t perfectly aligned in the grid with the snake. But let’s go back to where we were: snake dot eat So, in the Snake object, this means, I need to write a function called eat and this function is going to receive a position, a vector, for where that food is and, I could check if they’re in exactly the same space But I’m pretty sure that if I just use the distance between where the snake actually is (x and y) to where the food is (x and y) and if I just check that that distance is less than one pixel I should probably check two pixels or three pixels, but, whatever. I’m going to say return true. In other words, I want this function to tell me whether or not the snake reached the food And, if it’s true what do I want to do with this information? So I want to come back here and say If the snake eats the food then I want to… what? Pick a new location Oh, you know what I realized? It’s not— food does not equal pickLocation This function I wrote just sets the location for that food itself So I can just call pickLocation again, it’s not returning anything Boy, my mind is getting fuzzy toward the end of these videos with only two minutes left. Let’s see, I think we’re going to be really close now. So, now we should see— I’m going to move Come on, be on the grid. Look at that, it’s right on the grid! And I can eat that piece of food and it will go somewhere new This is fun to play. I don’t have time to play this right now. I’ve got to keep moving. Okay, so what do I need to do? If it gets the food, it needs to become longer How do I keep track of a snake that has a length to it? Well I need some sort of array some sort of variable to keep track of how long is that snake So, let’s go back to the code. We’ve got to go back to the snake object. And let’s add something called this dot total, and that equals one. Because, the snake— And, you know what, I’m going to do something a little bit goofy. Which is that I’m going to keep the x and the y as the current location And the array that I’m going to store, the length of that array, is just its history. So, at first its zero as it only has its current location and the rest of it This is actually going to be useful later I just realized. And, I’m going to create another variable called tail which is going to be an array So, one thing for sure is If it eats the food, total should go up by one So, total should go up by one. Now, as it moves… I want to have a loop What goes in this loop? I definitely want to loop through that total And, actually, I want to do all of this right before… Right before it moves, oh boy. I kind of need to work this out, I only have thirty eight second but I need to work this out a little bit in my head here So, if this is the array and this is the snake’s current location Maybe what I want is to put its current location in the last spot and shift everything down, the history down So, this is where it was four moments ago Three moments ago, two moments ago, one moment ago. That’ll do. So, the first thing I need to do in this array is shift all the spots. So I really want to actually loop through total minus one And I want to say tail index i equals tail index i plus one Now, I’m sure my time has expired now, We’re going to see how long this takes I’m going to click a little window here, say okay, and it stops at one second And it’s going to say time expired And you know what— we’ll leave that there. You’ll see how long this video is and that’s how long it took. Okay, so this is going to shift everything over by one And then when I’m done, I want the very last spot Which is tail [index] total minus one to equal createVector… this dot x, this dot y So this now allows,— that’s its current location and then it can move And so now, when I’m drawing it in addition to drawing the rectangle at its current location, I need to also say Draw all the rect— draw its tail So, I want a rectangle at tail index i— And I realised i’ve made a classic JavaScript error Classic JavaScript error. I’ve got this thing called tail, which is really important But, it’s this dot tail tail is part of the snake! So everywhere I put tail, I forgot this dot tail This happens to me all the time This is like, the bane of my existence Oh, and this dot total also! Oh, boy So, I think I probably— I’m looking around, this dot tail this dot tail, this dot tail, this dot tail this dot total, this dot total I should just have a big blinking sign in front of me that just says “this dot” “this dot” “this dot” “this dot” Okay, let’s run this and see if this works now. Hit refresh, I don’t know; I’m sure I missed something. Come on, eat that food, argh! total is not defined on line 12 So, there’s a place that I forgot it line 12 this dot total plus plus let’s hope we didn’t miss— Okay, I’ve got to— I’m trying to look at the camera to make eye contact with you And, oh look at that, the snake is— Oh! Cannot read property x of undefined! snake.js:42 Okay, it extended by one But how come when it extended by two it didn’t work? Line 42… This seems totally reasonable to me So what happened? This show is always happening… Okay, let’s think about what order all this stuff is happening Maybe that’s the issue? Oh boy, we’ve really got— This video is going to be a little bit long… because I’m going to debug this now Back again Little bit of splicing and dicing here but I’m going from where I— I’m going from where I want to add the tail of the snake So when the snake eats the food, the total goes up. total is keeping track of how many bits of history of the snake’s length do we have left? So, I know what I want to do is: Any time this dot total does not— Okay, so one thing I always need to do, is I always need to shift and I actually have a diagram I’m just going to add this in here What I need to do here is— I always need to shift… … the tail down I need to shift everything down in the history So, I’m going to say: this dot tail index i equals this dot tail index i plus one This is going to shift the spots down as the snake moves All of its spots shift down so I can get the new spot in the end of the array Right? Because, what I want, is to then say: this dot tail… … index total minus one… …equals… … the new location So, I have this array that always shifts down And I get— I have this array that always shifts everything back and then the new spot goes in the end So, let me explain to you what I mean I have this diagram from my Technical Difficulty part But, err, I’m over here now Argggh Boy, everything is falling apart today Come on over here, button. So, in other words, I have this array Let’s just imagine for a second that this is the history of where the snake has been. So, the new location is going to go in the end and all the other spots will shift down, and the oldest location will be deleted So, this is what I’m doing here Now, if however— The, uhm— If, however, the snake has eaten a piece of food It should actually get bigger and the new location should go over here So, if you think about this, what I’m saying is there’s two different possibilities: If this dot total equals this dot tail dot length, meaning that no food has been eaten, so the total is the same as the existing array length then just shift everything over And give me my last spot. Otherwise, only put the new spot in and I don’t need to shift So, in that sense this can go over here So, the shifting, this is a small tiny nuance but the shifting only happens— The shifting only happens if we haven’t eaten any food because the new spot has to go in here, and everything has to get shifted over If we’ve eaten food, we just add a new spot on And now— oops, I’m tripping over. Now, we should be able to run this and see— Ah, but you know what? I need to add to draw— I need to also— In show— In the show function, I need to also draw a rectangle where… … where everything is Oh, I’m losing steam here today. Uhm, okay, so I need to draw a rectangle at: this dot tail index i dot x and this dot tail index i dot y All these will be white. And, I was mucking around with this, let’s make this 20 Refresh, oops! total is not defined! Ah, I forgot the “this dot” Err, and somewhere here… Erm, under line thirty this dot total – classic JavaScript error! Always forgetting the “this dot” Okay, here we go, now run this again. Come on, I’m going to eat this piece of food and my snake is going to be two rectangles long I’m going to eat another piece of food It’s three rectangles long! Another piece of food… It’s four rectangles long! Guess what now Now we need to figure out: When should the snake die? Now, I should do something if it hits the edge But, I’ll add that in another day What I’m going to do right now is if the snake hits part of its body then it’s dead So, this is something we can really just write a new function for this dot death I don’t like the word death it seems so— Ah well, fine, we’ll just use it as that’s what it is. So, what I need to do is: Loop through every spot in the tail And remember the tail does not include its actual head Err this dot this dot tail dot length And, what I’m going to check and see is: I err— I’m going to look at each position which is this dot tail index i and let’s look at the distance Again, just like how we checked if it ate the food Let’s look at the distance between the x location and that particular spot on the tail If [the] distance is less than one Like if it’s really gotten there Really you want to check if they’re exactly equal but I’m just— If it’s less than one then: I’m going to set toal back equal to zero And this.tail back equal to nothing So, we’re just going to have it go back to nothing So, this is now checking If it’s— if— If its front location has ever— right? If it’s— If whatever is in the new spot is connected with any of these And we need to make sure we do this before we shift anything in because we don’t want its current spot to have actually shifted into the array So, now we should be able to go back to sketch and I should be able to add right up here After update— let’s do this— Yeah, I think— I don’t think it should matter but I’m going to check it before I update it That makes sense, right? Uh, actually, do you know what I think I need to do? Is, I need to check it— No no no no no, this is no good This is actually— We’ve got to be thoughtful about this I actually want to check it when? I want to check it right here the moment x moves to the next spot Which is fine, because I want to check it— It does this after and then I check and then I do all this shifting So, that should actually be fine So we’re just going to say “s dot death” right here And we’re going to run this Now, I’ve got to get it to be a little bit long So I have to play this for a little bit and get good at it Uh-oh. Oh! Big problem! I can’t hit the edge, hitting the edge is very bad Let’s start over and let’s just— I’m going to deal with the edges later, let’s just not hit the edge Okay, I think once I’m four—length four— I can probably Ahh, go backwards Oh, no no no, I just died there Because I went backwards Okay everybody, hold on Let’s— Let’s— Let’s have a little bit of a— Let’s actually— Let’s go back to this. Let’s console log “Starting over” There’s a really easy way to test this: Which is just to be able to go backwards, which I should probably protect against. So let’s be— Let’s be a length one… two.. Yeah, you can see I started over because I just went backwards So, we should probably not allow the snake to ever be able to go backwards So I’m going to add something in right now which is— I’m just going to add mousePressed And I’m going to say s dot— I’m going to sort of cheat By just saying, every time I press the mouse I’m going to add as if I’m eating food so we can really test to make sure this is working So, I’m just adding a lot of spots An now, you can see That works So, if I ever intersect one of my existing spots I have to start over So, there’s— I’m going to end this now because we kind of have the complete game basically We have the snake object. It has a few bits of functionality, right? It can check to see if it found a piece of food by checking the distance between it and the food If it is, it increases its size We can move it. Which means it keeps track of its history shifting everything down It moves to the next spot and its keeping itself on the screen and it’s also now checking to see if it’s intersecting with any of its previous spots So, what’s missing, that I will add later after the fact when you look at the code for this, Is it’s missing: Number 1 is it shouldn’t be allowed to go backwards. Maybe it should be, but you know, you as the user of the game should just know not to do that. And also, I need to deal with the edges. So I should also add something in this death function that if you hit an edge, maybe, of the window You also— You also, kind of, lose your life so to speak Which actually, I just realized is happening because of this constrain Because constrain keeps it in the same place as it was previously Which means it will then figure out that is— That it’s intersecting where it was previously and call starting over So that’s actually working. Okay, this— Uhm— So, uh— And, scene!

100 thoughts on “Coding Challenge #3: The Snake Game

  1. If you want to know what happened during "technical difficulties"! https://youtu.be/yUO2bWfBgN8?t=1253

  2. it's incredible how this guy films something in 2016 and make it look like 1998. awesome content tho. 😀

  3. I was wondering, since using global variables is kind of meh, how can I avoid it while still using keyPressed() function. How can I get to the snake without global variable. Is there any way ? Thanks!

  4. Please can you code the schelling's segregation model using java please!!!! You will save my life 🙁 Help!!!

  5. i don't see you are calling functions, only defining them.. sorry im noob. can you explain how?
    actually i had tons of questions in the first 60 seconds. but impossibe to ask all of them lol.

  6. Jesus you're amazing Im a literal newbie to programing and I understand what you're talking + you make everything look so easy

  7. I'm having a problem with installing p5.js, it wont load error: Expected identifier, string or number
    Code: 800A0404

  8. I've taken my time to learn python and I really enjoy it but java looks great as well should I learn java next?

  9. How do you get your rectangle if you are not even calling this shit? How do you get chrome execute it instead of just view the file? All I see is some code but I have no idea how all this is even working.
    And cut this positive crap, I wanted to see the JS expert and not a fucking clown, laughing at your own geeky jokes is something you dont want to do if you want to have any charisma at all.

  10. var s;

    function setup() {
    createCanvas(400, 400);

    s = new Snake()
    }

    function draw() {
    background(51);
    s.update()
    s.show()
    }

    function Snake() {
    this.x = 0;
    this.y = 0;
    this.xspeed = 1;
    this.yspeed = 0;

    this.update = function() {
    this.x = this.x + this.xspeed;
    this.y = this.y + this.ypseed;
    }

    this.show = function() {
    rect(this.x, this.y, 10, 10)
    fill(255)
    }
    }

    can u find any mistake?

  11. How do I make the snake not go into itself? I have it set up like this: https://gyazo.com/7445ec3e5776b23f1442a4553087e184 but when the user presses both the up and the right arrow, it kills the snake because it goes to the opposite direction.

  12. "we need something to call the size of this grid, I dunno what to call it.. what, R.
    R? R.. let's call it R.

    What we want to do is call it SCL"

  13. hello!! yo, I love your videos so much. i can watch the whole episoda again and again. I also love the video about the double pendulum. Thank you for all of this

  14. function keyPressed() { is not working for me, even if i copy-paste it from the p5js website…
    Can someone help me please?

  15. Hey! So about 2:45 in I saw that in my code s.update(); was getting an error. It said that s.update is not a function?

  16. 📲*00212.645.75.23.01* *Whatapps*📲
    ســمــعــت🧏‍♂️ كـثـيـر مـن الــشــبــاب يـبـحـثـون عــن طـريـقـة فـعـالـة✅ لـتـكـبـيـر الـقـضـيـب
    وأنــا أبـشـركـم😉 أنــي حـصـلـت عـلـى الــطــريــقــة الأصــح👍 والــمــنــاســبــة👍 وهــتــشــكــرنــي بــعــديــهــا
    تــواصــل مـعـي وأنــا بـشـرح لــك سـر الـوصـفـة الـواتـسـاب *00212645752301*📲تحدي

  17. Man, 3rd time watching this. Watched it just before I started doing JS, when I just started learning, and now. I finally understand what's happening hahaha

  18. var subscribe = new youtube.Subscriber;
    var like = youtube.video.like();
    var hitBell = youtube.video.bellHit();

    function theGoodGood(user => {
    user.subscribe()
    user.like()
    user.hitBell()
    });

    function load() {
    this.user(theGoodGood)
    }

  19. There is a collaboration between many YouTubers called "Teem Trees" who want to plant 20 million trees around the world by 2020, they need your help, You can give them money. If you give a dollar, you will help them plant a tree …

    If you would like to make a donation, visit this site: https://teamtrees.org/

  20. Hey Man!
    I have a problem with making may tail follow the "head" it seems like my snake only moves as 1 line (horizontal/vertical), and I can't seem to find the problem.

  21. Thanks so much for doing this video. I was just about to give up on javascript until I saw p5 here. It's the best tool I've used in a while, not to mention it's online. I don't have a computer so I rely on web-based things. All I've gotta do is find a java version of this and I'll be all set. I wish processing ran online Lol

  22. Ok so I downloaded Sublime Text and coded the 3 pages that you did and ran it but nothing happened.. Is there something else I am supposed to have downloaded like a pack or something to do this?

  23. you are so great!!! so funny, brilliant, like a brain stimulator haha. i’m new to code, addicted to learning and using it, so i installed git last week! this is how i discovered your channel with the video series « git for poets », a true masterpiece! thank youuuuu haha! i’m a fan now! and you dont know it but you are my teacher from now on. you cover so many different things, just great! and sooooo fun to watch! 🤙🏾❤️

  24. CAFFEINE

    Love your content BTW.

    Do you happen to have a Nintendo Switch by chance? If so may I suggest looking at FUZE? It's pretty amazing and would give you another platform for more tutorials/content. It uses a modern form of BASIC and allows you to develop/code programs and games directly on the Nintendo Switch! Both 2D and 3D! Please check it out! 🙏🏻

  25. Great video. I tried to speed code Snake. Please check it out and leave a comment. https://www.youtube.com/watch?v=kLHgmw81FtM

  26. i just made a simple C++/OpenGL game. it is a 3D arcade game like infamous Space Invaders & Snake Games all togather in one game. it is a simple high velocity and hell-bullets game- like. check out my latest game video in my channel.

  27. Hello, I started learning programming some days ago and I wonder how long will it take me to learn to make stuff like this if I learn 3 hours a day, every day. And also what's the best language to start with? Because I started with python. Also I am a kid so I am not that smart.

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2019 Explore Mellieha. All rights reserved.