Monster shadow

VIDEO

Create 2048 in Unity - Learn how to make a grid game

Description:
Let's create 2048 together! This was a really fun little project. I haven't played much 2048 but it seemed interesting so I figured I'd make a little tutorial for it!
ADD A COMMENT

Konstantin
Great videos man. I learn so much. Waiting for every new video you upload. Keep it Up! PS I believe the chances of spawning 4s are actually 10%.
Tarodev
Oh yeah? Damn, I probably should have looked it up 😂 Glad you enjoyed it mate!
Haapavuo
Your channel will grow exponentially if you manage to mute your keyboard from the mic. It makes much noise and it's hard to concentrate now.
Tarodev
I watch this video and cringe... You're 100% right. Since then I've improved my setup and my keyboard is very quiet now (check one of my recent videos for comparison). Thanks for the feedback!
Алексей Малапов
Спасибо
Dean Aviv
Great video and channel, kept it as short as possible while keeping it informative and interesting.
Tarodev
Thanks! Glad you enjoyed it 😊
Ushing Marma
Block Types can not be show in unity Inspector.But Why??
Konstantin
I believe it's because the Block class derives from the MonoBehaviour class. You actually need to make the class Serializable to see it in the inspector.
Ege T.
Hello. I'm newly getting into Unity and I was looking at your videos for inspiration in order to create a whole different game as exercise. Your videos have been very helpful and I find your code fairly easy to comprehend. However after watching this video and the "Create a grid in Unity" video I have a question: var freeNodes = _nodes.Where(n => n.OccupiedBlock == null).OrderBy(b => Random.value).ToList(); -> from what I've seen, you use this randomly ordered free node list in order to randomly place your blocks. What I'm wondering is that instead of creating blocks in completely random places, what kind of logic would allow me to spawn a block on the nearest empty node to another block. I've been trying to wrap my head around this and I would be very happy if you have an answer or a direction to point me to. In any case, thank you for your videos.
Ege T.
@Tarodev Simple enough. Thank you again. Update: I've updated the lambda expression inside _nodes.Where() to include the conditions with Vector2.left/right/up/down added and it works perfectly! Thanks for letting me know of the directional vector2 methods!
Tarodev
@Ege T. Use the function I wrote to find a node at a position. As the argument use the currents block position + Vector2.left/right/up/down. Then check if it has an occupied block
Ege T.
@Tarodev Thank you for the answer! What I don't know yet is how I can tell which blocks are surrounding the block I designated while I'm going through the list I already have.
Tarodev
Hey Ege, thanks for watching. That could be achieved in a few ways. Create a list, loop through your current blocks and add it's surrounding nodes which are empty to the list. Now you can perform the freeNodes check on this new list.
kar bon entertainment
Hi I'm a new game developer n I'm concurrently working on Sudoku game but need a little help to complete my game could you help?
Tarodev
What do you need help with? Might be best to pop into my discord.
Baris Dincer
Informative as always :)
Brani_Dev
Every video from you is a GEM keep doing these ;)
Diru Diaz Rusiñol
pole
SEE ALL COMMENTS


Transcript:

in this video i'll take you through how i recreated
the classic 2048 game let's get into it all right let's start
by making a folder and let's call this scripts
and i'm going to create a game manager script here
now this game is little so i'm probably going to keep most of the logic
just in the game manager in one central place instead of splitting it across
multiple files and let's just remove this stuff from
there so what do we need we need a serialized
field and this will be an inch for the width
just to fold this to four and create another one let's call this
height and then let's make a function called
generates whoops generates grid let's actually call this directly from
start generate grid in here we want to
loop over our x so our width and then inside here we
want to also loop over our y
so if this looks a little bit confusing you can go check out
a more detailed description in the video up above
and then come back so now we need to instantiate uh
tiles or i'm going to call them nodes probably so
there'll be four nodes down and then four nodes up so
four by four square so let's create a new script here let's call it
node and while we're here let's actually also create another script called
block like that now we need a visual
for this node so let's create a new empty object i'm going to call this node
let's reset that to zero then let's create a
empty under it and call this the visual aspect of it and then add a
sprite renderer now we need some sprites to go in here so
in photoshop i have prepared two sprites one for the block and one for the board
the only difference is the board has like this small rounded edge
whereas the block has a more rounded edge
i will include both of these sprites as well as a
font which i'm going to be using in the in a package file so just check the
description and you can just import those
directly in just like that so i'm going to chuck those sprites
there i'm just going to leave that there for
now so these sprites are actually 2048 funnily enough
by 2048 so make sure you go to your 2d texture settings and ensure that
pixels per unit is set to 2048 i made them that big just so that
they're uh nice and crisp uh even when we're zoomed in so our
node let's put that in there so there is our
first node and on the node object itself let's attach the script there and then
let's make a folder called prefabs
and plonk that in and let's do pretty much the same thing
for the block and add a visual underneath it
[Music] could have just duplicated the other one
but live and learn so this node i'm also going to use for
the the block because why not so i'm just
going to chuck the node in there and then chuck the script on
the block and then let's make a prefab there cool
delete that from the same all right back in our game manager let's
create a new reference here and this will be for a private
uh node [Music]
and this will be the node prefab so then here we can say bar node equals
and we'll instantiate our a new node uh of type node prefab
and the beautiful thing about this is we can actually use the
world's transform positions as the x and the y so we don't even need to store the
x and the y on the node or the blocks we just need to know their transform
position so that makes it nice and easy so we'll say it's going to be at vector
3 x y actually we can use vector2
and then rotation will be identity and i'm sure you guys can hear the kids in
the background uh covered is tough on parents
so okay so let's see what that does let's create a game manager script
i mean a game manager object here so game manager
check game manager on it 4 4 and let's do the node
if we just press play now we'll see that it spawns our grids
so obviously that is not ideal as we want a little bit of space in between us
so on our node prefab go to our visual node i'm going to just
change that to 0.9 scaling obviously the z doesn't do anything but
so there we go a bit better now
it would be good if we could spawn a board on the back here
so on this board board sprite ensure that it's single
in your sprite editor what you can do is you can actually move
this in so let's just say we'll move it 50 pixels
on the left top right and bottom so now what that means is this will act
as a constant on the on the corners but
everything in here will actually stretch because obviously it doesn't matter how
far this is going to stretch it's going to look perfectly fine as
long as the corners don't stretch so apply that so let's make a prefab for
that let's chuck the board on the screen zero it out and actually that's all we
need to do so let's just make that a prefab and
delete that from the same now in our game manager let's add a
serialized field private and this can just be a reference
straight to a sprite renderer even though
this is a prefab we actually only care about the sprite render so we'll grab
that directly so we'll call this board uh prefab so then down here under our
grid let's say board equals um instantiates
board prefab now where is the center of the map
right now let's just do zero and identity
so to get the center of the map let's make a new variable here called center
and let's make this a new vector 2 and this will be
the actually we need to cast this to a float to ensure we don't lose anything
this will be width divided by 2 minus 0.5
and then this one will be float it will be the height of the map
divided by 2 minus 0.5 like that and now we can just chuck this
right here so that will pull it put it at the dead center of
our nodes like that so let's just try that out
back into unity and let's add the board and then also let's go into
the board and actually i've got a color palette here which i
will include in the description but i'm going to just be copying this
these hex codes uh like that so that's the color that
i'm going to have as my board and then the node i'm going to change
the color to this hex code
just like that cool bananas and also while i'm at it i've also got a
nice little color code for my camera so i'm gonna do that
now let's see and yes you can see that the board is in the direct center
but it is not the correct shape is it needs to be four by four
uh so if you actually pull your board out here
and then you just try to stretch it like this and look at the corners
you'll see that they're they're not too pretty so what you need to do
is change it from draw mode simple to sliced
and now you've got this width and height category and if you now just pull this
width out you'll see that it is using our
sliced sprite that we did earlier okay so make sure it's on sliced and
then save your prefab again and now in our script we can simply say
board now remember we're actually directly referencing the sprite render
as our prefab so we can say size equals new vector 2
and we can just chuck in our width and our height
and that should do it just fine okay so we need to make sure uh
our board is on order layer zero let's make our
nodes on order layer one and while we're at it let's make our block
on order layer two so now if we press play
yeah the board is in fact behind it now it would be nice if we can kind of uh
make the same spacing around as as as well as we've got in here so all
we need to do really is actually it'll be better if we do
this live so if we click on our board and maybe make it like 1.05
no yeah about that 1.03 should probably just about do it that's
about even right yeah that looks pretty good
so on our board let's make it 1.03 1.03 now when we press play yeah just about
good cool so now let's center our camera whenever this
gets generated so we've already got our center here so now
we can just say camera dot main dot transform
[Music] dot position equals mu vector 3 now we
need to do it in vector 3 because we need to move our camera back we don't
want to put it on 0z so we'll say center x center y
and then -10 which is the default position of the camera there we go
and let's zoom it in so you could put logic to
auto-generate the the size to ensure that the screen is kind of taken up
uh the the game board's kind of taking up most of the room but i'm just going
to do just going to hard code 205 for now
perfect all right next step would be to
spawn blocks on the on the page on the board so let's make a
new private block this will be the block prefab
and let's make a new function here called void spawn
blocks [Music]
and let's actually take in a number here because we would probably like
because we would like the first turn to actually spawn two blocks
and all the subsequent turns can just can just spawn the one
so let's do four and loop over the amount that we've
taken in and we'll say block equals instantiates
block prefab and now we need a randomly selected
node which is free don't we so uh let's make a function that returns a node gets
random available node now we actually need a list of our nodes
so we're we're spawning our nodes here but we're not actually storing them so
let's make a private list and this will be of type node
nodes and then before we generate the grid let's actually instantiate the list
i mean uh initiate the list and now in this list we can say nodes.add
and just add in the node there and while we're at this let's uh also make a
list for blocks as we know we're going to need them and
we may as well just initiate that list there too cool
bananas okay so we can say here uh
return nodes actually not let's not do it this way
we'll do it in a more efficient way we can do this we can say bar
uh three nodes equals nodes where
and then we actually need to know here if the node is free or not
so let's go into our node and remove this
and i'm going to have public block occupied block so this will always be
filled whenever a block lands on this on this node so now we can say down here
where n occupied block equals null so we're
going to grab all the nodes in the grid uh that don't have a block on it yet and
we want a random one so we're going to go
order by and we're just going to say we're going to use a random value to
order them to order them by and then yep so let's
do that so now we have a we have a count here so we
know when the game ends the game ends when there's no free
available spots isn't isn't there so we'll say uh if
three nodes dot count equals
well we could say zero here but what we actually want to do
is we want to spawn a block first we want to show that the board fills up
so what we actually want to do is we want to we want to check if there's one
because if there's one free node here that's good we'll fill that will fill
the node because this will always be just one remember because there's only
two at the very start so they're never going to have a problem here
so we check is there one free node okay cool spawn it but bad luck you've
lost the game so so here we'll just say here and uh we'll
say lost the game down here so
now that we've got these free nodes let's
say for each uh free notes and let's
just take the amount that's required okay so we don't need this for loop
anymore you can go away instead of just say block and this is
saying that we're enumerating it twice so let's send it to a list
just so it uh doesn't have to actually activate two times
so now let's spawn our block and let's put it on the node and it
would be nice if instead of going node.transform position
here as we're going to be doing this a lot
let's actually make a little getter here so it will be
public uh vector2 call it pos and let's just return transform.position
just like a little helper function so node.pause
and just identity is fine now we
need to give these blocks a number and a color so let's create a
little struct this will be serializable public struct block type
let's type and this will have a public int
value and a public color color like that and then up here we can
make a serialized list private list block type types
[Music] whoops that's going to be serialized
field okay so now that we've got these types
we can initialize this block with a type so let's go to our block
script and let's create a little function here
and this will be our initialize function so a net this will be a type
block type we'll take in like and then we'll have a public int value
here to store our value so now we can say value equals type
dot value and then we'll have a serialized curve here which will
give us reference to our sprite renderer and then uh we'll set our renderer.color
equal to type dot color and i think that's all we need there so
on our game manager now that we've got our block we can say block.net
and we need a block type here so let's create a little getter
for grabbing a block type so private block type get
lock type by value and this will be the value that we're
sending in and then we'll return block
whoops types first and then should be type type of value
is equal to the value that we sent in now that we've got this block type
we say get block type by value and let's just say two for now
and we'll just we'll just spawn twos so we're coming down here let's actually
call spawn blocks after we generate that grid and we'll
just say two for now okay because we're just
doing this first test we're grabbing our free nodes
okay so that will basically be every single node to begin with we're
saying okay we're just going to take a certain amount from this free nodes list
and we're going to loop over it and we're going to spawn a block in each of
those and that's they're also ordered randomly
okay so we're grabbing them randomly and then we're initializing the block
and then once that has finished obviously this will come into play later
we're going to say you know if every single if every single node is taken now
you've lost the game so bad luck and now let's set up our block preverb
so back in unity let's pull it our block here
let's add a visual element to it and while we're at it let's add text to
this so that we know what we're actually looking at so
3d objects and i'm going to use text mesh pro you can just use the standard
3d text i prefer text mesh pro because it gives you
far better options if you haven't imported it into your project yet simply
click import text mesh pro essentials that'll just
import and you can in fact create your own text
dash assets with text message pro man i can't
talk so windows text mesh pro font asset creator and you
can just chuck in like a ttf here and then
generate your font but i've done that for you with this
font asset that i gave you to import so i'm just going to slide that into there
and it will be our new font asset and i'm going to center
it and then let's uh scale this way down
like that and i'm going to change the color of my block just so we can see the
text better and it's also behind this so if you
remember our ordering layer for our block is two
and text mesh pro actually also has that same setting so if we go to our extra
settings uh extra settings you can see order in
layer let's change that to three and let's just ensure that it's always
going to be kind of in the square here i'm going to
auto size and this our biggest number will be
2048 so as long as it fits there you can just click auto size um but you
don't really want it being too big uh if it's just the one so make max size
something like 32 or something and in that case they'll
they'll all kind of be uniform uniform enough anyway uh also
let's give it like a little bit of shadowing it'll make it look better
so down here in underlay let's add an underlay
underlay and then add just like a little bit
just like that just kind of makes it pop a little bit
yeah there we go i'm gonna spin down my gizmos they're too big
cool bananas so back in our block let's make a reference here serialize
field private
[Music] text mesh pro yes that one
text and then we'll say here text dot text
equals type dot value to string there we go so now our block
gets initialized and we've got we we've got the same one prefab for all of the
block types so that keeps it nice and clean now back
on our block let's send in our text and just to make it clear let's call
this super value test now let's save our prefab
and get it out of here all right cool so let's just make sure we've got
everything hooked up we've got this which spawns our grid centers our board
centers our camera we're going to find all the grid spare
squares available we're going to spawn as many blocks as we've told it to
and that should work and it's going to be spawning blocks of 2 so let's press
play and that did not work so what have we
got block prefab did i not set that in a game manager no i didn't so block
in there and play and that didn't work either
what else did i miss ah we didn't set up our block types
okay so just expand the types there let's
add our first one two the next one will be four
the next one will be eight sixteen
[Music] 256
[Music] 512.
1024 and the magic one two forty eight beautiful so now i'm
going to go through and just add all the hex codes for this i'm just gonna speed
this up because it will be boring as well
okay got him no i missed one got it cool all right
now that we've got those we should just be able to press play
and there we go and also we need to downsize our blocks
in the same way that we downsized our nodes and we use
i think 0.9 yeah 0.9 so let's go back to our block
visual aspect and then change that down now that we've done that we actually
need to make this a little bit smaller cool press play there we go
how's that look not bad pretty okay so a few things i know
i noticed i mean i've only played 2048 a few times to be honest
i just thought it would be fun to make but i did notice that they
were not just spawning twos they were also spawning
fours and it looked like they were a little bit rarer so instead of just
sending in two let's do a random
dot value which will give us something between zero and one
as a float and let's say if it's over 0.8
[Music] let's give it a two otherwise let's give
it a oh no let's give it a four otherwise let's give it a two so that
should hopefully give us a four every now and then
so back in unity let's just try that there we go beautiful
okay so now instead of just having this all kind of like just plonked like
saying generate grid spawn blocks um let's create a little bit of
organization here so public uh game state whoops
that is of type enum so this will be generates level
spawning blocks waiting inputs
[Music] moving
moving and then maybe win lose yeah that'll be good
okay so up here let's say a private void change states
this will take in a game state new states
and we'll have a private game states of type states and this will set our
state equals to this new state
now this is just a typical game manager again if you don't know what a game
manager is i've made a detailed video on it so go click that
and come back it's a very important game concept
so now we've got this we'll add a switch statement here and we'll take in the
actual state of the enum and i'm just going to generate these all
these different switch cases so that's just all of those now instead
of calling generate grid directly here let's say and start we're going to
actually get the ball rolling here we'll say change state and we'll say
ob type generate grid so when the game starts we'll call this function and
we'll be able to generate grid so we're going to generate
grid here now we're generating grid so we're going to
do all that and we don't want to do this here so we're going to say
down here we're going to say all right now that we've generated our grid let's
change state again to spawning blocks so then in spawning
blocks we're going to go here i'm going to say
spawn blocks and here for the amount we only want to
spawn one we only want to spawn
two blocks on the first turn and then one every subsequent turn
so what we need to do is create a private int and this will be the
round and then when we're generating grid
this should almost be called setup game but generating grid like we're
initializing a lot of stuff here so let's all
let's always make sure that round is equal to zero so we're on round zero
and then on here spawn blocks will say if the round
is equal to zero let's spawn two blocks otherwise let's spawn one
and we can actually avoid adding a whole a
an extra line somewhere around here iterating the round because we can just
say uh round plus plus so this is going to
say zero first and then it's going to add one to it for
the next time it's used but for the first time this is going to
be called it's going to just say is 0 equal to 0 if so 2
so that's just a nice little way to write it as long as you know that you
don't need this round object anywhere else to say round zero during
the round let's just iterate it straight away okay
so that's enough for episode one it's probably getting a little bit long
so in next episode we will learn how to actually
shift the blocks and then combine them and we'll be on our way to a pretty
complete game i'm only going to make this two parts so
stay tuned and i'll have the next one up in absolutely no time flat
uh see ya