JavaScript Game Tutorial - Advanced Techniques

  Рет қаралды 26,705

Franks laboratory

Franks laboratory

Күн бұрын

Пікірлер: 89
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Part 1 here, have fun! :D kzbin.info/www/bejne/mV6UlXWaZsR6bqM What else should we implement
@cwlindWX
@cwlindWX 2 жыл бұрын
Great stuff Frank! Whether in this series or somewhere else, it would be cool to see how an area or world map is slowly revealed as the player moves around. I was watching this video (kzbin.info/www/bejne/bHSuiGqqgdtom5I) and he uses the P5.js library. And I thought, I bet Frank don't need no stinkin' library! (Since you are the canvas master! Nothing wrong with using libraries!). Anyway, I watched that video and wondered if you wanted a challenge or video idea :) Thanks again!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
@@cwlindWX Hi Clark, I could do that scratch card effect with vanilla, it wouldn't actually take much more code than using a library. Not sure how I would implement this particular effect into a game. I could for example do that with each level you uncover a bigger portion of the game world. I will put it on my list, let's see if I can include something like that in a future project, thank you for the idea.
@abitala
@abitala 2 жыл бұрын
Thank you very much, Frank, for a useful and unique course, you opened the world of web game development to me) I noticed one thing about fps control that might be helpful: when we check "if (timer > interval)..." we get error in one deltaTime iteration Because, for example, fps = 20 => interval = 1000/20 = 50 And if 16.666666 * 3 then we get 49.999998 It's almost an early 50, but we technically need another iteration. So I suggest "if (timer >= interval - deltaTime)..." Found by accident while debugging player teleportation and mana replenishment timers hah Thanks again for your work, I wish you good luck in the growth of the channel) 🔥
@javifontalva7752
@javifontalva7752 Жыл бұрын
​@@Frankslaboratory Maybe making a platform game would be cool.
@marcus_lyn
@marcus_lyn 2 жыл бұрын
random small improvement I found: this movement code for the background causes a small stutter when we reset the image back to x=0, this is because the game speed pushes x by 3 and sometimes pushes x past the ultimate width, so when we get set back to 0 you can see the stutter, we also did not account for the gamespeed in this scenario. To fix this, in the update method for Layer class, I instead increment x by the width of the background image, and I also subtract the game speed to keep moving seamlessly. code: if (this.x < -this.width) this.x += this.width - (this.game.speed*this.speedModifier);
@atticusyong2927
@atticusyong2927 Жыл бұрын
Can someone help me? My code not working... background.js class Layer { constructor(game, width, height, speedModifier, image) { this.game = game this.width = width this.height = height this.speedModifier = speedModifier this.image = image this.x = 0 this.y = 0 } update() { if (this.x < -this.width) this.x = 0 else this.x -= this.game.speed * this.speedModifier } draw(context) { context.drawImage(this.image, this.x, this.y, this.width, this.height) context.drawImage(this.image, this.x + this.width, this.y, this.width, this.height) } } export class Background { constructor(game) { this.game = game this.width = 1667 this.height = 500 this.layer1image = document.getElementById('layer1') this.layer2image = document.getElementById('layer2') this.layer3image = document.getElementById('layer3') this.layer4image = document.getElementById('layer4') this.layer5image = document.getElementById('layer5') this.layer1 = new Layer(this.game, this.width, this.height, 0, this.layer1image) this.layer2 = new Layer(this.game, this.width, this.height, 0.2, this.layer2image) this.layer3 = new Layer(this.game, this.width, this.height, 0.4, this.layer3image) this.layer4 = new Layer(this.game, this.width, this.height, 0.8, this.layer4image) this.layer5 = new Layer(this.game, this.width, this.height, 1, this.layer5image) this.backgroundLayers = [this.layer1, this.layer2, this.layer3, this.layer4, this.layer5] } update() { this.backgroundLayers.forEach(layer => { layer.update() }) } draw(context) { this.backgroundLayers.forEach(layer => { layer.update(context) }) } } player.js import { Sitting, Running, Jumping, Falling } from "./playerStates.js" export class Player { constructor(game) { this.game = game this.width = 100 this.height = 91.3 this.x = 0 this.y = this.game.height - this.height - this.groundMargin this.vy = 0 this.weight = 1 this.image = document.getElementById('player') this.frameX = 0 this.frameY = 0 this.maxFrame this.fps = 20 this.frameInterval = 1000/this.fps this.frameTimer = 0 this.speed = 0 this.maxSpeed = 10 this.states = [new Sitting(this), new Running(this), new Jumping(this), new Falling(this)] this.currentState = this.states[0] this.currentState.enter() } update(input, deltaTime) { this.currentState.handleInput(input) // Horizpntal Movement this.x += this.speed if (input.includes('ArrowRight')) this.speed = this.maxSpeed else if (input.includes('ArrowLeft')) this.speed = -this.maxSpeed else this.speed = 0 if (this.x < 0) this.x = 0 if (this.x > this.game.width - this.width) this.x = this.game.width - this.width // Vertical Movement this.y += this.vy if (!this.onGround()) this.vy += this.weight else this.vy = 0 // Sprite Animation if (this.frameTimer > this.frameInterval) { this.frameTimer = 0 if (this.frameX < this.maxFrame) this.frameX++ else this.frameX = 0 } else { this.frameInterval += deltaTime } } draw(context) { context.drawImage(this.image, this.frameX * this.width, this.frameY * this.height, this.width, this.height, this.x, this.y, this.width, this.height) } onGround() { return this.y >= this.game.height - this.height - this.game.groundMargin } setState(state, speed) { this.currentState = this.states[state] this.game.speed = this.game.maxSpeed * speed this.currentState.enter() } } playerStates.js const states = { SITTING: 0, RUNNING: 1, JUMPING: 2, FALLING: 3 } class State { constructor(state) { this.state = state } } export class Sitting extends State { constructor(player) { super('SITTING') this.player = player } enter() { this.player.frameX = 0 this.player.maxFrame = 4 this.player.frameY = 5 } handleInput(input) { if (input.includes('ArrowLeft') || input.includes('ArrowRight')) { this.player.setState(states.RUNNING, 1) } } } export class Running extends State { constructor(player) { super('RUNNING') this.player = player } enter() { this.player.frameX = 0 this.player.maxFrame = 8 this.player.frameY = 3 } handleInput(input) { if (input.includes('ArrowDown')) { this.player.setState(states.SITTING, 0) } else if (input.includes('ArrowUp')) { this.player.setState(states.JUMPING, 1) } } } export class Jumping extends State { constructor(player) { super('JUMPING') this.player = player } enter() { if (this.player.onGround()) this.player.vy -= 27 this.player.frameX = 0 this.player.maxFrame = 6 this.player.frameY = 1 } handleInput(input) { if (this.player.vy > this.player.weight) { this.player.setState(states.FALLING, 1) } } } export class Falling extends State { constructor(player) { super('FALLING') this.player = player } enter() { this.player.frameX = 0 this.player.maxFrame = 6 this.player.frameY = 2 } handleInput(input) { if (this.player.onGround()) { this.player.setState(states.RUNNING, 1) } } } script.js import { Player } from './player.js' import { InputHandler } from './input.js' import { Background } from './background.js' window.addEventListener('load', function() { const canvas = document.getElementById('canvas1') const ctx = canvas.getContext('2d') canvas.width = 500 canvas.height = 500 class Game { constructor(width, height) { this.width = width this.height = height this.groundMargin = 80 this.speed = 0 this.maxSpeed = 4 this.background = new Background(this) this.player = new Player(this) this.input = new InputHandler() } update(deltaTime) { this.background.update() this.player.update(this.input.keys, deltaTime) } draw(context) { this.background.draw(context) this.player.draw(context) } } const game = new Game(canvas.width, canvas.height) console.log(game) let lastTime = 0 function animate(timeStamp) { const deltaTime = timeStamp - lastTime lastTime = timeStamp ctx.clearRect(0, 0, canvas.width, canvas.height) game.update(deltaTime) game.draw(ctx) requestAnimationFrame(animate) } animate(0) })
@DannyHille
@DannyHille 2 жыл бұрын
Tip: when using "Enum types" like states, you can use Objet.freeze to ensure the values doesn't change: like this: const states = Object.freeze({SITTING:0, RUNNING:1});
@PopLll-lo9ot
@PopLll-lo9ot Жыл бұрын
Hi can someone help me in console say currentstate undefined please someone help me
@dinhson9588
@dinhson9588 Жыл бұрын
hi teacher, im doing same with you but my player not moving when he standing ?? maybe my chrome have problem??
@PhorssaOneDev
@PhorssaOneDev Жыл бұрын
Hi Frank, I completed this part a few days ago...thank you!Very informative. I am HOOKED! 😀
@phoenixxofficial
@phoenixxofficial 2 жыл бұрын
A lot of great information, wonderfully explained with useful on screen notes to help with understanding - good job as always Frank! (:
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Phoenixx, glad you find my new teaching style useful, still improving it :D
@carltone
@carltone 2 жыл бұрын
Frank, love the code refinements, I always learn something new from your excellent tutorials. Thanks for sharing your knowledge!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Thanks Carl, I'm explaining some things in this series I haven't shown before, let's see if it's still beginner friendly, maybe my future projects will have to be a bit simpler. Glad you found some value
@javifontalva7752
@javifontalva7752 Жыл бұрын
This is my next challenge. Bring it on!
@christopherc4526
@christopherc4526 2 жыл бұрын
This channel is a great find. Thank you for these excellent tutorials. Wishing you great success.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Chris, nice to meet you, glad you found some value!
@nyupyu
@nyupyu Жыл бұрын
My dog jumping soo fast on 165hz refresh rate screen and I can't find solution. Someone know what should I do?
@Frankslaboratory
@Frankslaboratory Жыл бұрын
You can use delta time to throttle the entire animation loop and max it at around 60fps. I did it in the game tutorial I released last week
@nicklansbury3166
@nicklansbury3166 2 жыл бұрын
Another masterpiece. Thanks Frank. Enjoy your weekend.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Nick! Have a great weekend :)
@scottatkinson7649
@scottatkinson7649 11 ай бұрын
Hi Frank, I'm loving your tutorial and learning so much. You started mobile controls but how do you add different states on mobile.
@Radu
@Radu 2 жыл бұрын
Thanks! I'll need to use that deltaTime technique at some point. Just one question: doesn't this make it refresh slower than the frameInterval? (because you use if(this.frameTimer>this.frameInterval). It would be nice to see a plot of the this.frameTimer values as they accumulate over time. I assume the average value to be something like (frameInterval+deltaTime)/2.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Yes. This technique is not completely accurate because, there is a leftover part of deltaTime value after every reset. For complete cross device behaviour that leftover value would have to be accounted for but I think for the purposes of a project like this it works well enough.
@Radu
@Radu 2 жыл бұрын
@@Frankslaboratory I see. Thank you, Frank!
@ZilaAi96
@ZilaAi96 Жыл бұрын
Bro dog animating too fast how can i slow it
@Frankslaboratory
@Frankslaboratory Жыл бұрын
You can control frame rate with delta time calculation. Comparing old and the current timestamp. I do it in most of my game dev classes, didn't do it in this one
@anaccount687
@anaccount687 2 жыл бұрын
How did you do the energy?
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
It's just a simple object and a couple of if else statements. I'm doing a replenishing ammo in the next class releasing next week, it's the same thing, I will explain it there.
@javifontalva7752
@javifontalva7752 Жыл бұрын
This is my next challenge. Bring it on!
@funnyanimalworld7579
@funnyanimalworld7579 2 жыл бұрын
amazing video and explanation
@CodingBill
@CodingBill 2 жыл бұрын
I love the way you teach things :)
@ivgadev
@ivgadev 2 жыл бұрын
I hate you. Now I feel not to have hours in a day to play with this new knowledge, lmao
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Ivan, there are indeed many use cases for this technique. For example player can have a special animation loop that plays once when entering or exiting each state, if you have sprite sheet for that. Also it can be used to create pause/play/menu functionality when applied to the main game object. I might show how to do all of that later.
@ivgadev
@ivgadev 2 жыл бұрын
@@Frankslaboratory Thank you so much for the ideas and for your free content. I've learned so much from you :)
@VeGaDrOnE
@VeGaDrOnE Жыл бұрын
I followed along, step by step, but when it's time to see the images scrolling in the background i see my character in a perfect white void 😅 i think the problem is here: update(){ if (this.x < - this.width) this.x = 0; else this.x -= this.game.speed * this.speedModifier; } with this function, if i console log the array entries with: console.log(this.backgroundLayers[0].x, this.backgroundLayers[0].y); i noticed that the x is NaN and so the program dosen't draw the images. I checked your code and my code several times but it's EXACTLEY the same. How it's possible that is NaN?
@Frankslaboratory
@Frankslaboratory Жыл бұрын
Its NaN because one the line where you are calculating that x value, one of the operands is undefined. You need to track that logic until you find where you made a typo
@VeGaDrOnE
@VeGaDrOnE Жыл бұрын
@@Frankslaboratory I assigned this.x = 0 in the Layer class constructor and then i used: update(){ if (this.x < - this.width) this.x = 0; else this.x -= this.game.speed * this.speedModifier; }. i check if is NaN, i opened the object in console, the problem is the x NaN and the entire update method give me undefined. If i took out the minus sign before the first this.width in the if condition x is 0 and the images are there but dosen't move.
@VeGaDrOnE
@VeGaDrOnE Жыл бұрын
YES! I did it you you were right there was a typo! Thanks!
@Frankslaboratory
@Frankslaboratory Жыл бұрын
@@VeGaDrOnE glad you worked it out, nice! :)
@souerico
@souerico Жыл бұрын
Just discovered the channel! It is amazing!I'm learning a lot! Thank you so much!
@Frankslaboratory
@Frankslaboratory Жыл бұрын
Nice to meet you Erico!
@techtime3125
@techtime3125 2 жыл бұрын
Dude I started this series when I started learning js but i didnt understand anything now i am much advanced and I restarted this, dude the way you explain and the easy way you code i love that
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
It feels good when you see yourself progressing doesn't it. I usually have to do each new technique 3 to 5 times before it starts making sense to me. Practice is important. Have fun with the project
@techtime3125
@techtime3125 2 жыл бұрын
@@Frankslaboratory Yeah Agreed
@palmpixiplus
@palmpixiplus Жыл бұрын
This finally made Enums make so much sense to me. Thank you so very much!!!!
@Frankslaboratory
@Frankslaboratory Жыл бұрын
I'm here to help!
@TheLegendOfNiko
@TheLegendOfNiko 2 жыл бұрын
Thank you so much mate. I’ve been looking for a way to create this for months !!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Happy to help! :)
@programer115
@programer115 2 жыл бұрын
hello teacher, the tutorial was very good, the game is beautiful🧐
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Alessandro, glad you found some value! :)
@cosmincosmin4451
@cosmincosmin4451 2 жыл бұрын
Can I find jobs in this direction? JS 2d games? Or is it just for fun?
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
There are more and more companies doing 2D browser games. If you're good with JavaScript you can get many jobs. Also the logic is easily transferable to other programming languages if needed. When you get a job in a good company they don't care what language you know, as long as you are good at it, they will train you in their specific stack when you join
@Avinashkumar-zz8qi
@Avinashkumar-zz8qi 2 жыл бұрын
Nice video sir. Thank you for the tutorials.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Happy to help Avinash, comment 5 sec after release haha, nice
@AshTech-Designs
@AshTech-Designs 2 жыл бұрын
Thanks , You always deliver
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Glad you found some value :D
@barryglibb1448
@barryglibb1448 2 жыл бұрын
Loving this series so far, and indeed all your videos having recently discovered your channel. I'm a JS developer of business applications with some 15 years experience and it's nice to be able to follow along with your well-written and explained code to use my skills in a different way. Great job! +1 sub, +1 notification from me.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Ben, nice to see that my videos could be interesting even for experienced developers. Appreciate your support, thank you for letting me know you found some value!
@h4m2_
@h4m2_ Жыл бұрын
how do you cap the fps so the game doesn't move as fast. I'm getting 144 fps because of my monitor and I find it way too quick.
@Frankslaboratory
@Frankslaboratory Жыл бұрын
Using delta time you set timer and interval for serving animation frames. I'll do in in the project I'm releasing this Friday
@h4m2_
@h4m2_ Жыл бұрын
@@Frankslaboratory omg thank you so much for the quick reply. I'll try it right now! Doesn't this just cap the fps of the sprite?
@h4m2_
@h4m2_ Жыл бұрын
@@Frankslaboratory I see we also are not using deltaTime in the update class in player.js. I skipped the states etc as I plan to use a still image and not animations etc.
@Frankslaboratory
@Frankslaboratory Жыл бұрын
@@h4m2_ deltaTime can cap anything, it just measures milliseconds so you can use that to trigger periodic event to cap fps of a sprite on a single object or of the entire game, it's the same technique, just needs a small adjustment. In the class I just finished filming I used it that way so that it caps everything. It will cover high refresh rate screens
@h4m2_
@h4m2_ Жыл бұрын
@@Frankslaboratory thank you very much for this amazing content. I'm looking forward to Friday now!
@Kucingku46
@Kucingku46 2 жыл бұрын
Request tutorial idle game with js
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Rifan, what are some examples of idle game genre
@aitorplaza2560
@aitorplaza2560 2 жыл бұрын
Hi Frank, Awesome course, i'm followig it and I'm enjoying it very much. I just have one question, why do we need to set up a server? I've tried launching the game without the server, just opening the index.html file and it does not work. I'll thank you if you can clearify this.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Aitor, I briefly mention the reason in the beginning, it's because we are splitting code into modules, multiple files, and we are exporting and importing. This only works when run though a server. If you want it to work locally you would have to put all javascript into a single file. it could be challenging if you are a beginner because the order in which you declare classes is important, they don't hoist
@aitorplaza2560
@aitorplaza2560 2 жыл бұрын
@@Frankslaboratory thank you very much, Frank. Very well explained. I watched both videos in their entirety and missed that comment, my fault 😅. Keep up the good work!!
@jasmin8501
@jasmin8501 2 жыл бұрын
Hello, how are you?? ..excuse me, do you have a Java language course?
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Jasmin, I only do JavaScript, for Java there are some other experts here on KZbin
@jasmin8501
@jasmin8501 2 жыл бұрын
@@Frankslaboratory Can you advise me how to make an application for student absence please
@sertansantos3032
@sertansantos3032 2 жыл бұрын
First, thanks for all the effort Frank
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Sertan, you are fast! :D
@kamalkishior6383
@kamalkishior6383 2 жыл бұрын
Thank you Sir, :)
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Happy to help Kamal
@technoinfoworldwide2329
@technoinfoworldwide2329 2 жыл бұрын
is this game series finished?
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Almost, there will be more episodes to finish the full game
@CSEGNaveensaireddy
@CSEGNaveensaireddy 2 жыл бұрын
Hi sir please make this game installable
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi, this is a browser game, not sure if JavaScript can do installable games, probably you need something like C+ for that?
@CSEGNaveensaireddy
@CSEGNaveensaireddy 2 жыл бұрын
Ok Sir
@lexart1
@lexart1 2 жыл бұрын
Díky. Skvělá práce. Skvělý tutoriál.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Cestina, to uz jsem dlouho nevidel :D Ahooj
@evaristocuesta
@evaristocuesta 2 жыл бұрын
Excellent!!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Evaristo, I used state design pattern only because of your advice, otherwise this code would look very different ! :)
@jeesjans9676
@jeesjans9676 2 жыл бұрын
thanks!!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Glad to help Jees
JavaScript Game Tutorial - Many Different Enemies
24:37
Franks laboratory
Рет қаралды 15 М.
JavaScript Sprite Animation
34:11
Franks laboratory
Рет қаралды 68 М.
Help Me Celebrate! 😍🙏
00:35
Alan Chikin Chow
Рет қаралды 45 МЛН
小天使和小丑太会演了!#小丑#天使#家庭#搞笑
00:25
家庭搞笑日记
Рет қаралды 24 МЛН
6 Months of Learning JavaScript Game Dev in 6 Minutes
6:35
Suboptimal Engineer
Рет қаралды 122 М.
I Tried Making an FPS Game in JavaScript
8:19
SimonDev
Рет қаралды 132 М.
JavaScript Game Tutorial - Particles & Interactions
31:10
Franks laboratory
Рет қаралды 12 М.
SKIN EFFECT! Why Current Doesn’t Run Inside
13:12
ElectroBOOM
Рет қаралды 252 М.
JavaScript Game Tutorial - Final Polish
22:04
Franks laboratory
Рет қаралды 10 М.
I redesigned my game
23:32
jdh
Рет қаралды 9 М.
HTML5 Canvas CRASH COURSE for Beginners
51:26
Franks laboratory
Рет қаралды 218 М.
The Home Server I've Been Wanting
18:14
Hardware Haven
Рет қаралды 166 М.
How To Code Flying Creatures with JavaScript
49:34
Franks laboratory
Рет қаралды 34 М.
Help Me Celebrate! 😍🙏
00:35
Alan Chikin Chow
Рет қаралды 45 МЛН