Coding Challenge #115: Snake Game Redux

Coding Challenge #115: Snake Game Redux

(train horn) – Happy back to school. It is August 31st, school
for me starts next week. On The Coding Train, I am going to attempt to do a classic again. I am going to attempt
to do a coding challenge and pick the Snake Game. And yes, I have done this before, but I’m going to do this
in order to celebrate something that was announced today, the P5JS web editor. (audience cheering sound effect) So the P5JS official web editor is out and I’m going to try… The nice thing about
this is when I code this, at the end of it, stop
with the sound effects, at the end of this, you will
be able to just go directly to this URL, which I will
include in the video description, and hit duplicate. You’ll have to make an
account for the web editor, hit duplicate and then
make your own version of it from my code and share that with me. So I will include all about how to do that in the video description and I’m
going to give myself about… Oh, my watch isn’t on. There’s not timer but
I actually have to go, I have to be home very soon
so I’m going to give myself about 20 minutes, which of
course, this is going to take longer than that but
let’s see how it goes. All right so however long this video is, is however long it takes. Hopefully, there will be no edits. Everyone once in a while, you know, there just has to be an edit ’cause the whole system crashes. I better get coding. (deep exhale) Snake game. Have you ever played the Snake Game? The idea of the snake game is there is a canvas, you are a dot, like a little
square on that canvas. Another dot, or another
little square, appears, which is a piece of food. You want to move, you can only move to the
right, up or down, along, grab that piece of food. Once you grab that piece of food, a new piece of food appears somewhere else and you get a little more on your tail. You get another piece of your body and you get the next piece
of food and it gets longer and it gets longer and
anytime you hit the edge, if you run into one of the edges, you die, the game’s over. Or if you hit another part of your body, and it becomes much harder as your body gets longer and longer. That’s the snake game, that’s
what I’m going to code. So in order to do this, I’m going to use object
oriented programming. In my previous version
of the coding challenge, I used like this
constructor function thing and now we have ES6 classes. I want like a happy sound (horn blares). So one thing I’m going to do
is I’m going to show you… Andby the way, if you
want to know all about the P5JS web editor, check
a link to a Medium article that is in the video’s description and a whole bunch of videos
from the Processing Foundation. THere’s a nice video
with Cassie Tarakajian, who created the editor,
describing all of it’s features. But one feature is that I can go over here and find this little
(tongue clicks) thing, this little tick, less
than, greater than sign. Whatever it is, and I can say, “Add file.” And I’m going to add a file and
I’m going to call it, “Snake.js” and now, I have a file called, “Snake.js” where I can create the snake class. Now, if you’ve never done object oriented programming before, the idea is that this is a teth-link for this snake object that
I’m going to make in my code. And it has a constructor function. I will refer you to my tutorials about broken object programming ES6 classes. Now… But in order for… I need to actually go into index.html so that the page, when I run the code, is actually using both
sketch.js and snake.js. So that’s there. So now I have sketch.js,
which is just a… Oh, and I need to see this. A 400 by 400 canvas. And snake.js, which has nothing in it. But what I’m going to do is I’m
going to say, let snake, and end setup, set-up being where the code starts in a P5JS sketch. Snake equals new snake. So I’ve made a new snake
and what do I want to do? And I want to update the
snake’s location every frame and I want it to display it. So the idea here is I
want to say Snake.update and I want to say I’ll use show as meaning
show yourself, display. Hmm, what is this? Snake.update is not a function. Oh come on, I have to
write the code for it? Yes, I have to write the code for it. So if I’m going to write
a function called update, that means I have to put a
function in the snake class called update and then I have to put
a function called show. Ta-da, I’m done. Coding challenge complete,
snake game not all. So this is like the skeleton of the code but I actually need to put stuff in here and I’m going to hit shift
tab to tidy up the notation. Okay, what do I need? So I’m going to do
something a little weird. I know that what I need is an array because even though the snake’s position, you could think of as like
a single X,Y location, I botched this the last time I did this. Really, what I want is an array because I want to keep track of a
list of all of its locations. And maybe the first element
and probably, more easily, the last element of the array. When with only one thing, is it’s the sort of head of the snake, the front part of the snake. So I’m going to do that. I’m going to say this, I’m going to call
it a body, is an array and then I’m going to
say, this.body index zero. I’m going to put one
thing is createVector. Now, createVector is a function in P5 that creates a vector object
and that vector object has an X and a Y. So I’m going to create it at zero, zero. And then in update, I’m going to say this.body index zero.x plus equal this.xspeed I’ll call it xspeed or
xdirection or something and this.body.Y, index zero.y
equals this.ydirection. Oh, this is so ugly but it’s the way I’m doing it, right? Instead of having… It’s a little weird like
really, it’s just one thing that’s moving around, I
just have an X and a Y. Instead, I have a body index zero X and a body index zero Y because later, imma get to add more pieces to the body. So if I run this, what’s
this.xdirection, this.ydirection? Doesn’t even exist so those
are going to be variables that tell me is the snake
moving to the right or left? Is the snake moving up and down? So those values, this.xdir will start them at zero. (deep exhale) So there’s zero and so… And then show. I am going to do something,
I am going to say… What do I want to do? Showing the snake is drawing a rectangle. I’m going to do something
a little bit weird. So I’m going to draw… Again, eventually, this
is going to become a loop ’cause I’m going to be
drawing all the pieces of it. But let’s just start with
putting in the X and a Y and I’m just going to say,
I’m going to make it 10. This is going to be a little weird. Actually, 10 by 10, the rectangle, and I’m sorry that you can’t see all the code, let me… I’m not used to doing
challenges with the web editor so let’s see if I can make
this a little bit wider. There we go. So okay rectangle and then say fill zero, just to make it black and look at that. Already, I see that… I better save this. Oh saved a minute ago. It’s auto saving, that’s wonderful. There it is right there. Let me make X direction one. (groans) Oops, two equals by accident. Look, it’s moving now, right? Because the ID in update
the body’s, head’s X location is increasing, right? If I made this 100, it’s
moving really, really fast. 10, it’s moving pretty fast. If I change this back to
zero and make this one, it’s moving down. I could do all sorts of
weird things, make that five. But that’s not, no
longer in the snake game. The snake game, by definition, I can only move
horizontally or vertically. So I’m going to start these at zero and then I’m also, just right now, I’m going to change this to one. I’m going to explain, I’m
going to do this in a funny way that I think might work well. It’s a tiny little dot, a one
pixel dot, that rectangle. I am going to now, in
sketch, I am going to have the keyboard be the controls. So I’m going to say, keyPressed. Oh, I forgot how to do this already. (chuckles) So if key equals up, what is it in P5? Basically keyPressed is an event that whenever I press a
key, this function happens, that I can check what key did I press. But I totally can never remember how to write this function. So let’s try and look at the P5 reference. Somebody maybe in the chat will tell me. Let’s look at keyPressed. If value equals zero, no. If keyCode equals left arrow. This is good, this is what I want. It’s the keyCode. So key is for which character I press but
if I’m using the arrows, I need to use left arrow erase. Let me actually just grab this and I’m going to say if keyCode, and I know I can use
this switch statement. I’m just not going to right now, okay? (sniffles) Please don’t, don’t at me. That’s what I’m supposed to say. Somebody taught me that
who’s younger than me. (chuckles) keyCode equals left arrow, keyCode equals right arrow, doing a terrible job at paste, paste, down arrow, up arrow, ah. Don’t hide. Auto format, there we go. Okay. So now what I want to do is
if it’s the left arrow, then snake.setdirection this is the way I did
it before, I remember. Left is negative one to the… Negative one along the X and zero along the Y. So I’m going to write a
function that’s like saying set the direction. So this is for left, this is for right, this is for… (moans) I’m so freaked out. Down, I’m remaking this video, why? This is for up, negative one. Okay, tidy code. So I think this is the right idea. Depending on which key I press, move the snake in that direction. So now, I can say… I can write this function, setDirection and I’m getting an X and a Y and I’m just sayinf
this.xdirection equals X, and this.ydirection equals Y. So whatever comes into the
function sets those things. The people, I can see the chat over there, “Please do a switch statement.” No, duplicate my code and change
it and make it better, use a switch statement. Okay. So now, I’m going to do
this, lets zoom in, here. Let’s see if this works. Come on, no, I have to click ’em. Yes! Down, look at this. So now it’s working, right? So I’m pressing all the keys
and I’m moving it around. Perfect. Now, I need to deal with something. I don’t want to have to
zoom in, it’s so tiny. So ultimately, there’s an issue here. I want to think about the
snake in units of one. Here’s my snake, it moves one pixel over, it moves one pixel over,
it moves one pixel over. But I have a canvas that’s 400 by 400 and I probably want to draw
is as a 10 by 10 thing. So I want to have a variable, I’m going to have a variable,
I’m going to call it R-E-Z, short for resolution. Can you see that? And I’m just going to make that 10. So that variable, and
actually, to be honest, I could just use, you
know what I could do? I could just use the scale function. I’m just going to use the scale. So I was going to use math and I was going to always
multiply it’s X location by that resolution. And use the resolution for the width but the truth of the matter
is P5 has a scale function so I’m going to say
let resolution equal 10 and then in the draw
function, I could just say scale by resolution. And what that’s going
to go, and notice like see, look at that, I
can change this to 50, I can make this 10, I can make this 100. It’s just scaling it up and
if I move this to the… And so now, if I make this 10 and I move to the right, it’s actually moving
every 10 pixels, also, ’cause when it changes by one, it moves 10 and I could… What I might want to do is, you know, normally, I want the
animation to go really fast but imma change the frame rate to five, just to slow it down so we can what’s… What’s a little tricky here,
when using the P5 web editor is I need to click over here to give this preview page focus so that it gets the key commands. So now you can see it moving over. And this, you know, this can… The frame rate, typically, I
don’t want to slow the frame rate of the the animation down. But this is a way I can control
the speed of the sketch. So this is what I’m going to do, okay. (deep exhale) So now, I need… Ah, okay. So I need to have a food, a piece of food. So I’m going to make the piece of food just a vector. At some random… I could make a food class
but I think that’s overkill. I’m going to make it a… Ah, okay. So here’s, now, a tricky thing. I want the food… Okay, let’s say my sketch
is 400 by 400 and really… So really, my world is 40 by 40 but I scaled it up by 10. So I need a variable to keep track of actual
dimensions of the world. So I’m going to say… I’m going to use W, well, I don’t know. I’m starting to think of columns or… I’m going to say W. Equal… I’m going to actually just
put let W and let H, here. So I’m going to say W equals
floor width divided by resolution. So what is this? Width divided by resolution
is 400 divided by 10, which is 40. And the reason why I’m using floor there, is just in case my math is off, I want W to be an integer, a whole number, that will take off the decimal place. H equals floor height. And of course, it’s a square, so I don’t really need to
add the two separate values but your window might not be a square. There, okay. So… So now that I have that, why was I doing this again (chuckles)? Oh, the food. Because now, I want to get an X position and guess what? I remember this from before. I’m going to write a function, food location, foodLocation. And what happens in this function is I pick an X, which is floor random W and a Y. Floor… So I need a spot, random H, right? I need to find a random spot for the food and set that there. And then in draw, I’m
going to make the food a red, I might be standing a
little in front of the code but hopefully this is okay. And I’m going to say rectangle food.x food.y one, one. So you know, I guess I could
make it a point or something but it’s just everything is of unit one scaled up. Okay, can I… Oh and I need to actually call at the beginning, foodLocation. And Y, oh, it’s not… You know what I need to do here? Is I need to say noStroke. That stroke is getting
scaled in a strange way so this is actually 10 by 10 pixels. It was much bigger because with a stroke there, that’s getting scaled as well. So now we can see… Woops. If I click over here, we
can see and eventually… Come on, get that piece of food. Okay so now, good, so this is working. Ah, the snake game is working. Oh, this is good. This is much better than I did before. (chuckles) Helps to do this a second time even though that was a couple years ago. Let’s make this 20 just because I want to
be able to see it better. Okay so that’s good. Let me just make sure things
are lining up, excellent. So now, I need a test. I’m going to say food. So that means I need a function and let’s put that… I don’t know if the order matters so much. I’m going to put this here. And I’m going to say, eat food, I’m just going to make
an argument called position so basically, the food
is getting passed in here and I’m eating the food
if now, this is a really, probably a bad idea
because you never know, in java script, if you’ve
really got the number like three or if by
accident, you have the number 3.00000001 (laughs). But I’m going to test, in theory, if the X, Y of the head of the snake is the same as the X,
Y of a piece of food. If they’re equal, I should be eating food so let’s… Let’s just see if that works. So I’m going to say if… Well first, let X equal… Let’s just put this in
a separate variable. Let Y equal this. I’m going to get that head
of the snake location. If x equals pos.x and y equals pos.y, then return true and also say console… Console, I’m going to say print. I could say console log print food eaten. Okay so let’s see if this works. It’s a little bit dangerous,
a little treacherous and I’m going to say
return false, otherwise. And then, in the sketch,
I’m going to say, if… If, I’m going to have
this return something, if you eat the food, then you just need a
new foodLocation, right? So immediately, you should
pick a new random location. Okay, let’s try this. (scoffs) I missed it. Ah, I can’t get it. Oh, so that’s working. All right so I think all
my flooring of the numbers, you know, maybe I need
to have some better… This seems to be fine. So I’m going to live with that. I’m happy with it. Okay so now, we are so close. What do I need to do? This is going remarkably well. (knocking) That’s a sure sign for
something to go wrong. I’m going to say this.grow. If I eat the food, I
want the snake to grow. If I’m calling a function
that I intend to be part of the snake object,
within the snake class, I need to reference it
by saying this.grow. So that means I need to
write another function, grow. And what that means is I
want to expand the array. (deep inhale) Okay, okay, ooh, this is
the tricky part (groans). This is where everything
went wrong before. I’m not even looking at that chat, there’s a chat going on, I’m sure everyone’s screaming at me. (chuckles) I’m going to add another variable, this.len for length, length of the snake and it starts as one. So if that, at that a minimum,
I know when I want to grow, I want length to go up by one. I want the length to increase and I need to add
something onto the array. Add something to the end, add something to the beginning, this is unclear to me. So first of all, let’s try… So let’s just try saying this.body…. So first, let me get the last… I’m thinking about this. You know what? I think this is going to be… I think, actually, this
is simpler than I think. Let’s just try saying
this.body.push createVector. So I’m just going to push
a blank vector into it. I know I need something else in the array so let me just… And push it so that it adds
to the end of the array, maybe I want to put it at the beginning. I’ll figure that out in a second but I’m just going to push
at the end of the array. And actually, now, I’m
realizing the flaw in that but that’s okay. Yeah so actually, so pushing… I could put it in the beginning and that would actually work, I think. But okay, we’re going to figure this out. I’m trying to think it through so it’s easier to think
it through, just code it. So what I want to do
now, this whole thing… So first of all, what this mean is anytime I want to draw the snake, I
don’t actually want to draw… I don’t want to draw just a single rectangle, I want to draw all the rectangles. So I’m going to say… I could use like a for
of loop or something but I’m just going to say, I’m just going to use a
regular, old fashioned this.forloop, this.body.length, I plus plus and then this loop will go around here. Uh-oh, oh no, oh no. (buzzer buzzes) Oh no! I’ve killed the editor. Let’s see when it last auto submit. I’m going to quickly click
off this auto refresh. And where did I last leave off? (yells) That’s not so bad. So the last time it auto saved was here and I am going to… I’m going to retype my loop more carefully without having auto refresh on. I is less than this.body.length, I have to more this, now,
back all the way over here. I plus plus and I’m going to auto format that and I’m going to say this.body.i so now I’m drawing every element in there. Okay. So now I’m going to hit save. Project is saved so I have that. Oh, I lost what I wrote
in grow (chuckles). Live and learn. Move this over here. Oh, oh right, ’cause I
had this open, that’s why. So this actually comes back here. So grow, what did I do in that? I said this.body.push createVector and I said this.length. I don’t know if I need
this length variable, to be honest ’cause by definition, the length of the array
is the length variable. (chuckles) I’m so sad. And then did I add that? Then I added that. Let’s see, I lost some code. You’re not working… You’re not really coding
if you don’t lose some code every once in a while to an infinite loop. Okay. So here, we’re good. Now this… What’s going to happen
here is really weird but I’m going to get the food. Oops, shoot, I missed the food. So interestingly, why am I not seeing… I would imagine that
I would see another… So one thing, I would
guess that I’m going to see another appendage but it
would just be at zero, zero. Oh, look at me, look at
this, push createVector, createVector at zero, zero. Let me just do that. So that, I forgot. So what we’re going to see here is this. There we go. So that second part of the snake is there but it’s up there. So what I need to do now is when I’m updating the snake’s location, I’m going to comment
this out for a second. The first thing that I want to do, and there’s shift, okay? There’s an array function called shift. I forgot one. Last time I did this, I didn’t use that, I just manually moved all
the spots in the array. Let’s look at array javascript shift. I don’t actually know
what this function does but everyone was telling
me I should do it. Shift. Oh, look at that. That’s so perfect. So this is what I want, I want to shift all the elements down one and I guess I’m losing one. So let me just see about, let me see if I understand this. So just in the console, let me practice this. Let array equal five,
six, nine, 100, five. So that’s what in the array and if I say array.shift, woops, no. That’s what it returns. Did it shift it? But it shifted. Oh so it’s giving me the
thing that it got rid of and then it’s making it one less. So this is perfect, this
exactly what I need. Oh, I love it. So actually, all I need to do, every time in update,
is say this.body.shift and then that’s moving everything over and then the last spot so one thing I need to do is let me save where it currently is. So let me pop… Pop doesn’t remove it
from the array, right? So if I say array.pop, that gave me the element five but the array still… Oh no, I got rid of it. How do I get something off the end without removing it? Oh, un-shift adds from the beginning. That’s interesting. How do I get the last element without removing it? Well, I’m just going to
do it the manual way, this. I’m just going to say
let head equal this.body. And this.body.length minus one. That’s the last element .copy. So this is me taking the last element and making a copy of it. And then what I want to do
is say head.x plus equal this.xdirection head.y
plus equal this.ydirection and then I just want to put that back on. So I want to like save where
it was and then move that and then the body is all there. Yeah so I’m being told this
is actually how to do it. So that’s the last element, copying it. Let’s… So one thing that I want
to do, what’s wrong here? This.body index this… Cannot read property copy of undefined. So do I not have… Oh, because I’m doing it after shift. And if I’m shifting something with zero… Yeah, if I’m shifting
something with zero… So shift has to happen after, right? ‘Cause if it only has one thing in it, I shift it, it’s gone. Okay. So this is working, now. Oh look at that, so this worked. (laughs) And it made it longer but it
created it back at the start so I need to keep that
location when I grow it. So the same thing I need to do here, in grow, what I want to do is not add. What I want to do is do this exact same thing and then push, right? I want to take the last one and add it to the end. So I need to just duplicate
where it was before to the end. I think this should do the trick. Yep. Is it… Am I going one step behind by accident? I’m not sure. That’s pretty good. I don’t know why the food… Oh. Oh, you know what? It’s not getting in
until I get to the back. Why? Because eat is always checking this one. I need to check the last element. Same thing, this is very
awkward, the way I’m doing it. And I’m sure somebody will
make their own version that’s less awkward but I need to check the location of the head against the food. Here we go, let’s try this one more time. Snake game go. There we go and up. Yeah, this is better. Okay, great, this is working. Yay! All right, now guess what? One more thing. I need to know when to restart the game. When do I die? So I’m going to do… I’m going to do a function
called like check, you know, check for death or like
I don’t know, endGame? And what I need to do is I need to check if the head intersects with
any of the other positions. So the head, as we know, is… Well, it’s this. This is a little bit
weird, what I’m doing. That’s the last spot and now I can say, for let I equals zero. I is less than this.body.length minus one. I don’t want to check
the head against itself. I plus plus. I’m going to say let part equal this.body index I. If part index… If part.x equals X and part.y equals Y, then return true. The game is over or if X is greater than what was it, W? Minus one? Or if it’s gone off the
screen or X is less than zero, Or Y is greater than H minus one, or Y is less than zero,
then also return true. We should probably check that first. ‘Cause if you’re off the
edge, I don’t need to check… I don’t need to check
any of the body parts. (deep inhale) Ah, oh but I need to first
get the X and Y values. So I’m doing something a little weird but sometimes I’m using the vector and I’m saying pause that X, pause that Y, as soon as I’m pulling out
the X and Y from the vector. And then at the end, I’m
going to say, return false. So let’s see if now, I
can get endGame to work. So in here, I’m going to
say, also now at the end, if snake.endgame, I’m just going to say print. Print end game and I’m going to say background 255, zero, zero, and noLoop so I’m just going
to completely shut down the P5 sketch if the game ends. So this is not necessarily
what you want to do for like interaction design but
I’m just testing the feature. So the first thing I’m going to do is just try to go off the edge. So I’m going to go off the bottom. Yeah, okay so that works, so going off the edge,
at least the bottom. I should probably test the other edges. Oh, what just happened there? And I took my auto refresh off. I’m going to put that on. So if I go off the top,
ooh, that didn’t work. I probably had a mistake
somewhere in there. If oh, Y, this should be Y. Woops, that was a mistake. So (groans), all right hopefully, that fixed that. I’m going to… And now what I need to do, so one thing I need to do,
just to be able to test better, is I’m going to add something, I’m going to add the mousePressed function And I’m going to say this, snake.grow. So anytime I click the mouse,
I’m going to grow the snake so I could do it, sort
of test this feature. Oh, woops, shoot. Oh and you know what? I should set the snake in the middle. So the snake’s location
should probably be, initially, W divided by two and H divided by two and I’ve got to keep
everything an integer. So I’ve got to put floor in here, just in case. All right. So now, let me… Whoa, why did that… Oh. Oh because when I grow, the head becomes the same location as the other part of the body. And then I check to see
if the game is over. Shouldn’t it fix it with… Oh but if it’s not moving… So I got to move it first. I mean this should be okay (chuckles). No because if I click, I have to get focused. Ah (deep sigh). This is like a silly debugging thing. So what I’m going to do is
I’m going to have it grow with the space bar, not mousePressed. Else if key equals space. I’m just trying to do this to debug it and so I can do whatever I want. And I click over here and I move it, so I’m going to make it longer. So now let’s see if it dies, yep. Okay, great (loud clap). So (bell dings) I think
I finished this game. Really, what I want to do is
come up with an end screen or restart the game or
have some sort of score. Let’s see, before I go,
how long I can play it before I die. And oh, let me just show you something. If I go, I’m going to hit save. If I go under… This is a feature of the web editor. I’m going to go file share, I’m going to go here and I’m going
to grab this full screen URL, I’m going to grab it, I’m
going to open a new tab, and now it’s just the game. I’m going to make it bigger for fun times. I’m going to click it here and ready? I’m going to play the game. Goodbye, make your own
version, look for the link, sign up for a P5 web editor account, hit duplicate, make your own version, share it in the comments. There will be a page, which you could also share it. This is much too easy, I’m
going to be here forever. I’m going to look at the… Well, this is working (chuckles). I made the game. I can go home now. Let’s just see how long this goes for. (yells)
Okay, I died. I don’t know why I died. Oh, I hit backwards. (bell dings) (buzzer buzzes) So good thing I hit
backwards (trumpet fare) the game is over. Thank you, thank you. So that might be a bug that I want to fix. So that actually, if I hit back… But I guess you shouldn’t lose the game if you hit backwards. I don’t know. You know, you can make the
design more interesting, you can do all sorts of things. You can now make your own
version of the snake game in P5, in the web editor,
instantly share it. Thank you to the The
Processing Foundation, Cassie Tarakajin, all the people who made
contributions to the P5 web editor, and all the people who have
worked on P5JS over the years. I’m so excited to be
able to make tutorials and coding challenges with this. I’ll still use my other workflow
and I will use processing but I hope you enjoyed this video and I will see you (train horn)
next time on Coding Train. (upbeat electronic music)

100 comments / Add your comment below

  1. Finally, after so much searching and being confused, this seems to have a good way to scale up graphics. Does anyone know if this would be ideal for making a game with retro-style art with big pixels? I'm really new to professional languages.

  2. I would've created a class for the food and that the snake has a method eat(Food food){} and then just add the food to the array body of the snake

  3. Hello, thank you, I can finally hopefully learn P5 for once instead of simply watching you make some cool stuff for fun every week:

    Please take a look from your code, i haven't changed much except for fixing the last bug where when you pressed the opposite direction of the direction your snake was moving, then the snake got killed. You can find the code here: … hopefully later i can add like a reset function or end game screen. Thank you 🙂

  4. Next snake needs two additions: preventing food to spawn on top of it and no possibilty to backtrack i.e. if you're going left pressing right arrow does nothing instead of killing you because you ran into yourself

  5. Can you make a part 2 about point scoring and a endgame text on screen maybe? and if you want to add textures (if that is possible) that you drew yourself, how is that possible?

  6. I swear you’re reading my mind, the day after I start making flappy bird with genetic algorithms you make a video on it, now a week after I start my snake game you make a video on it. You’re a legend don’t stop please!

  7. I made a version that simplifies some things a little. It separates the head from the body, so it can be referenced directly, it integrates the update and eat functions since eating is equivalent to NOT removing the end of the tail, and it uses a map of key->direction vectors to eliminate the if cascade/switch.

  8. 16:28 – 16:42 if anyone is interested in the "why" behind this, it's caused by a floating point rounding error.

    For a great explanation of the issue, check out Computerphile's "Floating Point Numbers" video. watch?v=PZRI1IfStY0

  9. It's not really necessary but you should use a getter for snake's head, you repeat that code to get head way too much ;p (also .slice(-1) would return last element too)

  10. The p5js online editor is a nice idea. Even though it lacks some IDE features (such as code autocompletion), the direct integration of the canvas next to the editor, and especially the ability to share the result, are worth it.

  11. Thank you for this great tutorial Dan. How could one take this tutorial implement machine learning -> let the snake learn to avoid obstacles, and itself, and find food?

  12. You could have done it much quicker if you used an online tutorial, I like the Coding Train's tutorial most. Love you Dan, keep it up!

  13. Hasn't the p5 web editor existed for like a year at least? I did notice that it isn't on the alpha sub domain anymore, but it has been fully functional for a while now along with saving sketches and etc.

  14. You CAN use a switch statement for the controls, but you really shouldn't. It's OK for smaller projects like this, but it's really easy to make it a habit, and the switch is a LOT less efficient to execute than a chained if statement. This is mostly due to a switch checking every possible outcome every time, while an if will skip an instruction that fails a check, meaning every statement in the rest of that chain will be skipped as well, saving you a TON of checks in the long run.

    ES6 is especially good at this, as if you have AND statements, if any check to the left of the AND fails, it won't even try the right, it'll break and move on.

    Imagine checking keyboard inputs for diagonal movements in a 30 frames per second game. That's 9 possible combinations (all button presses plus no button press) that will be checked 30 times per second. That's 270 checks per second in a switch, but only 8 in a chained if (because you don't need a check for the default in an if statement). Now add a shoot button or two, an action button, a jump button, a slide button, a few item buttons and some other interactions and you can see how quickly this adds up to a very resource heavy task for the code engine. And that's just the controls!

  15. Daniel, what is the math to animate this animation ? Do you wanna a challenge?

  16. Here is one version I made where the edge of the screen teleports you to the other side, like in Pac-Man. It's also a bit faster, and some colors have been changed.

  17. 27:22 : If you declared some variable in the constructor to be the head it would be better than typing this.body[this.body.length-1] everytime
    this.head = this.body[this.body.length-1];
    and then use this.head.x or this.head.y or whatever you want from it … i think this would be better if it works ?

  18. I used your last coding challenge to make my own version, and I used an options array to make sure food spawned on available spaces 🙂

  19. Does someone knows how can i move an ellipse when my mouse is pressed, and leave it in that position when i stop it? on P5

  20. Thanks a lot for remaking this tutorial! It was the first "The Coding Challenge" I have completed from your series. After that I have been learning a lot (just two months). This time my code looks much more better, it is so pleasurable to revisit some of your code from time to time and see the progress you have made.

    For anyone who do this game: try to use getter in your snake class for getting the latest element in your body array:

    class Snake {
    constructor() {
    this.body = [createVector()]; // initializing head as the 1st element
    this.direction = createVector(0, 0);

    get head() {
    return this.body[this.body.length – 1];

    after that when you need the head => just call it like snake.head, no ( ) is needed. This will make your code compact.

  21. Can someone help me and tell me how exactly the update function work? I don't really understand how all the body parts get updated and i've followed it frame by frame. There is must be something behind the scene with the shift function. Thanks

  22. What is the difference between pre process JavaScript or process JavaScript AKA PJs, I've been seeing that everywhere, especially when it comes to drawing tutorials.
    How do you implement PJs versus regular vanilla JavaScript?, is it some type of package management, or can you do it by CDN?
    That might seem like Anubis question of some but for someone who is just picking up vanilla it is pretty decent at vanilla Js, what would they have to do to get started in PJs? Because I see a lot of code for drawing that works in PJs but doesn't work in plain vanilla JavaScript, so I imagine it's just adding a library somewhere? Or is there more to it? Sorry for the new question, it might sound kind of dumb but I'm definitely interested in seeing what PJs can do, and adding it as one of the Frameworks that I commonly use, because it seems like it has a lot of power when it comes to drawing or certain aspects like that.
    Do people usually Implement PJs into websites at all?

  23. A lot of newer people do have trouble when people write their code in those dry functions. Is there any way to actually write that code a little more sloppily so beginners can get it? 0:40?
    This may also seem silly but one of the things I see on ww3 all the time is there examples are always something something my function call function, and that can be just a little confusing when it's only a few lines of code, I wish more tutorials would show us the sloppy way, and then the dry way.
    Sometimes for lack of a better word we want something to happen or an event to fire without a function and usually beginners and intermediate should learn that first before they begin to get into the more functional type of programming. Because what you see someone more advanced writing all these functions it kind of becomes unclear as to what they're doing, at least in some cases this guy is a super great teacher but that's just something I've noticed with JavaScript as a whole. It's been far better in my experience that people learn to make certain things run without having to call them inside of function, and then showing the way when you do call the function that weigh more is explained and more of a big picture of the language can be understood.

  24. Is there a way to make snake using completely vanilla JavaScript, without the canvas.
    Just using something like on key up on key down or some type of event listeners, IDK I'm sure the tutorials are out there fam. But some people usually watching these channels are such experts they could pretty much write that out in vanilla in like 5 minutes, or at least read out what events you should be using if you're using or taking the vanilla JavaScript throughout and not using the canvas

  25. 2:25 I know it's super hard for people to make successful clones of websites, example would be something like gab for Twitter. There's an issue with medium while it's a great site it tends to cater to people with only one kinds of worldview on one side of the spectrum.
    Sometimes a lot of that s*** in programming doesn't matter but if you do that for a living it can kind of add up.
    Like I get kind of bummed when I have to go to medium to read certain things because I know the people at the top when it comes to medium have an agenda.
    I wish a successful clone of medium could be done in the right people on the other side of the spectrum could actually populate the site and make it something, because a good percentage of the population is being completely ignored and scrutinized for not having the same consensus worldview that a lot of people want them to have, aka the same view the people at the top on medium have.
    Those parts of the tech world could be way better as they only satisfy less than half of the population, USA wise.

  26. Hey Daniel, how about doing a simple version of a falling-sand game (there's a wikipedia article that describes what they are.) Note that this is different from sandpiles, which you've already done.

  27. Hi Dan, I've made some changes on your game, check it out! List of changes: score system, speed variable based on progress, head separated from body, round fruit, high score db with firebase, got rid of "scale" so I can draw thinner lines, "switch" for key pressed, combo-like animation, booster key to speed things up for a while, some other things I don't remember anymore.
    I don't know why the firebase couldn't work with the "gstatic" link on index, I had to put a copy of the firebase.js on the project to make it work. If anyone can fix this please let me know. Hope you enjoy! or[email protected]/sketches/rkVDxv3F7

  28. I made it using canvas and vanilla js if anyone is interested.

  29. Nice and quick coding!
    I think in foodLocation() you might want to check that the food and snake are not overlapping.

  30. I added some stuff to your code!
    (To see most of the changes I made, look in the settings.js file and read the comments)
    Edit: I made it so it's best played in fullscreen, although you can change the size of the canvas to make it small enough for the editor

  31. Well I learnt my answer on the question “Where do you think we should start learning coding” hihi <3 thank you so much!

  32. Not sure if this solution is any easier:

    The array of the snake adds a new head in the front of an array and removes the last element if the snake's body is longer than "len" — the length of the snake

    Known bug:
    If the player wins (fills all the cells) the game will freeze due to a do — while never finishing

    Played around a little bit more with it and changed it from a classic snake to a more dynamic snake:

  33. I love making prototypes and one handy (yet simple) prototype I made up is the end() function:

    Array.prototype.end = Array.prototype.end || function () { return this[this.length – 1]; }

    And then you can call it with an array, let's say "this.body" in Dan's video, calling "this.body.end().x" will give you back the last element's x, which is the end of the array, instead of having to type "this.body[this.body.length -1].x" It is a little more handy than having to call the array multiple times in a statement. Saves some elbow grease lol

  34. you should also make the snake not able to go backwards (for example if you're going right you should only be able to go up or down, not left.)

  35. so I'm using VSC on windows 7 and i have a ton of extensions… more importantly the p5canvas and everything with javascript so i have no idea why the output is giving me error
    "Line X, col X: "let" is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
    does this mean use firefox browser instead of chrome when testing my .html file that has the snake.js file script coded into it or what the hell is going on??
    i have no idea what moz or es6 extension is because even after installing Es6 on VSC it.. still.. has.. this.. error

  36. What's your beef with switch/case? All those spaghetti conditions are redundant and result in long lines.

    However, there is another way you could have done it that is even better.

    Make an array with 4 indexes, containing the appropriate vectors for LEFT, UP, RIGHT, DOWN … in that order. Then just pass dirArray[keyCode-37] to your update function.

    The array can be a constant so you aren't creating those vectors every frame. Also the keyPress conditions are completely eliminated.

    If 37 is too ambiguous for you, make another constant ARROW_KEYS_OFFSET = LEFT_ARROW; /*37*/ and do dirArray[keyCode -ARROW_KEYS_OFFSET]

  37. a bit late to the party but I have a question. I want to use this code for a game, but need to change a few things. I've changed most of them but I need help on one thing. Upon pressing each arrow key, I want it to only move once, not continuously and when the key is held, it moves continuously until released

  38. I tried copying and pasting the code into my p5.js editor and got error: Uncaught ReferenceError: Snake is not defined (sketch: line 12).

    The code works fine in the codingtrain editor, any ideas why I might be getting the error when I copy and paste it?

  39. 1 question, why was there a gap between the body parts of the snake the last time and why does the body look like a single entity this time around? Can anyone please explain?

  40. Can anyone explain why there is sfx automatically added to the game?? I can't find where the code is to remove it

  41. I don't want to know more about p5.js, I want to know more about how you do those crazy sound effects 😀

  42. Coding Challenge: Make an Etch-A-Sketch Make sure to include a "Shake" Function to lighten all drawn material but not delete it this will allow for Shading.

    It would allow users to make legit art and probably stick with 1 pixel scale 🙂

  43. you could have added some resistance (if the last key pressed was right, we can't press left, only up or down and so on)

  44. Great video! I made an A* based snake AI: 🙂

  45. Man, is a switch that terrible ?? C'on !
    That's the last time I show you, you brat !
    case LEFT_ARROW:
    case RIGHT_ARROW:
    case UP_ARROW:
    case DOWN_ARROW:

  46. Just started coding and found your vids! Can you tell me what the in the HTML are for? I tried it without them and it wouldn't work, so what vital function do they server how would I make this without sourcing Cloudflare?

Leave a Reply

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