background top icon
background center wave icon
background filled rhombus icon
background two lines icon
background stroke rhombus icon

Download "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course"

input logo icon
Video tags
|

Video tags

javascript
javascript mastery
js mastery
master javascript
decentralized applications
ethereum code
smart contracts
web3
web3 explained
web3 tutorial
web3 development
web based game development
web game development
browser game development
web 3.0
web 3
web 3.0 explained
web3 game development
web 3 nft
web 3 nft tutorial
nft card game
nft board game
nft development tutorial
avalanche
avalanche blockchain
reactjs
reactjs game
react js game
js game
Subtitles
|

Subtitles

subtitles menu arrow
  • ruRussian
Download
00:00:00
web 3.0 has the potential to change the
00:00:04
internet as we know it forever you're
00:00:07
still early in catching the trend right
00:00:09
now and building your first blockchain
00:00:12
application hi there and welcome to the
00:00:15
project video where you'll build and
00:00:17
deploy an online
00:00:19
multiplayer web 3 NFD card game powered
00:00:24
by Avalanche create your characters
00:00:27
create and join live battles choose your
00:00:31
Battleground and battle other players in
00:00:35
real time with a stunning design
00:00:38
interactive gameplay smart wallet
00:00:41
pairing live interaction with smart
00:00:43
contracts and most importantly the
00:00:46
ability to battle other players in real
00:00:49
time avax Gods is the best and the only
00:00:52
web 3 online multiplayer card game that
00:00:56
you can currently find on YouTube you
00:00:59
might be wondering why what are the
00:01:01
prerequisites for building such a
00:01:02
fantastic game you need to know
00:01:04
JavaScript and feel comfortable with
00:01:06
react if this is your first time
00:01:08
learning web 3 I suggest you watch the
00:01:11
build and deploy a modern web3
00:01:13
blockchain app video first and then come
00:01:16
back to watch this one building this
00:01:18
phenomenal game will give you a proper
00:01:20
understanding of how to create regular
00:01:23
web-based games but it will also give
00:01:25
you detailed insights into the world of
00:01:28
web3 how to interact with smart
00:01:30
contracts pair to Smart wallets and
00:01:33
listen to Smart contract events we're
00:01:36
going to start easy and then move to
00:01:38
more complex topics I'll explain every
00:01:41
step of the way alongside building this
00:01:43
application you'll also learn how to
00:01:46
connect a regular react.js application
00:01:48
to the blockchain and pair to your
00:01:51
wallet you'll also learn about the
00:01:53
solidity programming language and how
00:01:55
smart contracts written in solidity work
00:01:58
you'll learn how to create smart
00:02:00
contracts and decentralized applications
00:02:02
on the Avalanche platform Avalanche is
00:02:05
the fastest smart contracts platform out
00:02:08
there it allows you to build fast
00:02:11
low-cost solidity compatible apps on top
00:02:14
of that with subnets Avalanche allows
00:02:17
you to build your own custom Network
00:02:19
optimized to fit all of your Project's
00:02:22
needs
00:02:23
subnets will give web3 games complete
00:02:26
control over their own customizable
00:02:28
blockchain networks without sacrificing
00:02:31
security or decentralization that allows
00:02:35
you to rapidly scale your user base set
00:02:38
customizable rules for your blockchain
00:02:39
and focus on gameplay essentially with
00:02:43
avalanche's help you'll learn how to
00:02:45
create a full-fledged web 3.0 online
00:02:49
multiplayer game and learn the ins and
00:02:51
outs of blockchain in a single video
00:02:54
besides the speed and inexpensiveness of
00:02:57
using Avalanche the thing I like about
00:03:00
it the most is its backwards
00:03:02
compatibility with existing ethereum
00:03:04
virtual machine tools and workflows let
00:03:07
me explain suppose you have experience
00:03:10
creating web 3D apps for any ethereum
00:03:13
virtual machine or use tools Like
00:03:15
metamask Remix truffle hard hat web3js
00:03:19
ethers JS or open Zeppelin and More in
00:03:23
in that case precisely the same scripts
00:03:26
and workflows will work on Avalanche
00:03:29
with no changes needed isn't that great
00:03:33
we'll use the most in demand
00:03:35
Technologies today and I'll teach you
00:03:37
how to deploy your game online so you
00:03:40
can play it with your friends share it
00:03:42
with your potential employers and put it
00:03:44
in your portfolio if this video reaches
00:03:46
20 000 likes I'm recording another web 3
00:03:50
video
00:03:51
what I've just showed you might seem
00:03:53
simple but trust me there's a lot of
00:03:56
blockchain and web3 logic happening
00:03:59
behind the scenes and I strongly believe
00:04:01
that building this app is the best way
00:04:04
to truly understand how web3 and smart
00:04:07
contracts work excellent with that said
00:04:10
there's just one more important
00:04:12
announcement I want to share with you
00:04:14
before we dive into the project
00:04:16
since this is a web 3 heavy
00:04:18
project-based video I've also prepared
00:04:21
for you two entirely free web 3
00:04:24
resources one is a comprehensive web3
00:04:27
roadmap and the other is a solidity
00:04:30
cheat sheet the link to download these
00:04:32
resources entirely for free is in the
00:04:34
description on top of that I've also
00:04:37
created a web 3.0 course in which you'll
00:04:40
build an entire fully functional nft
00:04:43
Marketplace this 10 hour course dives
00:04:47
into everything you need to know about
00:04:48
solidity web3 and smart contracts also
00:04:52
since you're watching this video by
00:04:54
using the link in the description you're
00:04:56
gonna get a special discount code that's
00:04:58
going to automatically be applied for
00:05:00
you during checkout this groundbreaking
00:05:03
project will impress your potential
00:05:04
employers making
00:05:06
jsmastery.pro the only source of
00:05:09
knowledge needed to land your dream high
00:05:11
paying web3 job that you can enjoy for
00:05:14
many years to come with that said let's
00:05:17
Dive Right into today's video
00:05:20
[Music]
00:05:28
to get started we're going to create an
00:05:31
empty new folder on our desktop let's
00:05:34
call it nft underscore card underscore
00:05:37
game I also opened an empty Visual
00:05:40
Studio code window so simply drag and
00:05:43
drop that folder
00:05:45
once you do that we're gonna have our
00:05:48
folder opened in the most popular code
00:05:50
editor out there
00:05:51
so now what we can do is we can go to
00:05:54
view and then terminal this is going to
00:05:57
open up the built-in integrated vs code
00:06:00
terminal we can also click right here to
00:06:03
open up the Explorer and we are ready to
00:06:05
start setting up our project structure
00:06:07
we are going to start this video off
00:06:10
with the web 3 blockchain side of things
00:06:12
so to get started let's right click
00:06:15
right here and create a new folder
00:06:18
called web3 now inside of our terminal
00:06:22
we can CD or change directory into web3
00:06:26
now to properly initialize our
00:06:28
blockchain side of things we're going to
00:06:30
have to follow a couple of steps and run
00:06:32
a couple of commands but don't worry I'm
00:06:35
gonna show you how to do everything step
00:06:37
by step to make things even easier for
00:06:40
you I've created an entire GitHub
00:06:42
repository with the finalized code while
00:06:45
you're here feel free to give it a star
00:06:48
in here you can scroll down and you can
00:06:51
see all the instructions on setting up
00:06:53
the web3 part of their projects written
00:06:55
step by step but don't worry we're going
00:06:58
to go through everything together and
00:07:00
I'm gonna show you how to go through
00:07:02
every single one of these steps to
00:07:04
ensure that you can follow along nicely
00:07:06
another great thing we've recently done
00:07:08
on the GSM YouTube channel is created a
00:07:12
special Discord Community this Discord
00:07:14
Community is huge and we are already at
00:07:18
over 14 000 members but that's not what
00:07:22
I want to share with you what I do want
00:07:24
to share with you is this special video
00:07:27
help section in here we're going to have
00:07:30
a special Forum board for every single
00:07:32
one of our videos so if you're
00:07:34
experiencing some issues with the setup
00:07:36
the best way to get help is not going to
00:07:39
be through YouTube comments rather It's
00:07:41
Gonna Be by creating a new help Post in
00:07:44
this special video help Channel there
00:07:47
myself other administrators and other
00:07:49
people will be able to assist you
00:07:52
with that said let's begin with
00:07:54
initializing our web 3 side of things
00:07:56
once we are in the web3 directory we can
00:08:00
run the MPX hard hat command
00:08:03
you might get prompted to install hard
00:08:05
hat in that case simply press Y and
00:08:08
press enter once you do that we can
00:08:11
choose typescript but no worries no
00:08:13
typescript knowledge will be required
00:08:15
for hard hat project root simply press
00:08:18
enter
00:08:19
and press enter one more time
00:08:23
there we go this just initialized a
00:08:25
project inside of our web3 directory
00:08:28
if you scroll a bit up you can see that
00:08:30
we need to install some dependencies to
00:08:32
run the sample project so let's simply
00:08:34
copy this message right here
00:08:36
paste it and then press enter this is
00:08:39
going to install a couple of Dev
00:08:40
dependencies
00:08:42
that's going to take just a moment and
00:08:44
I'll be right back alongside those Dev
00:08:47
dependencies we're gonna also need a
00:08:49
couple of regular dependencies so let's
00:08:51
run npm install add open Zeppelin
00:08:56
forward slash contracts
00:08:59
dot EnV at nomic Labs forward slash hard
00:09:04
hat Dash ethers and you can press enter
00:09:07
these dependencies installed really
00:09:09
quickly if you want to be sure to get
00:09:11
the right ones you can simply copy this
00:09:13
command from here as well
00:09:15
there we go we can clear the terminal
00:09:18
now we have installed all the important
00:09:20
dependencies we're gonna use for the web
00:09:22
3 side of things the next thing we have
00:09:25
to do is install the browser wallet
00:09:28
extension
00:09:30
that's going to allow us to interact
00:09:32
with the blockchain through our browser
00:09:33
our application will be written in
00:09:36
solidity
00:09:37
but we'll be using Avalanche to build
00:09:40
the app faster and at lower costs so
00:09:44
it's going to allow us to launch those
00:09:46
ethereum dabs even more quickly with
00:09:49
transactions happening instantly because
00:09:51
of that we'll be using avalanche's
00:09:54
special core wallet core is a metamask
00:09:58
alternative for Avalanche dapps
00:10:01
the application you'll build today will
00:10:03
work just fine with the metamask wallet
00:10:05
but since we're building on top of
00:10:08
avalanche core is going to be much much
00:10:11
faster and since we're building a game
00:10:13
we need to be as interactive as possible
00:10:17
that's why I decided to use the core
00:10:20
wallet to get the core wallet on the
00:10:22
Chrome browser you can simply go to
00:10:24
Chrome web store and then search for
00:10:27
core
00:10:28
if you're using another browser that
00:10:30
doesn't support core yet I would suggest
00:10:32
switching to Chrome at least for the
00:10:34
purposes of this video because Chrome
00:10:36
also allows us to have multiple accounts
00:10:38
which we'll have to use to test the
00:10:41
online multiplayer game functionality so
00:10:43
it might be a good chance to switch to
00:10:45
Chrome if not if you really want to
00:10:48
stick with another browser in that case
00:10:49
you'll have to use metamask so keep in
00:10:52
mind the transactions will be a bit
00:10:54
slower than on core
00:10:56
with that said I have entirely removed
00:10:59
core from my browser so I can guide you
00:11:01
step by step on how to install it so
00:11:04
let's click add to Chrome
00:11:06
it's going to automatically open up this
00:11:08
window and you can click create a new
00:11:11
wallet
00:11:13
you can click I agree
00:11:15
in here you can enter your wallet name
00:11:17
I'm gonna do something like JS Mastery
00:11:19
you can choose your password I'm gonna
00:11:22
go with something really simple
00:11:24
and you can agree and acknowledge and
00:11:27
click save
00:11:28
now in here you're going to get your
00:11:30
secret recovery phrase this is the most
00:11:33
sacred password there is when it comes
00:11:36
to blockchain wallets of course on mine
00:11:38
there won't be any real funds so I can
00:11:40
show it to you but keep this one to
00:11:42
yourself write it down somewhere because
00:11:45
we're gonna need it to initialize our
00:11:47
wallet I'm gonna copy it
00:11:49
save it somewhere click understand and
00:11:53
click next
00:11:54
now I'm gonna paste into URL here what I
00:11:57
copied so we can see the words and it
00:12:00
asks us to verify these secret recovery
00:12:02
phrase so let's select the word that
00:12:05
comes after mule let's find it it's
00:12:07
going to be SEC word that comes after
00:12:10
nuclear is going to be picture and a
00:12:13
word that comes after shallow
00:12:16
that's going to be safe and let's click
00:12:19
next
00:12:21
there we go our wallet is here and let's
00:12:24
just click the extensions Tab and let's
00:12:27
spin it for easy access
00:12:29
there we go our wallet is now here we're
00:12:33
going to set it as a default wallet as
00:12:35
well perfect now what we have to do as
00:12:38
well is open the extension
00:12:41
click the settings right here by
00:12:43
clicking the hamburger menu
00:12:44
go to Advanced and then turn on the test
00:12:48
net mode this is going to allow us to
00:12:50
interact with test Networks
00:12:53
great now we need to fund our wallet
00:12:56
from the avax faucet to do that you can
00:12:59
click the link down in the description
00:13:00
it's going to lead you to the
00:13:03
faucet.avax.network you can choose the
00:13:06
network Fuji C chain avax is the token
00:13:09
and you can click connect
00:13:11
it's immediately going to prompt your
00:13:12
wallet and you can click approve and
00:13:15
just click request to avax there we go
00:13:18
transaction successful and in just a
00:13:21
couple of seconds if you open up your
00:13:23
wallet again you should be able to see
00:13:25
two avax right here it is so great that
00:13:29
we got the tokens really fast when you
00:13:31
install core it's most likely going to
00:13:34
give you a lot of messages so you have
00:13:36
to click this icon right here go to
00:13:39
console settings and then click selected
00:13:42
context only because that way you can
00:13:45
filter out all of the ethers related
00:13:47
messages
00:13:48
now we can go back to our Visual Studio
00:13:50
code and we can create a new DOT EnV
00:13:54
file inside of the web3 folder so that's
00:13:57
going to be dot EnV again make sure that
00:14:01
it is inside of the web3 folder as we're
00:14:03
going to have another EnV for the client
00:14:05
side there create a private underscore
00:14:09
key variable and for now we're going to
00:14:12
leave this empty now in here we'll have
00:14:14
to put the private key of our wallet so
00:14:17
here's how to get it open up the core
00:14:19
extension
00:14:20
click the hamburger menu on the top left
00:14:23
go to security and privacy
00:14:26
click show recovery phrase
00:14:29
and then enter your password
00:14:32
once you do that it's going to show you
00:14:34
your recovery phrase again keep this to
00:14:37
yourself you need to copy it and then
00:14:40
you can head to
00:14:42
wallet.avax.network again the link is
00:14:44
going to be down in the description
00:14:46
click access wallet
00:14:49
choose mnemonic key phrase
00:14:52
and paste your phrase right here
00:14:54
immediately you'll be logged into your
00:14:57
wallet and in here if it's not selected
00:14:59
already
00:15:00
choose the Fuji test Network to be
00:15:03
connected to it now go to manage keys on
00:15:07
the left side sidebar and click view C
00:15:10
chain private key
00:15:13
finally
00:15:14
copy it now we can go back to vs code
00:15:17
and you can paste it right here equal to
00:15:20
your private key
00:15:21
great now we have funds and we're
00:15:25
connected to our wallet we can close
00:15:27
this open up the folder and go to the
00:15:32
hardhat.config.ts in here we have a
00:15:34
basic configuration what you can do
00:15:37
right now is go into the description of
00:15:39
this video and find a GitHub gist I
00:15:41
provided just for you there you'll be
00:15:44
able to find a new and updated
00:15:46
hardhat.config dot DS and you can simply
00:15:50
paste it right here this hard hat config
00:15:53
contains a bit more settings to make
00:15:56
sure our app is deployed properly on the
00:15:58
Fuji test Network on top of that I've
00:16:01
also included some comments right here
00:16:03
explaining how to deploy this contract
00:16:06
later on on your own subnet initially
00:16:10
the decentralized application you're
00:16:12
going to build in this video will be
00:16:14
deployed on the C chain of our primary
00:16:16
subnet on our testnet called Fuji and we
00:16:20
can see that right here eventually as
00:16:23
your app grows you will probably want to
00:16:25
move it to your own subnet
00:16:28
if you want to learn more about subnets
00:16:30
why would you ever need to deploy in a
00:16:32
subnet or how would you Deploy on a
00:16:35
subnet then you're going to find these
00:16:37
links incredibly useful essentially the
00:16:41
4G C chain testnet is great for
00:16:43
developing but as your app starts
00:16:46
growing and you start driving a lot of
00:16:48
transactions and gas fees then it might
00:16:51
be a good idea to migrate to a subnet
00:16:54
instead of the first link you have a lot
00:16:56
of information on when you might want to
00:16:58
use a subnet versus a c chain testnet
00:17:01
and inside of a second link you have
00:17:04
complete documentation on how to
00:17:06
accomplish that on your own essentially
00:17:08
transactions on the C chain might take
00:17:11
about 2 to 10 seconds the ones on the
00:17:14
subnet will be much faster also on C
00:17:17
chain we're relying on the avax token to
00:17:19
confirm transactions but on the subnet
00:17:22
we can create our own token essentially
00:17:25
you will be in complete control over the
00:17:28
net work and its inner workings and I've
00:17:31
also left out the structure to put in a
00:17:34
subnet right here in case you want to do
00:17:36
that later on on your own great that's
00:17:39
going to be it for our hard hat config
00:17:41
DS now we can close that and we can go
00:17:44
into scripts and open up the deploy.ts
00:17:47
script inside of here you can see some
00:17:50
demo code that hard hat created again
00:17:53
down in the description in that same
00:17:55
GitHub gist you can find the updated
00:17:58
deploy.ts script and you can simply
00:18:01
paste it here it is as simple as
00:18:04
creating a new contract Factory right
00:18:06
here and then deploying it after we do
00:18:09
that the only thing we want to get is
00:18:11
the address of the deployed smart
00:18:13
contract which is the only thing that
00:18:16
this deploy script does great and to
00:18:19
finalize our web3 side of things of
00:18:21
course the most important part is
00:18:23
missing and that is the contracts and of
00:18:27
course our smart contract we're going to
00:18:29
delete this log that Soul as that is a
00:18:32
demo smart contract and we're going to
00:18:34
create our own called avax Gods dot Sol
00:18:39
the smart contract created for this
00:18:42
application has about 500 lines and I
00:18:47
don't simply want you to copy and paste
00:18:49
what I'm typing for 500 lines so again
00:18:52
in that same GitHub gist in the
00:18:54
description down below there's going to
00:18:56
be a complete avax
00:18:58
gods.soul smart contract
00:19:00
as you can see it is a long contract and
00:19:04
it has a lot of code but don't worry
00:19:07
we're going to go through everything
00:19:08
together and I'm going to explain all of
00:19:11
the most important functionalities I was
00:19:14
thinking about this for a long time what
00:19:16
I want you to Simply copy every
00:19:18
character I'm writing for these 500
00:19:20
lines or would I want to connect this to
00:19:24
the front end and then come back and
00:19:27
reference the smart contract in places
00:19:29
where it makes sense that way we can
00:19:32
come back and explore specific functions
00:19:35
exactly where we're using them that way
00:19:38
we are still going to explain all the
00:19:40
most important functionality but you'll
00:19:43
also be able to see what it does on the
00:19:45
front end and how it behaves in my
00:19:48
opinion you're going to learn about
00:19:49
events about Constructors functions and
00:19:53
everything so much better if we show it
00:19:56
how it's already written and then
00:19:58
explain over it hopefully that makes
00:20:00
sense Sense on the other hand if you'd
00:20:02
like me to create a complete course
00:20:04
where we go in depth about writing this
00:20:07
smart contract by hand you can let me
00:20:09
know down in the comments and if that's
00:20:11
something you would be interested in and
00:20:13
you need it right now then I have
00:20:15
phenomenal news for you just recently we
00:20:19
published cryptocad an entire nft
00:20:21
Marketplace application course inside of
00:20:24
this 12 hour course you're going to
00:20:26
create your own blockchain based
00:20:29
Marketplace application where people can
00:20:31
discover create purchase and sell nfts
00:20:34
and the best thing about it is that
00:20:37
everything is written in solidity from
00:20:40
scratch which means that you're going to
00:20:42
master solidity by creating an entire
00:20:45
smart contract from scratch you're gonna
00:20:47
learn how to leverage and test smart
00:20:50
contracts harness the power of
00:20:52
blockchain and use it on a real nexgs
00:20:55
application it has beautiful designs and
00:20:57
you're going to learn how to create
00:20:59
explore nfts page listed nfts my nfts
00:21:03
and how to upload your own nfts to the
00:21:06
blockchain so one more time if this is
00:21:09
something you would be interested in the
00:21:10
link is going to be down in the
00:21:12
description and because you're watching
00:21:14
this video you're gonna have a special
00:21:16
unique YouTube discount code
00:21:19
so feel free to check it out with that
00:21:21
said now that we have our smart contract
00:21:24
our deploy script and our hard hat
00:21:27
config we are ready to deploy the smart
00:21:29
contract to the blockchain and as I've
00:21:32
said don't worry we're gonna come back
00:21:34
and explore the functionalities of the
00:21:36
smart contract in depth as we're
00:21:39
implementing them on the front end
00:21:41
to deploy our smart contract we can go
00:21:43
to view and then terminal
00:21:45
first we need to compile it so let's run
00:21:48
the MPX hard hat compile command and
00:21:52
make sure that you're in the web3
00:21:53
directory this process is going to take
00:21:56
a couple of seconds and I'm gonna be
00:21:58
right back
00:22:00
and there we go the contract has been
00:22:02
compiled finally we need to deploy the
00:22:05
smart contract on the Fuji test net by
00:22:08
running the command MPX hard hat run
00:22:12
scripts forward slash deploy dot TS dash
00:22:17
dash Network space Fuji
00:22:21
this process usually takes about a
00:22:23
minute and your smart contract is going
00:22:25
to be deployed I was wrong it actually
00:22:28
took about five seconds and here it is
00:22:30
now there is one more important thing we
00:22:33
need to do and that is save the address
00:22:36
of the deployed smart contract so for
00:22:39
now let's simply safely store it inside
00:22:42
of the dot EnV so let's say contract
00:22:45
underscore address is equal to and let's
00:22:49
put it here we're gonna use it later on
00:22:52
on the client side to access all the
00:22:54
functionalities of the contract and also
00:22:57
later on we're going to use the contract
00:23:00
ABI which is right here to be able to
00:23:03
fetch all of the functions on the client
00:23:05
side so we can call them and we can
00:23:07
manipulate with the data on the smart
00:23:09
contract
00:23:10
great with that said we're done with the
00:23:13
web 3 side of things but as I've said as
00:23:16
we're developing the front end and
00:23:18
integrating the smart contract we're
00:23:20
going to come back many times to the
00:23:22
smart contract to check things like
00:23:24
create battle create different players
00:23:27
and actually work with the game
00:23:29
functionality we're gonna explore all of
00:23:32
this code as we're developing it with
00:23:35
that said we're now ready to create our
00:23:37
front-end side of things and then we'll
00:23:39
be able to connect the two to make
00:23:41
initializing and starting up our
00:23:44
client-side a bit simpler I prepared a
00:23:48
client starter folder for you that's
00:23:50
going to allow us to really quickly get
00:23:52
you up and running and then we can focus
00:23:55
on what matters which is building out
00:23:57
the application's logic creating the UI
00:24:00
and ux and finally integrating it with
00:24:04
the web3 smart contract so down below in
00:24:07
the description you can find a link to a
00:24:10
zipped version of the client starter
00:24:12
simply download it unzip it and then you
00:24:15
can come to the file explorer right
00:24:17
click and then click paste finally we
00:24:21
can rename this to something like client
00:24:23
which is the client side of our
00:24:25
application if we expand our client we
00:24:28
can see that this is a regular react.s
00:24:31
application built using Veet Veet is a
00:24:36
new and modern create react app
00:24:38
alternative that is a lot faster than
00:24:41
create react app
00:24:43
in here I've also set up a basic tailfin
00:24:46
configuration with some colors that
00:24:48
we'll be using background images and a
00:24:52
font family alongside that there is a
00:24:55
package.json that contains just a couple
00:24:57
of dependencies
00:24:59
as you can see we'll be using packages
00:25:01
like ethers and the web3 model to make
00:25:04
the web3 integration possible then we'll
00:25:08
be using the react model to show some
00:25:10
information on the screen we'll be using
00:25:12
the react Parallax tilt and react tool
00:25:15
tab to make things a bit more
00:25:17
interactive and finally we're using the
00:25:19
react router Dom to of course create
00:25:21
routing now we can dive into the source
00:25:24
folder to explore the app in more depth
00:25:28
right here it seems like there's a lot
00:25:30
of things happening but all of these are
00:25:33
mostly just empty folder with basic
00:25:35
starter files so let's look into the
00:25:38
assets folder first in here I prepared
00:25:41
for you all background images all sounds
00:25:46
like attack defense and explosion
00:25:48
they're going to be used throughout the
00:25:49
application and I've also prepared for
00:25:52
you attack and defense icons as well as
00:25:56
all of the cards that there are so this
00:25:59
is going to be an interesting video but
00:26:01
as you can see there is a lot of files
00:26:04
so I needed to make sure that you have
00:26:06
everything to be ready to get started
00:26:09
with coding out the logic when it comes
00:26:12
to the components there is just one
00:26:13
component prepared for you here which is
00:26:16
the onboard model this is a basic often
00:26:19
used web3 component that just checks
00:26:22
that everything is set up properly it
00:26:24
makes sure that we have the core wallet
00:26:27
installed all also make sure that we are
00:26:30
connected to our wallet and that we are
00:26:32
on the right Network and finally that we
00:26:35
have enough avax tokens but since we're
00:26:38
fine with all of these checks we
00:26:40
shouldn't see the model at all which is
00:26:42
why I provided it to power up that model
00:26:45
we also have the onboard utils and even
00:26:49
more important we have a
00:26:51
animations.js file which provides us the
00:26:55
explosion animations we'll be using
00:26:57
this is a long file but this isn't the
00:27:00
code that I've created from scratch I
00:27:03
found it on this great codepan
00:27:05
Repository
00:27:06
as you can see this animation has been
00:27:08
created by David and we simply have to
00:27:11
click for 8-bit Dom action
00:27:14
so I'm going to click it a couple of
00:27:16
times and this is going to be exactly
00:27:18
what our players will see once their
00:27:21
cards are attacked great finally on top
00:27:24
of that we have a basic home page and we
00:27:28
have some often used Styles we'll be
00:27:30
using across our application like text
00:27:33
Styles we have also a higher order
00:27:35
component Styles Battleground pages and
00:27:39
regular containers great and finally we
00:27:42
have an index.css file where we're
00:27:45
importing tailwind and the font we'll be
00:27:47
using throughout our application
00:27:50
finally there is a main.jsx file where
00:27:53
we imported the routes or the router
00:27:56
from the react router Dom and right now
00:27:58
there is just one route there which is
00:28:01
the Home Route great now you know
00:28:04
everything there is to know about our
00:28:06
current starter folder to run our
00:28:08
application we have to go to view and
00:28:11
then terminal then we have to CD dot dot
00:28:14
to go One Directory back and then we
00:28:17
have to CD into client finally we can
00:28:20
run npm install to install all the
00:28:23
necessary dependencies
00:28:25
this process is going to take just a
00:28:27
couple of seconds because most of the
00:28:29
things will be coding from scratch and
00:28:32
finally once that is done you can run
00:28:34
mpm run Dev which is going to start our
00:28:38
veed application on localhost 5173 and
00:28:42
there we go a blank white screen that
00:28:45
says avax gods web 3 nft battle style
00:28:50
card game made with love by JavaScript
00:28:52
Mastery and as you can see I think that
00:28:55
now you can trust me that this is just
00:28:57
an empty boilerplate folder because
00:28:59
there is nothing on the screen no
00:29:01
functionality whatsoever we're going to
00:29:04
code everything from scratch and make it
00:29:08
look like this
00:29:09
so to get started we can now put our
00:29:12
browser side by side with our editor and
00:29:16
finally we can close our terminal and we
00:29:19
can go to source and then home this is
00:29:22
going to be our app's starting point
00:29:25
right off the bat we're gonna start with
00:29:27
something phenomenal that not a lot of
00:29:30
people teach you
00:29:31
if you check out the finished website
00:29:33
you can notice that we have our home
00:29:36
page welcome to evax Gods a web 3 NFD
00:29:39
card game connect your wallet to start
00:29:42
playing the ultimate web 3 Battle card
00:29:44
game this is great but then if we move
00:29:47
to forward slash create Dash battle you
00:29:51
can see that the design is essentially
00:29:54
the same the logo is there we have a
00:29:57
title we also have a subheading and we
00:30:00
have an image and the footer at the
00:30:02
bottom but what changed is the content
00:30:05
for the text right here here and then
00:30:08
the input inside of the component
00:30:10
so as I've said I'm quite excited about
00:30:13
this part because I'm gonna teach you
00:30:15
how to accomplish code reasonability in
00:30:18
react using higher order components
00:30:22
that's something that not a lot of
00:30:24
people teach you so let's dive right
00:30:27
into it
00:30:28
to start creating our high order
00:30:30
component we can open up the components
00:30:32
and create a new file right inside of
00:30:35
there let's call it page hoc like higher
00:30:39
order component Dot jsx
00:30:42
inside of there you can run rafce to
00:30:47
create a basic react functional
00:30:49
component structure if that didn't work
00:30:51
for you you can go to extensions and
00:30:54
then type es7 Plus
00:30:56
Snippets like this this is the extension
00:31:00
you need to be able to run RAF CE once
00:31:03
you install it this should work
00:31:05
perfectly inside of our high order
00:31:07
component which for now looks just like
00:31:09
a regular component we can import the
00:31:12
use navigate hook coming from react
00:31:17
router Dom as later on we're going to
00:31:19
use it to re-navigate somewhere we can
00:31:22
also import the logo as well as the hero
00:31:26
IMG
00:31:27
coming from dot slash assets
00:31:31
and we can also import these styles
00:31:34
as a default import coming from dot
00:31:38
slash Styles great the difference
00:31:41
between a higher order component and the
00:31:44
regular component is that as a first
00:31:46
parameter it's going to accept a new
00:31:49
component that we're going to pass into
00:31:51
it essentially it's going to act as a
00:31:54
wrapper for that smaller inside
00:31:57
component we can also pass some
00:31:59
additional things like a title and a
00:32:02
description
00:32:04
finally due to the way we'll be calling
00:32:07
our higher order component we have to
00:32:09
add one more function right here
00:32:11
essentially it's going to be a function
00:32:13
inside a function
00:32:16
you're going to see really quickly how
00:32:18
we're going to call it in here we can
00:32:20
initialize that navigate Hook by saying
00:32:23
const navigate is equal to use navigate
00:32:26
finally let's start creating the layout
00:32:29
first we're going to have a div that's
00:32:31
going to have a class name equal to
00:32:34
Styles dot hoc container
00:32:39
inside of there we're going to have
00:32:41
another div that's going to have a class
00:32:43
name
00:32:44
equal to styles
00:32:47
dot hoc content box
00:32:51
and if you're wondering where these
00:32:53
styles are coming from you can always
00:32:55
hold Ctrl and then click on that name
00:32:58
it's going to show you exactly what
00:33:00
styles are being used here and this is
00:33:03
using Tailwind so if you're not sure
00:33:06
what py8 or small or PX means you can
00:33:10
quickly look that up in Tailwind docs
00:33:12
just go to tailwindcss.com and search
00:33:16
for by for example immediately you'll be
00:33:20
able to see that that serves your
00:33:23
padding and it provides padding y on
00:33:26
y-axis meaning vertical if you want to
00:33:29
search for something else like Flex call
00:33:31
let's see Flex Dash call and immediately
00:33:35
you can see that this is used to
00:33:37
position the items vertically great so
00:33:40
now you know that you can research any
00:33:42
property we're using right here with
00:33:44
that said let's continue with the layout
00:33:46
inside of this div let's also create an
00:33:49
image that's going to be a self-closing
00:33:52
image tag with a source equal to logo
00:33:55
alt equal to logo class name equal to
00:33:59
Styles dot hoc logo and it's going to
00:34:04
have an unclick property with a callback
00:34:06
function where we're going to Simply
00:34:09
navigate to just forward slash meaning
00:34:12
the home page
00:34:14
great now if we save this nothing is
00:34:17
going to happen because we're not yet
00:34:20
using this page higher order component
00:34:22
so now let me show you how we can use it
00:34:25
before we do that let's export it from
00:34:28
our components folder by creating a new
00:34:31
index.js file and then inside of there
00:34:33
we can import it by saying import page
00:34:37
hoc
00:34:39
from that slash page hoc and then we can
00:34:42
say export object and then we can put
00:34:45
that component right there this is now
00:34:48
going to allow us to go back into home
00:34:50
and then import the page hoc inside of
00:34:55
curly braces like this import page hoc
00:34:59
from dot dot slash components great so
00:35:05
finally how do you use it what is the
00:35:07
difference between a higher order
00:35:08
component and a regular component
00:35:11
well a high order component can wrap
00:35:14
another component
00:35:16
and in this case we're going to wrap our
00:35:18
home right at the bottom where the
00:35:20
expert is so right here let's call the
00:35:23
page hoc
00:35:25
let's call it as a function and the
00:35:27
first parameter is going to be that
00:35:29
second component which is going to be
00:35:31
the home now if we save this and reload
00:35:35
the page
00:35:36
you can immediately see that everything
00:35:39
becomes dark and we can see the logo
00:35:41
that is coming from our page hoc but
00:35:45
this is not that interesting yet because
00:35:47
we cannot see anything else how can we
00:35:50
see this content from the home page as
00:35:52
well that is the custom content right
00:35:55
well to be able to see that we can go
00:35:57
back to page hoc and we can make use of
00:36:00
the first prop which is a component so
00:36:03
right below the image we can create one
00:36:06
more div
00:36:07
let's give it a class name equal to
00:36:10
Styles dot hoc body wrapper and inside
00:36:15
of there let's render a self-closing
00:36:19
component tag and save it
00:36:22
as soon as you do that you'll be able to
00:36:24
see barely that all of her texts
00:36:26
appeared right here even though it is
00:36:29
dark right now we know that it is there
00:36:32
so how else can we modify a higher order
00:36:35
component well we specified that it's
00:36:38
going to accept some additional props so
00:36:40
let's pass them let's pass an empty
00:36:43
react fragment that's going to say
00:36:45
welcome to avax Gods let's also add a
00:36:49
Break Tag here and then we can say a web
00:36:52
3 NFD card game this is the title let's
00:36:58
also add another fragment and in here
00:37:00
let's say connect
00:37:03
your wallet
00:37:05
to start playing
00:37:07
and let's add a Break Tag and then we
00:37:10
can say the ultimate web3 battle
00:37:14
card game
00:37:15
of course we have to add a comma right
00:37:18
here
00:37:19
great so now how do we retrieve that
00:37:22
data inside of our high order component
00:37:24
well we have the title and description
00:37:27
props so right here inside of the hoc
00:37:31
body wrapper let's go ahead and create a
00:37:34
div
00:37:35
that div is going to have a class name
00:37:38
equal to flex Flex Dash row and W Dash
00:37:44
full inside of there we can render an H1
00:37:47
element that's going to render the title
00:37:51
and right below that we can render a p
00:37:54
element keep in mind we're below this
00:37:57
div right here that's going to render
00:37:59
the description now let's save that and
00:38:03
immediately we can see our text right
00:38:05
here of course it's not really styled so
00:38:08
let's apply some styles to rh1 let's
00:38:12
give it a class name equal to it's going
00:38:15
to be a template string of flex now a
00:38:18
dynamic dollar sign curly braces Styles
00:38:21
dot head text and finally head Dash text
00:38:26
if we save this this is already looking
00:38:29
better we can now unzoom it
00:38:31
and let's also add the styles to the
00:38:34
description by saying class name is
00:38:37
equal to Dollar side curly braces Styles
00:38:40
dot normal text and also my for margin y
00:38:45
10 and save it there we go this is
00:38:50
looking great let's expand it just a bit
00:38:53
there we go it looks even better now and
00:38:56
for now let's remove these three
00:38:58
elements as we no longer need them we
00:39:01
have everything inside of our higher
00:39:03
order component
00:39:05
now let's go back into it and let's
00:39:08
apply the image as well as the footer as
00:39:11
well
00:39:12
to do that we can go below our component
00:39:15
now and Below one more div
00:39:17
let's create a P tag that's going to
00:39:20
have a class name
00:39:22
equal to Styles dot footer text and in
00:39:27
there we can say made with love by JSM
00:39:33
if we save this we can see it right
00:39:35
there and just to match the theme a bit
00:39:37
more we can change this to made wet and
00:39:40
then this purple heart right here and of
00:39:43
course feel free to change this name to
00:39:45
your own finally let's get that great
00:39:47
image so below the speed tag and Below
00:39:50
one more div we can create a final div
00:39:53
of this component it's going to have a
00:39:56
class name equal to flex and flex dash
00:39:59
one and inside of it we can render a
00:40:02
self-closing image that's going to have
00:40:05
the source equal to Hero IMG we're gonna
00:40:09
also give it an ALT tag hero Dash IMG
00:40:12
and we're going to give it a class name
00:40:15
equal to
00:40:17
W-4 on extra large devices height is
00:40:21
full as well and it's going to be object
00:40:24
cover
00:40:25
now if we save this we have a beautiful
00:40:29
home page component but more than that
00:40:32
it is not just a home we already
00:40:35
discussed that we're going to use the
00:40:37
same layout for the home page for the
00:40:39
create battle page for the choose
00:40:41
Battleground page and for join panel
00:40:44
page that's three to four different
00:40:46
pages they're gonna have a similar
00:40:48
layout so let me show you how we can
00:40:51
make full use of our higher order
00:40:53
component and how we can make things
00:40:55
reusable let's create a new page right
00:40:59
inside of the pages folder called create
00:41:03
battle.jsx for now we can copy the
00:41:06
entire home page and then paste it right
00:41:09
here the only thing we have to do is
00:41:11
change the home in line 5 and 14 to
00:41:15
create battle inside of create battle
00:41:19
we're gonna say something like
00:41:21
create BR and then right here we can say
00:41:26
a new battle and under description we
00:41:30
can say something like create your own
00:41:34
battle and wait for other players to
00:41:39
join you
00:41:40
there we go and finally we have to go
00:41:43
inside of the main
00:41:45
there we're gonna have to import the
00:41:47
create battle so from the pages folder
00:41:50
let's first export it by right clicking
00:41:53
the page and creating a new file called
00:41:56
index.js there we can import our home
00:41:59
page coming from dot slash home
00:42:02
and we can also import our create battle
00:42:06
page coming from create battle and we
00:42:10
can export both of these inside of a
00:42:13
object that's going to look like this
00:42:15
home and create battle
00:42:17
that's going to allow us to go back into
00:42:19
Main and import both the home
00:42:23
and the create battle in one line
00:42:27
clean and simple and that's going to be
00:42:29
coming from dot slash page
00:42:32
we can now duplicate this route
00:42:35
change it to create forward slash battle
00:42:38
and change the render page to create
00:42:42
battle
00:42:43
now if we save this
00:42:45
we can manually go to forward slash
00:42:48
create Dash battle and check it out
00:42:52
same layout but different text and
00:42:55
different elements if we now go back
00:42:58
you can see the difference we did this
00:43:00
just by literally having an empty
00:43:03
component and using a page higher order
00:43:06
component
00:43:07
of course inside of here now we can
00:43:10
create additional elements such as an H1
00:43:13
with a class name let's do text Dash
00:43:16
white and say hello from create battle
00:43:21
now if we save this and go to forward
00:43:25
slash create Dash paddle you can see
00:43:28
hello from create battle let's make that
00:43:31
a bit bigger so text Dash XL and we can
00:43:35
copy this and put the same thing into
00:43:37
home
00:43:38
which is going to say hello from home
00:43:41
and we can now keep switching between
00:43:43
the two which means that we can now have
00:43:46
the entire design being the same with
00:43:49
almost little to no effort as this
00:43:52
component is already coded out but we
00:43:54
can keep changing what goes inside of
00:43:58
these component with the logic and with
00:44:00
everything else that is in there perfect
00:44:02
I'm really happy that this early in the
00:44:05
video I got to show you the power of
00:44:08
using higher order components if you
00:44:11
like this part of the video go down to
00:44:13
the comments right now and let me know
00:44:15
if you do that I'll try to teach these
00:44:18
lectures as often as possible in future
00:44:21
videos also if you like this segment
00:44:24
You're Gonna Love what we do on
00:44:27
jsmastery.pro there we have professional
00:44:30
10 hour plus courses where we Dive In
00:44:33
Depth into react topics just like this
00:44:36
one
00:44:37
we have two courses right now the film
00:44:39
Park course which Dives in depth about
00:44:41
react and then the nft marketplace
00:44:44
course which takes nextges and web 3
00:44:47
solidity development to the next level
00:44:49
again I just wanted to put that out
00:44:51
there with that said we're now ready to
00:44:54
continue with the development of our
00:44:56
great application believe it or not
00:44:58
we're gonna jump right into action we're
00:45:02
gonna close or create battle Home
00:45:04
Hardware component and Main and we're
00:45:06
gonna Focus straight on the applications
00:45:09
context so we can go to source and we
00:45:12
can create a new folder in the source
00:45:14
folder called context this is not going
00:45:18
to be a regular context this is going to
00:45:21
be a context through which we're going
00:45:23
to connect our front-end application to
00:45:25
the web3 smart contract so let's create
00:45:28
a new
00:45:29
index.jsx file inside of there we can
00:45:33
import react we're gonna also import
00:45:36
create 8 context
00:45:38
use context use effect use ref and use
00:45:44
State I think that you can already see
00:45:47
that we're using almost all
00:45:50
functionalities from react so this will
00:45:53
be a lengthy component and it won't be
00:45:56
easy but we're going to go through it
00:45:58
we're gonna also import something known
00:46:01
as ethers coming from ethers this is a
00:46:04
package that's going to allow us to
00:46:06
interact with the smart contract we're
00:46:08
going to also import the web3 model as a
00:46:12
default import
00:46:13
like this coming from web3 model as we
00:46:18
discussed before this is going to help
00:46:20
us kind of set up the onboarding flow of
00:46:23
our application to make sure that the
00:46:25
user is properly connected to the
00:46:27
application and let's also import the
00:46:31
use navigate hook coming from
00:46:34
react-router Dash Dom then we can start
00:46:37
creating our context we can say const
00:46:39
Global context is equal to create
00:46:44
context like this
00:46:46
and then we can say export const Global
00:46:51
context provider is equal to a function
00:46:55
that has just one prop of children and
00:46:59
it's going to have a return as it is a
00:47:01
regular react component now what we want
00:47:04
to return is going to be a global
00:47:07
context dot provider a component that
00:47:10
looks like this and it accepts one prop
00:47:14
which is called value this is an object
00:47:17
where we can pass all of the values
00:47:19
which we want to share with every single
00:47:21
component in our application so right
00:47:24
here inside of the context we're going
00:47:26
to interact and connect with our smart
00:47:29
contract and then we're going to pass
00:47:31
all of those values here so we can
00:47:34
utilize them from every single component
00:47:36
within our application finally we're
00:47:39
going to also have a helper function or
00:47:42
a helper hook called export const use
00:47:46
Global context which is going to be
00:47:48
equal to a callback function where we're
00:47:52
going to call the use context and we're
00:47:54
going to pass in that Global context
00:47:56
this is going to allow us to call it
00:47:58
from other components as an example for
00:48:01
now let's pass a demo variable
00:48:05
equal to test to our value like this and
00:48:10
now we can try getting access to that
00:48:12
value from our other components
00:48:15
the first thing we have to do is go
00:48:17
inside of Main and we have to wrap our
00:48:19
entire application with our provider so
00:48:23
right here we can say import
00:48:25
Global context Provider from dot slash
00:48:29
context and then right here above routes
00:48:31
we can create a global context provider
00:48:35
component and we can put all of the
00:48:37
routes inside of it let's make sure to
00:48:40
properly indent that
00:48:42
there we go and the routes go inside
00:48:45
hopefully this makes sense so what we
00:48:48
have just done is we wrapped our entire
00:48:51
application with the global context
00:48:54
provider that means that now inside of
00:48:57
the home we should be able to
00:48:59
successfully use the demo variable we
00:49:02
have created now we're going to go back
00:49:04
to home page here
00:49:06
now the reason we can't see our app is
00:49:08
because we're not returning anything
00:49:10
from our context as you can see it is
00:49:13
empty that's why we have to put the
00:49:16
children right here which means return
00:49:18
everything that we pass to our app in
00:49:21
this case that's going to be our home
00:49:24
component great
00:49:27
now as I promised let's try testing out
00:49:30
the context from within our home
00:49:32
application right here we can import
00:49:36
use Global context coming from
00:49:40
Context the only thing we have to do to
00:49:44
get that demo variable is say const demo
00:49:48
is equal to
00:49:50
use Global context and now we can
00:49:54
console log it or even better we can
00:49:56
print it out so right here let's create
00:49:59
an H1 let's give it a class name
00:50:02
equal to
00:50:05
text Dash XL and text Dash white and
00:50:09
inside of there let's render the demo
00:50:12
variable
00:50:13
as soon as we do that we can see test
00:50:15
which means that we're successfully
00:50:17
passing the value from our Global
00:50:20
context provider all the way to our home
00:50:22
component
00:50:23
although passing something like demo is
00:50:26
not that cool so we're going to remove
00:50:27
that for now
00:50:29
and remove from here as well what is
00:50:32
cool is fetching the entire data from
00:50:34
the smart contract and then being able
00:50:37
to pass it right here so that is exactly
00:50:39
what we're going to do next we're going
00:50:42
to have a series of use effects which
00:50:44
we're going to use to connect to our
00:50:46
smart contract as soon as the
00:50:48
application loads
00:50:50
first we need to connect with our smart
00:50:53
wallet with core so to do that let's
00:50:56
create a new use State field which is
00:50:59
going to be called wallet address and at
00:51:03
the start it's going to be set as an
00:51:05
empty string
00:51:06
now let's create a function const update
00:51:09
current wallet address
00:51:14
it's going to be an asynchronous
00:51:15
function
00:51:17
and right inside of there we can say
00:51:19
const accounts is equal to a weight
00:51:22
window dot ethereum dot request and then
00:51:28
inside of there we can pass the method
00:51:30
equal to eth underscore request accounts
00:51:36
now you might be wondering what is this
00:51:38
ethereum object on the window object how
00:51:42
does that exist well let's go to inspect
00:51:45
let's open up the console and let's Type
00:51:48
window Dot ethereum
00:51:51
as soon as you do that you'll see that
00:51:53
there is a lot of different variables
00:51:55
which we can call
00:51:57
in here we have Constructors assign
00:51:59
create a lot of different things is
00:52:01
happening here and that is due to the
00:52:04
fact that we have core installed same
00:52:06
thing is happening with metamask it
00:52:08
injects web3 functionalities right into
00:52:11
your browser now let's try to console
00:52:14
log those accounts
00:52:17
there we go
00:52:19
I'm going to open up the inspect element
00:52:22
console and now of course we have to
00:52:25
call this function so let's create a use
00:52:27
effect
00:52:28
we're going to only call it at the start
00:52:31
which means that our dependency array is
00:52:33
going to be empty
00:52:35
and we're going to call our update
00:52:38
current wallet address like so
00:52:41
let's save it
00:52:43
now we get a message that essentially
00:52:46
says that we cannot connect yet and that
00:52:49
is because we haven't yet set up the
00:52:51
smart contract provider so let's do that
00:52:54
right away I'm going to create one more
00:52:57
use effect and bear with me there will
00:53:00
be a couple in this index file so let's
00:53:03
create a new use effect right below this
00:53:06
one
00:53:07
and it's also going to be called just at
00:53:10
the start of the application so
00:53:12
dependency array is going to be empty
00:53:15
there we can create a new function const
00:53:18
set smart contract and provider
00:53:23
and it's also going to be an
00:53:25
asynchronous function we're going to
00:53:27
call that function immediately as soon
00:53:29
as the website loads the reason why we
00:53:32
had to create this function and not just
00:53:34
write the code here is because it's
00:53:35
asynchronous we want to get access to
00:53:38
some async code
00:53:39
so let's initialize the web3 model
00:53:42
const web3 model is equal to new web3
00:53:47
model and we call it as a function const
00:53:50
connection is equal to a weight web3
00:53:53
model dot connect
00:53:56
const new provider is equal to
00:54:00
new ethers dot providers dot web3
00:54:05
provider and we're going to pass in that
00:54:08
connection we established here then we
00:54:11
need to get a signer who is signing the
00:54:13
contract which is going to be equal to
00:54:15
new provider dot signer
00:54:19
and finally we're gonna get a new
00:54:21
contract which is going to be equal to
00:54:24
new ethers.contract and in here we have
00:54:27
to pass the data from the smart contract
00:54:30
that we have created but of course we
00:54:33
don't have that data yet or do we well
00:54:37
we technically do but it is inside of
00:54:40
the web3 folder we are yet to pass it
00:54:43
into our client-side application but
00:54:45
even with this change done you can see
00:54:48
that we got a core notification which is
00:54:51
great for now I'm gonna reject this as
00:54:53
we're going to connect later on first
00:54:55
let's inject our smart contract into our
00:54:58
front-end application we're going to do
00:55:00
that by creating a new empty folder
00:55:03
inside of the source folder called
00:55:05
contract
00:55:07
inside of there we're going to create a
00:55:10
new index.js file
00:55:12
there we're gonna need to export that
00:55:15
address we saved before so it's going to
00:55:18
be export const address and it's going
00:55:22
to be equal to an empty string and
00:55:24
finally we can go back into web 3 . EnV
00:55:28
and we can copy this contract address we
00:55:30
saved and delete it from here make sure
00:55:33
to copy the contract address and not the
00:55:35
private key and finally you can paste it
00:55:38
here there is one more thing that we'll
00:55:40
have to do and that is take the
00:55:43
artifacts contracts and then copy and
00:55:46
paste the havax gods.json right inside
00:55:50
of our contract folder so simply drag
00:55:53
and drop it right here then inside of
00:55:55
the index we can import it
00:55:58
import contract from dot slash evox
00:56:02
gods.json and then we can export the ABI
00:56:06
from that contract so export const
00:56:08
inside of an object ABI equal as ABI in
00:56:12
capital letters or just a colon right
00:56:15
here and then is equal to contract
00:56:19
if you're wondering what an API is an
00:56:21
ABI is an application binary interface
00:56:24
it is a context that you can think of as
00:56:27
an interface between two program modules
00:56:29
essentially it allows our front-end side
00:56:32
to call the functions that we have
00:56:34
created inside of our smart contract we
00:56:37
need it to properly pair the two
00:56:39
with that said we can now go back inside
00:56:42
of our context and we can actually pass
00:56:44
the right values in of course let's
00:56:47
first import them so at the top we can
00:56:50
say import
00:56:52
ABI and address all capitalized from dot
00:56:57
slash that's going to be contract
00:57:02
and finally we can pass them right here
00:57:05
new ethers contract we're gonna pass in
00:57:08
the address
00:57:10
the ABI and the signer that's all that
00:57:15
we need to properly create a new
00:57:17
contract
00:57:18
now what are we going to do with that
00:57:19
contract well let's set it to the state
00:57:22
so we can use it later on
00:57:24
I'm going to create two new state fields
00:57:27
use state
00:57:29
that's going to be a provider
00:57:32
set provider and at the start it's going
00:57:35
to be set to an empty string and also
00:57:37
use state
00:57:40
contract set contract and that's going
00:57:44
to be set to an empty string as well
00:57:47
finally we can scroll down and we can
00:57:49
say set provider
00:57:51
and we're going to pass in the new
00:57:53
provider and we can say set contract and
00:57:56
pass in the new contract which means
00:57:58
that we're successfully setting these
00:58:00
values to the state and as you can see
00:58:02
the update current wallet address where
00:58:05
we request for accounts now actually is
00:58:08
popping up right here so let's click
00:58:10
approve great this means that we have
00:58:14
connected our wallet to our application
00:58:16
now that application is not going to
00:58:18
jump in again instead of console logging
00:58:21
the accounts let's set them to the state
00:58:23
so we can say if
00:58:24
accounts
00:58:26
then set wallet address to accounts zero
00:58:32
because we only want to set the first
00:58:34
one now we want to call this function on the
00:58:36
first reload which is happening here and
00:58:39
we can also call it whenever we change a
00:58:41
wallet inside of core because core gives
00:58:44
us the possibility to do that
00:58:46
so let's say window Dot ethereum
00:58:50
dot on
00:58:52
accounts changed
00:58:55
there we want to call the update current
00:58:58
wallet address as well perfect now we
00:59:02
have set up two different use effects
00:59:04
since we're gonna have many let's
00:59:06
properly document them the first one
00:59:08
right here which is actually a function
00:59:10
being called inside of a use effect
00:59:12
let's put it like this
00:59:14
set the wallet address to the state
00:59:18
that's what it is doing and then this
00:59:21
one right here it's going to be used for
00:59:25
setting rather set the smart contract
00:59:30
and the provider to the state
00:59:33
and now you can collapse them by
00:59:35
clicking the arrow right here
00:59:37
that's going to make it easy for us to
00:59:40
continue developing our application as
00:59:42
we're going to have a lot of functions
00:59:43
and a lot of use effects but great job
00:59:46
so far our wallet is actually connected
00:59:49
this by itself should be enough to pass
00:59:52
this data into our home component and
00:59:55
start connecting our first user so let's
00:59:58
do just that if we go to Value right
01:00:01
here we can pass our contract as one of
01:00:05
the props and wallet address as the
01:00:08
second
01:00:09
going back to our home we can now get
01:00:12
that contract and wallet address
01:00:15
straight from the context I think that
01:00:18
you can now see the power of what we're
01:00:20
doing the next thing we have to do is
01:00:23
create this input as well as the
01:00:25
register button so we can successfully
01:00:28
register users to our great game
01:00:31
let's get started by giving this Dev a
01:00:34
class name
01:00:35
equal to flex and flex Dash coal inside
01:00:40
of there we want to render two custom
01:00:42
components the first one on the list is
01:00:45
going to be a custom reusable
01:00:48
self-closing input tag of course this
01:00:52
component doesn't yet exist but we're
01:00:54
going to create it right now let's go
01:00:57
into our components let's create a new
01:01:00
custom
01:01:02
input.jsx and let's run rafce inside of
01:01:06
there let's go into the index of the
01:01:08
components now inside of the components
01:01:11
index.js we can export our newly created
01:01:14
custom input component by importing it
01:01:16
here
01:01:17
custom input and then finally we can
01:01:21
export it there we go let's save it go
01:01:25
back to the home component
01:01:27
and in here we can import the custom
01:01:30
input component from components let's
01:01:34
save it go back to our app
01:01:37
and if you reload the page you should be
01:01:39
able to see custom input right here in
01:01:43
Black letters now let's create a custom
01:01:46
state right here inside of the home
01:01:48
called player name
01:01:50
that's going to be use State player name
01:01:54
and set player name right here and
01:01:57
finally it's going to be set to an empty
01:01:59
string at the start
01:02:02
now to this input we can pass in a label
01:02:05
equal to name
01:02:08
we can also pass in a placeholder equal
01:02:11
to enter your player name
01:02:14
we can also pass in a value equal to
01:02:17
player name and a handle value change
01:02:21
equal to set player name this custom
01:02:25
input is going to be an incredibly
01:02:27
reusable component so we're immediately
01:02:29
passing everything as props and finally
01:02:32
we have to of course import the use
01:02:35
state from react there we go now we can
01:02:39
jump into the custom input component and
01:02:41
we can start developing it
01:02:43
don't worry it's going to be pretty
01:02:45
straightforward
01:02:46
first things first we have to import
01:02:49
styles from dot slash Styles we're going
01:02:54
to also create a specific regular
01:02:56
expression so let's call it regex it
01:02:59
starts with a forward slash
01:03:01
then we have a carrot sign
01:03:04
inside of square brackets We Have A to Z
01:03:08
all uppercased then we have a to z
01:03:12
lowercased and then 0 to 9 like this and
01:03:17
then we can put a plus and a dollar sign
01:03:20
and we can close it with another forward
01:03:22
slash this right here is a regular
01:03:25
expression for all characters that are
01:03:28
within a to z capital A to Z lowercase
01:03:31
or numbers these are the only valid
01:03:34
characters for our player name instead
01:03:37
of our custom input we're also accepting
01:03:39
some props which we sent before such as
01:03:42
label placeholder value and handle value
01:03:46
change we pass those straight from home
01:03:50
our component is going to be an empty
01:03:53
react fragment inside of which we're
01:03:55
going to have a label that label is
01:03:58
going to have an html4 property equal to
01:04:01
name in a string like this
01:04:03
then we're going to give it a class name
01:04:05
equal to Styles dot label and we're
01:04:09
going to pass in the actual label in
01:04:12
there as you can see we have name right
01:04:14
here finally we're going to create a
01:04:16
self-closing input tag below let's give
01:04:19
it a type equal to text
01:04:21
let's give it a placeholder equal to
01:04:24
placeholder
01:04:25
right immediately we can see something
01:04:27
but of course it doesn't yet look good
01:04:30
let's add a value equal to Value let's
01:04:34
add an on change property and that on
01:04:36
change is going to be equal to callback
01:04:39
function where we get an event but then
01:04:42
we have to check if e dot Target dot
01:04:45
value is not empty
01:04:48
or if
01:04:50
regex.test is
01:04:53
e.target.value meaning does it pass our
01:04:55
test of being only a character or a
01:04:59
number only if that is the case we can
01:05:01
call the handle value change and provide
01:05:04
the target value now if you try typing
01:05:06
letters or numbers it's going to work
01:05:09
but if you try with special characters
01:05:11
it's not going to let you which is
01:05:13
exactly what we wanted finally let's
01:05:15
give it a class name
01:05:18
equal to Styles dot input
01:05:22
perfect this is looking so much better
01:05:25
I'm loving this of course this doesn't
01:05:28
yet have functionality but it will soon
01:05:30
now of course every input also needs a
01:05:34
button that does something with that
01:05:35
input so our next job is going to be to
01:05:38
go to home and right here we can create
01:05:41
a custom button component a self-closing
01:05:45
tag it's going to accept a title as a
01:05:48
prop which is going to say register
01:05:50
it's going to accept a handle click
01:05:54
which for now we're going to set as an
01:05:56
empty callback function
01:05:57
and it's also going to accept rest
01:06:00
Styles which are going to be a specific
01:06:03
styles for this specific button and
01:06:05
that's going to be set to mt6 as margin
01:06:08
top now of course if we save this it's
01:06:11
not gonna work because the button
01:06:12
doesn't exist but let's go ahead and
01:06:14
create it
01:06:15
inside of components we can create a new
01:06:18
file called
01:06:20
button.jsx or rather we called it custom
01:06:23
button.jsx
01:06:25
run rafce and let's also export it from
01:06:29
the index
01:06:30
that's going to be right here custom
01:06:33
button from dot slash custom button and
01:06:37
we added right here now if we go back
01:06:41
and reload the page we of course have to
01:06:44
go back to home and import it from here
01:06:48
custom
01:06:50
button and there we go it says custom
01:06:53
button but it's not yet custom as we
01:06:56
didn't style it so now let's go into the
01:06:59
components folder and let's open up the
01:07:01
custom button and let's jump right into
01:07:04
it the button is going to be even
01:07:06
simpler than the input inside of here we
01:07:09
can import styles from dot slash Styles
01:07:13
and we can immediately accept all the
01:07:16
props we passed such as title
01:07:20
handle click
01:07:22
and rest styles
01:07:26
and we can make use of them
01:07:28
we're going to return a simple button
01:07:31
component
01:07:33
button is going to be of a type is equal
01:07:36
to button
01:07:38
it's going to have a class name equal to
01:07:41
a template string that's going to say
01:07:44
styles.btn as well as rest styles
01:07:49
and finally we're going to give it an on
01:07:51
click equal to handle click and let's
01:07:54
pass in the title as soon as we do that
01:07:57
and save you can see the register button
01:08:00
right here now it seems that our rest
01:08:03
styles are not being applied because we
01:08:06
cannot see that margin top so let's go
01:08:08
back to home
01:08:09
and rest Styles looks like I typed rest
01:08:13
type this right here was supposed to be
01:08:15
rest Styles and there we go now we have
01:08:19
a beautiful home page with an input and
01:08:22
a register button but of course we're
01:08:25
just diving into action as now we have
01:08:27
to implement the handle click for our
01:08:30
register button to actually register our
01:08:34
user in that ladies and gentlemen will
01:08:37
be our first interaction with the smart
01:08:40
contract today I've showed you how to
01:08:42
set the smart contract app and deployed
01:08:45
I showed you how to create higher order
01:08:46
components and initialize this great
01:08:49
application but now we're actually
01:08:51
interacting with the smart contract we
01:08:54
can set ourselves up for success by
01:08:57
creating a new handle click function
01:08:59
const handle click
01:09:01
is equal to
01:09:03
async function like this and now finally
01:09:07
of course we can call it when we click
01:09:10
the button so we can pass the handle
01:09:12
click
01:09:13
right here
01:09:15
phenomenal let's make our first
01:09:17
interaction with a smart contract to
01:09:20
start interacting with our smart
01:09:22
contract we're going to create a try and
01:09:25
catch block because sometimes the
01:09:28
requests we try to make from the front
01:09:29
end aren't going to be successful so we
01:09:32
have to properly catch those errors for
01:09:36
now let's simply alert the error right
01:09:38
here and later on we're going to create
01:09:40
a proper error handling with a model
01:09:43
that's going to pop up and say Hey you
01:09:46
have an error but more importantly
01:09:47
what's going to happen if we are
01:09:50
successful so right here we can create a
01:09:53
new contract call by saying await
01:09:56
contract dot is player we call that as a
01:10:00
function and we provide a wallet address
01:10:04
as a parameter so now how did I know
01:10:07
that how did I know that there is the is
01:10:10
player function and that we have to pass
01:10:12
the wallet address as the parameter well
01:10:14
finally now is the time that we're gonna
01:10:17
go back to our web 3 side of things
01:10:19
we're going to open up our contracts and
01:10:22
open up the avax gods.soul in here we're
01:10:26
going to use the control or command F
01:10:28
and we're going to search for is player
01:10:32
function let's see where is it declared
01:10:35
in this case it's going to be the first
01:10:37
instance of its occurrence and that's
01:10:39
going to be on line 66. so let's explain
01:10:43
it function is player which accepts a
01:10:46
parameter of type address which is
01:10:49
called addr it is a public function
01:10:52
which means that we can call it from
01:10:53
outside and it's going to return a
01:10:56
Boolean so we know that as well if layer
01:10:59
info when accessed by this specific
01:11:02
address is equal to zero that means that
01:11:04
the player under that address doesn't
01:11:06
exist so we're going to return false
01:11:08
else else we're going to return true
01:11:10
okay this is quite simple to start with
01:11:13
so now we can go back we know that this
01:11:16
function is returning a Boolean so we
01:11:18
can say const
01:11:20
player exists is equal to a weight
01:11:24
contract dot is player great and I'm
01:11:27
going to make this just a bit bigger so
01:11:29
everything fits in one line
01:11:31
and we can collapse this as well there
01:11:34
we go so now we have a variable that
01:11:37
lets us know if a player under this
01:11:39
address has already created a player
01:11:42
account so we can say if no player
01:11:45
exists
01:11:46
in that case we can call a new function
01:11:49
in this case GitHub co-pilot autofilled
01:11:52
it for me but let's write it one more
01:11:54
time I'll wait
01:11:56
contract dot register player
01:12:00
we're going to pass in the player name
01:12:02
that player name is coming from this
01:12:04
input that we created right here let's
01:12:07
see what else do we have to pass this
01:12:09
function so one more time we're going to
01:12:11
go back to the contract and we're going
01:12:13
to search for register player
01:12:16
line 150 it accepts a couple of
01:12:19
different parameters a property called
01:12:22
name and also a property called game
01:12:25
token name so let's pass that as well in
01:12:28
this case a game token can be the same
01:12:30
as player name that's totally fine and
01:12:33
we can go back to the smart contract and
01:12:35
explore what this function does first of
01:12:38
all when you see require in solidity it
01:12:41
is some kind of a check a statement that
01:12:43
can throw us out of the function call so
01:12:46
in this case we want to require that a
01:12:48
player is not already registered and we
01:12:51
can do that by calling the function we
01:12:53
saw just before the is player function
01:12:56
so right here we're saying if not is
01:12:59
player message that sender meaning the
01:13:01
one who is trying to make this call then
01:13:04
we're going to say player already
01:13:06
registered
01:13:07
if that is not the case we can proceed
01:13:09
with the function and in here we're
01:13:11
going to give it an underscore ID where
01:13:13
we're going to give it an ID equal to
01:13:15
the current number of players
01:13:17
then we're going to push a player to the
01:13:20
player's array by creating an instance
01:13:22
of a player with the player's address a
01:13:26
name and then the values of 10 25 and
01:13:29
false what are these values well let's
01:13:32
control or command click the player and
01:13:35
in here we can see that that is the
01:13:36
player mana and player health and the
01:13:40
Boolean variable that says are we
01:13:42
currently in battle so going back Mana
01:13:45
is 10 health is 25 and then we are not
01:13:49
currently in battle once we push that
01:13:51
player we're going to Simply create the
01:13:53
player info mapping and we're going to
01:13:55
also automatically create a random game
01:13:57
token and most importantly we're gonna
01:14:01
emit a new player event that is the most
01:14:05
important part of this register player
01:14:07
function because we'll be able to listen
01:14:09
to the new player event on the front end
01:14:11
and then we'll be able to fetch it and
01:14:14
then do something based on that event
01:14:16
perfect now that we know that let's go
01:14:19
back to home and let's finalize this
01:14:21
function
01:14:22
of course we have to show something to
01:14:24
the user while this function is being
01:14:26
executed so now might be the best time
01:14:28
to create our alerts both for errors and
01:14:32
for successful messages so let's go back
01:14:35
to our index our context and the right
01:14:38
here let's create a new use state
01:14:41
that use state is going to be called
01:14:44
show alert
01:14:46
and also set show alert and at the start
01:14:49
it's going to be an object that's going
01:14:52
to have a status equal to false meaning
01:14:55
it's currently not showing type equal to
01:14:58
info and also a message equal to an
01:15:02
empty string now we're going to scroll
01:15:04
down and we're going to create one more
01:15:07
use effect
01:15:08
so let's say use effect
01:15:10
this time the Callback function is going
01:15:13
to have something in the dependency
01:15:15
array meaning it's going to change based
01:15:18
on one parameter and that parameter is
01:15:20
going to be show Alert in here we can
01:15:23
check if show alert
01:15:27
question mark dot status
01:15:29
so if the status is currently true
01:15:32
meaning the alert is showing then we
01:15:34
want to create a new timer by saying
01:15:37
constimer is equal to set timeout
01:15:41
that is going to be equal to a callback
01:15:43
function and there we want to set show
01:15:46
alert
01:15:48
to be equal to status false
01:15:51
type info
01:15:53
and message is an empty string meaning
01:15:57
we're canceling it and that is going to
01:16:00
happen within five seconds so right here
01:16:03
to close the timer off or to close the
01:16:05
set timeout off we can say 5000. so what
01:16:10
this means is we are going to show the
01:16:12
alert of course but we want to close it
01:16:15
after five seconds which is why we're
01:16:17
using a timer in react when you're using
01:16:20
a timer you want to also return
01:16:23
and then you want to clear the timeout
01:16:25
by passing the timer it is always good
01:16:28
to clear all the timers when you're
01:16:30
setting them inside of use effects great
01:16:33
now that we have the show alert and set
01:16:35
show alert we can pass those values
01:16:38
right in our context that's going to be
01:16:41
show alert
01:16:42
and set show alert which means that we
01:16:46
can use them inside of our home
01:16:48
component right now simply by getting
01:16:50
them from the top in this case we're
01:16:52
going to need only the set show alert
01:16:56
and we're going to set it right here
01:16:58
after our await is done so right here we
01:17:02
can say set show alert
01:17:05
we're going to pass in an object
01:17:07
let's pass the status of true as we do
01:17:10
want to show it let's pass the type
01:17:12
equal to info because we haven't yet
01:17:16
registered the player we're just
01:17:17
registering it so we want to show some
01:17:19
information and not yet a success
01:17:21
message
01:17:22
and finally let's also provide a message
01:17:25
that's going to be something like a
01:17:28
template string
01:17:30
player name
01:17:32
is being summoned there we go
01:17:35
this is great now for error messages I
01:17:40
had some problems with this error
01:17:42
messages are gonna come in a weird
01:17:43
format and we have to parse them before
01:17:46
showing them on the screen
01:17:48
so let's give it a shot let's try to
01:17:50
purposely get to an error here I think
01:17:53
we'll be able to achieve that by
01:17:55
entering the name like test right here
01:17:57
clicking register
01:18:00
and there we go contract dot is player
01:18:03
is not a function so in this case we get
01:18:06
an error that I wasn't expecting this
01:18:09
right here says that there is no is
01:18:11
player function on our contract right
01:18:14
here so let's reload the screen
01:18:16
let's try it one more time and yep still
01:18:19
the same thing so let's debug it I'm
01:18:22
gonna add a console.log statement right
01:18:25
here and I'll try to console log the
01:18:28
contract to see if it is really there
01:18:30
I'm going to open up inspect element
01:18:33
and I'm gonna put it at the bottom so we
01:18:36
can better see it
01:18:38
I'm gonna clear it and reload the page
01:18:40
it seems already that we're getting an
01:18:42
error right here and if we proceed with
01:18:45
testing
01:18:46
yep still the same thing new provider
01:18:49
dot signer is not a function and that is
01:18:52
happening inside of the set smart
01:18:54
contract and provider so let's go back
01:18:57
to our index and let's search for the
01:19:00
set smart contract and provide their use
01:19:02
effect in this case I made a typo
01:19:05
instead of signer here we need to put
01:19:07
get signer this is going to be good
01:19:10
let's save it okay we still get this
01:19:13
error but now if I type test and click
01:19:17
okay there we go now we get a different
01:19:19
error right here which is good a
01:19:22
different error always means that you've
01:19:23
done something
01:19:24
it says resolver or address is not
01:19:27
configured for ens name argument name
01:19:30
value invalid argument
01:19:32
and in the console we did get the
01:19:35
contract and that contract seems to have
01:19:38
all the functions that we can call one
01:19:40
of them should be is player and we can
01:19:43
see that it is there let's also check
01:19:46
out our initial function right here
01:19:48
update current wallet address
01:19:53
window.ethereum.request and right here I
01:19:56
misspelled method so that's why it
01:19:58
couldn't request accounts let's simply
01:20:00
go ahead and switch this to Method
01:20:02
reload and everything seems to be great
01:20:05
so now let's give it a shot let's try to
01:20:08
enter the player name click test
01:20:11
and again we want to test out the
01:20:14
rejection right here we want to test out
01:20:16
the errors so I'm going to click reject
01:20:18
and we do get an object object as the
01:20:21
error
01:20:22
and as you can see we get code 4001 and
01:20:26
there is the message user rejected the
01:20:29
error and also we have original data and
01:20:33
original code there is the message we
01:20:35
want to extract this message seems
01:20:38
pretty straightforward so we can do it
01:20:39
manually if we go back to home and right
01:20:43
here we can use the same set show alert
01:20:47
we can take it and in this case status
01:20:50
is going to be true type is going to be
01:20:52
error and then we can put the message to
01:20:56
be equal to we could do what is that
01:20:59
error dot data or no just error.message
01:21:03
so right here error
01:21:07
Dot message great now we are properly
01:21:11
setting the alerts right here but we
01:21:14
don't yet have a component that would
01:21:16
display them so that's going to be our
01:21:18
next task let's delete this console log
01:21:21
and let's create a new component inside
01:21:24
of the components folder let's call it
01:21:27
alert Dot jsx inside of that alert we
01:21:31
can run refce and we can import
01:21:35
the alert icon
01:21:38
that's coming from
01:21:40
assets we're going to also import Styles
01:21:45
coming from dot slash Styles our alert
01:21:50
is going to accept two things a type is
01:21:53
a success info or error and of course
01:21:56
it's also going to accept the message
01:21:59
our alert is going to be a div that's
01:22:02
going to have a class name equal to now
01:22:05
bear with me it's going to be a template
01:22:07
string with Styles dot alert container
01:22:12
as well as Styles dad Flex Center
01:22:17
inside of that div we're gonna also have
01:22:20
another div that's going to have a class
01:22:23
name equal to again a template string
01:22:26
off Styles dot alert wrapper
01:22:31
as well as styles
01:22:33
and then inside of square brackets type
01:22:36
because we want to show a starts for
01:22:38
info success and error depending on
01:22:41
which one is it and finally we can
01:22:44
render the alert icon to which we can
01:22:47
pass the type equal to type and next to
01:22:51
it we can pass the message
01:22:53
that's going to be it for our alert
01:22:56
component we can now export it right
01:22:58
here from our components
01:23:01
that's going to be alert
01:23:03
and also at the bottom
01:23:07
finally we're going to go back into our
01:23:09
page hoc because we're going to be using
01:23:12
this across our entire application and
01:23:14
that's where we want to import our alert
01:23:17
inside of here we're going to use
01:23:19
something from Context so we can say
01:23:21
import
01:23:22
use Global context
01:23:26
from dot slash context
01:23:29
we can get something from it right here
01:23:31
const show alert
01:23:34
is equal to use Global context and based
01:23:39
on that right here below the inner
01:23:41
opening div we can say
01:23:44
if show alert
01:23:46
question mark dot status is Trudy
01:23:49
meaning just exists then we want to show
01:23:52
a self-closing alert component
01:23:55
we're going to pass in a type
01:23:58
equal to show alert DOT type
01:24:02
and also pass in a message equal to show
01:24:06
alert Dot message
01:24:08
there we go so now if we reload this
01:24:11
it's going to say that we have to import
01:24:13
the alert component so let's do that
01:24:16
that's going to be import alert from dot
01:24:19
slash alert and there we go it seems to
01:24:22
be already showing although there is no
01:24:25
message
01:24:26
so now let's go back
01:24:29
let's go all the way back to our home
01:24:32
page or rather the context of our
01:24:34
application
01:24:35
the status is initially false so that
01:24:38
should be good
01:24:40
and let's check are we setting it to
01:24:42
True somewhere in here it's also false
01:24:44
so it shouldn't be showing if we reload
01:24:47
yep it still seems to be there
01:24:50
what if we try again initiating that
01:24:53
error so I'm going to click right here
01:24:55
and I'm going to click reject there we
01:24:58
go we get the error and the notification
01:25:00
seems to be here at least the icon but
01:25:04
it's barely visible
01:25:05
so there's definitely something we have
01:25:07
to fix with that alert since it's not
01:25:10
being closed let's go to where we
01:25:12
initialized it that's going to be at the
01:25:14
top and it looks like I set the status
01:25:17
to be a string of false instead of a
01:25:19
Boolean value if we fix this there we go
01:25:23
it's gone but now if we try to test it
01:25:25
out with this error right here
01:25:28
by clicking register and then rejecting
01:25:31
we don't yet see it here I mean I see
01:25:35
the dark icon but then this gets back
01:25:38
right here so most likely yep the
01:25:41
Boolean is here as well as false so we
01:25:44
just have to put it as a Boolean not as
01:25:46
a string but yeah it's still not showing
01:25:49
the Styles as it should so let's go back
01:25:52
to where we call it which is right here
01:25:55
status is true it looks like that's my
01:25:58
bad this was supposed to be a Boolean
01:26:00
value elsewhere as well and finally a
01:26:04
message
01:26:05
I just noticed right here the type for
01:26:07
error is supposed to be failure as
01:26:10
that's how I defined it inside of styles
01:26:13
so failure right here finally let's give
01:26:16
it one last shot for this error message
01:26:19
test register
01:26:22
I'm gonna reject it and there we go
01:26:25
although the message isn't appearing
01:26:27
right there so looks like it's not
01:26:29
getting the error Dot message although
01:26:32
it is here that's why I said I had some
01:26:34
issues with how the errors worked let's
01:26:37
try to counterlock the error one more
01:26:39
time
01:26:41
alongside console logging the error Dot
01:26:44
message to see where does it disappear
01:26:47
and let's repeat the process one more
01:26:49
time
01:26:50
as you can see it seems that it just
01:26:53
contains the code and nothing else in
01:26:56
there we cannot access this data right
01:26:58
here so what we can do for now is simply
01:27:01
right here create our own message saying
01:27:05
something went wrong and then later on
01:27:07
we're going to dive deeper into how to
01:27:09
handle errors now if we test this one
01:27:12
final time I'm gonna register
01:27:15
and I'm going to click reject
01:27:18
and as you can see we get a beautiful
01:27:20
error message saying something went
01:27:22
wrong that's going to go away in five
01:27:25
seconds perfect now is the time that we
01:27:28
actually test if the success call is
01:27:31
working so we want to successfully
01:27:33
register a player to do that let's add a
01:27:37
real name in this case I'm going to do
01:27:39
JS Mastery and I'm going to click
01:27:42
register and finally I'm gonna click
01:27:44
approve
01:27:46
we see JS Mastery is being summoned this
01:27:49
process usually does take a couple of
01:27:51
seconds
01:27:52
and for now there isn't really a way for
01:27:55
us to check if our user has been created
01:27:58
that is where the events come into play
01:28:02
Because when we register a player we are
01:28:06
emitting a new player event so we have
01:28:10
to go back to our context and now we
01:28:13
have to make use of event listening to
01:28:15
be able to listen to what our events are
01:28:18
saying to us to start working with our
01:28:21
events we're going to create a new file
01:28:23
inside of the context folder let's call
01:28:27
it create event listeners.js
01:28:32
inside of here we can import
01:28:35
ethers coming from ethers we can also
01:28:39
import the API coming from dot slash
01:28:44
contract that's going to be all that we
01:28:46
need for now and we can create a special
01:28:49
function called add new event this
01:28:53
function is going to accept something
01:28:55
known as an event filter
01:28:58
a provider and a callback or CB for
01:29:02
short so what do we want to do with it
01:29:04
well we want to first of all say
01:29:07
provider dot remove listener and we want
01:29:11
to pass in the event filter
01:29:13
what this line is ensuring is to not
01:29:16
have multiple listeners on the same
01:29:20
event at the same time so before we add
01:29:24
a new one we're going to remove the
01:29:25
previous ones then once we have removed
01:29:28
the previous ones we can say provider
01:29:30
dot on
01:29:32
event filter
01:29:33
we're going to get the logs right here
01:29:36
inside of the Callback function we want
01:29:38
to parse those logs by saying const
01:29:40
parse log is equal to parentheses new
01:29:45
ethers dot utils dot interface
01:29:49
with a capital I and we pass in the ABI
01:29:53
go inside of both parentheses and then
01:29:56
type parse log and we of course want to
01:29:59
pass in the logs this is a built-in
01:30:01
ethers functionality finally we want to
01:30:04
pass the logs as a first and only
01:30:06
parameter to our callback function I
01:30:09
know this was messy but believe me it's
01:30:11
going to make sense really soon once we
01:30:14
start creating all of those event
01:30:15
listeners so let's do just that let's
01:30:18
create a new function export const
01:30:22
create event listeners
01:30:26
it's going to be a function that's going
01:30:28
to later on accept a few parameters for
01:30:31
now we don't have to accept anything
01:30:34
and the first thing we're going to do is
01:30:36
we're going to call the const in this
01:30:38
case new player event filter
01:30:43
we're going to set that equal to
01:30:44
contract dot filters Dot new player so
01:30:50
when you create a contract and specify
01:30:52
an event for that contract such as the
01:30:55
new player event you'll immediately be
01:30:58
able to filter the calls for that
01:31:01
contract and that's exactly what we're
01:31:03
doing right here now this is not going
01:31:05
to work right off the bat because we
01:31:07
don't yet have the access of the
01:31:09
contract in this file but let's continue
01:31:12
with the logic and then we can import
01:31:13
the contract through props
01:31:16
so now that we have the filter we can
01:31:19
call the add new event function that we
01:31:22
created above
01:31:24
and we're going to pass in the new
01:31:26
player event filter
01:31:30
there we go finally we have to pass the
01:31:33
provider as the second prop and then we
01:31:36
have the Callback function inside of
01:31:38
that callback function remember we're
01:31:40
passing the parse logs so we can
01:31:43
destructure that and then we get arcs or
01:31:46
arguments for short
01:31:48
finally we can cause a log
01:31:51
new player
01:31:53
created
01:31:55
and then we can also console log the
01:31:57
arcs while we're here why also not show
01:32:00
a notification or an alert so we can say
01:32:03
if
01:32:04
wallet address
01:32:06
is triple equal to
01:32:09
arcs dot owner in that case we can set
01:32:13
show alert
01:32:16
we're gonna do a status of true we're
01:32:19
gonna do a type of success
01:32:22
and we can do a message
01:32:24
equal to
01:32:26
player has been
01:32:29
successfully
01:32:31
registered
01:32:33
there we go so now we added a new event
01:32:36
listeners but as you can notice our
01:32:39
contract is not defined our provider is
01:32:42
not defined our wallet address is not
01:32:45
defined because this function is not
01:32:47
within our context we are yet to call it
01:32:50
there so let's do just that above our
01:32:53
use effect for alerts we're going to
01:32:55
create a new use effect
01:32:59
this use effect is going to have a
01:33:01
callback function and for now we're
01:33:03
going to leave the dependency array
01:33:05
empty
01:33:06
in here we're going to check if the
01:33:08
contract exists and in that case we're
01:33:12
going to call the create event listeners
01:33:15
function
01:33:16
also you need to make sure to import it
01:33:18
at the top import create event listeners
01:33:21
from create event listeners I just
01:33:24
noticed I have a typo right here so
01:33:26
that's going to be event right here
01:33:29
there we go
01:33:31
and also update it here
01:33:34
now we can call that function and inside
01:33:37
of an object we can provide all of the
01:33:39
props that we need to use inside of
01:33:41
there one of the props is going to be
01:33:43
navigate we're going to pass in the
01:33:45
contract we're going to also pass the
01:33:47
provider we can also pass the wallet
01:33:51
address
01:33:52
let's pass the set show alert as well
01:33:57
and that's going to be it for now
01:33:59
now if we go back we're getting all of
01:34:02
these values through props so let's make
01:34:04
use of them we are getting inside of an
01:34:07
object you need to destructure navigate
01:34:11
contract
01:34:13
provider
01:34:15
wallet address
01:34:17
and set show alert
01:34:20
great this should make our event
01:34:23
listeners work
01:34:25
so hopefully we'll be able to
01:34:27
re-initialize our player or rather
01:34:29
should they say we should not be able to
01:34:31
initialize a new player because under
01:34:33
this address that we have registered
01:34:35
right here we already created a player
01:34:38
before when we weren't listening for it
01:34:40
but still it was created so let's give
01:34:43
it a shot one more time I'm going to
01:34:46
reload the page
01:34:47
type in JS mastery
01:34:50
and I'm going to click register but as
01:34:52
you can see nothing happens that is
01:34:55
because in the home we are already
01:34:57
checking if the player exists right here
01:34:59
and it looks like it does so it's not
01:35:02
letting us do what we need to do and
01:35:06
that's okay because later on we'll need
01:35:08
to test with multiple players anyway so
01:35:10
what we can do is go to your core wallet
01:35:12
click right here under your name and
01:35:15
click add account
01:35:17
in this case it's going to give me a
01:35:19
couple of notifications
01:35:21
I'm gonna close some
01:35:25
and I'm gonna improve my account
01:35:29
now we can switch back to our first
01:35:31
account
01:35:32
and we can click the plus button at the
01:35:35
bottom right
01:35:36
let's send some funds in this case I'm
01:35:39
going to choose my account I'm going to
01:35:41
choose account two
01:35:42
and let's send it about 0.4
01:35:46
avax should be enough
01:35:48
and let's click next and send now
01:35:52
you need avax to be able to do any
01:35:54
transactions and register the user as
01:35:57
well
01:35:58
so let's go to account 2 and immediately
01:36:01
we get prompted to connect to wallet to
01:36:04
the site which we do want to do
01:36:06
now if we reload the page we should be
01:36:09
able to create a new player so let's try
01:36:12
with account 2 in my case and I'm going
01:36:14
to click register we do get a
01:36:17
notification and we can click approve
01:36:20
but still we didn't get that
01:36:22
notification even though we know that
01:36:24
the player is created because now we
01:36:26
cannot click the register button again
01:36:28
most likely the reason why the event
01:36:31
listener didn't work is back inside of
01:36:34
the use effect we forgot to pass the
01:36:36
contract as a dependency array here and
01:36:40
it is possible that at the time while
01:36:42
we're trying to execute this while we're
01:36:44
trying to set up event listeners we
01:36:46
didn't have a contract right here
01:36:48
existent because it was just being set
01:36:51
to the state so once we add this and
01:36:54
save you can notice that we get a lot of
01:36:57
Errors saying that navigate is not
01:36:59
defined
01:37:01
navigate is a function coming from use
01:37:03
navigate
01:37:05
so we can Define it at the top
01:37:07
let's say const navigate is equal to use
01:37:11
navigate and call it as a hook
01:37:15
that fixes the issue and I'm guessing
01:37:17
that the next time we create a new
01:37:19
player we will get a notification We're
01:37:22
not gonna test that out now because we
01:37:24
would have to create yet another account
01:37:26
for now we're happy with those too of
01:37:29
course we'll have to create many players
01:37:30
as we test the game's full functionality
01:37:33
so now that we do have a player what is
01:37:36
the next thing we have to do well a
01:37:39
player doesn't have anything to do on
01:37:41
the home page anymore we need to
01:37:43
redirect them to the create battle page
01:37:46
so let's do just that let's go back to
01:37:49
home for one final time and right here
01:37:52
below the handle click we're gonna add
01:37:55
another use effect
01:37:57
use effect
01:37:58
that is going to happen when the
01:38:01
contract changes so right here we're
01:38:03
going to add a contract as a dependency
01:38:05
array and then we're going to create a
01:38:08
new function const check for player
01:38:11
token and that's going to be an
01:38:14
asynchronous function
01:38:16
inside of here we first want to check if
01:38:19
a player exists so for that we're going
01:38:22
to call the same function we called
01:38:23
right here const player exists is equal
01:38:26
to a weight contract dot is player
01:38:30
and we can paste that here
01:38:32
then we want to check if a player token
01:38:35
exists and remember player token is
01:38:38
being created at the same time while we
01:38:41
are registering them so we can check for
01:38:43
that by saying const
01:38:45
player token exists
01:38:49
is equal to a weight contract dot is
01:38:53
player token and we pass in the wallet
01:38:56
address that is yet another function
01:38:58
inside of our smart contract
01:39:01
finally if both a player exists and
01:39:06
player token exists then we want to use
01:39:11
the navigate function
01:39:13
to go to forward slash create battle
01:39:16
let's save it
01:39:18
in this case it looks like use effect is
01:39:20
not defined so at the top we can import
01:39:23
use effect
01:39:25
save it
01:39:26
there we go we are back
01:39:29
and I'm gonna reload the page
01:39:32
it didn't seem to me that we were
01:39:34
redirected so what we can do is we can
01:39:37
cancel that log
01:39:39
player exists as well as player token
01:39:43
exists but of course it's not happening
01:39:45
because we never called the check for
01:39:47
player token function so let's do that
01:39:50
right here if the contract exists then
01:39:54
we want to call the check for player
01:39:58
token function there we go this is
01:40:02
looking good to me
01:40:03
and we do get player exists is true and
01:40:07
player token exists is true which is
01:40:09
exactly as we expected but it looks like
01:40:12
we forgot to Define navigate so one more
01:40:14
time at the top we can import
01:40:18
use navigate
01:40:20
coming from react router Dom
01:40:24
we can Define it right here
01:40:26
const navigate as equal to use navigate
01:40:30
call it as a hook and now we have it
01:40:33
let's reload the page
01:40:35
and there we go hello from create battle
01:40:40
isn't that great and now a cool thing is
01:40:43
if you try to go back manually to
01:40:46
forward slash
01:40:48
it's going to redirect you back to
01:40:51
create a battle because you have
01:40:53
connected your account and also you have
01:40:56
a player that is phenomenal that means
01:41:00
that we are ready for the next stage of
01:41:02
our application and that is allow the
01:41:05
player to create a battle
01:41:07
to do that you can hold Ctrl or command
01:41:10
and then press w a couple of times make
01:41:13
sure you are inside of your Visual
01:41:15
Studio code to close all of your tabs if
01:41:18
you press Ctrl W while in Chrome that
01:41:20
would have closed the Chrome tab so
01:41:22
sorry that happened with that said we
01:41:25
are ready to continue working on our app
01:41:27
and we're going to continue right inside
01:41:30
of create battle so now we can go inside
01:41:33
of pages and we can go inside of create
01:41:37
battle you can see how simple it is now
01:41:39
that we use the page higher order
01:41:41
component
01:41:43
but you're gonna notice that we also
01:41:45
created a couple of other reusable
01:41:46
components which are going to be the
01:41:48
custom input and the custom button so
01:41:51
now our job is going to be much easier
01:41:53
with that said let's start working on
01:41:56
the create a new battle page to start
01:41:59
creating our battle page let's first
01:42:02
import a couple of hooks from react and
01:42:05
those are going to be use state
01:42:08
as well as use effect hux we can also
01:42:13
import the infamous
01:42:15
use navigate which we forgot so far a
01:42:18
couple of times from react Dash router
01:42:21
Dash Dom
01:42:22
we're gonna also import styles
01:42:26
coming from dot slash Styles we can
01:42:30
import the global context or the hook we
01:42:34
created for the global context called
01:42:36
use Global context coming from dot slash
01:42:40
context and since we already have a
01:42:43
couple of components built in we can
01:42:45
import the custom Button as well as a
01:42:49
custom input component
01:42:51
and let's initialize the navigate
01:42:53
variable so we don't forget so that's
01:42:56
going to be use navigate
01:42:59
great
01:43:00
finally let's focus on the jsx side of
01:43:03
things we're going to have an empty
01:43:05
react fragment right inside of here and
01:43:08
then inside of there we're going to have
01:43:10
a div
01:43:11
that div is going to have a class name
01:43:14
equal to flex Flex Dash call and mb-5
01:43:19
for margin bottom inside of there we're
01:43:22
going to render a custom input
01:43:24
self-closing component and below that
01:43:27
we're going to render a custom button
01:43:30
self-closing component if we save this
01:43:33
you can see that we get an input and a
01:43:34
button and let's add all of the
01:43:37
necessary props such as label which is
01:43:40
going to be battle let's add a
01:43:42
placeholder equal to enter battle name
01:43:46
finally we'll have to add a value but
01:43:50
we're not going to initialize the state
01:43:51
for that value inside of create battle
01:43:54
because we're going to need elsewhere in
01:43:56
other components as well so what we can
01:43:59
do is we can go to our index of the
01:44:02
context and let's create a new use State
01:44:05
field at the top so right here use state
01:44:10
that's going to be battle name and set
01:44:13
battle name equal to an empty string at
01:44:16
the start
01:44:17
now we can pass that value right here
01:44:19
through the value of the context battle
01:44:22
name and set battle name
01:44:25
now going back to create battle that's
01:44:27
going to allow us to get a couple of
01:44:29
things from the context
01:44:31
things such as the contract to be able
01:44:34
to make contract calls and also battle
01:44:37
name and set battle name
01:44:42
that's equal to use Global context and
01:44:46
we call it as a hook now we can add the
01:44:50
value to the custom input equal to
01:44:53
battle name and we can add the handle
01:44:56
value change equal to set battle name
01:45:01
when it comes to the button we can pass
01:45:04
the title equal to create battle we can
01:45:07
pass the handle click which is going to
01:45:10
be equal to a handle click function we
01:45:13
haven't yet created but we can right now
01:45:15
const handle click is equal to
01:45:19
an arrow function
01:45:22
and finally we can pass rest styles
01:45:26
equal to
01:45:27
mt-6 to divide it from the input if we
01:45:31
save this you can see how simple this
01:45:33
was considering that we had pre-built
01:45:35
components and a pre-built higher order
01:45:38
component now we have a home component
01:45:40
and a create a battle component now to
01:45:44
take this even further we're going to
01:45:46
add an additional P tag below this div
01:45:50
that's going to say
01:45:52
or join already existing battles that's
01:45:57
another one of our apps functionalities
01:45:59
let's style that
01:46:01
class name equal to Styles dot info text
01:46:06
and on click we want to create a
01:46:09
callback function where we're going to
01:46:11
navigate to forward slash join Dash
01:46:15
battle
01:46:16
if we save this you can see that now we
01:46:18
have that as well
01:46:20
but if we click it join panel doesn't
01:46:22
yet exist so let's create a new page
01:46:25
called join battle
01:46:29
.jsx
01:46:30
and we can of course run rafce
01:46:34
and let's also export it from our index
01:46:38
so that's going to be here and here
01:46:40
and we can call it join battle
01:46:45
finally inside of the main we can import
01:46:48
join battle
01:46:51
and we can duplicate the route instead
01:46:54
of create battle that's going to be
01:46:57
join battle and right here join battle
01:47:02
if we save this we can now see this join
01:47:05
battle text but it's not yet looking
01:47:08
good but you already know the drill to
01:47:11
instantly make it so much better we're
01:47:14
just gonna use our higher order
01:47:16
component so let's go ahead and import a
01:47:19
couple of things
01:47:20
we're gonna import the use effect coming
01:47:24
from react
01:47:25
let's also import
01:47:28
the use navigate
01:47:30
coming from react router Dom
01:47:35
let's also import the use Global context
01:47:39
coming from context
01:47:43
let's import the custom button component
01:47:48
and also the page hoc
01:47:53
and that's coming from dot slash
01:47:55
components
01:47:57
and finally let's import the Styles
01:47:59
coming from dot slash styles
01:48:02
great now you know the drill we can
01:48:05
simply wrap the join battle with a page
01:48:08
hoc the first parameter is the component
01:48:11
itself the second one is the title join
01:48:15
b r a battle
01:48:19
and then we're gonna create another one
01:48:22
for description that's going to be join
01:48:25
already existing battles and we can also
01:48:29
add a comma right here if we save that
01:48:33
and the reload
01:48:35
there we go join a battle page is now
01:48:39
done which is perfect now if we click
01:48:42
the icon on top left that's going to
01:48:44
redirect us back to home but remember we
01:48:46
have an instant redirect to the create a
01:48:49
battle so now we can switch between
01:48:51
those two now inside of here let's
01:48:54
create a subtitle to show the existing
01:48:57
battles let's call it an H2 element
01:49:01
and let's say available battles
01:49:06
like this
01:49:07
and let's give it a class name
01:49:11
equal to
01:49:13
Styles dot join head text and save this
01:49:18
there we go available battles and also
01:49:21
at the bottom let's add a P tag that's
01:49:24
going to have a class name
01:49:27
equal to Styles dot info text
01:49:31
and this B tag is going to say or create
01:49:36
a new battle this button is going to
01:49:40
navigate to the create battle page so
01:49:43
alongside importing use navigate we have
01:49:45
to initialize it cons navigate is equal
01:49:49
to use navigate and we can give it an on
01:49:52
click
01:49:55
equal to a callback function
01:49:57
where we navigate to forward slash
01:50:01
create Dash battle and finally we can
01:50:05
now switch between the two isn't this
01:50:09
beautiful and you can see how simple
01:50:12
this is just due to the fact that we
01:50:15
created this higher order component
01:50:17
beautiful
01:50:19
great so now of course one player will
01:50:22
be able to create a battle and the other
01:50:25
one will be able to join that existing
01:50:28
battle so first let's focus on the
01:50:31
create a battle smart contract
01:50:33
functionality to do that we can close
01:50:36
most of the files and go back to the
01:50:38
create battle page there we created this
01:50:42
handle click component so filling it in
01:50:45
is going to be our next task the first
01:50:48
thing we have to do is make this
01:50:50
function asynchronous because contract
01:50:52
interactions take time then we want to
01:50:55
make sure that the user actually filled
01:50:58
in some characters so we can say if no
01:51:01
battle name
01:51:03
or no battle name dot trim then we want
01:51:09
to return null we want to exit the
01:51:11
handle click function otherwise we can
01:51:14
open up a try and catch block
01:51:17
and we can await right here
01:51:21
contract dot create battle and we're
01:51:25
gonna pass in the battle name so now
01:51:28
might be the best time to jump straight
01:51:31
into the smart contract code and to see
01:51:33
how the create battle functionality
01:51:35
works so let's do that by going to web3
01:51:39
contracts and let's search for create
01:51:42
battle line
01:51:44
218 function create battle that accepts
01:51:49
a battle name as the first and only
01:51:51
parameter
01:51:52
we have two requirements first first of
01:51:56
all the player must be registered we
01:51:58
have already done that and second of all
01:52:00
the battle will be the same name must
01:52:02
not exist okay that's good then what
01:52:06
we're doing is we're creating a special
01:52:09
battle hash let's Google what this
01:52:12
function does I'm going to paste it
01:52:14
right here and as you can see this is an
01:52:17
online hash function it's going to
01:52:20
generate specific hash based on some
01:52:22
input that we pass in so if you pass a
01:52:25
battle name it's going to generate a
01:52:27
hash of that string great in this case
01:52:30
we're doing just that we're passing that
01:52:32
name then we're creating a new battle
01:52:35
we're initializing it so first of all
01:52:38
we're setting the battle status as
01:52:40
pending because a player hasn't yet
01:52:42
joined the battle we are providing a
01:52:45
unique battle hash we are providing the
01:52:47
panel name and we're adding the player
01:52:50
addresses this is the address of of the
01:52:53
player that created a battle and then
01:52:55
the second player we're setting it as
01:52:57
the address 0 meaning it does not exist
01:53:00
because player 2 is empty until they
01:53:03
join the battle
01:53:04
then we provide the moves in here this
01:53:07
is going to be a Boolean variable of has
01:53:10
the player made the move or not at the
01:53:12
start both players haven't made their
01:53:15
moves so it's zero and finally we have
01:53:17
the address of the winner in this case
01:53:19
it is empty until the battle ends
01:53:23
then we get the ID of the battle we push
01:53:26
the battle into the battles array and
01:53:28
then we return it great this is all the
01:53:31
functionality of creating a battle and
01:53:34
finally when it comes to errors for now
01:53:37
we can simply console log the error
01:53:39
until we Implement better error handling
01:53:42
now before we actually test the create
01:53:45
battle functionality I want to create a
01:53:49
waiting screen because the battle isn't
01:53:52
instantaneous you don't immediately jump
01:53:54
into the Battleground first you have to
01:53:57
wait for another player to join you
01:53:59
that's why we're gonna have a special
01:54:02
weight game screen
01:54:04
so right here we can create a new use
01:54:07
State called weight battle and set
01:54:11
weight battle and at the start it's
01:54:13
going to be set to false
01:54:15
then right here after we create a battle
01:54:18
we want to set weight battle to true and
01:54:23
then based on that right here we can
01:54:25
render a component
01:54:27
that component is going to be called
01:54:30
game load so let's create a new
01:54:33
component under components game load Dot
01:54:36
jsx
01:54:38
let's run rafce inside of there and
01:54:41
let's export that component as we always
01:54:44
do so that is going to be game load
01:54:50
great we can now go back to create
01:54:52
battle and we can import it from the top
01:54:55
we are importing other components
01:54:57
already so let's add game load to the
01:55:01
list
01:55:02
finally right here below this empty
01:55:05
fragment we can say if weight battle
01:55:08
meaning weight battle and end then show
01:55:12
the game load component
01:55:15
if we save that and reload
01:55:19
We're not gonna see it because Wade
01:55:21
battle is false but for now let's set it
01:55:24
to True at the start so we can actually
01:55:26
see how the weight battle is going to
01:55:28
look like
01:55:29
and there we go right now it is a simple
01:55:32
string that says game load let's jump
01:55:35
into it and let's implement the entire
01:55:38
jsx of our game load component to do
01:55:41
that we're going to import
01:55:43
use navigate
01:55:46
from
01:55:47
react-router Dash Dom
01:55:50
we're going to also import a custom
01:55:52
button coming from dot slash custom
01:55:55
button we're going to also import use
01:55:59
Global context coming from
01:56:02
Context we can also import
01:56:06
player01 and player zero two which are
01:56:10
coming from dot slash assets if we
01:56:14
control click to check it out you can
01:56:17
see that a player one if we find it is
01:56:20
going to be this icon right here and
01:56:24
finally we can import the Styles coming
01:56:28
from styles
01:56:31
great our game load component is going
01:56:34
to immediately get the wallet address
01:56:38
from the context thankfully we have it
01:56:41
there so that's going to be wallet
01:56:42
address
01:56:43
is equal to use Global context and we
01:56:48
can also initialize navigate by saying
01:56:51
const navigate is equal to a call to the
01:56:53
use navigate hook
01:56:55
great now let's start with the layout
01:56:58
first we're going to have a div and that
01:57:01
div is going to have a class name equal
01:57:04
to a template string where we have
01:57:06
styles dot Flex between
01:57:10
as well as Styles dot game load
01:57:15
container if we save that you can see
01:57:18
that everything is going to turn in a
01:57:20
bit of a color purple right that's
01:57:23
because we want to show something on top
01:57:25
of the screen because we are waiting for
01:57:27
another player to join then inside of
01:57:30
there we can have a div that's going to
01:57:33
have a class name
01:57:35
equal to Styles dot game load BTN box
01:57:41
and inside of there we can render our
01:57:44
reusable custom button self-closing
01:57:48
component we can give it a title equal
01:57:51
to choose Battleground
01:57:54
we're going to give it a handle click
01:57:56
equal to
01:57:59
navigate
01:58:01
forward slash Battleground make sure to
01:58:05
put inside of a callback function
01:58:07
and we're going to give it rest Styles
01:58:10
equal to empty Dash sex and there we go
01:58:15
don't click it now because you're going
01:58:16
to go away to a page that doesn't yet
01:58:18
exist but we're going to create it soon
01:58:20
for now let's focus on what matters
01:58:23
let's create a div below this div right
01:58:27
here
01:58:29
that Dev is going to have a class name
01:58:31
equal to a template string of flex-1
01:58:36
Styles dot Flex Center inside of a
01:58:41
dynamic block of code dollar sign curler
01:58:43
braces and flex Dash coal inside of
01:58:46
there we can show an H1 that's going to
01:58:49
have a class name
01:58:51
equal to
01:58:52
a template string of styles dot head
01:58:57
text
01:58:59
as well as text Dash Center
01:59:02
and it's going to say waiting for a
01:59:07
then a Break Tag and then we can add
01:59:10
worthy opponent da da da there we go
01:59:14
this is already looking better we can
01:59:16
also add a P tag below
01:59:19
and say class name is equal to Styles
01:59:23
dot game load text and we can say Pro
01:59:28
tip
01:59:30
while you're waiting
01:59:34
choose your preferred
01:59:37
Battleground there we go this is quite
01:59:40
cool later on we'll be able to choose
01:59:43
the Battleground which we're gonna
01:59:44
battle on isn't that great but for now
01:59:48
let's continue with our waiting screen
01:59:51
inside of this div below the P tag we're
01:59:54
going to create another div
01:59:56
that div is going to have a class name
01:59:58
equal to Styles dot game load players
02:00:03
box
02:00:04
inside of there we're going to have
02:00:06
another div that's going to have a class
02:00:09
name
02:00:10
equal to dollar sign curly braces inside
02:00:14
of a template string
02:00:15
Styles dot Flex Center
02:00:19
as well as Flex bash coal
02:00:22
and inside of there we want to show an
02:00:25
image a self-closing image tag that's
02:00:28
going to have a source of player 0 1
02:00:32
and a class name of styles dot game load
02:00:36
player IMG like this
02:00:40
if we save that we can see this player
02:00:42
icon appear right there
02:00:45
below it let's also add a b tag with a
02:00:49
class name equal to Styles dot game load
02:00:53
player text and inside of there let's
02:00:57
render the wallet address
02:00:59
dot slice from 0 to 30 just to make it a
02:01:03
bit shorter and there we go we have our
02:01:06
wallet address so we know it's really us
02:01:10
finally below this div containing the P
02:01:14
tag we can create an H2
02:01:16
and there we can give it a class name
02:01:20
equal to Styles dot game load vs all
02:01:25
uppercased and there we can say vs
02:01:28
finally we can duplicate this div above
02:01:33
paste it below the vs and now we're
02:01:36
doing the same thing for the opposing
02:01:37
player it's going to be player 0 2. and
02:01:41
instead of wallet address we're simply
02:01:43
going to show a lot of question marks
02:01:45
because we don't yet know who is going
02:01:48
to join
02:01:49
so something like this should work let's
02:01:53
save it and there we go this is looking
02:01:56
great
02:01:57
that's going to be it for the game load
02:02:00
component we can now go back and we can
02:02:03
set it to false initially because we're
02:02:05
not yet waiting for the battle we
02:02:08
haven't yet created it so now would be a
02:02:11
great time to create a new battle to
02:02:14
test out the create battle functionality
02:02:16
so let's enter the battle name I'm gonna
02:02:20
do JSM battle and I'm going to click
02:02:23
create battle
02:02:26
a new core notification appears and I'm
02:02:29
gonna click approve
02:02:32
and we got a waiting for everybody
02:02:34
opponent right here which means that we
02:02:38
have successfully created a battle now
02:02:41
if somebody reloads the page the game
02:02:43
load is going to disappear but the
02:02:46
battle still exists
02:02:48
and as you can see that indeed is the
02:02:50
case so how would you solve that how
02:02:53
would you check if the battle is already
02:02:55
created well we will need to have an
02:02:58
object that's going to keep track of an
02:03:01
active battle so for that let's move
02:03:04
straight into our index.js inside of
02:03:07
context there we're going to create
02:03:09
believe it or not yet another use effect
02:03:12
this one is going to be used to set the
02:03:16
game data to the state
02:03:19
that's going to be useful later on once
02:03:21
we want to map over the active games or
02:03:24
if you want to check if the current
02:03:25
player is in a game so let's create a
02:03:28
new use effect
02:03:32
and if you're wondering why do we have
02:03:34
so many use effects if they have the
02:03:37
same dependency array then we could have
02:03:39
put all the code in the same use effect
02:03:41
well it's always better to stay
02:03:44
organized so simply add a comment above
02:03:47
each one and separate them by purpose
02:03:50
and don't just put all the code in one
02:03:52
place it's going to hardly be readable
02:03:55
with that said this one is going to be
02:03:58
executed whenever the contract changes
02:04:02
so right now let's create a new function
02:04:04
const fetch game data is equal to an
02:04:09
async function
02:04:10
and just so I don't forget let me call
02:04:12
it immediately right here fetch game
02:04:15
data inside of there we want to check if
02:04:18
the smart contract exists or we can even
02:04:21
do that right here by not calling the
02:04:24
function if it doesn't so if contract
02:04:27
exists then call the fetch game data
02:04:29
function and then inside of there we
02:04:32
want to first get all available battles
02:04:36
so const fetched battles is equal to a
02:04:41
weight contract dot get all battles
02:04:45
again how do we know that this exists
02:04:48
well let's go back to our smart contract
02:04:52
and let's search for get all battles as
02:04:56
you can see this is a really simple
02:04:58
getter function that simply Returns the
02:05:01
array of all active battles
02:05:04
with that said let's console log it
02:05:06
let's see if her battle is there so
02:05:09
Khan's a log fetched battles let's save
02:05:13
it and let's go to console and check it
02:05:16
out it seems like we're getting an array
02:05:18
of two battles but the first one is just
02:05:21
zero whenever you're fetching some data
02:05:23
from the smart contract the first
02:05:25
element is always going to be just empty
02:05:28
so keep that in mind we start from one
02:05:31
in this case and there we go Believe It
02:05:34
or Not JSM battle is here and we can see
02:05:37
the address of the player that created
02:05:39
the battle that is great we can also see
02:05:43
the battle status of zero which means
02:05:45
that it is pending nobody has joined yet
02:05:47
great there will be some battles that
02:05:51
players will have already joined in but
02:05:53
we also want to filter them to show only
02:05:55
depending ones so if somebody goes to
02:05:58
the join existing battles we only want
02:06:01
to show the ones that nobody has joined
02:06:03
in before so let's create a filter const
02:06:07
pending battles
02:06:09
is equal to fetched battles dot filter
02:06:14
where we get a battle as a parameter and
02:06:17
then we want to check if battle Dot
02:06:21
Battle status
02:06:23
is triple equal to zero that means that
02:06:26
it is pending now what we want to do is
02:06:29
we want to find a battle that our
02:06:31
current player has created because that
02:06:34
is an active battle so let's say fetched
02:06:37
battles
02:06:39
dot for each battle
02:06:43
we want to have an if statement if
02:06:46
battle dot players dot find
02:06:50
player
02:06:51
and then player dot to lowercase
02:06:57
is triple equal to wallet address
02:07:01
dot two lowercase that means that our
02:07:05
player has the same address as the
02:07:09
address of the wallet in the browser in
02:07:12
that case we can do something so let's
02:07:14
open a block and then we can have one
02:07:17
more check if
02:07:20
battle.winner dot starts with is equal
02:07:24
to 0x00 that means that we don't have a
02:07:28
winner and that the battle is still
02:07:30
active if that is the case we can create
02:07:33
a new variable right here at the top let
02:07:36
active battle set it to null
02:07:41
and right here we can override it with
02:07:44
the actual battle so active battle is
02:07:47
equal to battle great finally we can set
02:07:50
all of this info to the state
02:07:53
so let's create a new State field at the
02:07:55
top
02:07:57
that's going to be use State let's call
02:08:00
it game data
02:08:03
set game data and at the start it's
02:08:05
going to be equal to an object that has
02:08:08
a player's array set to an empty array
02:08:11
pending battles array
02:08:14
of course at the start set to an empty
02:08:16
array as well and it has an active
02:08:19
battle which is a default set to null
02:08:23
great now we can update that game data
02:08:26
right here by saying set game data
02:08:32
create an object
02:08:33
pending battles is equal to pending
02:08:36
battles dot slice one remember we want
02:08:40
to start from one and we're gonna also
02:08:43
pass the active battle which we got from
02:08:46
the fetched battles that is great
02:08:49
now it looks like we have an error
02:08:52
that is most likely with this if
02:08:54
statement right here so let's see if
02:08:56
we're appropriately closing it
02:09:01
it seems we are
02:09:03
but it seems that something else is off
02:09:06
so let's see what is that
02:09:08
or properly closing this
02:09:11
the fetch game function
02:09:14
the error is right here pending battles
02:09:17
is actually going to be pending battles
02:09:19
that slice and then one there we go so
02:09:23
now if we fix that we're properly
02:09:25
updating the state with our game data we
02:09:28
can of course pass that game data right
02:09:31
here through our value of the context
02:09:34
and now we can go back into create
02:09:37
battle and continue with what we have
02:09:39
started now based on this data we can
02:09:42
know if the currently logged in player
02:09:44
has created a battle or not so let's
02:09:47
create a use effect inside of create
02:09:49
battle
02:09:51
there we go it's going to change when
02:09:54
the game data changes remember we're
02:09:56
getting the game data from the context
02:10:01
and there we want to check if game data
02:10:05
question mark DOT active battle
02:10:08
question mark Dot Battle status
02:10:11
is triple equal to zero in that case we
02:10:14
want to set weight battle to true and
02:10:18
there we go it works and now if you
02:10:20
reload you can see we're still waiting
02:10:23
for where the opponent that's great we
02:10:26
have successfully put one account on
02:10:29
hold
02:10:30
now to properly test the functionality
02:10:32
we have to implement the join battle as
02:10:35
well so we can do that by switching to
02:10:39
our different core count
02:10:41
that's going to be account 2 and we can
02:10:44
reload the page
02:10:46
there we go this player hasn't created a
02:10:49
battle but now is our turn to go to join
02:10:52
or the existing battles
02:10:54
and right here we have to list it as an
02:10:58
available battle we haven't yet done
02:11:00
that so now we can close all the files
02:11:03
and open up the join battle.jsx
02:11:07
inside of here we have to use that new
02:11:10
game data to actually list the available
02:11:13
battles
02:11:14
to map over depending battles we can
02:11:17
make use of our context so right here
02:11:20
above our navigate let's say const we
02:11:25
can get the contract we can get the game
02:11:27
data we can also get the set show alert
02:11:32
and we'll need set battle name as when
02:11:36
we're joining we also need to set that
02:11:39
battle name and finally the wallet
02:11:41
address and that is equal to the use
02:11:44
Global context now below available
02:11:47
battles we can make some space and we
02:11:50
can create a div
02:11:52
this div is going to have a class name
02:11:55
equal to Styles dot join container there
02:12:00
we can open a new Dynamic block of code
02:12:02
and say game data dot pending battles
02:12:07
dot length meaning if they exist in that
02:12:11
case question mark So if there are any
02:12:15
pending battles
02:12:17
then we want to go to gamedata dot
02:12:21
pending battles
02:12:23
Dot and we want to call a DOT filter on
02:12:27
it
02:12:28
before we do that let's also add the
02:12:30
case if there aren't any pending battles
02:12:33
in that case we can show A P tag
02:12:37
like this
02:12:38
and we can give it a class name
02:12:41
equal to Styles dot join loading
02:12:46
and in there we can say something like
02:12:48
reload the page to see new battles
02:12:53
great now if we save this something will
02:12:57
be wrong let's try to open the console
02:13:00
to see what exactly
02:13:02
it seems like undefined is not a
02:13:04
function add filter so we have to
02:13:07
provide it a callback function
02:13:11
and if we save everything is looking
02:13:13
good but of course we haven't yet
02:13:15
filtered the pending battles so how are
02:13:19
we going to do that well we're gonna get
02:13:21
a battle and in here we have to find
02:13:24
battles that don't match any that the
02:13:27
current player has already created so we
02:13:30
can say no battle dot players that
02:13:34
includes
02:13:35
wallet address
02:13:38
so not the battles that the current
02:13:39
player has created otherwise he would be
02:13:42
playing himself
02:13:43
great so now we have filtered them and
02:13:47
now we have to map through them so we're
02:13:49
going to call a map where we get a
02:13:51
battle as well as the index
02:13:55
and for each battle we want to instantly
02:13:57
return something so use parentheses here
02:14:00
instead of curly braces we're going to
02:14:03
return a div for each battle and that
02:14:06
div is going to have a key equal to
02:14:08
battle.name plus index to make it unique
02:14:12
and give it a class name equal to Styles
02:14:16
dot Flex between
02:14:20
inside of there we're gonna have a P tag
02:14:23
that's going to have a class name equal
02:14:26
to Styles dot join battle title and
02:14:32
there we can render the index plus one
02:14:36
there we go so now if we save this
02:14:39
you can see a number one meaning there
02:14:42
is one battle and also next to that
02:14:45
let's render a battle dot name
02:14:49
and there we go JSM battle a battle we
02:14:53
indeed did create
02:14:55
below that battle name we can create a
02:14:58
custom button and we can give it a title
02:15:01
that's going to say join
02:15:04
finally we can give it a handle click
02:15:08
it's going to have a callback function
02:15:10
it's going to call a handle click
02:15:12
function
02:15:14
and we want to pass a battle.name to it
02:15:18
to know which battle do we want to join
02:15:21
of course this handle click is a
02:15:24
function we haven't yet created so let's
02:15:26
do that right away const handle click
02:15:29
is an async function
02:15:33
and that seems to be good for now so now
02:15:37
if we save this we have one available
02:15:40
battle which is exactly as it should be
02:15:42
and we have a join button now the code
02:15:46
of the join battle handle click function
02:15:48
is going to be similar to the create
02:15:51
battle click but of course there's going
02:15:53
to be one important difference and that
02:15:55
is going to be instead of create battle
02:15:57
we're going to join it
02:15:59
first let's set the battle name to the
02:16:02
state equal to the battle name that
02:16:05
we're passing through params as you can
02:16:07
see right here then let's open a new try
02:16:11
and catch block
02:16:13
and say await
02:16:16
contract
02:16:17
dot join battle
02:16:19
and we're gonna pass in the battle name
02:16:22
so we know which battle do we want to
02:16:24
join to
02:16:25
now let's learn more about the join
02:16:28
battle function inside of the smart
02:16:30
contract let's search for it on line 242
02:16:35
we can see the join battle functionality
02:16:38
it accepts a battle name as the first
02:16:41
and only prop then it gets the battle by
02:16:45
the battle name we have to make sure
02:16:48
that the battle has not already started
02:16:50
and we have to require that a second
02:16:53
player is joining the battle we cannot
02:16:55
join a battle we created finally we want
02:16:58
to require that a player that is joining
02:17:01
is not currently in battle after we pass
02:17:04
all of these checks then we can set the
02:17:07
battle status to start it and we can set
02:17:10
the second player to the player that
02:17:12
joined the battle finally we update the
02:17:15
statuses of both of these players to
02:17:18
true to be in battle
02:17:20
and finally we emit a new battle event
02:17:24
which we can listen for on the front end
02:17:27
great now we know how the join battle
02:17:29
works as well once we join the battle
02:17:31
let's also show an alert so set show
02:17:35
alert with a status equal to true
02:17:39
type is equal to success and finally a
02:17:43
message is equal to joining
02:17:46
and that's going to be
02:17:49
a template string of battle name of
02:17:52
course we have to use backticks
02:17:55
there we go and for the error for now
02:17:59
let's simply console log it so Kanza log
02:18:01
error
02:18:03
great now that is done already but let's
02:18:07
not make a mistake that we did when
02:18:10
creating a battle
02:18:11
we don't want to join now and then what
02:18:14
happens we don't know we want to set up
02:18:17
the event listener for the join battle
02:18:19
event so that we can properly listen for
02:18:22
it and then redirect both players to the
02:18:25
Battleground area great to do that we're
02:18:29
going to go to our create event
02:18:32
listeners file and we have to add a
02:18:36
second event which is going to be a new
02:18:39
game token
02:18:41
so right here we can copy the first two
02:18:44
lines right here still inside of the
02:18:47
create event listeners right here let's
02:18:50
make some space I'm going to paste those
02:18:52
two lines but now instead of the new
02:18:55
player event filter it's going to be new
02:18:59
battle event filter and filters dot new
02:19:04
battle make sure to change this as well
02:19:07
and of course add new event new battle
02:19:11
event filter and we get arguments now we
02:19:14
can start working on the code of what is
02:19:16
going to happen once this event is
02:19:19
dispatched of course our goal is going
02:19:22
to be to navigate both players to the
02:19:25
Battleground area and it looks like we
02:19:28
forgot the closing parentheses great
02:19:30
with that said let's get started with
02:19:33
the new battle event listener to get
02:19:36
started we can as we did before add a
02:19:40
console log right here so that we know
02:19:42
that the event happened so let's do
02:19:44
console.log and let's do something like
02:19:47
new battle started
02:19:50
we can also console log the arcs and in
02:19:53
this case we're going to console log the
02:19:55
wallet address because there are two
02:19:58
players we're gonna get one from our own
02:20:01
wallet address and we're gonna get one
02:20:03
from the arguments of the other player
02:20:05
so now that we know that let's create an
02:20:08
if statement and in here we have to
02:20:11
check if the wallet address
02:20:14
dot to lowercase is triple equal to args
02:20:19
dot player one dot two lower case
02:20:24
or wallet address
02:20:27
dot to lowercase is triple equal to args
02:20:32
dot player two dot two lowercase so we
02:20:36
want to make sure that our player is
02:20:38
either a player one or a player 2. if
02:20:42
that is the case then we want to
02:20:44
navigate to forward slash battle forward
02:20:47
slash args
02:20:50
Dot Battle name perfect so we are ready
02:20:54
to start with the battle
02:20:56
finally Once We join the battle we want
02:20:59
to update the game data so to accomplish
02:21:02
that we can go back to our context
02:21:06
that's going to be the index.js file and
02:21:09
at the top of the file we can create a
02:21:11
new use State field that use state is
02:21:16
going to be called update game data and
02:21:20
at the start it's going to be set to
02:21:22
zero
02:21:23
now we can take that update game data
02:21:26
function and we can pass it to our
02:21:29
create event listeners which is let's
02:21:33
find it
02:21:34
right here so here we can pass set
02:21:37
update game data
02:21:40
and now what we can do is below the
02:21:43
navigate we can set update game data
02:21:48
like this of course we have to get it so
02:21:51
let's get it from the parameters of this
02:21:54
function
02:21:55
set update game data
02:21:58
and what we want to do there is get
02:22:00
access to the previous or prev update
02:22:03
game data and then we want to return
02:22:06
pref update game data
02:22:10
plus one we want to increment that
02:22:12
variable based on this state we'll know
02:22:15
when we have to reload the battle screen
02:22:18
to show new and updated information so
02:22:21
going back to the index now we can
02:22:24
update the game data right here which is
02:22:26
this use effect
02:22:27
more specifically we can update it once
02:22:31
the update game data variable changes so
02:22:34
right here we're going to pass the
02:22:36
update game data as the second
02:22:38
dependency parameter great with that
02:22:41
said our event listener is now done and
02:22:45
before we try and join the JSM battle
02:22:47
let's go ahead and create a new battle
02:22:50
page so let's create a new page called
02:22:53
battle
02:22:55
jsx
02:22:57
let's run refce inside of there
02:23:00
and this one is not going to be a higher
02:23:03
order component wrapper because this is
02:23:05
going to be our game battle page it's
02:23:08
going to be entirely different so for
02:23:10
now let's first do some imports in there
02:23:13
we can import the use effect
02:23:17
as well as the use State coming from
02:23:20
react we can also import the use params
02:23:25
as well as use navigate which is coming
02:23:29
from react router Dom
02:23:31
then we can import these Styles coming
02:23:35
from dot slash styles
02:23:37
we can import a couple of components so
02:23:40
that's going to be our alert and that's
02:23:44
all that we need for now from dot slash
02:23:46
components
02:23:49
we can also import our context or rather
02:23:51
use Global context from dot slash
02:23:55
context
02:23:57
and we can import a couple of assets
02:23:59
such as attack
02:24:02
attack sound
02:24:03
defense
02:24:06
defense sound
02:24:08
player zero one as player01 icon
02:24:13
and player zero two as player zero two
02:24:17
icon and that's coming from assets
02:24:23
finally we're going to import the play
02:24:26
audio
02:24:28
function from dot slash utils forward
02:24:32
slash animation dot Js
02:24:36
great now we have all the Imports let's
02:24:39
try to use some of them inside of the
02:24:41
top of our component let's try to get
02:24:44
something from the global context things
02:24:46
like Contract game data wallet address
02:24:51
show alert
02:24:54
set show alert and that's going to be it
02:24:57
for now that is equal to use Global
02:25:00
context
02:25:01
we also want to create two new use
02:25:04
States so let's create a new use State
02:25:07
that's going to be player one which is
02:25:11
going to at the start be equal to an
02:25:13
empty object and we also want to get
02:25:15
player 2 and set player 2 which is at
02:25:19
the start going to be equal to an empty
02:25:21
object as well then we're going to
02:25:23
re-navigate to a page that looks like
02:25:25
this forward slash battle forward slash
02:25:28
and then right here this is going to be
02:25:30
a name of the battle
02:25:32
so how do we get the name well we get it
02:25:35
from params so we can say const battle
02:25:38
name is equal to use params
02:25:43
and finally we can initialize the
02:25:45
navigate function great so now we have
02:25:49
all of the Imports I don't think we have
02:25:51
routed to this page yet so let's go to
02:25:54
index to export our battle page
02:25:58
we can do it just by changing the name
02:26:00
right here and exporting it so that's
02:26:03
going to be battle
02:26:04
and now back in main we can import the
02:26:08
battle page
02:26:10
and then we can duplicate this route
02:26:12
here we can set the path to be equal to
02:26:16
battle forward slash and then Colin
02:26:18
battle name which means that this
02:26:21
parameter is going to be dynamic and
02:26:23
then there we can render the battle
02:26:25
component
02:26:27
great now we can go back and let's just
02:26:31
style the battle component a bit better
02:26:33
so that once we get re-navigated after
02:26:35
joining we can already see something on
02:26:38
the screen to do that we can create a
02:26:40
new div
02:26:41
and that div is going to have a class
02:26:44
name equal to a template string of
02:26:47
styles Dot Flex between Styles Dot Game
02:26:52
container
02:26:54
and in here we have to render the
02:26:56
current Battleground this right here is
02:26:59
going to be a special variable that's
02:27:01
going to say on which Battleground are
02:27:03
we currently on so if we check our
02:27:07
styles
02:27:08
inside of Tailwind you can see that we
02:27:10
have different background images based
02:27:13
on different Battleground names so let's
02:27:16
go back and for now let's try to hard
02:27:18
code it right here
02:27:20
as astral that might work if not we're
02:27:24
gonna switch it later and inside of here
02:27:26
right now I want to render the battle
02:27:28
name so I'm going to create an H1 that's
02:27:30
going to render the battle name and
02:27:33
let's give it a class name equal to text
02:27:37
Dash XL and text White
02:27:41
great now let's save this
02:27:44
and I think we are ready to join the
02:27:46
battle to test the functionality
02:27:49
I'm gonna click join or the existing
02:27:52
battles I'm going to click join let's
02:27:55
also open up the inspect element to see
02:27:57
what's happening and let's join we get a
02:28:01
new notification which is always a good
02:28:03
sign and I'm gonna click approve
02:28:06
joining JSM battle that's looking good
02:28:08
to me
02:28:10
and the redirect happened we also got a
02:28:14
notification from our event listener so
02:28:17
now if we go back to creative at
02:28:19
listener we can see that this is the one
02:28:21
that happened new battle started we got
02:28:24
the arguments which contained the battle
02:28:27
name the player one and the player 2
02:28:30
which is great and the wallet address is
02:28:33
there so now we were redirected to
02:28:35
forward slash battle and then forward
02:28:37
slash JSM battle but the screen simply
02:28:41
seems to be white
02:28:43
so let's try to reload the page and yep
02:28:47
nothing seems to be on there so let's
02:28:50
check if the battle page is properly
02:28:52
routed so let's see since we have a
02:28:56
white background it looks like the
02:28:58
background wasn't applied which is fine
02:29:00
but if we change the color of this text
02:29:02
back to black we might be able to see it
02:29:05
and there we go JSM battle which means
02:29:08
that it's properly reading the
02:29:09
parameters so that's great we have all
02:29:12
of the data we needed so far and we are
02:29:14
ready to code out the looks of the
02:29:16
Battleground page
02:29:18
first things first let's focus on the
02:29:20
Battleground background so what we can
02:29:23
do is we can go back to the index.js and
02:29:26
we can create a new use State at the top
02:29:29
yep another one so right here we're
02:29:32
going to create a new use State and
02:29:35
let's call it bowel ground you can use a
02:29:38
capital G or lowercase G whatever one
02:29:41
you use make sure to stick to that do
02:29:43
not have any issues later on and at the
02:29:46
start let's call it BG Dash astral we'll
02:29:50
have to use this prefix of BG Dash and
02:29:53
then the name of the Battleground for
02:29:55
now it's going to be static but later on
02:29:57
we'll be able to update it using the set
02:30:00
Battleground page so now let's pass the
02:30:03
Battleground as well as the set
02:30:05
Battleground all the way down to our
02:30:08
context so right here
02:30:10
Battleground as well as
02:30:14
set Battleground
02:30:16
there we go
02:30:18
perfect now we can go back to our battle
02:30:20
page and we can import the Battleground
02:30:25
and we can simply render that string
02:30:28
right here instead of Astral
02:30:31
now if we save that that actually works
02:30:35
because we put BG in front and if you
02:30:38
look at the Tailwind styles if you put
02:30:41
these background images then you have to
02:30:43
put the BG Dash and then the name of
02:30:45
that Battleground so that's looking
02:30:48
great now let's continue adding to our
02:30:51
Battleground this is looking great even
02:30:53
on smaller screens but if we expanded
02:30:56
it's looking even better now let's go
02:30:59
back a bit
02:31:00
and let's start implementing it
02:31:03
first we're going to focus on extracting
02:31:06
all important player data because we
02:31:08
have to pass that player data all the
02:31:10
way to the components that are going to
02:31:12
present it so let's create a new use
02:31:15
effect right here
02:31:18
there we go that use effect is going to
02:31:21
happen when the contract changes meaning
02:31:23
when it first gets updated when the game
02:31:26
data changes and when the battle name
02:31:29
changes as well great so how are we
02:31:32
going to fetch all of the important game
02:31:34
data let's create a new function called
02:31:37
const get player info and that's going
02:31:41
to be equal to an async function like
02:31:44
this
02:31:45
let's not forget to immediately call it
02:31:47
down here so we can say if there is a
02:31:51
contract and if there is game data DOT
02:31:55
active battle only if that is true then
02:31:59
we want to call the get player info
02:32:01
function now inside of the get player
02:32:04
info we're going to create a new try and
02:32:07
catch block there we can say let
02:32:11
player01 address
02:32:13
is equal to null and let player02
02:32:18
address
02:32:19
is equal to null as well that means that
02:32:22
we're simply setting up the variables so
02:32:25
we can use them later on once we
02:32:27
initialize them now we have to check if
02:32:30
gain data
02:32:32
DOT active battle
02:32:35
dot players zero dot two lowercase
02:32:40
is triple equal to wallet address
02:32:44
dot to lower case if that is the case
02:32:49
that means that our player 0 1 address
02:32:53
is equal to game data dot activebattle
02:32:58
dot players zero because we verify that
02:33:02
right here active battle player 0 is
02:33:05
equal to wallet address dot to lowercase
02:33:08
and this right here was supposed to be
02:33:10
players plural and based on that we also
02:33:14
know that the player 2 address is equal
02:33:16
to
02:33:17
activepaddle.players one there we go
02:33:21
else
02:33:22
if the wallet address is not equal to
02:33:25
the player 0 that must mean that it is
02:33:28
equal to player 1. so we can copy these
02:33:31
two values and we can simply change the
02:33:33
numbers meaning Player 1 address is
02:33:36
equal to players 1 and then player 2
02:33:39
address is equal to players zero there
02:33:43
we go based on these addresses we can
02:33:45
now fetch proper player data first we
02:33:49
need to get the token and we can do that
02:33:51
by saying const P1 token data is equal
02:33:55
to a weight contract dot get player
02:34:00
token
02:34:01
and we pass in the player01 address we
02:34:06
can dive into our smart contract to see
02:34:08
what the get player token function does
02:34:11
so if we check it right here and find
02:34:14
where it is initialized we can see that
02:34:16
it simply returns a specific player
02:34:19
token then we can get the player one
02:34:22
cons player 0 1 is equal to a weight
02:34:26
contract dot get player and there we
02:34:30
also have to pass the address of the
02:34:31
player and we can duplicate that and we
02:34:34
can repeat the process with the player02
02:34:37
and pass in the player02 address
02:34:41
now let's dive into this smart contract
02:34:43
to see what the get player function does
02:34:45
so one more time going back and
02:34:48
searching for it get player there we go
02:34:51
it simply returns a player
02:34:54
it is a getter function
02:34:56
now based on these variables we can make
02:34:59
use of them to get player health bars
02:35:02
Mana bars and attack and defenses so we
02:35:05
can say const
02:35:07
P1 ATT as attack is equal to P1 token
02:35:13
data dot attack strength
02:35:16
dot to number
02:35:19
there we go we can duplicate that
02:35:22
and then we're going to get the P1 def
02:35:25
as defense and that's going to be
02:35:27
defense
02:35:29
strength
02:35:30
now we want to get P1 and P2 help and
02:35:33
Mana bars and we can do that by saying
02:35:35
const p1h is equal to player01 dot
02:35:40
player Health dot to number we can
02:35:44
duplicate that three more times the
02:35:47
second one is going to be P1 Mana so we
02:35:50
can simply change the player Health to
02:35:52
player Mana
02:35:54
we're gonna have player two health and
02:35:57
then player 2 Mana
02:35:59
player 2 health is going to be like this
02:36:01
we have to change the number player two
02:36:04
player two and we have to change the
02:36:07
player Mana right here again make sure
02:36:10
that you have it exactly like this P1
02:36:12
attack P1 token data attack strength P1
02:36:16
def P1 token data defense strength and
02:36:18
then P1 health is player one Health P1
02:36:21
Mana player one Mana P2 health is player
02:36:24
2 health and then P2 Mana is player 2
02:36:27
Mana great now that we have those values
02:36:31
we can set them to the state so we can
02:36:33
say set player one
02:36:36
is dot dot dot we want to spread all the
02:36:39
values of the player 0 1 we want to set
02:36:42
the ATT to be equal to P1 ATT as an
02:36:46
attack death is going to be P1 def
02:36:49
health is going to be set to p1h and
02:36:54
Mana is going to be set to p1m we can
02:36:57
duplicate this
02:36:59
set the player to
02:37:01
spread the player 0 to
02:37:03
set the attack to be equal to X just a
02:37:07
string of X and Def equal to a string of
02:37:09
X because we don't know the opposing
02:37:11
players attack and defense strengths but
02:37:14
we do know their health and Mana so we
02:37:17
can set P to health and P2 Mana great
02:37:21
and finally for the error for now we can
02:37:24
simply console.login
02:37:27
great so now we're getting all of the
02:37:29
player data and we're setting it to
02:37:32
player one and two States it also looks
02:37:35
like I have a typo right here address
02:37:37
with a single D so this has to be the
02:37:40
same as these variables right here to
02:37:43
make sure it works great now we can make
02:37:45
use of these player data variables so
02:37:48
let's scroll down and let's create a lot
02:37:51
of different reusable functions so we
02:37:53
can create the layout of our game first
02:37:56
let's show the alert at the top of the
02:37:59
battle page the same as we did with the
02:38:01
page higher order component so we can go
02:38:03
here and we can copy this alert prompt
02:38:06
because the higher order component is
02:38:09
used in all the home pages but it's not
02:38:11
used in the battle so we have to paste
02:38:13
it here as well so show alert that
02:38:17
status and alert show alert type and
02:38:20
show alert message great now we can show
02:38:24
a custom player info component so right
02:38:27
here let's create a player info
02:38:29
component and to that component we're
02:38:32
gonna pass a player which is going to be
02:38:34
equal to player 2 because we're showing
02:38:37
them at the top first we are on the
02:38:40
bottom page of the screen and we also
02:38:42
want to show the icon so player icon is
02:38:45
equal to player 0 2 icon
02:38:50
and we can also pass empty as margin top
02:38:55
now of course if we save that's not
02:38:57
going to work because this component
02:38:59
doesn't yet exist so in this file we're
02:39:02
going to use a couple of components
02:39:03
we're going to create a player info
02:39:05
component a card component an action
02:39:08
button and also the game info so what do
02:39:12
you say that now we go to the components
02:39:14
folder and create a basic structure for
02:39:17
all of these components we'll be using
02:39:19
so let's start from the action button
02:39:22
that's going to be action
02:39:25
button.jsx and we can create an rafce
02:39:28
inside of there then we're going to also
02:39:31
create a card component so card.jsx and
02:39:35
we can also run rafce
02:39:37
finally we're going to use the game info
02:39:40
component
02:39:41
.jsx and we can run rafc e and finally
02:39:46
the one we already called is the player
02:39:48
info component Dot jsx and we can also
02:39:53
run rafce now we can go to index and we
02:39:56
can export all of these components so
02:39:59
we're going to have the action button
02:40:03
then we're going to have a card
02:40:05
component
02:40:07
then we're going to have a game info
02:40:10
component
02:40:12
and finally we're going to have a player
02:40:14
info component
02:40:17
there we go so now we can export all
02:40:20
four of these right here
02:40:22
and we of course need to add the commas
02:40:26
there we go finally going back to R
02:40:29
that's going to be battle page we can
02:40:33
now import all of these components at
02:40:35
the top so let's import alongside the
02:40:38
alert that's going to be action button
02:40:42
card
02:40:44
game info and player info components
02:40:49
great now we can continue creating the
02:40:52
basic layout keeping in mind that all of
02:40:54
the components are going to be here so
02:40:57
below our player info we're gonna have a
02:41:00
div and that div is going to have a
02:41:03
class name
02:41:04
equal to inside of curly braces Styles
02:41:08
dot Flex Center and also Flex Dash call
02:41:14
and my 10. inside of that Dev we want to
02:41:18
show a card component so right here we
02:41:21
can render a self-closing card component
02:41:24
that component is going to have a couple
02:41:26
of props such as card is equal to player
02:41:30
2. title is equal to player 2 question
02:41:34
mark dot player name
02:41:36
not the action button here
02:41:38
we're also going to give it a player 2
02:41:40
variable to know to differentiate
02:41:42
different cards and then we have to
02:41:45
provide a card ref which is going to be
02:41:47
equal to a ref that we're going to
02:41:49
create later on for now let's simply
02:41:51
leave this as an empty string now below
02:41:54
that card we're going to create one more
02:41:56
div
02:41:57
and that div is going to have a class
02:42:00
name equal to flex items Dash Center and
02:42:04
flex Dash row
02:42:06
inside of there we want to render the
02:42:08
action button
02:42:11
so this is going to be the action button
02:42:13
to attack a player so it is a
02:42:16
self-closing component
02:42:18
that's going to have an image URL equal
02:42:21
to attack
02:42:22
it's going to have a handle click equal
02:42:25
to for now we're going to leave this as
02:42:28
an empty callback function and we're
02:42:29
going to implement the functionality
02:42:30
later on and we can add rest Styles
02:42:34
equal to
02:42:36
mr-2 for margin right
02:42:38
hover border Dash yellow Dash 400. great
02:42:45
now we can copy the card one more time
02:42:47
below the action button
02:42:50
this is going to be the card for player
02:42:52
one so we can say car displayer one
02:42:54
title is player one that player name and
02:42:57
right here we don't need to provide any
02:43:00
player 2 variable but we can provide the
02:43:03
rest Styles equal to mt-3 to divide it
02:43:07
from the top card and finally we can
02:43:09
copy the action button and place it
02:43:11
below the card because this time this is
02:43:14
going to be a defense action button
02:43:16
instead of margin right 2 we're going to
02:43:19
have a margin left 6 and the hover is
02:43:23
going to be border Dash red Dash 600 for
02:43:27
defense finally below this div and Below
02:43:31
one more div we want to show the player
02:43:33
info
02:43:34
for the other player remember we have
02:43:37
already created it for the one at the
02:43:39
top but we can now copy this
02:43:42
paste it here and that's going to be
02:43:44
player one as well as player zero one I
02:43:48
can and below that we want to show the
02:43:52
game info component just a simple
02:43:55
self-closing component
02:43:58
now if we save this you can see that the
02:44:01
text is here it's barely visible but all
02:44:04
parts are here the player info at the
02:44:07
top the opposing players cards then we
02:44:11
have our own card as well as the action
02:44:13
buttons next to that card then we have
02:44:16
our own player info and finally we have
02:44:19
the game info so everything is looking
02:44:23
great to me but now is the time that we
02:44:25
jump into all of these components
02:44:28
individually and we create their look
02:44:30
and feel so let's go ahead and let's get
02:44:33
started from top to bottom the first one
02:44:36
on our list is going to be the player
02:44:38
info component this one is going to be
02:44:41
interesting because we're going to have
02:44:43
different colors on the health bars
02:44:45
depending on how much health does a
02:44:47
player have so it's definitely an
02:44:50
interesting functionality to think about
02:44:52
how to implement but I'm going to show
02:44:54
you how to do it in this video so let's
02:44:57
start to buy importing react tooltip
02:45:01
coming from react Dash tooltip then we
02:45:05
can also import the styles
02:45:08
coming from dot slash Styles then we can
02:45:12
set a constant variable const Health
02:45:15
points this is going to be a number of
02:45:18
help points which is going to be a total
02:45:20
of 25.
02:45:22
then we know that we're passing three
02:45:24
different things into the player info
02:45:26
component we're passing a player a
02:45:29
player icon
02:45:31
and finally a Mt or margin top property
02:45:35
now based on that let's render the look
02:45:38
and feel of it we can first have a div
02:45:40
and that div will have a class name
02:45:43
equal to
02:45:45
styles.flex Center and then only if
02:45:49
there is margin top then we want to add
02:45:52
mt4 otherwise we're going to add mb4
02:45:56
like this great so for the first card we
02:45:59
want to push it away from the top and
02:46:01
for the second one we want to push it
02:46:02
away from the bottom
02:46:04
then inside of there we're going to have
02:46:06
an image tag this image is going to have
02:46:09
a source equal to player icon
02:46:13
and it's going to have an ALT tag equal
02:46:15
to player 2.
02:46:18
finally we can give it a class name
02:46:20
equal to w-14 for width age-14 for
02:46:24
height object Dash contain
02:46:27
and rounded Dash full to make it into a
02:46:30
circle if we save that we can now see
02:46:33
that we get a opponent right here on the
02:46:35
top and we get the blue one on the
02:46:38
bottom we can also add a data Dash 4
02:46:41
property right here and that's going to
02:46:44
be equal to player Dash if we are empty
02:46:49
that means that it is player one and
02:46:52
then otherwise it's going to be player
02:46:54
2. and we can also give it a data
02:46:57
Dash tip property this will allow us to
02:47:01
know which image is this player
02:47:03
representing
02:47:04
great now below that image we're going
02:47:06
to have a div and that div is going to
02:47:10
have another data Dash 4 property and
02:47:14
this is going to be for health
02:47:17
and one more time we're going to copy
02:47:19
what we had above so that's going to be
02:47:22
Dash and then if it's empty then it's
02:47:24
going to be 1 otherwise it's going to be
02:47:27
2. so we're going to paste that right
02:47:29
here and then the data Dash tip is going
02:47:33
to be equal to
02:47:34
health
02:47:36
and then player DOT health like this
02:47:40
finally let's give it a class name equal
02:47:42
to Styles dot player health
02:47:46
and there we go there is the bar where
02:47:49
the health will go but now is our time
02:47:51
to actually put the hell the bars inside
02:47:54
of this health div so to do that we'll
02:47:57
have to find a way to represent the
02:48:00
number 25 as specific bars
02:48:03
to do that we're going to open a dynamic
02:48:06
block of code we're going to make an
02:48:08
array and then we're going to spread the
02:48:11
array of player.health
02:48:14
then we're going to take the keys out of
02:48:17
that property and we want to map over
02:48:19
that we're going to map over each
02:48:21
individual item and we're going to also
02:48:24
get the index
02:48:26
now we want to return something for each
02:48:28
property and we're going to return a div
02:48:31
that div is going to have a key which is
02:48:35
going to be equal to
02:48:36
let's do player Dash item Dash and then
02:48:40
we can render the item right here
02:48:43
and let's give it a class name
02:48:46
in this case that's going to be Styles
02:48:49
dot player
02:48:51
health bar
02:48:53
if we save this nothing is going to
02:48:55
happen yet that's because we have to
02:48:57
calculate the health level we have to
02:49:00
know is it green is it red or is it
02:49:03
Orange
02:49:04
to do that we can create a new function
02:49:06
at the top const health level
02:49:10
it's going to take in the health points
02:49:12
and then based on that we can check
02:49:15
inside of parentheses if points is
02:49:19
larger than or equal to 12. in that case
02:49:23
we can render the BG Dash green Dash 500
02:49:27
cooler then we're going to have an else
02:49:30
and we want to check if points is
02:49:32
greater than or equal to six then we
02:49:35
want to render the BG Dash orange Dash
02:49:38
500 and else we want to render the BG
02:49:42
Dash red Dash 500 and now we can put
02:49:46
that health bar here
02:49:48
that's going to be Health level and
02:49:51
we're going to pass in the player.health
02:49:55
if we save that you can see all of the
02:49:57
health bars right there
02:49:59
but you can see they're kind of close
02:50:01
together right we have to divide them
02:50:03
somehow but how are we going to know how
02:50:06
many there are if we put a too large of
02:50:09
a margin something like margin right
02:50:11
uh let's do two then they're gonna
02:50:14
spread too thin but if there isn't a lot
02:50:17
of them then we have to increase the
02:50:19
width or lower the margin so we're going
02:50:22
to create another function to calculate
02:50:24
that as well const margin indexing is
02:50:28
going to be equal to a function that's
02:50:29
going to accept an index as the
02:50:31
parameter and then we're going to check
02:50:34
if index is not equal to health points
02:50:38
minus 1
02:50:41
then we're going to return
02:50:43
mr-1 else we're going to return
02:50:47
mr-0 and now we can pass that margin
02:50:51
indexing right here as a function and
02:50:54
pass the index as well once we call this
02:50:57
this is going to look much better
02:51:00
perfect I like this
02:51:02
now we have to do a similar thing for
02:51:05
the Mana but we're just going to have a
02:51:07
circle that's going to say the number of
02:51:09
the Mana that we have so what we can do
02:51:12
is we can now close this div as that is
02:51:16
a self-closing div so I'm just going to
02:51:17
close it right here
02:51:19
and then below this block of code and
02:51:22
below the div that's wrapping it we can
02:51:24
create a new div
02:51:26
and this div is going to be for the Mana
02:51:30
and it's also going to have a data for
02:51:32
property the reason why we're adding
02:51:34
this is because the reactult package is
02:51:37
going to use it later on so once we
02:51:39
hover over it we'll be able to get more
02:51:41
information
02:51:42
so data for Mana Dash if it's empty then
02:51:47
it's one otherwise it's two we can say
02:51:50
data Dash tip it's going to say simply
02:51:53
Mana
02:51:55
and the class name is going to be
02:51:58
a template string
02:52:01
of styles dot Flex Center
02:52:05
Styles dot glass effect
02:52:08
and styles dot player Mana
02:52:12
inside of there we can render a dynamic
02:52:15
string of player dot Mana or zero now if
02:52:20
we save that you can see game is slowly
02:52:23
starting to make sense because we can
02:52:25
see that both players have full health
02:52:28
as the game just started 25 health and
02:52:31
they both have 10 Mana which is exactly
02:52:33
as it should be that is great finally
02:52:36
let's add the tooltips to make even more
02:52:39
sense of the game data
02:52:41
first we're going to add a react tooltip
02:52:44
component
02:52:45
and this one needs to have an ID so the
02:52:49
ID is going to be equal to a template
02:52:51
string of player Dash and we're going to
02:52:54
do the same thing one more time if it's
02:52:56
empty then we're going to say one
02:52:59
else it's going to be 2. it's going to
02:53:02
also have an effect which is going to be
02:53:04
set to solid and it's going to have a
02:53:07
background color which we can set to
02:53:09
something like hash 7f
02:53:13
4 6 F 0 I found this colder to work
02:53:17
really good
02:53:19
and inside of there we can render two
02:53:21
different P tags the first P tag is
02:53:24
going to render the name of the player
02:53:26
so we can render a span inside of there
02:53:30
and that span is going to render the
02:53:33
name or rather it's going to say name
02:53:36
right here
02:53:37
and after the span we can render the
02:53:40
player
02:53:41
question mark dot player name now the P
02:53:44
tag is going to have a class name equal
02:53:47
to Styles dot player info and the span
02:53:50
is going to have a class name equal to
02:53:54
Styles dot player info span great
02:53:59
now we can duplicate the speed tag below
02:54:02
and the second time we want to render
02:54:04
the address of the player so in here we
02:54:07
can say player dot player address
02:54:11
question mark dot slice from 0 to 10
02:54:13
only first 10 characters
02:54:16
now let's save this we get an error
02:54:19
because we are missing a DOT right here
02:54:22
but if we save that we get an error
02:54:25
again so let's open up the inspect
02:54:28
element let's go to console
02:54:31
it looks like that slice is undefined
02:54:33
because the player info is typed wrong
02:54:36
here that shouldn't been here at all
02:54:38
sometimes autocorrect messes things up
02:54:41
but check this out if you now hover over
02:54:44
the player you can see name account 2
02:54:46
name account 2 which doesn't seem to be
02:54:49
right right now we'll have to fix that
02:54:52
and then also we can see the address of
02:54:54
that account which is great
02:54:57
I'm now wondering why the account is the
02:55:00
same for both or at least the name and
02:55:03
the address also seems to be the same
02:55:05
for both so if you go back to battle
02:55:07
That's player info
02:55:09
the first one should be player 2 and the
02:55:11
second one should be player one
02:55:14
which seems to be good right here but
02:55:17
then if we go above
02:55:20
let's check where we're setting them set
02:55:22
Player 1 set player 2 that's looking
02:55:25
good to me we spread the player one we
02:55:29
spread the player 2 attack defense
02:55:32
health
02:55:34
all looking good
02:55:36
that's interesting Player 1 player two
02:55:39
yep that's looking good to me and in
02:55:42
here the error could be in here if
02:55:44
active players 0 is the wallet address
02:55:47
then we know that the zero player is the
02:55:50
player one and then we know that the
02:55:52
player 2 is the second index else player
02:55:56
one is the second player and player 2 is
02:55:58
Index 0. this is looking good to me as
02:56:01
well so right now I cannot seem to find
02:56:03
an issue with this so we're gonna
02:56:05
definitely revisit this later on if the
02:56:08
issue persists but now we can go back
02:56:10
and we can also add the tooltips for the
02:56:13
health and for the Mana so let's create
02:56:15
another react tooltip
02:56:18
this one is going to be self-closing
02:56:21
we're going to give it an ID equal to a
02:56:24
string of Health Dash Mt
02:56:28
in that case one
02:56:31
and then in here we're going to have two
02:56:33
let's give it an effect of solid and
02:56:36
let's give it a background color
02:56:39
the same as we did before so we can copy
02:56:43
it right from here that's for the health
02:56:46
so if you hover over the health bar now
02:56:48
you can see Health 25 which is great
02:56:50
it's much easier than reading all the
02:56:52
lines individually
02:56:53
and we can duplicate that say Mana right
02:56:56
here and save it and now it's gonna say
02:57:00
that this is Mana this is a beautiful
02:57:02
way to add interactivity to your
02:57:04
application you can see it was so easy
02:57:07
to add these tooltips but they help so
02:57:09
much
02:57:10
so this is looking great to me right now
02:57:13
we just gave much more sense to the game
02:57:16
since now we have the icons we have the
02:57:18
health bars and the Mana bars now is the
02:57:21
time that we implement the next step of
02:57:24
the battle page which in this case is
02:57:27
going to be the cards themselves the
02:57:30
main star of the show so let's jump into
02:57:33
the card and let's get started to start
02:57:36
implementing our card component we can
02:57:39
import something known as tilt from
02:57:42
react
02:57:43
forward slash
02:57:45
Dash parallax
02:57:47
Dash tilt you're gonna quickly see what
02:57:51
this package does it's quite cool and
02:57:53
then we can import these Styles coming
02:57:56
from dot slash styles
02:57:59
we can also import something known as
02:58:01
all cards coming from dot slash assets
02:58:06
this is an array of all card assets that
02:58:09
we have prepared now what we want to do
02:58:12
is fetch a random card acid from The
02:58:15
Collection so let's create a function
02:58:18
generate
02:58:20
random card image
02:58:23
that's going to be a function
02:58:25
there we can tap into all cards
02:58:29
access the math.floor and then math that
02:58:34
random and then we can multiply that by
02:58:37
all cards dot length minus one this
02:58:41
function right here is going to help us
02:58:42
generate a random card once we do that
02:58:45
we can say const IMG one is equal to
02:58:48
Generate random card image and also we
02:58:51
can do the same thing for image 2. that
02:58:54
way we're making sure that every player
02:58:56
has a unique card
02:58:58
now our function does accept some
02:59:01
parameters things like card title card
02:59:03
ref and player two so let's get them
02:59:06
right here
02:59:07
card
02:59:09
title rest styles
02:59:12
card ref and player two
02:59:16
inside of here let's create a div that's
02:59:20
going to have a reference to this card
02:59:22
and reference is going to be card ref
02:59:25
if we save this it might break the
02:59:27
application as I thought if we put it as
02:59:30
an empty string it's still going to
02:59:32
break because it's not allowing us to
02:59:34
pass faulty references so for now let's
02:59:36
remove that part we're going to bring it
02:59:38
back in later when we will need to add
02:59:40
those explosion animations
02:59:42
for now let's add a class name equal to
02:59:45
a template string of styles Dot card
02:59:48
container and also rest styles
02:59:53
now inside of there we want to render
02:59:55
the image
02:59:56
this image is going to have a source
02:59:58
equal to player 2. if it is a player 2
03:00:02
then it's going to be image 2 else it's
03:00:05
going to be image 1. it's going to have
03:00:08
an ALT equal to card
03:00:10
and it's going to have a class name
03:00:12
equal to Styles Dot card IMG
03:00:17
once we save this you can see one card
03:00:20
the second one seems to be broken though
03:00:22
so something doesn't seem to be right in
03:00:26
this case I think I forgot to add a
03:00:29
parenthesis to wrap the all cards dot
03:00:32
length minus one because what it was
03:00:34
doing so far it was multiplying the math
03:00:36
at random times all cars that length and
03:00:39
then decrementing one we want to do this
03:00:42
together and then multiply it once we do
03:00:44
that we can see two great cards and
03:00:47
every time that you save a file you're
03:00:48
gonna get two new ones which is
03:00:51
phenomenal the game is already looking
03:00:54
so much better now you can see that the
03:00:57
attack and defense values are currently
03:00:59
empty so now we have to add them and you
03:01:02
can also see that the action buttons are
03:01:04
not currently used so soon enough we're
03:01:07
going to implement those as well but
03:01:09
that's in a separate component for now
03:01:11
let's focus on attack and defense values
03:01:13
below our image let's create a div and
03:01:17
that div is going to have a class name
03:01:20
equal to a template string of styles Dot
03:01:23
card Point container on small devices
03:01:27
it's going to have a left property of
03:01:30
21.2 percent I found this value as it's
03:01:34
very specific but to work the best and
03:01:37
then the left is going to be 22 percent
03:01:40
right here
03:01:42
and finally we can give it a Styles dot
03:01:44
Flex Center
03:01:46
inside of that div we want to render a P
03:01:49
tag this P tag is going to have a class
03:01:52
name equal to a template string again of
03:01:56
styles
03:01:58
Dot card point
03:02:00
and text Dash yellow Dash 400.
03:02:04
and it can render a dynamic property of
03:02:07
card.att
03:02:09
if we save that you can see a number 9
03:02:12
here and X right there if we mess with
03:02:15
the percentages a bit like let's do 10
03:02:18
you can notice it is a bit off but with
03:02:20
those values we're ensuring that it's
03:02:22
always going to be right in the middle
03:02:24
with that said we can now duplicate this
03:02:27
div below
03:02:29
in here what we have to change are the
03:02:31
percentages so let's do
03:02:33
14.2 here
03:02:35
for the left in this case it's not going
03:02:38
to be left it's going to be right and
03:02:40
let's do something like 15 percent
03:02:43
and we're going to change the color to
03:02:46
text Dash red Dash 700.
03:02:50
and there we go the opposing players
03:02:53
values are hidden right here and then in
03:02:56
here we have 9 and 9 and now we know our
03:02:59
attack and defense values which don't
03:03:01
seem to be right yet but we're hopefully
03:03:03
gonna fix that soon
03:03:05
finally we need the title of our player
03:03:08
So Below this div we can create one more
03:03:11
div
03:03:12
that div is going to have a class name
03:03:15
equal to a template string of styles Dot
03:03:18
card text container and styles dot Flex
03:03:24
Center
03:03:25
inside of there we can render a P tag
03:03:29
and that P tag is going to render the
03:03:31
title
03:03:33
if we save that we can see account 2 and
03:03:36
JS Mastery oh interesting so it is
03:03:38
picking up JS Mastery right here that's
03:03:40
good
03:03:41
and then we want to give that a class
03:03:44
name equal to Styles Dot card
03:03:48
text
03:03:49
if we save that this is looking
03:03:51
phenomenal if we expand our browser our
03:03:55
game is looking much more like a game
03:03:58
now this is such a beautiful
03:04:00
Battleground we have our images but most
03:04:03
importantly our data is right here
03:04:05
although these percentages don't seem to
03:04:08
be right right now we'll have to look

Description:

Web 3.0 has the power to change the internet as we know it forever. You're still early in catching the trend right now and building your first blockchain application. Create your characters, create and join live battles, choose your battleground, and battle other players in real-time! This video is a collaboration between Avalanche and JS Mastery. ⭐ Avalanche - https://www.avax.network/ ⭐ Download Core - https://chromewebstore.google.com/detail/core-crypto-wallet-nft-ex/agoakfejjabomempkjlepdflaleeobhb ⭐ Learn more about the latest Avalanche News - https://medium.com/avalancheavax ⭐ Follow Avalanche on Twitter for the latest updates - https://twitter.com/avalancheavax Avalanche is an open, programmable smart contracts platform for decentralized applications. It allows you to build fast, low-cost, Solidity-compatible dApps, and launch customized blockchain networks via Subnets. Create without limits - Build anything you want, any way you want. Avalanche has the tooling and composability you need to speed from concept to launch. Learn more about building on Avalanche with the below developer resources: 📙Developer Documentation - https://docs.avax.network/ 📙Avalanche-Cli - https://github.com/ava-labs/avalanche-cli 📙Avalanche Network Runner - https://github.com/ava-labs/avalanche-network-runner 📙AvalancheJS - https://github.com/ava-labs/avalanchejs 📙Postman Collection - https://github.com/ava-labs/avalanche-postman-collection Become a Web3.0 Pioneer by Building an Advanced NFT Marketplace App: 💻 JS Mastery Pro - https://www.jsmastery.pro/ ✅ A special YOUTUBE discount code is automatically applied! 📙 The Web 3.0 Developer Roadmap : https://resource.jsmastery.pro/web3.0-roadmap 📙 The Ultimate Solidity CheatSheet : https://resource.jsmastery.pro/solidity-cheatsheet 🐛Got stuck? Get your bugs resolved immediately - https://discord.com/servers/javascript-mastery-programming-coding-community-710138849350647871 📚 Materials/References: GitHub Code (give it a star ⭐): https://github.com/adrianhajdin/project_web3_battle_game/tree/main Starter Code - https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/adrianhajdin/project_web3_battle_game/tree/main/client-starter GitHub Gist Code Snippets: https://gist.github.com/adrianhajdin/cc3befc6cc1ed69f59334edacbcdb91e Deployment - https://hostinger.com/javascriptmastery With a stunning design, interactive gameplay, smart wallet pairing, live interaction with smart contracts, and, most importantly, the ability to battle other players in real-time, AvaxGods is the best and the only Web3 battle-style online multiplayer card game that you can currently find on YouTube. In this course, you'll learn the following: - How to connect a regular React.js application to the blockchain and pair it to your wallet - You’ll also learn about the solidity programming language and how smart contracts written in Solidity work - You’ll learn how to create smart contracts and decentralized applications on the Avalanche platform 💻 Join JSM on Discord - https://discord.com/invite/n6EdbFJ 🐦 Follow JSM on Twitter - https://twitter.com/jsmasterypro 🖼️ Follow JSM on Instagram - https://www.facebook.com/unsupportedbrowser 💼 Business Inquiries: [email protected] 👇 Time Stamps 00:00:00 Intro 00:05:27 Web3 Setup 00:23:41 Client-side Setup 00:29:25 Higher Order Components 00:44:52 React Web3 Context 01:09:15 Smart Contract Interaction 01:27:52 Smart Contract Event Listeners 01:41:59 New Battle and Join Battle Page 02:22:47 Battle Page 03:07:42 Game Info 03:17:02 Change Battleground 03:29:04 Web3 Modal 03:39:47 Battle Functionality 03:47:58 Custom Error Handling 03:59:04 Explosion Animation 04:22:46 Exit Battle Functionality 04:27:38 Bug Fixes 04:39:28 Code Overview 04:41:27 Deployment

Preparing download options

popular icon
Popular
hd icon
HD video
audio icon
Only sound
total icon
All
* — If the video is playing in a new tab, go to it, then right-click on the video and select "Save video as..."
** — Link intended for online playback in specialized players

Questions about downloading video

mobile menu iconHow can I download "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course" video?mobile menu icon

  • http://unidownloader.com/ website is the best way to download a video or a separate audio track if you want to do without installing programs and extensions.

  • The UDL Helper extension is a convenient button that is seamlessly integrated into YouTube, Instagram and OK.ru sites for fast content download.

  • UDL Client program (for Windows) is the most powerful solution that supports more than 900 websites, social networks and video hosting sites, as well as any video quality that is available in the source.

  • UDL Lite is a really convenient way to access a website from your mobile device. With its help, you can easily download videos directly to your smartphone.

mobile menu iconWhich format of "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course" video should I choose?mobile menu icon

  • The best quality formats are FullHD (1080p), 2K (1440p), 4K (2160p) and 8K (4320p). The higher the resolution of your screen, the higher the video quality should be. However, there are other factors to consider: download speed, amount of free space, and device performance during playback.

mobile menu iconWhy does my computer freeze when loading a "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course" video?mobile menu icon

  • The browser/computer should not freeze completely! If this happens, please report it with a link to the video. Sometimes videos cannot be downloaded directly in a suitable format, so we have added the ability to convert the file to the desired format. In some cases, this process may actively use computer resources.

mobile menu iconHow can I download "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course" video to my phone?mobile menu icon

  • You can download a video to your smartphone using the website or the PWA application UDL Lite. It is also possible to send a download link via QR code using the UDL Helper extension.

mobile menu iconHow can I download an audio track (music) to MP3 "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course"?mobile menu icon

  • The most convenient way is to use the UDL Client program, which supports converting video to MP3 format. In some cases, MP3 can also be downloaded through the UDL Helper extension.

mobile menu iconHow can I save a frame from a video "Build and Deploy an Online Multiplayer Web 3 NFT Card Game | Full Course"?mobile menu icon

  • This feature is available in the UDL Helper extension. Make sure that "Show the video snapshot button" is checked in the settings. A camera icon should appear in the lower right corner of the player to the left of the "Settings" icon. When you click on it, the current frame from the video will be saved to your computer in JPEG format.

mobile menu iconWhat's the price of all this stuff?mobile menu icon

  • It costs nothing. Our services are absolutely free for all users. There are no PRO subscriptions, no restrictions on the number or maximum length of downloaded videos.