1629125220
This Edureka video gives you a brief overview of Artificial intelligence and machine learning in gaming. The following topics will be covered:
Evolution Of Gaming
AI in Gaming
Future Of Gaming
Career Opportunities In Gaming
#ai #artificialintelligence #machinelearning #gamedev
1629088515
Trong hướng dẫn Unity cho người mới bắt đầu, bạn sẽ học về Tags trong lập trình Game
++++ Tài Liệu học : https://bit.ly/3k8j2F7
#unity #gamedev
1628922407
In this Flutter Tutorial, we will be taking a look at creating a base for Jardinains (Pong) Game in Flutter from Scratch. I will be going through the code, explaining to you all the important concepts. This tutorial will help you understand the implementation for Collision detection in games and a lot more to work on your own Flutter Game Projects.
I will be adding a lot more features to this game, so make sure you follow the code on Git Repository:
✔ Git: https://github.com/retroportalstudio/flutter_jardinains
#flutter #gamedev
1628910127
Seth welcomes Shivani Santosh Sambare to talk about Prebuilt Docker Images for Inference in Azure Machine Learning. Stay tuned as we get back to working on the Roshambo game.
Jump to:
00:17 Show begins
00:29 Welcome Shivani
00:38 What are the challenges working with ML environments?
01:11 Solutions to ML challenges/environments = Prebuilt Docker Images for Inference
02:12 How do I make this work with other specialized environments?
04:10 Demo: Deploying PyTorch model using Azure ML
04:30 Scoring script
06:50 End demo & recap
09:06 Learn more
#machinelearning #ai #gamedev #docker #azure
1628883540
For game developers the user experience is the point. But too often game developers spend countless hours on mundane and repetitive tasks that do not make the game more entertaining. These include tasks like cache management on the client, standing up and maintaining REST servers for data transfer, and the operations of databases for scale and schema migrations.
Learn how the Realm .NET SDK, now with Unity support, can store data and replicate data via Realm Sync to MongoDB Atlas through the MongoDB Realm serverless platform. In this session we’ll explore what it takes to develop cross-platform (Android, iOS, Mac, Windows) games using the popular Unity game development framework and MongoDB Realm.
#unity #mongdb #gamedev #realm
1628610592
In this tutorial, I build a Star Wars Memory Game with React hooks and Typescript. I also use Styled Components for styling and Vite as a package bundler.
Project files: https://github.com/weibenfalk/react-memory-ts
#react #typescript #javascript #gamedev
1628524278
Course timestamps:
0:00:00 - Intro
0:01:31 - Setting up
0:16:03 - Moving and Manual Collision Detection
1:03:06 - Tilemap and Designing Dungeon
1:40:31 - Interactive Objects and Inheritance
2:15:37 - Saving Game's State
2:41:31 - Floating Text System
3:11:11 - Top Down Combat System
4:13:32 - Animator and Weapon Swing Animation
4:35:27 - Character Menu and the new UI System
6:00:00 - Polishing and Adding Content
#csharpf #unity #gamedev
1628064906
Nowadays Unity game development is more in demands. And no doubt their are many companies out their who provides you Unity game development services. But, how to find best one?
There are several unity game development companies available in the market that have established a strong foot in the industry by their impressive and innovative results. Today game development needs considerable additional efforts and creativity to sustain a good position and to keep a consistent user base because of the cut-throat competition.
Below are the points that you must consider while hiring best Unity Development Companies for your game design
Game development is the process of constant evaluation in the current version and incorporating creativity through precise implementation. Though, game development with unity is currently in demand due to its features like
Below are some of the best Unity 3D game development companies that can help you to build your own game.
Auxano Global Services has rich experience over Unity 3D game development platform being an experienced firm in the field of cross mobile app development with its highly talented team. We strive towards delivering the users and customers an exclusive gaming environment to capture the interests. Our Unity 3D game development company strive hard and evolve out creating noteworthy applications which are highly influential to conquer customer’s interests.
2. Quytech
Quytech works with Startups and Enterprises, helping them in fine-tuning the latest mobile strategies. We provide end to end solutions starting from conceptualization to deployment support. Our solutions and allied services speak as we stand on our client expectations. Moreover, our solutions have set the universally defined benchmarks of quality, performance, and productivity in the industry.
3. Bitbean
Bitbean has acquired a name for helping businesses grow exponentially because of our trademark Shifting Perspectives® methodology, exceptional teamwork, and Silicon Valley standard of tech excellence. Woven into our corporate DNA is the acumen and innovative thinking of the NYC Jewish business community, driving us to relentlessly raise the bar on what custom software can achieve for all companies who are striving to be industry leaders.
1627976220
In this tutorial, we will learn How to make Tic Tac Toe in C++. The Tic Tac Toe game is played between two players in which Xs and 0s are marked alternatively between the spaces. We will learn how to make the structure of the game and create it using C++ code. This C++ tutorial will give you the idea to create interesting games.
#cplusplus #gamedev
1627938240
There are different ways to express and end condition in a game. It's up to you as the creator of the game to say why the game has ended. Here are some reasons, if we assume we are talking about the space game you have been building so far:
If people enjoy your game they are likely to want to replay it. Once the game ends for whatever reason you should offer an alternative to restart.
Think a bit about under what conditions you find a game ends, and then how you are prompted to restart
You will be adding these rules to your game:
Locate the files that have been created for you in the your-work sub folder. It should contain the following:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| life.png
-| index.html
-| app.js
-| package.json
You start your project the your_work folder by typing:
cd your-work
npm start
The above will start a HTTP Server on address http://localhost:5000. Open up a browser and input that address. Your game should be in a playable state.
tip: to avoid warnings in Visual Studio Code, edit the window.onload function to call gameLoopId as is (without let), and declare the gameLoopId at the top of the file, independently: let gameLoopId;
Track end condition. Add code that keeps track of the number of enemies, or if the hero ship has been destroyedby adding these two functions:
function isHeroDead() {
return hero.life <= 0;
}
function isEnemiesDead() {
const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead);
return enemies.length === 0;
}
Add logic to message handlers. Edit the eventEmitter to handle these conditions:
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
second.dead = true;
hero.incrementPoints();
if (isEnemiesDead()) {
eventEmitter.emit(Messages.GAME_END_WIN);
}
});
eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
enemy.dead = true;
hero.decrementLife();
if (isHeroDead()) {
eventEmitter.emit(Messages.GAME_END_LOSS);
return; // loss before victory
}
if (isEnemiesDead()) {
eventEmitter.emit(Messages.GAME_END_WIN);
}
});
eventEmitter.on(Messages.GAME_END_WIN, () => {
endGame(true);
});
eventEmitter.on(Messages.GAME_END_LOSS, () => {
endGame(false);
});
Add new message types. Add these Messages to the constants object:
GAME_END_LOSS: "GAME_END_LOSS",
GAME_END_WIN: "GAME_END_WIN",
Add restart code code that restarts the game at the press of a selected button.
Listen to key press Enter. Edit your window's eventListener to listen for this press:
else if(evt.key === "Enter") {
eventEmitter.emit(Messages.KEY_EVENT_ENTER);
}
Add restart message. Add this Message to your Messages constant:
KEY_EVENT_ENTER: "KEY_EVENT_ENTER",
Implement game rules. Implement the following game rules:
Player win condition. When all enemy ships are destroyed, display a victory message.
First, create a displayMessage() function:
function displayMessage(message, color = "red") {
ctx.font = "30px Arial";
ctx.fillStyle = color;
ctx.textAlign = "center";
ctx.fillText(message, canvas.width / 2, canvas.height / 2);
}
Create an endGame() function:
function endGame(win) {
clearInterval(gameLoopId);
// set a delay so we are sure any paints have finished
setTimeout(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (win) {
displayMessage(
"Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew",
"green"
);
} else {
displayMessage(
"You died !!! Press [Enter] to start a new game Captain Pew Pew"
);
}
}, 200)
}
Restart logic. When all lives are lost or the player won the game, display that the game can be restarted. Additionally restart the game when the restart key is hit (you can decide what key should be mapped to restart).
Create the resetGame() function:
function resetGame() {
if (gameLoopId) {
clearInterval(gameLoopId);
eventEmitter.clear();
initGame();
gameLoopId = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPoints();
drawLife();
updateGameObjects();
drawGameObjects(ctx);
}, 100);
}
}
Add a call to the eventEmitter to reset the game in initGame():
eventEmitter.on(Messages.KEY_EVENT_ENTER, () => {
resetGame();
});
Add a clear() function to the EventEmitter:
clear() {
this.listeners = {};
}
Congratulations, Captain! Your game is complete! Well done!
Add a sound! Can you add a sound to enhance your game play, maybe when there's a laser hit, or the hero dies or wins? Have a look at this sandbox to learn how to play sound using JavaScript
Your assignment is to create a fresh sample game, so explore some of the interesting games out there to see what type of game you might build.
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/6-end-condition/README.md
#gamedev #javascript #html
1627938000
In this lesson, you'll learn how to add scoring to a game and calculate lives.
To be able to display a game score on the screen, you'll need to know how to place text on the screen. The answer is using the fillText() method on the canvas object. You can also control other aspects like what font to use, the color of the text and even its alignment (left, right, center). Below is some code drawing some text on the screen.
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "right";
ctx.fillText("show this on the screen", 0, 0);
The concept of having a life in a game is only a number. In the context of a space game it's common to assign a set of lives that get deducted one by one when your ship takes damage. It's nice if you can show a graphical representation of this like miniships or hearts instead of a number.
Let's add the following to your game:
Locate the files that have been created for you in the your-work sub folder. It should contain the following:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
You start your project the your_work folder by typing:
cd your-work
npm start
The above will start a HTTP Server on address http://localhost:5000. Open up a browser and input that address, right now it should render the hero and all the enemies, and as you hit your left and right arrows, the hero moves and can shoot down enemies.
Copy over the needed assets from the solution/assets/ folder into your-work folder; you will add a life.png asset. Add the lifeImg to the window.onload function:
lifeImg = await loadTexture("assets/life.png");
Add the lifeImg to the list of assets:
let heroImg,
...
lifeImg,
...
eventEmitter = new EventEmitter();
Add variables. Add code that represents your total score (0) and lives left (3), display these scores on a screen.
Extend updateGameObjects() function. Extend the updateGameObjects() function to handle enemy collisions:
enemies.forEach(enemy => {
const heroRect = hero.rectFromGameObject();
if (intersectRect(heroRect, enemy.rectFromGameObject())) {
eventEmitter.emit(Messages.COLLISION_ENEMY_HERO, { enemy });
}
})
Add life and points.
Initialize variables. Under this.cooldown = 0 in the Hero class, set life and points:
this.life = 3;
this.points = 0;
Draw variables on screen. Draw these values to screen:
function drawLife() {
// TODO, 35, 27
const START_POS = canvas.width - 180;
for(let i=0; i < hero.life; i++ ) {
ctx.drawImage(
lifeImg,
START_POS + (45 * (i+1) ),
canvas.height - 37);
}
}
function drawPoints() {
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.textAlign = "left";
drawText("Points: " + hero.points, 10, canvas.height-20);
}
function drawText(message, x, y) {
ctx.fillText(message, x, y);
}
Add methods to Game loop. Make sure you add these functions to your window.onload function under updateGameObjects():
drawPoints();
drawLife();
Implement game rules. Implement the following game rules:
For every hero and enemy collision, deduct a life.
Extend the Hero class to do this deduction:
decrementLife() {
this.life--;
if (this.life === 0) {
this.dead = true;
}
}
For every laser that hits an enemy, increase game score with a 100 points.
Extend the Hero class to do this increment:
incrementPoints() {
this.points += 100;
}
Add these functions to your Collision Event Emitters:
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
second.dead = true;
hero.incrementPoints();
})
eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => {
enemy.dead = true;
hero.decrementLife();
});
Do a little research to discover other games that are created using JavaScript/Canvas. What are their common traits?
By the end of this work, you should see the small 'life' ships at the bottom right, points at the bottom left, and you should see your life count decrement as you collide with enemies and your points increment when you shoot enemies. Well done! Your game is almost complete.
Your code is almost complete. Can you envision your next steps?
Research some ways that you can increment and decrement game scores and lives. There are some interesting game engines like PlayFab. How could using one of these would enhance your game?
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/5-keeping-score/README.md
#gamedev #javascript #html
1627936500
In this lesson you will learn how to shoot lasers with JavaScript! We will add two things to our game:
In short, you -- the hero -- need to hit all enemies with a laser before they manage to move to the bottom of the screen.
Do a little research on the very first computer game ever written. What was its functionality?
Let's be heroic together!
How do we do collision detection? We need to think of our game objects as rectangles moving about. Why is that you might ask? Well, the image used to draw a game object is a rectangle: it has an x, y, width and height.
If two rectangles, i.e a hero and enemy intersect, you have a collision. What should happen then is up to the rules of the game. To implement collision detection you therefore need the following:
A way to get a rectangle representation of a game object, something like this:
rectFromGameObject() {
return {
top: this.y,
left: this.x,
bottom: this.y + this.height,
right: this.x + this.width
}
}
A comparison function, this function can look like this:
function intersectRect(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
To destroy things in a game you need to let the game know it should no longer paint this item in the game loop that triggers on a certain interval. A way to do this is to mark a game object as dead when something happens, like so:
// collision happened
enemy.dead = true
Then you an proceed to sort out dead objects before repainting the screen, like so:
gameObjects = gameObject.filter(go => !go.dead);
Firing a laser translates to responding to a key-event and creating an object that moves in a certain direction. We therefore need to carry out the following steps:
The laser needs to fire every time you press a key, like space for example. To prevent the game producing way too many lasers in a short time we need to fix this. The fix is by implementing a so called cooldown, a timer, that ensures that a laser can only be fired so often. You can implement that in the following way:
class Cooldown {
constructor(time) {
this.cool = false;
setTimeout(() => {
this.cool = true;
}, time)
}
}
class Weapon {
constructor {
}
fire() {
if (!this.cooldown || this.cooldown.cool) {
// produce a laser
this.cooldown = new Cooldown(500);
} else {
// do nothing - it hasn't cooled down yet.
}
}
}
Refer to lesson 1 in the space game series to remind yourself about cooldowns.
You will take the existing code (which you should have cleaned up and refactored) from the previous lesson, and extend it. Either start with the code from part II or use the code at Part III- starter.
tip: the laser that you'll work with is already in your assets folder and referenced by your code
Locate the files that have been created for you in the your-work sub folder. It should contain the following:
-| assets
-| enemyShip.png
-| player.png
-| laserRed.png
-| index.html
-| app.js
-| package.json
You start your project the your_work folder by typing:
cd your-work
npm start
The above will start a HTTP Server on address http://localhost:5000. Open up a browser and input that address, right now it should render the hero and all the enemies, nothing is moving - yet :).
Setup a rectangle representation of your game object, to handle collision The below code allows you to get a rectangle representation of a GameObject. Edit your GameObject class to extend it:
rectFromGameObject() {
return {
top: this.y,
left: this.x,
bottom: this.y + this.height,
right: this.x + this.width,
};
}
Add code that checks collision This will be a new function that tests whether two rectangles intersect:
function intersectRect(r1, r2) {
return !(
r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top
);
}
Add laser firing capability
Add key-event message. The space key should create a laser just above the hero ship. Add three constants in the Messages object:
KEY_EVENT_SPACE: "KEY_EVENT_SPACE",
COLLISION_ENEMY_LASER: "COLLISION_ENEMY_LASER",
COLLISION_ENEMY_HERO: "COLLISION_ENEMY_HERO",
Handle space key. Edit the window.addEventListener keyup function to handle spaces:
} else if(evt.keyCode === 32) {
eventEmitter.emit(Messages.KEY_EVENT_SPACE);
}
Add listeners. Edit the initGame() function to ensure that hero can fire when the space bar is hit:
eventEmitter.on(Messages.KEY_EVENT_SPACE, () => {
if (hero.canFire()) {
hero.fire();
}
and add a new eventEmitter.on() function to ensure behavior when an enemy collides with a laser:
eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => {
first.dead = true;
second.dead = true;
})
Move object, Ensure the laser moves to the top of the screen gradually. You'll create a new Laser class that extends GameObject, as you've done before:
class Laser extends GameObject {
constructor(x, y) {
super(x,y);
(this.width = 9), (this.height = 33);
this.type = 'Laser';
this.img = laserImg;
let id = setInterval(() => {
if (this.y > 0) {
this.y -= 15;
} else {
this.dead = true;
clearInterval(id);
}
}, 100)
}
}
Handle collisions, Implement collision rules for the laser. Add an updateGameObjects() function that tests colliding objects for hits
function updateGameObjects() {
const enemies = gameObjects.filter(go => go.type === 'Enemy');
const lasers = gameObjects.filter((go) => go.type === "Laser");
// laser hit something
lasers.forEach((l) => {
enemies.forEach((m) => {
if (intersectRect(l.rectFromGameObject(), m.rectFromGameObject())) {
eventEmitter.emit(Messages.COLLISION_ENEMY_LASER, {
first: l,
second: m,
});
}
});
});
gameObjects = gameObjects.filter(go => !go.dead);
}
Make sure to add updateGameObjects() into your game loop in window.onload.
Implement cooldown on the laser, so it can only be fired so often.
Finally, edit the Hero class so that it can cooldown:
class Hero extends GameObject {
constructor(x, y) {
super(x, y);
(this.width = 99), (this.height = 75);
this.type = "Hero";
this.speed = { x: 0, y: 0 };
this.cooldown = 0;
}
fire() {
gameObjects.push(new Laser(this.x + 45, this.y - 10));
this.cooldown = 500;
let id = setInterval(() => {
if (this.cooldown > 0) {
this.cooldown -= 100;
} else {
clearInterval(id);
}
}, 200);
}
canFire() {
return this.cooldown === 0;
}
}
At this point, your game has some functionality! You can navigate with your arrow keys, fire a laser with your space bar, and enemies disappear when you hit them. Well done!
Add an explosion! Take a look at the game assets in the Space Art repo and try to add an explosion when the laser hits an alien
Experiment with the intervals in your game thus far. What happens when you change them? Read more about JavaScript timing events.
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/4-collision-detection/README.md
#gamedev #javascript #html
1627935300
Games aren't much fun until you have aliens running around on screen! In this game, we will make use of two types of movements:
So how do we move things on a screen? It's all about cartesian coordinates: we change the location (x,y) of the object and then redraw the screen.
Typically you need the following steps to accomplish movement on a screen:
Here's what it can look like in code:
//set the hero's location
hero.x += 5;
// clear the rectangle that hosts the hero
ctx.clearRect(0, 0, canvas.width, canvas.height);
// redraw the game background and hero
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = "black";
ctx.drawImage(heroImg, hero.x, hero.y);
Can you think of a reason why redrawing your hero many frames per second might accrue performance costs? Read about alternatives to this pattern.
You handle events by attaching specific events to code. Keyboard events are triggered on the whole window whereas mouse events like a click can be connected to clicking a specific element. We will use keyboard events throughout this project.
To handle an event you need to use the window's addEventListener() method and provide it with two input parameters. The first parameter is the name of the event, for example keyup. The second parameter is the function that should be invoked as a result of the event taking place.
Here's an example:
window.addEventListener('keyup', (evt) => {
// `evt.key` = string representation of the key
if (evt.key === 'ArrowUp') {
// do something
}
})
For key events there are two properties on the event you can use to see what key was pressed:
Key event manipulation is useful outside of game development. What other uses can you think of for this technique?
There are some special keys that affect the window. That means that if you are listening to a keyup event and you use these special keys to move your hero it will also perform horizontal scrolling. For that reason you might want to shut-off this built-in browser behavior as you build out your game. You need code like this:
let onKeyDown = function (e) {
console.log(e.keyCode);
switch (e.keyCode) {
case 37:
case 39:
case 38:
case 40: // Arrow keys
case 32:
e.preventDefault();
break; // Space
default:
break; // do not block other keys
}
};
window.addEventListener('keydown', onKeyDown);
The above code will ensure that arrow-keys and the space key have their default behavior shut off. The shut-off mechanism happens when we call e.preventDefault().
We can make things move by themselves by using timers such as the setTimeout() or setInterval() function that update the location of the object on each tick, or time interval. Here's what that can look like:
let id = setInterval(() => {
//move the enemy on the y axis
enemy.y += 10;
})
The game loop is a concept that is essentially a function that is invoked at regular intervals. It's called the game loop as everything that should be visible to the user is drawn into the loop. The game loop makes use of all the game objects that are part of the game, drawing all of them unless for some reason shouldn't be part of the game any more. For example if an object is an enemy that was hit by a laser and blows up, it's no longer part of the current game loop (you'll learn more on this in subsequent lessons).
Here's what a game loop can typically look like, expressed in code:
let gameLoopId = setInterval(() =>
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawHero();
drawEnemies();
drawStaticObjects();
}, 200);
The above loop is invoked every 200 milliseconds to redraw the canvas. You have the ability to choose the best interval that makes sense for your game.
You will take the existing code and extend it. Either start with the code that you completed during part I or use the code in Part II- starter.
Locate the files that have been created for you in the your-work sub folder. It should contain the following:
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
You start your project the your_work folder by typing:
cd your-work
npm start
The above will start a HTTP Server on address http://localhost:5000. Open up a browser and input that address, right now it should render the hero and all the enemies; nothing is moving - yet!
Add dedicated objects for hero and enemy and game object, they should have x and y properties. (Remember the portion on Inheritance or composition ).
HINT game object should be the one with x and y and the ability to draw itself to a canvas.
tip: start by adding a new GameObject class with its constructor delineated as below, and then draw it to the canvas:
class GameObject {
constructor(x, y) {
this.x = x;
this.y = y;
this.dead = false;
this.type = "";
this.width = 0;
this.height = 0;
this.img = undefined;
}
draw(ctx) {
ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
}
}
Now, extend this GameObject to create the Hero and Enemy.
class Hero extends GameObject {
constructor(x, y) {
...it needs an x, y, type, and speed
}
}
class Enemy extends GameObject {
constructor(x, y) {
super(x, y);
(this.width = 98), (this.height = 50);
this.type = "Enemy";
let id = setInterval(() => {
if (this.y < canvas.height - this.height) {
this.y += 5;
} else {
console.log('Stopped at', this.y)
clearInterval(id);
}
}, 300)
}
}
Add key-event handlers to handle key navigation (move hero up/down left/right)
REMEMBER it's a cartesian system, top-left is 0,0. Also remember to add code to stop default behavior
tip: create your onKeyDown function and attach it to the window:
let onKeyDown = function (e) {
console.log(e.keyCode);
...add the code from the lesson above to stop default behavior
}
};
window.addEventListener("keydown", onKeyDown);
Check your browser console at this point, and watch the keystrokes being logged.
Implement the Pub sub pattern, this will keep your code clean as you follow the remaining parts.
To do this last part, you can:
Add an event listener on the window:
window.addEventListener("keyup", (evt) => {
if (evt.key === "ArrowUp") {
eventEmitter.emit(Messages.KEY_EVENT_UP);
} else if (evt.key === "ArrowDown") {
eventEmitter.emit(Messages.KEY_EVENT_DOWN);
} else if (evt.key === "ArrowLeft") {
eventEmitter.emit(Messages.KEY_EVENT_LEFT);
} else if (evt.key === "ArrowRight") {
eventEmitter.emit(Messages.KEY_EVENT_RIGHT);
}
});
Create an EventEmitter class to publish and subscribe to messages:
class EventEmitter {
constructor() {
this.listeners = {};
}
on(message, listener) {
if (!this.listeners[message]) {
this.listeners[message] = [];
}
this.listeners[message].push(listener);
}
emit(message, payload = null) {
if (this.listeners[message]) {
this.listeners[message].forEach((l) => l(message, payload));
}
}
}
Add constants and set up the EventEmitter:
const Messages = {
KEY_EVENT_UP: "KEY_EVENT_UP",
KEY_EVENT_DOWN: "KEY_EVENT_DOWN",
KEY_EVENT_LEFT: "KEY_EVENT_LEFT",
KEY_EVENT_RIGHT: "KEY_EVENT_RIGHT",
};
let heroImg,
enemyImg,
laserImg,
canvas, ctx,
gameObjects = [],
hero,
eventEmitter = new EventEmitter();
Initialize the game
function initGame() {
gameObjects = [];
createEnemies();
createHero();
eventEmitter.on(Messages.KEY_EVENT_UP, () => {
hero.y -=5 ;
})
eventEmitter.on(Messages.KEY_EVENT_DOWN, () => {
hero.y += 5;
});
eventEmitter.on(Messages.KEY_EVENT_LEFT, () => {
hero.x -= 5;
});
eventEmitter.on(Messages.KEY_EVENT_RIGHT, () => {
hero.x += 5;
});
}
Setup the game loop
Refactor the window.onload function to initialize the game and set up a game loop on a good interval. You'll also add a laser beam:
window.onload = async () => {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
heroImg = await loadTexture("assets/player.png");
enemyImg = await loadTexture("assets/enemyShip.png");
laserImg = await loadTexture("assets/laserRed.png");
initGame();
let gameLoopId = setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawGameObjects(ctx);
}, 100)
};
Add code to move enemies at a certain interval
Refactor the createEnemies() function to create the enemies and push them into the new gameObjects class:
function createEnemies() {
const MONSTER_TOTAL = 5;
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
const STOP_X = START_X + MONSTER_WIDTH;
for (let x = START_X; x < STOP_X; x += 98) {
for (let y = 0; y < 50 * 5; y += 50) {
const enemy = new Enemy(x, y);
enemy.img = enemyImg;
gameObjects.push(enemy);
}
}
}
and add a createHero() function to do a similar process for the hero.
function createHero() {
hero = new Hero(
canvas.width / 2 - 45,
canvas.height - canvas.height / 4
);
hero.img = heroImg;
gameObjects.push(hero);
}
and finally, add a drawGameObjects() function to start the drawing:
function drawGameObjects(ctx) {
gameObjects.forEach(go => go.draw(ctx));
}
Your enemies should start advancing on your hero spaceship!
As you can see, your code can turn into 'spaghetti code' when you start adding functions and variables and classes. How can you better organize your code so that it is more readable? Sketch out a system to organize your code, even if it still resides in one file.
While we're writing our game without using frameworks, there are many JavaScript-based canvas frameworks for game development. Take some time to do some reading about these.
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/3-moving-elements-around/README.md
#gamedev #javascript #html
1627933500
The canvas is an HTML element that by default has no content; it's a blank slate. You need to add to it by drawing on it.
Read more about the Canvas API on MDN.
Here's how it's typically declared, as part of the page's body:
<canvas id="myCanvas" width="200" height="100"></canvas>
Above we are setting the id, width and height.
The Canvas is using a cartesian coordinate system to draw things. Thus it uses an x-axis and y-axis to express where something is located. The location 0,0 is the top left position and the bottom right is what you said to be the WIDTH and HEIGHT of the canvas.
Image from MDN
To draw on the canvas element you will need to go through the following steps:
Code for the above steps usually looks like so:
// draws a red rectangle
//1. get the canvas reference
canvas = document.getElementById("myCanvas");
//2. set the context to 2D to draw basic shapes
ctx = canvas.getContext("2d");
//3. fill it with the color red
ctx.fillStyle = 'red';
//4. and draw a rectangle with these parameters, setting location and size
ctx.fillRect(0,0, 200, 200) // x,y,width, height
The Canvas API mostly focuses on 2D shapes, but you can also draw 3D elements to a web site; for this, you might use the WebGL API.
You can draw all sorts of things with the Canvas API like:
Try it! You know how to draw a rectangle, can you draw a circle to a page? Take a look at some interesting Canvas drawings on CodePen. Here's a particularly impressive example.
You load an image asset by creating an Image object and set its src property. Then you listen to the load event to know when it's ready to be used. The code looks like this:
const img = new Image();
img.src = 'path/to/my/image.png';
img.onload = () => {
// image loaded and ready to be used
}
It's recommended to wrap the above in a construct like so, so it's easier to use and you only try to manipulate it when it's fully loaded:
function loadAsset(path) {
return new Promise((resolve) => {
const img = new Image();
img.src = path;
img.onload = () => {
// image loaded and ready to be used
resolve(img);
}
})
}
// use like so
async function run() {
const heroImg = await loadAsset('hero.png')
const monsterImg = await loadAsset('monster.png')
}
To draw game assets to a screen, your code would look like this:
async function run() {
const heroImg = await loadAsset('hero.png')
const monsterImg = await loadAsset('monster.png')
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(heroImg, canvas.width/2,canvas.height/2);
ctx.drawImage(monsterImg, 0,0);
}
You will build a web page with a Canvas element. It should render a black screen 1024*768. We've provided you with two images:
Hero ship
5*5 monster
Locate the files that have been created for you in the your-work sub folder. It should contain the following:
-| assets
-| enemyShip.png
-| player.png
-| index.html
-| app.js
-| package.json
Open the copy of this folder in Visual Studio Code. You need to have a local development environment setup, preferably with Visual Studio Code with NPM and Node installed. If you don't have npm set up on your computer, here's how to do that.
Start your project by navigating to the your_work folder:
cd your-work
npm start
The above will start a HTTP Server on address http://localhost:5000. Open up a browser and input that address. It's a blank page right now, but that will change
Note: to see changes on your screen, refresh your browser.
Add the needed code to your-work/app.js to solve the below
Draw a canvas with black background
tip: add two lines under the appropriate TODO in /app.js, setting the ctx element to be black and the top/left coordinates to be at 0,0 and the height and width to equal that of the canvas.
Load textures
tip: add the player and enemy images using await loadTexture and passing in the image path. You won't see them on the screen yet!
Draw hero in the center of the screen in the bottom half
tip: use the drawImage API to draw heroImg to the screen, setting canvas.width / 2 - 45 and canvas.height - canvas.height / 4);
Draw 5*5 monsters
tip: Now you can uncomment the code to draw enemies on the screen. Next, go to the createEnemies function and build it out.
First, set up some constants:
const MONSTER_TOTAL = 5;
const MONSTER_WIDTH = MONSTER_TOTAL * 98;
const START_X = (canvas.width - MONSTER_WIDTH) / 2;
const STOP_X = START_X + MONSTER_WIDTH;
then, create a loop to draw the array of monsters onto the screen:
for (let x = START_X; x < STOP_X; x += 98) {
for (let y = 0; y < 50 * 5; y += 50) {
ctx.drawImage(enemyImg, x, y);
}
}
The finished result should look like so:
Please try solving it yourself first but if you get stuck, have a look at a solution
You've learned about drawing with the 2D-focused Canvas API; take a look at the WebGL API, and try to draw a 3D object.
Learn more about the Canvas API by reading about it.
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/2-drawing-to-canvas/README.md
#gamedev #html #canvas
1627932600
In earlier lessons, there was not much need to worry about the design architecture of the apps you built, as the projects were very small in scope. However, when your applications grow in size and scope, architectural decisions become a larger concern. There are two major approaches to creating larger applications in JavaScript: composition or inheritance. There are pros and cons to both but let's explain them from within the context of a game.
One of the most famous programming books ever written has to do with design patterns.
In a game you have game objects which are objects that exist on a screen. This means they have a location on a cartesian coordinate system, characterized by having an x and y coordinate. As you develop a game you will notice that all your game objects have a standard property, common for every game you create, namely elements that are:
Think about a game like Pac-Man. Can you identify the four object types listed above in this game?
All we described above are behavior that game objects can have. So how do we encode those? We can express this behavior as methods associated to either classes or objects.
Classes
The idea is to use classes in conjunction with inheritance to accomplish adding a certain behavior to a class.
Inheritance is an important concept to understand. Learn more on MDN's article about inheritance.
Expressed via code, a game object can typically look like this:
//set up the class GameObject
class GameObject {
constructor(x, y, type) {
this.x = x;
this.y = y;
this.type = type;
}
}
//this class will extend the GameObject's inherent class properties
class Movable extends GameObject {
constructor(x,y, type) {
super(x,y, type)
}
//this movable object can be moved on the screen
moveTo(x, y) {
this.x = x;
this.y = y;
}
}
//this is a specific class that extends the Movable class, so it can take advantage of all the properties that it inherits
class Hero extends Movable {
constructor(x,y) {
super(x,y, 'Hero')
}
}
//this class, on the other hand, only inherits the GameObject properties
class Tree extends GameObject {
constructor(x,y) {
super(x,y, 'Tree')
}
}
//a hero can move...
const hero = new Hero();
hero.moveTo(5,5);
//but a tree cannot
const tree = new Tree();
Take a few minutes to re-envision a Pac-Man hero (Inky, Pinky or Blinky, for example) and how it would be written in JavaScript.
Composition
A different way of handling object inheritance is by using Composition. Then, objects express their behavior like this:
//create a constant gameObject
const gameObject = {
x: 0,
y: 0,
type: ''
};
//...and a constant movable
const movable = {
moveTo(x, y) {
this.x = x;
this.y = y;
}
}
//then the constant movableObject is composed of the gameObject and movable constants
const movableObject = {...gameObject, ...movable};
//then create a function to create a new Hero who inherits the movableObject properties
function createHero(x, y) {
return {
...movableObject,
x,
y,
type: 'Hero'
}
}
//...and a static object that inherits only the gameObject properties
function createStatic(x, y, type) {
return {
...gameObject
x,
y,
type
}
}
//create the hero and move it
const hero = createHero(10,10);
hero.moveTo(5,5);
//and create a static tree which only stands around
const tree = createStatic(0,0, 'Tree');
Which pattern should I use?
It's up to you which pattern you choose. JavaScript supports both these paradigms.
--
Another pattern common in game development addresses the problem of handling the game's user experience and performance.
Pub/Sub stands for 'publish-subscribe'
This pattern addresses the idea that the disparate parts of your application shouldn't know about one another. Why is that? It makes it a lot easier to see what's going on in general if various parts are separated. It also makes it easier to suddenly change behavior if you need to. How do we accomplish this? We do this by establishing some concepts:
The implementation is quite small in size but it's a very powerful pattern. Here's how it can be implemented:
//set up an EventEmitter class that contains listeners
class EventEmitter {
constructor() {
this.listeners = {};
}
//when a message is received, let the listener to handle its payload
on(message, listener) {
if (!this.listeners[message]) {
this.listeners[message] = [];
}
this.listeners[message].push(listener);
}
//when a message is sent, send it to a listener with some payload
emit(message, payload = null) {
if (this.listeners[message]) {
this.listeners[message].forEach(l => l(message, payload))
}
}
}
To use the above code we can create a very small implementation:
//set up a message structure
const Messages = {
HERO_MOVE_LEFT: 'HERO_MOVE_LEFT'
};
//invoke the eventEmitter you set up above
const eventEmitter = new EventEmitter();
//set up a hero
const hero = createHero(0,0);
//let the eventEmitter know to watch for messages pertaining to the hero moving left, and act on it
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
hero.move(5,0);
});
//set up the window to listen for the keyup event, specifically if the left arrow is hit, emit a message to move the hero left
window.addEventListener('keyup', (evt) => {
if (evt.key === 'ArrowLeft') {
eventEmitter.emit(Messages.HERO_MOVE_LEFT)
}
});
Above we connect a keyboard event, ArrowLeft and send the HERO_MOVE_LEFT message. We listen to that message and move the hero as a result. The strength with this pattern is that the event listener and the hero don't know about each other. You can remap the ArrowLeft to the A key. Additionally it would be possible to do something completely different on ArrowLeft by making a few edits to the eventEmitter's on function:
eventEmitter.on(Messages.HERO_MOVE_LEFT, () => {
hero.move(5,0);
});
As things gets more complicated when your game grows, this pattern stays the same in complexity and your code stays clean. It's really recommended to adopt this pattern.
Think about how the pub-sub pattern can enhance a game. Which parts should emit events, and how should the game react to them? Now's your chance to get creative, thinking of a new game and how its parts might behave.
Learn more about Pub/Sub by reading about it.
Originally published at https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/6-space-game/1-introduction/README.md
#gamedev #javascript