Compare commits
5 commits
265bde56b4
...
c34177b216
| Author | SHA1 | Date | |
|---|---|---|---|
| c34177b216 | |||
| 2cb12f93e8 | |||
| 3640242506 | |||
| 3b807a968c | |||
| 3f73f30f2d |
5 changed files with 59 additions and 26 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
> A JS / Canvas workshop rövid összefoglalója
|
> A JS / Canvas workshop rövid összefoglalója
|
||||||
## Mi az a JavaScript?
|
## Mi az a JavaScript?
|
||||||
|
|
||||||
+ Egy magasszintű, gyengén típusos, értelmezett nyelv.
|
+ Egy magas szintű, gyengén típusos, értelmezett nyelv.
|
||||||
+ A "böngészőben fut".
|
+ A "böngészőben fut".
|
||||||
+ Változatos módon tudja befolyásolni az oldal állapotát.
|
+ Változatos módon tudja befolyásolni az oldal állapotát.
|
||||||
+ A háttérben aszinkron módon képes szerverekkel kommunikálni ([AJAX](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX))
|
+ A háttérben aszinkron módon képes szerverekkel kommunikálni ([AJAX](https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX))
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
+ [HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)
|
+ [HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)
|
||||||
+ **[Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)**
|
+ **[Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)**
|
||||||
+ etc.
|
+ etc.
|
||||||
+ És természetesen minden olyan dologra képes, ami egy magasszintű nyelvtől elvárható.
|
+ És természetesen minden olyan dologra képes, ami egy magas szintű nyelvtől elvárható.
|
||||||
### [Kristóf nagyon jó JavaScript összefoglalója](https://github.com/kripod/schdesign-web-workshop/blob/master/notes/js.md)
|
### [Kristóf nagyon jó JavaScript összefoglalója](https://github.com/kripod/schdesign-web-workshop/blob/master/notes/js.md)
|
||||||
### Egy nem annyira jó, viszont annál tömörebb összefoglaló
|
### Egy nem annyira jó, viszont annál tömörebb összefoglaló
|
||||||
+ A konzolra kiírni (böngészőben **F12**-vel megnyitható) a ```console.log("szöveg");``` hívással lehet.
|
+ A konzolra kiírni (böngészőben **F12**-vel megnyitható) a ```console.log("szöveg");``` hívással lehet.
|
||||||
|
|
|
||||||
11
index.html
11
index.html
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="hu">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<meta name="theme-color" content="#A5402D" />
|
<meta name="theme-color" content="#A5402D" />
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css?family=Raleway"
|
href="https://fonts.googleapis.com/css?family=Raleway&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
<link rel="stylesheet" href="css/main.css" />
|
<link rel="stylesheet" href="css/main.css" />
|
||||||
|
|
@ -21,9 +21,10 @@
|
||||||
<div id="startText">
|
<div id="startText">
|
||||||
<h1>Avoid</h1>
|
<h1>Avoid</h1>
|
||||||
<p>
|
<p>
|
||||||
the red balls by moving your cursor (or finger) on the screen. Try
|
A relentless swarm is closing in on you. Guide your light across
|
||||||
eliminating the enemy balls by getting them to collide with each
|
the screen with your cursor (or finger), stay out of reach, and
|
||||||
other. Good luck!
|
outsmart your pursuers by luring them into crashing into one
|
||||||
|
another. How long can you survive?
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="endText">
|
<div id="endText">
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,14 @@ class CanvasHandler {
|
||||||
return unit * Math.sqrt(this.width * this.height);
|
return unit * Math.sqrt(this.width * this.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientToCanvas(clientX, clientY) {
|
||||||
|
const rect = this.canvas.getBoundingClientRect();
|
||||||
|
return [
|
||||||
|
((clientX - rect.left) / rect.width) * this.width,
|
||||||
|
((clientY - rect.top) / rect.height) * this.height,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
get width() {
|
get width() {
|
||||||
return this.canvas.width / window.devicePixelRatio;
|
return this.canvas.width / window.devicePixelRatio;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
class InputHandler {
|
class InputHandler {
|
||||||
constructor(idOfWatchedArea) {
|
constructor(canvasHandler) {
|
||||||
const elem = document.getElementById(idOfWatchedArea);
|
const elem = canvasHandler.canvas;
|
||||||
|
|
||||||
const handleMouse = ({ offsetX, offsetY }) =>
|
const handleMouse = ({ clientX, clientY }) =>
|
||||||
this.setPointerPosition([offsetX, offsetY]);
|
this.setPointerPosition(canvasHandler.clientToCanvas(clientX, clientY));
|
||||||
const handleTouch = ({ touches }) =>
|
|
||||||
this.setPointerPosition([touches[0].clientX, touches[0].clientY]);
|
const handleTouch = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const { clientX, clientY } = event.touches[0];
|
||||||
|
this.setPointerPosition(canvasHandler.clientToCanvas(clientX, clientY));
|
||||||
|
};
|
||||||
|
|
||||||
elem.addEventListener("mousemove", handleMouse);
|
elem.addEventListener("mousemove", handleMouse);
|
||||||
elem.addEventListener("touchmove", handleTouch);
|
elem.addEventListener("touchmove", handleTouch, { passive: false });
|
||||||
|
|
||||||
this.pointerPosition = [0, 0];
|
this.pointerPosition = [0, 0];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
js/main.js
44
js/main.js
|
|
@ -1,7 +1,8 @@
|
||||||
const enemySpawnFrequency = 4.5;
|
const enemySpawnFrequencyPerSecond = 4.5;
|
||||||
|
const maxDeltaTimeInMs = 50;
|
||||||
|
|
||||||
const canvasHandler = new CanvasHandler("canvas");
|
const canvasHandler = new CanvasHandler("canvas");
|
||||||
const inputHandler = new InputHandler("canvas");
|
const inputHandler = new InputHandler(canvasHandler);
|
||||||
|
|
||||||
let game;
|
let game;
|
||||||
function newGame() {
|
function newGame() {
|
||||||
|
|
@ -27,11 +28,16 @@ class Circle {
|
||||||
this.position = add(this.position, limit(deltaPosition, maxDistance));
|
this.position = add(this.position, limit(deltaPosition, maxDistance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(canvasHandler) {
|
draw(canvasHandler) {
|
||||||
canvasHandler.drawCircle(this.position, this.size, this.color);
|
canvasHandler.drawCircle(this.position, this.size, this.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
isTouching(other) {
|
isTouching(other) {
|
||||||
return magnitude(subtract(this.position, other.position)) < 2 * this.size;
|
return (
|
||||||
|
magnitude(subtract(this.position, other.position)) <
|
||||||
|
this.size + other.size
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,8 +52,8 @@ class Game {
|
||||||
);
|
);
|
||||||
|
|
||||||
this.circleHolder = [this.player];
|
this.circleHolder = [this.player];
|
||||||
this.spawnInterval = 1000 / enemySpawnFrequency;
|
this.spawnInterval = 1000 / enemySpawnFrequencyPerSecond;
|
||||||
this.previousSpawn = this.previousTimestamp = 0;
|
this.previousSpawn = this.previousTime = 0;
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
|
|
||||||
this.menuBox = document.getElementById("menuBox").style;
|
this.menuBox = document.getElementById("menuBox").style;
|
||||||
|
|
@ -55,16 +61,19 @@ class Game {
|
||||||
"none";
|
"none";
|
||||||
|
|
||||||
this.isActive = true;
|
this.isActive = true;
|
||||||
window.requestAnimationFrame(this.nextFrame.bind(this));
|
this.boundNextFrame = this.nextFrame.bind(this);
|
||||||
|
window.requestAnimationFrame(this.boundNextFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextFrame(timestamp) {
|
nextFrame(timestamp) {
|
||||||
if (this.isActive) {
|
if (this.isActive) {
|
||||||
canvasHandler.fillCanvas("rgba(165, 64, 45, 0.1)");
|
canvasHandler.fillCanvas("rgba(165, 64, 45, 0.1)");
|
||||||
this.spawnEnemyIfNeeded(timestamp);
|
this.spawnEnemyIfNeeded(timestamp);
|
||||||
this.moveCircles(timestamp);
|
this.moveCircles(timestamp);
|
||||||
window.requestAnimationFrame(this.nextFrame.bind(this));
|
window.requestAnimationFrame(this.boundNextFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spawnEnemyIfNeeded(timestamp) {
|
spawnEnemyIfNeeded(timestamp) {
|
||||||
if (timestamp - this.previousSpawn > this.spawnInterval) {
|
if (timestamp - this.previousSpawn > this.spawnInterval) {
|
||||||
this.circleHolder.push(
|
this.circleHolder.push(
|
||||||
|
|
@ -84,31 +93,42 @@ class Game {
|
||||||
this.score++;
|
this.score++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moveCircles(timestamp) {
|
moveCircles(timestamp) {
|
||||||
const deltaTime = this.getDeltaTime(timestamp);
|
const deltaTime = this.getDeltaTime(timestamp);
|
||||||
|
const collided = new Set();
|
||||||
for (let i = 0; i < this.circleHolder.length; i++) {
|
for (let i = 0; i < this.circleHolder.length; i++) {
|
||||||
this.circleHolder[i].move(deltaTime);
|
this.circleHolder[i].move(deltaTime);
|
||||||
this.circleHolder[i].draw(canvasHandler);
|
this.circleHolder[i].draw(canvasHandler);
|
||||||
|
|
||||||
for (let j = i + 1; j < this.circleHolder.length; j++) {
|
for (let j = i + 1; j < this.circleHolder.length; j++) {
|
||||||
if (this.circleHolder[i].isTouching(this.circleHolder[j])) {
|
if (this.circleHolder[i].isTouching(this.circleHolder[j])) {
|
||||||
if (this.circleHolder[i] == this.player) this.showEndScreen();
|
if (this.circleHolder[i] === this.player) {
|
||||||
else {
|
this.showEndScreen();
|
||||||
this.circleHolder.splice(i, 1);
|
return;
|
||||||
this.circleHolder.splice(j - 1, 1);
|
}
|
||||||
|
collided.add(i).add(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (collided.size > 0) {
|
||||||
|
this.circleHolder = this.circleHolder.filter(
|
||||||
|
(_, index) => !collided.has(index)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeltaTime(timestamp) {
|
getDeltaTime(timestamp) {
|
||||||
const tempPreviousTime = this.previousTime;
|
const tempPreviousTime = this.previousTime;
|
||||||
this.previousTime = timestamp;
|
this.previousTime = timestamp;
|
||||||
return timestamp - tempPreviousTime;
|
return Math.min(timestamp - tempPreviousTime, maxDeltaTimeInMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
showEndScreen() {
|
showEndScreen() {
|
||||||
document.getElementById("endText").style.display = "block";
|
document.getElementById("endText").style.display = "block";
|
||||||
document.getElementById("endScore").innerHTML = `Your score: ${this.score}`;
|
document.getElementById("endScore").innerHTML = `Your score: ${this.score}`;
|
||||||
|
document.getElementById("startButton").textContent = "Play again";
|
||||||
this.menuBox.display = "flex";
|
this.menuBox.display = "flex";
|
||||||
this.isActive = false;
|
this.isActive = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue