hello, everyone welcome to another coding challenge today's coding challenge is a Gari O Agario Agario a game that [I] was not familiar with until recently when little ott on github Suggested this particular game.
I looked it up.
[I] played it [for] a few minutes.
It's a massively multiplayer game created by [matias] valadares, [I] don't know if I'm Pronouncing that correctly you could go to Agario and play it yourself But basically you're this blob moving around the screen [and] you eat other blobs now.
Here's the thing This is actually quite complex.
The simple mechanic I think it's going to be hopefully something easy that I can implement in this short video but I'm going to do this in Several stages and So part one is going I'm going to implement the basic McCane mechanic and in part two I will start to look at how you [might] [oh] [I] might use how you might use websockets to create a multiplayer version in this game So this video is just going to be the basic game mechanic, so I'm using the p5.
js framework.
I'm using the sublime text editor I have a canvas and a black background.
That's all I'm starting with and I also have a [Javascript] file called blob [Ks] Where I'm going to write a constructor function to create this idea of a blob object the blob object will serve to be both You the blob moving around the screen as well as other little blobs that you are trying to eat So what does this blob need now? I'm going to use vector objects which are something that exists in P5 a vector being an object that stores an x and a y Component for a position on the screen and lots of other [things] [that] we could do with that so I'm going to say this dot Paz equals Create Victor Vector Victor, what's your Victor vector? With – height [-] and then I'm going to write a function called show which actually instance it's in these object I'm going to write this dot show equals function and I'm going [to] say fill 255 and I'm going to draw an ellipse at this x this dot y and I also I definitely need a variable to keep track Of the radius the size of this blob Let's just make it 32 or 64 to start with so then the size of the ellipse is the radius Times 2 and the height is the radius times 2 so now if I go to sketch, I can just [say] [var] blob blob equals new blob Blob dot show so let's just see where's the blob.
Oh something's going terribly wrong I'm kind of being silly here where I forgot the whole point of this was [I] made a Vector called paws for position and then I tried to draw it at this x which doesn't exist [so] [this] dot paws x this pause y There we go, so there we are in the window now this is something a little bit crazy as I just realized as part of this game, so I want to move around the space, so But the thing is I don't in the game this blob that you're seeing on the screen right here [it] moves But visually it stays the same and rather the world shifts relative to it So we've got to kind of figure that out, so I'm going to do something else here I think to help us where I'm going to make an array called blobs, but I need some better variable names blobs can be just an Empty array and by the way, I Think that I should give the blob a variable in the constructor So I can actually say how big to make it so I want this blob to be 64 and now I want to say Var I equals 0 I is less than I'm going to add 10 smaller blobs Bob Index I equals a new blob Which will be smaller all these blobs are going to be 16, and then now I can have a loop in the draw loop Where I call show and all those Now look at that.
They're all in the [centre].
That's a bit of a problem So how about we also something? We could do is in this blob object? [I] could also give it an x and a [y] and Then I could say here.
I want this blob to be this blob to be in the middle and I want these blobs to be at a random location And then the blob is made with that X&Y There we go, so this is where we're starting.
We have this idea of one blob.
That is me I am the blob and then lots of other little blobs that are food that I want to eat So now the way that the agario works is the blob moves in the direction of the mouse So let's see if we can figure out how to make that happen, okay? So what I want to do is add a function called update and Let's think about this camera [one] off Let's think about I have Some old flappy bird diagram here that I'm in a race.
Let's think about how this [actually] works So [here's] the blob and here is the mouse What I want is I need to create a vector [an] arrow that points from the blob towards the mouse and I want that to be the direction that it moves, so this is actually quite easy to do because Coming back over here if I know this position, and I know this position if I take this position [minus] this position I get a vector the points from here to there so I can actually use coming back over here.
I can say [Mouse] equals create vector Mouse x Mouse y, and then they could say mouse dot subtract this dot position, and then I can just say I could say mouse dot [know] set magnitude to like three set magnitude [just] takes that vector however long it might be and sets it to a specific magnitude, and then I could say this dot paws add to what am I doing this die Pod add mouse so really this is [how] I'm calculating the velocity and Whoops we got some errors [here] blob dot j.
S line five this update equals function oh And you know what would help if I call this dot update if I called blob update [mouse] is not defined I'm calling it velocity now so you can see how that blob is now following the mouse.
Here's the thing though It's moving and not the other stuff So I want the my view of the world to be relative to this particular object So how do we do that hmm? I have an idea what if Instead of what if okay, okay, okay? I'm going to use the translate function Let me come back over here this is where the [object] is and This is where the origin is Zero Zero, but let's say the object moves over here.
What if I move the origin over to here? then We should see it still.
Oh, I know I need to move the origin the other way if I move the origin over here, right? It would be kind of here which would appear back in the center of our screen I kind of got lost in my own thoughts there basically what I want to do is it's moving over here But I want to shift the view to be over there and the view of where we're seeing everything is kind of like where is the origin point in our canvas and Translate is a function that shifts the origin so what if I just said right here? Translate by blob position x blob position dot Y- now, I think this is going to be a little bit off, and you'll see why in a second It's working, but the blob is at the top left.
So really what I want to do is translate by the center because that's really where I want to have the view – that, and now we can see as I move the mouse [around] the blob is that always stays in the center, but these other things move Am I doing this right? Guys tell me in the chat if this is kind of the right idea It's not right look Is it yeah? Move this way move this way move up move down move this way move this way move this way move this way it is It's just sort of sort of strange to see let's add a lot more of these It feels like I'm steering it incorrectly Okay, people are saying it's right feel a little off to me but okay the other thing about okay the other [thing] [that's] a little bit crazy here is that? What's happening [now]? And we're back, so I forgot something [as] soon as I started moving it around I forgot that the this actual velocity is being tracked relative to the object's position Which now is off somewhere and that it's actually the mouse and the position in the same place and all sorts of I actually What I want now [is] I need to subtract Just the center of the window So I can actually just create a vector like this I don't want to actually in this anymore subtract the actual [position] of the object cuz the position object is relative the world But the users interaction is always relative to the center of the window, and so that's what that's what was messing things up So now you can see this work work slow now.
There's another sort of issue here which is that the world should really be much bigger than What I'm seeing actually the width of the the canvas itself and in that sense we can kind of do that really rather easily by saying [let's] pick a random x between like negative width and width divided times two and let's pick an a y Between negative height and height times two just so we have kind of like a larger space For the blobs to live in and [so] now You can see that as I move around There's a much kind of larger world of things for me to eat potentially Okay, so I think we're moving along here.
We've got the basic gist of the game Okay Now I need to add one [more] thing here Which is that if I eat one of these if I find one of these other pieces of blob things that eat it then I? Get a little bit bigger.
I think that's always it happens in the cave So one thing that I need to do is when we're looping through Bob's Index, I then blob grows and actually what I want to do is uh Remove that blob so blob Index dot splice Zero comma one I find myself saying this a lot these days [I] also want to loop through the array backwards because I Just said this in another video.
I made but if I am removing things from the array as I'm going forward through the array that the elements slide backwards, and I could skip one by accident [so] it's good to loop through the array backwards So let's see I want to check if the blob eats one of those other blobs Then I want to remove one [of] those other blobs from the array, and how do I determine if it eats it? The way that I do that is by writing a function eats Which receives another blob? I'll call other and I need to check something I need to know what is the distance between this blobs x? You know it and actually there is a P5 vector distance function so I say what is the distance between this blobs position and the other blobs position and If that distance is less than this blobs radius plus the other blobs radius, then we've eaten it Why is that true guddu oops? I hit the wrong button right if I have two objects and I check their distance relative [to] the sum of the two radiuses Radii if They're overlapping that sum that distance going to is going to be less than it if they're not Overlapping that distance is [going] to be greater than that son, so coming back over here We can now say if it eats it then I can also let's say this dot r gets bigger gets bigger by the others radius and also return true otherwise otherwise return False and Come over here [to] [the] blob come over here back to the main program And I think that's basically it so let's see how [that] works oops invalid Left-hand side and assignment on sketch 21 What's oh? Blah blank minus [one] okay, so we should see here up blobs index.
I dot splice is not a function Okay, [of] course what am I doing here? This is absolutely incorrect.
I don't know what I haven't eaten breakfast this morning Clearly I'm kind of struggling here for my energy.
I want to splice out of the array at index I one element which means remove index one element starting at Index I I don't know what I was [writing] before was completely wrong.
[uh] blobs splice [it] refresh here Come on.
Eat there.
We go eat eat eat [okay], so it's getting quite a bit too big just for meeting a blob so let's let's divide that let's multiply that by like [0.
2], and [we] can see there we go, and I think that what might be Okay, I'm back the chat.
Gave me some nice helpful suggestions a couple things about how the game actually works one is Increasing the blobs radius is not actually how the game works? And this is actually a great thing that you should learn about if [you're] not familiar with Because we often think of the blob a circle size as its radius But that's not really its size the size that we're seeing is its surface area the area which is calculated pi R squared so let's look at that, so let's actually let's fix that for a second, so I'm going to make a variable called sum, which is equal to [Pi] times this dot R times this dot R plus pi times Other dot R times other R.
So that is the sum of the two? Areas of both of the blob that's eating the smaller blob now the new Radius should be the radius that's associated with that particular Sum, and how do I get that well? let's think about this really quick if the Area equals Pi R squared then R squared equals area divided by Pi and R equals The Square root of area divided by [Pi] so I could just solve for R with that particular equation And I can come back to here [no] I'm getting a bad at my switching [soon].
I can come back to here and I can say this dot r equals the square root of that area What'd I say? Oh, no? No that area divided by [Pi] so let's take a look at that There we go.
That's such a more beautiful and elegant interaction now the other thing that I was told that actually happens with Dario is that instead of the Instead of you seeing your circle grow the actual view of the world kind of zooms out so while you're growing [what] you see is you stay the same size and the other? Circles kind of Shrink and we can do that in P5 using the scale function So in the same way that I use this translate function I could scale the world by the Blobs Current Radius divided by what it started with which is 64 so right if it's radius is 64 Then I'm scaling the word world by one so let's see how this works [now] the problem Is this is causing everything to shift to the [right]? Which is not great? so and And by the way the radius is getting bigger.
So [I] [want] to do it the other way 64 Divided by the Blobs Radius I Want it to shrink and so this is working But everything is kind of shifting up that's because I unfortunately am drawing everything relative to the top left So really what I want to do is I need to change the whole view of everything For the blob to start at zero [zero] which is better anyway, so I want the blob To start at zero zero let's go back to the main sketch I want me the blob to start at 0 0 and the other blobs can just go from negative [width] to positive with Negative height to positive height that should work on it I kind of had that weird before anyway And then the world is actually just drawn relative to negative the blobs position So I'm always doing everything relative to that particular blob which starts at 0 0 that's going to make things much better oops wait, wait wait with [-] Plus weight I Did this wrong? whoa – Yeah, there.
We go wait something is still off Keep that okay.
There's a there's a kind of an issue going on here So um let me think about this let me get this right here for a second I've I've done this twice now, but hopefully you're seeing an edited [version] of this now So the problem is actually that the first thing that I need to do is Translate to the center, so let's not do [anything] just right now, but translate to the center So now you can see this is where the blob moves freely around and it should be growing as it eats other blobs Now what I want to do is I want it to I want to scale it I wanted to scale it by its relative size relative its size relative to its [original] size So you can see the world is kind of shrinking rather than the blob growing But now that I have that I need to do the scale before I tran I offset the whole world then by Negative the blobs [x] [position] negative the blobs y position so now if I do it in that order You're good.
Oh, whoa I? Need a comma there now we can see we have the world doing what we originally hoped and intended it to do so so okay, so Now you can see that things are very kind of herky-jerky here And that's because everything happens instantly the scale changes instantly the view changes instantly and it could be nice To have things massaged a little bit smooth a little bit and a way to do that is with a function called MP5 called Lerp which stands for linear interpolation Instead of taking a value [in] [setting] it directly to the new value just want to kind of move Slowly towards that new value, and so let's let's do that with scale so the new scale is 64 blob Dot R But I need a variable I'm going to call I don't want to call it scale because there's a [P5] function called scale, so I'm actually to call it zoom so zoom on is start zoom equal to one and Zoom should always be the lerp between the value in between itself, and what the new zoom is and Now the last argument of this loop function.
I have [a] whole video about lerp you can find that video uh if I make it like point one Let's see what happens.
Oh wait hold on hold on hold hold on point nine.
Oh Wait, wait wait.
I got to actually put it in there.
Sorry everybody.
[I] got actually used the variable I created So what I want is I want it to be just a little bit 10% of the new value so that I interpolate towards it And can you see that happening kind of smoothly let me um so one thing I want to do just to make this more obvious is I'm going to just make it a ten times that amount whoops [oh] Okay, wait hold on hold on.
[I] think I had it opposite.
I [think] this should be 0.
9.
No hold on let's adjust the way the radius is growing to try to get a better look at this so I'm going to change the radius a Bit take away that they're using this surface area and just actually add the two radii together and then now we should be able to see and By the way, there's so many It's actually I shouldn't allow any of it also, like it eats a lot of blobs immediately so let me start with quite a few fewer, just ten and So now you can see what happens as I eat a blob it gets really big immediately But then the view kind of slowly interpolates and shrinks so you can obviously tune these numbers a little bit better But I'm going to go back now to the surface area and sort of see and I think I want to add one more Interpolation here, which is just to interpolate its velocity so that it doesn't immediately Get the new velocity but rather kind of smoothly turns a little bit as you move the mouse around I don't know that agario is actually doing that but I think that might be an interesting thing to add So I'm going to add that here in the blah object.
I'm going to say I'm going to give it a velocity I'm going to give it a variable velocity Create vector and it's going to be empty zero zero to start and then this is going to be its new velocity and It's new velocity has a magnitude of three and it's velocity [I'm] going to lurk To the new velocity by 0.
1.
So let's just see how that works is not defined, and of course I forgot Always these abyss guys is a blob dot ten and this needs this stop velocity so you can see It's kind of the turning is a little bit more interpolated now is a little bit smoother Is it still going in the right direction, right? So you could play with that number quite a bit like if I made this number you know 0.
01 It's turning is going to be quite slow if I made that number 0.
9 it's going to be as if it turns instantly so I'm going to just like to use point two and you can see now There's a lips a little bit smoother now.
Let's add.
Let's go back to the original sketch and let's add a whole bunch of these And you can [see] here I am eating them all moving around and you know as I eat them I should probably add new ones I've got a little bit of a performance issue because there's way too many of them You can see the scale and really kind of like zooming out on the world, but this is the basic game mechanic So I'm going to stop here on this particular video.
[I] encourage [you] to take this tweak It improve it a change the design of the blobs change the size of the world Maybe as an exercise add the feature of when you eat a smaller blob a new one gets added somewhere else [and] see what you can add to improve this and make this a little bit better I'm going to do two more videos this one video.
I'm just going to show you how to make this something That's a little bit blobby so the vertices kind of undulate a little bit so it's not a perfect circle I'm going to do that in a separate video and then in a third part of this challenge eventually at some point I'm going to look at multiplayer [networking] with this or multiple people could you play against each other and consume each other in this? Kind of blob way somebody also mentioned to me than the actual game the blob doesn't eat it immediately Maybe it has to envelop the whole thing or they squish against each other a little bit So there's some possible also like additional interesting features I could think about adding at some point did this suggest those and let me know in the [chat] what I got wrong with this game And also I'm gonna have to do some work in [the] chat [bells] someone mention about optimizing this all these square root Calculations are really slowing things down, and there's some ways around that that I think I could ultimately Do to kind of [optimize] and make it perform a bit faster which I'll look at at some point as well, okay So that is part one of Agario game in p5.
js coding challenge.
I'll see you at a future video.
Good.
Bye Thanks for watching.