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
|
||||
## 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".
|
||||
+ 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))
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
+ [HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)
|
||||
+ **[Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)**
|
||||
+ 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)
|
||||
### 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.
|
||||
|
|
|
|||
11
index.html
11
index.html
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="hu">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<meta name="theme-color" content="#A5402D" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Raleway"
|
||||
href="https://fonts.googleapis.com/css?family=Raleway&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="css/main.css" />
|
||||
|
|
@ -21,9 +21,10 @@
|
|||
<div id="startText">
|
||||
<h1>Avoid</h1>
|
||||
<p>
|
||||
the red balls by moving your cursor (or finger) on the screen. Try
|
||||
eliminating the enemy balls by getting them to collide with each
|
||||
other. Good luck!
|
||||
A relentless swarm is closing in on you. Guide your light across
|
||||
the screen with your cursor (or finger), stay out of reach, and
|
||||
outsmart your pursuers by luring them into crashing into one
|
||||
another. How long can you survive?
|
||||
</p>
|
||||
</div>
|
||||
<div id="endText">
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ class CanvasHandler {
|
|||
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() {
|
||||
return this.canvas.width / window.devicePixelRatio;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
class InputHandler {
|
||||
constructor(idOfWatchedArea) {
|
||||
const elem = document.getElementById(idOfWatchedArea);
|
||||
constructor(canvasHandler) {
|
||||
const elem = canvasHandler.canvas;
|
||||
|
||||
const handleMouse = ({ offsetX, offsetY }) =>
|
||||
this.setPointerPosition([offsetX, offsetY]);
|
||||
const handleTouch = ({ touches }) =>
|
||||
this.setPointerPosition([touches[0].clientX, touches[0].clientY]);
|
||||
const handleMouse = ({ clientX, clientY }) =>
|
||||
this.setPointerPosition(canvasHandler.clientToCanvas(clientX, clientY));
|
||||
|
||||
const handleTouch = (event) => {
|
||||
event.preventDefault();
|
||||
const { clientX, clientY } = event.touches[0];
|
||||
this.setPointerPosition(canvasHandler.clientToCanvas(clientX, clientY));
|
||||
};
|
||||
|
||||
elem.addEventListener("mousemove", handleMouse);
|
||||
elem.addEventListener("touchmove", handleTouch);
|
||||
elem.addEventListener("touchmove", handleTouch, { passive: false });
|
||||
|
||||
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 inputHandler = new InputHandler("canvas");
|
||||
const inputHandler = new InputHandler(canvasHandler);
|
||||
|
||||
let game;
|
||||
function newGame() {
|
||||
|
|
@ -27,11 +28,16 @@ class Circle {
|
|||
this.position = add(this.position, limit(deltaPosition, maxDistance));
|
||||
}
|
||||
}
|
||||
|
||||
draw(canvasHandler) {
|
||||
canvasHandler.drawCircle(this.position, this.size, this.color);
|
||||
}
|
||||
|
||||
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.spawnInterval = 1000 / enemySpawnFrequency;
|
||||
this.previousSpawn = this.previousTimestamp = 0;
|
||||
this.spawnInterval = 1000 / enemySpawnFrequencyPerSecond;
|
||||
this.previousSpawn = this.previousTime = 0;
|
||||
this.score = 0;
|
||||
|
||||
this.menuBox = document.getElementById("menuBox").style;
|
||||
|
|
@ -55,16 +61,19 @@ class Game {
|
|||
"none";
|
||||
|
||||
this.isActive = true;
|
||||
window.requestAnimationFrame(this.nextFrame.bind(this));
|
||||
this.boundNextFrame = this.nextFrame.bind(this);
|
||||
window.requestAnimationFrame(this.boundNextFrame);
|
||||
}
|
||||
|
||||
nextFrame(timestamp) {
|
||||
if (this.isActive) {
|
||||
canvasHandler.fillCanvas("rgba(165, 64, 45, 0.1)");
|
||||
this.spawnEnemyIfNeeded(timestamp);
|
||||
this.moveCircles(timestamp);
|
||||
window.requestAnimationFrame(this.nextFrame.bind(this));
|
||||
window.requestAnimationFrame(this.boundNextFrame);
|
||||
}
|
||||
}
|
||||
|
||||
spawnEnemyIfNeeded(timestamp) {
|
||||
if (timestamp - this.previousSpawn > this.spawnInterval) {
|
||||
this.circleHolder.push(
|
||||
|
|
@ -84,31 +93,42 @@ class Game {
|
|||
this.score++;
|
||||
}
|
||||
}
|
||||
|
||||
moveCircles(timestamp) {
|
||||
const deltaTime = this.getDeltaTime(timestamp);
|
||||
const collided = new Set();
|
||||
for (let i = 0; i < this.circleHolder.length; i++) {
|
||||
this.circleHolder[i].move(deltaTime);
|
||||
this.circleHolder[i].draw(canvasHandler);
|
||||
|
||||
for (let j = i + 1; j < this.circleHolder.length; j++) {
|
||||
if (this.circleHolder[i].isTouching(this.circleHolder[j])) {
|
||||
if (this.circleHolder[i] == this.player) this.showEndScreen();
|
||||
else {
|
||||
this.circleHolder.splice(i, 1);
|
||||
this.circleHolder.splice(j - 1, 1);
|
||||
if (this.circleHolder[i] === this.player) {
|
||||
this.showEndScreen();
|
||||
return;
|
||||
}
|
||||
collided.add(i).add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collided.size > 0) {
|
||||
this.circleHolder = this.circleHolder.filter(
|
||||
(_, index) => !collided.has(index)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getDeltaTime(timestamp) {
|
||||
const tempPreviousTime = this.previousTime;
|
||||
this.previousTime = timestamp;
|
||||
return timestamp - tempPreviousTime;
|
||||
return Math.min(timestamp - tempPreviousTime, maxDeltaTimeInMs);
|
||||
}
|
||||
|
||||
showEndScreen() {
|
||||
document.getElementById("endText").style.display = "block";
|
||||
document.getElementById("endScore").innerHTML = `Your score: ${this.score}`;
|
||||
document.getElementById("startButton").textContent = "Play again";
|
||||
this.menuBox.display = "flex";
|
||||
this.isActive = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue