mirror of
https://github.com/sigmasternchen/88x31breakout
synced 2025-03-15 07:59:00 +00:00
add system for launching balls
This commit is contained in:
parent
924e7d57c2
commit
3c6e1aff5f
8 changed files with 66 additions and 6 deletions
|
@ -1,8 +1,12 @@
|
|||
import {Position} from "./Position";
|
||||
import {ballSize} from "./geometry";
|
||||
import {choice} from "../utils";
|
||||
import {defaultBallSpeed, startAngles} from "./parameters";
|
||||
|
||||
export class Ball {
|
||||
private _position: Position;
|
||||
private phi: number;
|
||||
private speed: number;
|
||||
private readonly element: HTMLElement;
|
||||
|
||||
constructor() {
|
||||
|
@ -28,4 +32,14 @@ export class Ball {
|
|||
public setup(gameElement: HTMLElement): void {
|
||||
gameElement.appendChild(this.element);
|
||||
}
|
||||
|
||||
public launch() {
|
||||
this.phi = choice(startAngles);
|
||||
this.speed = defaultBallSpeed;
|
||||
}
|
||||
|
||||
public tick(delta: number) {
|
||||
this._position = this._position.moveInDirection(this.phi, this.speed * delta / 1000);
|
||||
this.redraw();
|
||||
}
|
||||
}
|
|
@ -10,6 +10,9 @@ export class Game {
|
|||
private paddle: Paddle;
|
||||
private balls: Ball[];
|
||||
|
||||
private running: boolean = false;
|
||||
private lastTickTimestamp: number = 0;
|
||||
|
||||
constructor(root: HTMLElement) {
|
||||
this.root = root;
|
||||
this.root.style.height = fieldHeight + "px";
|
||||
|
@ -26,7 +29,27 @@ export class Game {
|
|||
|
||||
public setup(): void {
|
||||
this.banners.forEach(banner => banner.setup(this.root));
|
||||
this.paddle.setup(this.root);
|
||||
this.paddle.setup(this.root, this.ballLaunchHandler.bind(this));
|
||||
this.balls.forEach(ball => ball.setup(this.root));
|
||||
}
|
||||
}
|
||||
|
||||
private ballLaunchHandler(ball: Ball): void {
|
||||
this.balls.push(ball);
|
||||
ball.launch();
|
||||
}
|
||||
|
||||
public run(): void {
|
||||
this.running = true;
|
||||
requestAnimationFrame(this.tick.bind(this))
|
||||
}
|
||||
|
||||
private tick(timestamp: number): void {
|
||||
const delta = timestamp - this.lastTickTimestamp;
|
||||
this.lastTickTimestamp = timestamp;
|
||||
|
||||
this.balls.forEach(ball => ball.tick.bind(ball)(delta));
|
||||
if (this.running) {
|
||||
requestAnimationFrame(this.tick.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,12 +41,20 @@ export class Paddle {
|
|||
this.redraw();
|
||||
}
|
||||
|
||||
public setup(gameElement: HTMLElement): void {
|
||||
public setup(gameElement: HTMLElement, ballLaunchHandler: (ball: Ball) => void): void {
|
||||
gameElement.appendChild(this.element);
|
||||
gameElement.addEventListener("mousemove", this.mouseHandler.bind(this));
|
||||
gameElement.addEventListener("mouseenter", this.mouseHandler.bind(this));
|
||||
gameElement.addEventListener("mouseleave", this.mouseHandler.bind(this));
|
||||
|
||||
gameElement.addEventListener("click", () => {
|
||||
if (this.ball) {
|
||||
const ball = this.ball;
|
||||
this.ball = null;
|
||||
ballLaunchHandler(ball);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.ball) {
|
||||
this.ball.setup(gameElement);
|
||||
}
|
||||
|
|
|
@ -15,4 +15,11 @@ export class Position {
|
|||
get y(): number {
|
||||
return this._y;
|
||||
}
|
||||
|
||||
public moveInDirection(phi: number, distance: number): Position {
|
||||
return new Position(
|
||||
this._x + Math.cos(phi) * distance,
|
||||
this._y - Math.sin(phi) * distance
|
||||
);
|
||||
}
|
||||
}
|
|
@ -5,4 +5,4 @@ export const fieldHeight = 500;
|
|||
export const paddleY = fieldHeight - 20;
|
||||
export const paddleHeight = 10;
|
||||
|
||||
export const ballSize = 15;
|
||||
export const ballSize = 15;
|
||||
|
|
3
src/game/parameters.ts
Normal file
3
src/game/parameters.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
export const defaultBallSpeed = 700; // pixel / s
|
||||
export const startAngles = [Math.PI / 4, Math.PI * 3 / 4];
|
|
@ -4,4 +4,5 @@ window.addEventListener("load", async () => {
|
|||
const game = new Game(document.getElementById("game"));
|
||||
await game.load();
|
||||
game.setup();
|
||||
game.run();
|
||||
});
|
|
@ -7,8 +7,12 @@ export function shuffleInPlace(array: any[]) {
|
|||
}
|
||||
}
|
||||
|
||||
export function toShuffled <T> (array: T[]) {
|
||||
export function toShuffled <T> (array: T[]): T[] {
|
||||
const copy = [...array];
|
||||
shuffleInPlace(copy);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
export function choice <T> (array: T[]): T {
|
||||
return array[0 | (Math.random() * array.length)];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue