Compare commits

..

No commits in common. "c34177b21653c170b78f0aec9b9d2dcca39f163f" and "265bde56b403a374449fdc8ba4db2351acaffda1" have entirely different histories.

5 changed files with 26 additions and 59 deletions

View file

@ -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 magas szintű, gyengén típusos, értelmezett nyelv. + Egy magasszintű, 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 magas szintű nyelvtől elvárható. + És természetesen minden olyan dologra képes, ami egy magasszintű 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.

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="hu">
<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&display=swap" href="https://fonts.googleapis.com/css?family=Raleway"
rel="stylesheet" rel="stylesheet"
/> />
<link rel="stylesheet" href="css/main.css" /> <link rel="stylesheet" href="css/main.css" />
@ -21,10 +21,9 @@
<div id="startText"> <div id="startText">
<h1>Avoid</h1> <h1>Avoid</h1>
<p> <p>
A relentless swarm is closing in on you. Guide your light across the red balls by moving your cursor (or finger) on the screen. Try
the screen with your cursor (or finger), stay out of reach, and eliminating the enemy balls by getting them to collide with each
outsmart your pursuers by luring them into crashing into one other. Good luck!
another. How long can you survive?
</p> </p>
</div> </div>
<div id="endText"> <div id="endText">

View file

@ -38,14 +38,6 @@ 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;
} }

View file

@ -1,18 +1,14 @@
class InputHandler { class InputHandler {
constructor(canvasHandler) { constructor(idOfWatchedArea) {
const elem = canvasHandler.canvas; const elem = document.getElementById(idOfWatchedArea);
const handleMouse = ({ clientX, clientY }) => const handleMouse = ({ offsetX, offsetY }) =>
this.setPointerPosition(canvasHandler.clientToCanvas(clientX, clientY)); this.setPointerPosition([offsetX, offsetY]);
const handleTouch = ({ touches }) =>
const handleTouch = (event) => { this.setPointerPosition([touches[0].clientX, touches[0].clientY]);
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, { passive: false }); elem.addEventListener("touchmove", handleTouch);
this.pointerPosition = [0, 0]; this.pointerPosition = [0, 0];
} }

View file

@ -1,8 +1,7 @@
const enemySpawnFrequencyPerSecond = 4.5; const enemySpawnFrequency = 4.5;
const maxDeltaTimeInMs = 50;
const canvasHandler = new CanvasHandler("canvas"); const canvasHandler = new CanvasHandler("canvas");
const inputHandler = new InputHandler(canvasHandler); const inputHandler = new InputHandler("canvas");
let game; let game;
function newGame() { function newGame() {
@ -28,16 +27,11 @@ 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 ( return magnitude(subtract(this.position, other.position)) < 2 * this.size;
magnitude(subtract(this.position, other.position)) <
this.size + other.size
);
} }
} }
@ -52,8 +46,8 @@ class Game {
); );
this.circleHolder = [this.player]; this.circleHolder = [this.player];
this.spawnInterval = 1000 / enemySpawnFrequencyPerSecond; this.spawnInterval = 1000 / enemySpawnFrequency;
this.previousSpawn = this.previousTime = 0; this.previousSpawn = this.previousTimestamp = 0;
this.score = 0; this.score = 0;
this.menuBox = document.getElementById("menuBox").style; this.menuBox = document.getElementById("menuBox").style;
@ -61,19 +55,16 @@ class Game {
"none"; "none";
this.isActive = true; this.isActive = true;
this.boundNextFrame = this.nextFrame.bind(this); window.requestAnimationFrame(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.boundNextFrame); window.requestAnimationFrame(this.nextFrame.bind(this));
} }
} }
spawnEnemyIfNeeded(timestamp) { spawnEnemyIfNeeded(timestamp) {
if (timestamp - this.previousSpawn > this.spawnInterval) { if (timestamp - this.previousSpawn > this.spawnInterval) {
this.circleHolder.push( this.circleHolder.push(
@ -93,42 +84,31 @@ 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) { if (this.circleHolder[i] == this.player) this.showEndScreen();
this.showEndScreen(); else {
return; this.circleHolder.splice(i, 1);
} 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 Math.min(timestamp - tempPreviousTime, maxDeltaTimeInMs); return timestamp - tempPreviousTime;
} }
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;
} }