No video

JavaScript Game Tutorial - Advanced Techniques

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

Franks laboratory

Franks laboratory

Күн бұрын

Пікірлер: 89
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Part 1 here, have fun! :D kzfaq.info/get/bejne/mZNhl6WVlsWraHU.html 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 (kzfaq.info/get/bejne/bKl7ipqlsdyZlWQ.html) 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.
@PhorssaOneDev
@PhorssaOneDev Жыл бұрын
Hi Frank, I completed this part a few days ago...thank you!Very informative. I am HOOKED! 😀
@javifontalva7752
@javifontalva7752 Жыл бұрын
This is my next challenge. Bring it on!
@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);
@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
@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
@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
@palmpixiplus
@palmpixiplus Жыл бұрын
This finally made Enums make so much sense to me. Thank you so very much!!!!
@Frankslaboratory
@Frankslaboratory Жыл бұрын
I'm here to help!
@nicklansbury3166
@nicklansbury3166 2 жыл бұрын
Another masterpiece. Thanks Frank. Enjoy your weekend.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Nick! Have a great weekend :)
@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!
@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});
@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! :)
@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!
@CodingBill
@CodingBill 2 жыл бұрын
I love the way you teach things :)
@lexart1
@lexart1 2 жыл бұрын
Díky. Skvělá práce. Skvělý tutoriál.
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Cestina, to uz jsem dlouho nevidel :D Ahooj
@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!
@AshTech-Designs
@AshTech-Designs 2 жыл бұрын
Thanks , You always deliver
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Glad you found some value :D
@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!
@funnyanimalworld7579
@funnyanimalworld7579 2 жыл бұрын
amazing video and explanation
@sertansantos3032
@sertansantos3032 2 жыл бұрын
First, thanks for all the effort Frank
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Sertan, you are fast! :D
@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 ! :)
@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
@scottatkinson7649
@scottatkinson7649 10 ай бұрын
Hi Frank, I'm loving your tutorial and learning so much. You started mobile controls but how do you add different states on mobile.
@programer115
@programer115 2 жыл бұрын
hello teacher, the tutorial was very good, the game is beautiful🧐
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Alessandro, glad you found some value! :)
@kamalkishior6383
@kamalkishior6383 2 жыл бұрын
Thank you Sir, :)
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Happy to help Kamal
@jeesjans9676
@jeesjans9676 2 жыл бұрын
thanks!!
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Glad to help Jees
@dinhson9588
@dinhson9588 Жыл бұрын
hi teacher, im doing same with you but my player not moving when he standing ?? maybe my chrome have problem??
@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!!
@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.
@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! :)
@Kucingku46
@Kucingku46 2 жыл бұрын
Request tutorial idle game with js
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Hi Rifan, what are some examples of idle game genre
@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
@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 :)
@PopLll-lo9ot
@PopLll-lo9ot Жыл бұрын
Hi can someone help me in console say currentstate undefined please someone help me
@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
@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!
@technoinfoworldwide2329
@technoinfoworldwide2329 2 жыл бұрын
is this game series finished?
@Frankslaboratory
@Frankslaboratory 2 жыл бұрын
Almost, there will be more episodes to finish the full game
@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 KZfaq
@jasmin8501
@jasmin8501 2 жыл бұрын
@@Frankslaboratory Can you advise me how to make an application for student absence please
@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
@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
@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) })
@javifontalva7752
@javifontalva7752 Жыл бұрын
This is my next challenge. Bring it on!
JavaScript Game Tutorial - Many Different Enemies
24:37
Franks laboratory
Рет қаралды 15 М.
State Management in Games
1:09:09
Franks laboratory
Рет қаралды 54 М.
UNO!
00:18
БРУНО
Рет қаралды 4,8 МЛН
JavaScript Game Tutorial - Final Polish
22:04
Franks laboratory
Рет қаралды 10 М.
JavaScript Sprite Animation
34:11
Franks laboratory
Рет қаралды 67 М.
Caught Cheating With Phone In His SOCK!
14:29
Chess Vibes
Рет қаралды 45 М.
Mario Game Tutorial with JavaScript and HTML Canvas
2:11:03
Chris Courses
Рет қаралды 600 М.
My TOP 5 Game Dev Books!
8:57
Unreal Robin
Рет қаралды 3,7 М.
How to Get Into the Games Industry - A Recruiter's Top 5 Tips
4:20
Massive Entertainment - A Ubisoft Studio
Рет қаралды 188 М.
Pixel Art RPG Maker with JavaScript
1:35:59
Franks laboratory
Рет қаралды 19 М.
Learn Creative Coding: Paint Brushes & Complex Shapes
33:58
Franks laboratory
Рет қаралды 47 М.
UNO!
00:18
БРУНО
Рет қаралды 4,8 МЛН