Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Juiciness #1

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/blueprints/blu_ball.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import {audio_source} from "../components/com_audio_source.js";
import {collide} from "../components/com_collide.js";
import {control_ball} from "../components/com_control_ball.js";
import {draw_rect} from "../components/com_draw.js";
import {move} from "../components/com_move.js";
import {Game} from "../game.js";
import {Blueprint2D} from "./blu_common.js";

export let ball_blueprint = <Blueprint2D>{
Using: [control_ball(), move(1, 300), collide(true, [20, 20]), draw_rect(20, 20, "orange")],
export let get_ball_blueprint = function(game: Game) {
let x = game.ViewportWidth / 2;
let y = game.ViewportHeight - 100;

return <Blueprint2D>{
Translation: [x, y],
Using: [
control_ball(),
move(Math.PI * 1.75, 500),
collide(true, [20, 20]),
draw_rect(20, 20, "orange"),
audio_source(),
],
};
};
6 changes: 5 additions & 1 deletion src/blueprints/blu_brick.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import {collide} from "../components/com_collide.js";
import {control_brick} from "../components/com_control_brick.js";
import {draw_rect} from "../components/com_draw.js";
import {entry} from "../components/com_entry.js";
import {fade} from "../components/com_fade.js";
import {Blueprint2D} from "./blu_common.js";

export function create_brick(width: number, height: number) {
export function create_brick(width: number, height: number, x: number, y: number, time: number) {
return <Blueprint2D>{
Using: [
control_brick(),
collide(false, [width, height]),
draw_rect(width, height, "green"),
fade(0),
entry([x, -100], [x, y], time),
],
};
}
21 changes: 21 additions & 0 deletions src/blueprints/blu_explosion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {draw_rect} from "../components/com_draw.js";
import {fade} from "../components/com_fade.js";
import {move} from "../components/com_move.js";
import {Blueprint2D} from "./blu_common.js";

export let get_blu_explosion = function(x: number, y: number, color: string, frames_alive: number) {
let number_of_explosions = 32;
let Children = [];
let step = (Math.PI * 2) / number_of_explosions;
let fade_step = 1 / frames_alive;

for (let i = 0; i < number_of_explosions; i++) {
Children.push(<Blueprint2D>{
Using: [draw_rect(20, 20, color), move(step * i, 1000), fade(fade_step)],
});
}
return <Blueprint2D>{
Translation: [x, y],
Children,
};
};
17 changes: 15 additions & 2 deletions src/blueprints/blu_paddle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import {collide} from "../components/com_collide.js";
import {control_paddle} from "../components/com_control_paddle.js";
import {draw_rect} from "../components/com_draw.js";
import {entry} from "../components/com_entry.js";
import {Game} from "../game.js";
import {Blueprint2D} from "./blu_common.js";

export let paddle_blueprint = <Blueprint2D>{
Using: [control_paddle(100), collide(true, [100, 20]), draw_rect(100, 20, "red")],
export let get_paddle_blueprint = function(game: Game) {
let x = game.ViewportWidth / 2;
let y = game.ViewportHeight - 20;

return <Blueprint2D>{
Translation: [x, y],
Using: [
control_paddle(100),
collide(true, [100, 20]),
draw_rect(100, 20, "red"),
entry([x, -10], [x, y], 1),
],
};
};
9 changes: 9 additions & 0 deletions src/blueprints/blu_tail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {draw_rect} from "../components/com_draw.js";
import {fade} from "../components/com_fade.js";
import {Blueprint2D} from "./blu_common.js";

export let get_blu_tail = function(width: number, height: number, color: string) {
return <Blueprint2D>{
Using: [draw_rect(width, height, color), fade(0.05)],
};
};
3 changes: 3 additions & 0 deletions src/components/com_audio_source.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ export interface AudioSource {
Idle?: AudioClip;
/** Elapsed time since the last clip change. */
Time: number;
/** Detune the track by this many half tones. */
HalfTones: number;
}

/**
@@ -23,6 +25,7 @@ export function audio_source(idle?: AudioClip) {
game[Get.AudioSource][entity] = <AudioSource>{
Idle: idle,
Time: 0,
HalfTones: 0,
};
};
}
8 changes: 6 additions & 2 deletions src/components/com_control_ball.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import {Entity, Game} from "../game.js";
import {Get, Has} from "./com_index.js";

export interface ControlBall {}
export interface ControlBall {
Bounces: number;
}

export function control_ball() {
return (game: Game, entity: Entity) => {
game.World[entity] |= Has.ControlBall;
game[Get.ControlBall][entity] = <ControlBall>{};
game[Get.ControlBall][entity] = <ControlBall>{
Bounces: 0,
};
};
}
12 changes: 11 additions & 1 deletion src/components/com_draw.ts
Original file line number Diff line number Diff line change
@@ -28,16 +28,26 @@ export interface DrawRect {
Width: number;
Height: number;
Color: string;
Alpha: number;
Filter: string;
}

export function draw_rect(Width: number, Height: number, Color: string) {
export function draw_rect(
Width: number,
Height: number,
Color: string,
Alpha: number = 1,
Filter = "none"
) {
return (game: Game, entity: Entity) => {
game.World[entity] |= Has.Draw;
game[Get.Draw][entity] = <DrawRect>{
Kind: DrawKind.Rect,
Width,
Height,
Color,
Alpha,
Filter,
};
};
}
25 changes: 25 additions & 0 deletions src/components/com_entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Entity, Game} from "../game.js";
import {ease_in_out_elastic} from "../math/easing.js";
import {Vec2} from "../math/index.js";
import {Get, Has} from "./com_index.js";

export interface Entry {
Initial: Vec2;
Final: Vec2;
Time: number;
CurrentTime: number;
Easing: Function;
}

export function entry(Initial: Vec2, Final: Vec2, Time: number) {
return (game: Game, entity: Entity) => {
game.World[entity] |= Has.Entry;
game[Get.Entry][entity] = <Entry>{
Initial,
Final,
Time,
CurrentTime: 0,
Easing: ease_in_out_elastic,
};
};
}
15 changes: 15 additions & 0 deletions src/components/com_fade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {Entity, Game} from "../game.js";
import {Get, Has} from "./com_index.js";

export interface Fade {
Step: number;
}

export function fade(Step = 0.1) {
return (game: Game, entity: Entity) => {
game.World[entity] |= Has.Fade;
game[Get.Fade][entity] = <Fade>{
Step,
};
};
}
12 changes: 12 additions & 0 deletions src/components/com_index.ts
Original file line number Diff line number Diff line change
@@ -4,8 +4,11 @@ import {ControlBall} from "./com_control_ball";
import {ControlBrick} from "./com_control_brick";
import {ControlPaddle} from "./com_control_paddle";
import {Draw} from "./com_draw";
import {Entry} from "./com_entry";
import {Fade} from "./com_fade";
import {Move} from "./com_move";
import {Named} from "./com_named";
import {Shake} from "./com_shake";
import {Transform2D} from "./com_transform2d";

export const enum Get {
@@ -18,6 +21,9 @@ export const enum Get {
Move,
Named,
Transform2D,
Shake,
Fade,
Entry,
}

export interface ComponentData {
@@ -30,6 +36,9 @@ export interface ComponentData {
[Get.Move]: Array<Move>;
[Get.Named]: Array<Named>;
[Get.Transform2D]: Array<Transform2D>;
[Get.Shake]: Array<Shake>;
[Get.Fade]: Array<Fade>;
[Get.Entry]: Array<Entry>;
}

export const enum Has {
@@ -42,4 +51,7 @@ export const enum Has {
Move = 1 << Get.Move,
Named = 1 << Get.Named,
Transform2D = 1 << Get.Transform2D,
Shake = 1 << Get.Shake,
Fade = 1 << Get.Fade,
Entry = 1 << Get.Entry,
}
17 changes: 17 additions & 0 deletions src/components/com_shake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Entity, Game} from "../game.js";
import {Get, Has} from "./com_index.js";

export interface Shake {
Duration: number;
Strength: number;
}

export function shake(Duration = 0, Strength = 5) {
return (game: Game, entity: Entity) => {
game.World[entity] |= Has.Shake;
game[Get.Shake][entity] = <Shake>{
Duration,
Strength,
};
};
}
16 changes: 14 additions & 2 deletions src/game.ts
Original file line number Diff line number Diff line change
@@ -6,20 +6,25 @@ import {ControlBall} from "./components/com_control_ball.js";
import {ControlBrick} from "./components/com_control_brick.js";
import {ControlPaddle} from "./components/com_control_paddle.js";
import {Draw} from "./components/com_draw.js";
import {Entry} from "./components/com_entry.js";
import {Fade} from "./components/com_fade.js";
import {ComponentData, Get, Has} from "./components/com_index.js";
import {Move} from "./components/com_move.js";
import {Named} from "./components/com_named.js";
import {Shake} from "./components/com_shake.js";
import {Transform2D, transform2d} from "./components/com_transform2d.js";
import {Vec4} from "./math/index.js";
import {sys_audio} from "./systems/sys_audio.js";
import {sys_collide} from "./systems/sys_collide.js";
import {sys_control_ball} from "./systems/sys_control_ball.js";
import {sys_control_brick} from "./systems/sys_control_brick.js";
import {sys_control_paddle} from "./systems/sys_control_paddle.js";
import {sys_draw2d} from "./systems/sys_draw2d.js";
import {sys_entry} from "./systems/sys_entry.js";
import {sys_fade} from "./systems/sys_fade.js";
import {sys_framerate} from "./systems/sys_framerate.js";
import {sys_move} from "./systems/sys_move.js";
import {sys_performance} from "./systems/sys_performance.js";
import {sys_shake} from "./systems/sys_shake.js";
import {sys_transform2d} from "./systems/sys_transform2d.js";
import {sys_ui} from "./systems/sys_ui.js";

@@ -53,6 +58,9 @@ export class Game implements ComponentData, GameState {
public [Get.Move]: Array<Move> = [];
public [Get.Named]: Array<Named> = [];
public [Get.Transform2D]: Array<Transform2D> = [];
public [Get.Shake]: Array<Shake> = [];
public [Get.Fade]: Array<Fade> = [];
public [Get.Entry]: Array<Entry> = [];

public ViewportWidth = window.innerWidth;
public ViewportHeight = window.innerHeight;
@@ -61,9 +69,10 @@ export class Game implements ComponentData, GameState {
public Audio: AudioContext = new AudioContext();
public InputState: InputState = {mouse_x: 0, mouse_y: 0};
public InputEvent: InputEvent = {mouse_x: 0, mouse_y: 0, wheel_y: 0};
public Camera: Entity = 0;

// Implement GameState
public ClearColor = <Vec4>[1, 0.3, 0.3, 1];
public ClearColor: string = "white";

private RAF: number = 0;

@@ -116,6 +125,9 @@ export class Game implements ComponentData, GameState {
sys_control_paddle(this, delta);
sys_control_ball(this, delta);
sys_control_brick(this, delta);
sys_shake(this, delta);
sys_fade(this, delta);
sys_entry(this, delta);
sys_move(this, delta);
sys_transform2d(this, delta);
sys_collide(this, delta);
6 changes: 6 additions & 0 deletions src/math/easing.ts
Original file line number Diff line number Diff line change
@@ -75,3 +75,9 @@ export function ease_in_out_circ(t: number) {
? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2
: (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;
}

export function ease_in_out_elastic(t: number) {
return (t -= 0.5) < 0
? (0.02 + 0.01 / t) * Math.sin(50 * t)
: (0.02 - 0.01 / t) * Math.sin(50 * t) + 1;
}
8 changes: 8 additions & 0 deletions src/math/vec2.ts
Original file line number Diff line number Diff line change
@@ -27,3 +27,11 @@ export function normalize(out: Vec2, a: Vec2) {
out[1] = a[1] * len;
return out;
}

export function lerp(out: Vec2, a: Vec2, b: Vec2, t: number) {
let ax = a[0];
let ay = a[1];
out[0] = ax + t * (b[0] - ax);
out[1] = ay + t * (b[1] - ay);
return out;
}
24 changes: 24 additions & 0 deletions src/sounds/snd_bounce_brick.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {AudioClip} from "../components/com_audio_source";

export let snd_bounce_brick = <AudioClip>{
Tracks: [
{
Instrument: [
4,
"lowpass",
11,
8,
false,
false,
8,
8,
[
["sine", 5, 1, 2, 4, 8, false, false, 8, 8, 8],
["triangle", 4, 2, 2, 7, 10, false, false, 8, 8, 7],
],
],
Notes: [72],
},
],
Exit: 0,
};
21 changes: 21 additions & 0 deletions src/sounds/snd_bounce_paddle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {AudioClip} from "../components/com_audio_source";

export let snd_bounce_paddle = <AudioClip>{
Tracks: [
{
Instrument: [
4,
"lowpass",
11,
4,
false,
false,
8,
3,
[["triangle", 8, 1, 2, 9, 8, false, true, 0, 2, 10], [false, 5, 1, 1, 4]],
],
Notes: [69],
},
],
Exit: 0,
};
21 changes: 21 additions & 0 deletions src/sounds/snd_bounce_wall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {AudioClip} from "../components/com_audio_source";

export let snd_bounce_wall = <AudioClip>{
Tracks: [
{
Instrument: [
4,
"lowpass",
8,
8,
false,
false,
8,
8,
[["sine", 8, 2, 2, 3, 8, false, false, 8, 8, 8], [false, 3, 1, 2, 6]],
],
Notes: [64],
},
],
Exit: 0,
};
7 changes: 6 additions & 1 deletion src/systems/sys_audio.ts
Original file line number Diff line number Diff line change
@@ -24,7 +24,12 @@ function update(game: Game, entity: Entity, delta: number) {
for (let track of audio_source.Trigger.Tracks) {
for (let i = 0; i < track.Notes.length; i++) {
if (track.Notes[i]) {
play_note(game.Audio, track.Instrument, track.Notes[i], i * interval);
play_note(
game.Audio,
track.Instrument,
track.Notes[i] + audio_source.HalfTones,
i * interval
);
}
}
}
57 changes: 56 additions & 1 deletion src/systems/sys_control_ball.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import {get_ball_blueprint} from "../blueprints/blu_ball.js";
import {get_blu_explosion} from "../blueprints/blu_explosion.js";
import {get_blu_tail} from "../blueprints/blu_tail.js";
import {Get, Has} from "../components/com_index.js";
import {Entity, Game} from "../game.js";
import {normalize} from "../math/vec2.js";
import {snd_bounce_brick} from "../sounds/snd_bounce_brick.js";
import {snd_bounce_paddle} from "../sounds/snd_bounce_paddle.js";
import {snd_bounce_wall} from "../sounds/snd_bounce_wall.js";

const QUERY = Has.Transform2D | Has.ControlBall | Has.Move | Has.Collide;
const QUERY = Has.Transform2D | Has.ControlBall | Has.Move | Has.Collide | Has.AudioSource;

export function sys_control_ball(game: Game, delta: number) {
for (let i = 0; i < game.World.length; i++) {
@@ -16,28 +22,39 @@ function update(game: Game, entity: Entity) {
let transform = game[Get.Transform2D][entity];
let move = game[Get.Move][entity];
let collide = game[Get.Collide][entity];
let audio = game[Get.AudioSource][entity];

if (transform.Translation[0] < 0) {
transform.Translation[0] = 0;
move.Direction[0] = -move.Direction[0];
audio.Trigger = snd_bounce_wall;
audio.HalfTones = 0;
}

if (transform.Translation[0] > game.ViewportWidth) {
transform.Translation[0] = game.ViewportWidth;
move.Direction[0] = -move.Direction[0];
audio.Trigger = snd_bounce_wall;
audio.HalfTones = 0;
}

if (transform.Translation[1] < 0) {
transform.Translation[1] = 0;
move.Direction[1] = -move.Direction[1];
audio.Trigger = snd_bounce_wall;
audio.HalfTones = 0;
}

if (transform.Translation[1] > game.ViewportHeight) {
transform.Translation[1] = game.ViewportHeight;
move.Direction[1] = -move.Direction[1];
audio.Trigger = snd_bounce_wall;
audio.HalfTones = 0;
}

if (collide.Collisions.length > 0) {
game[Get.Shake][game.Camera].Duration = 0.2;

let collision = collide.Collisions[0];
if (collision.Hit[0]) {
transform.Translation[0] += collision.Hit[0];
@@ -53,6 +70,44 @@ function update(game: Game, entity: Entity) {
move.Direction[0] = from_center / other_half;
move.Direction[1] = -move.Direction[1];
}

if (game.World[collision.Other.EntityId] & Has.ControlBrick) {
let control = game[Get.ControlBall][entity];
control.Bounces += 1;
audio.Trigger = snd_bounce_brick;
audio.HalfTones = control.Bounces;
}

if (game.World[collision.Other.EntityId] & Has.ControlPaddle) {
let control = game[Get.ControlBall][entity];
control.Bounces = 0;
audio.Trigger = snd_bounce_paddle;
audio.HalfTones = 0;
}

normalize(move.Direction, move.Direction);

game.Add(
get_blu_explosion(transform.Translation[0], transform.Translation[1], "white", 15)
);

if (Math.random() > 0.95) {
let child = game.Add({
...get_ball_blueprint(game),
Translation: [transform.Translation[0], transform.Translation[1]],
});
game[Get.Transform2D][game.Camera].Children.push(game[Get.Transform2D][child]);
game[Get.Transform2D][child].Parent = game[Get.Transform2D][game.Camera];
}
}

let angle = Math.atan(move.Direction[1] / move.Direction[0]);

transform.Rotation = angle;

game.Add({
...get_blu_tail(20, 20, "orange"),
Translation: [...transform.Translation] as [number, number],
Rotation: angle,
});
}
14 changes: 12 additions & 2 deletions src/systems/sys_control_brick.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Get, Has} from "../components/com_index.js";
import {Entity, Game} from "../game.js";
import {linear} from "../math/easing.js";

const QUERY = Has.Transform2D | Has.ControlBrick | Has.Collide;
const QUERY = Has.Transform2D | Has.ControlBrick | Has.Collide | Has.Fade;

export function sys_control_brick(game: Game, delta: number) {
for (let i = 0; i < game.World.length; i++) {
@@ -13,8 +14,17 @@ export function sys_control_brick(game: Game, delta: number) {

function update(game: Game, entity: Entity) {
let collide = game[Get.Collide][entity];
let translation = game[Get.Transform2D][entity].Translation;
let entry = game[Get.Entry][entity];
let fade = game[Get.Fade][entity];

if (collide.Collisions.length > 0) {
game.Destroy(entity);
fade.Step = 0.025;
entry.Initial = translation;
entry.Final = [translation[0], game.ViewportHeight + 20];
entry.Time = 0.5;
entry.CurrentTime = 0;
entry.Easing = linear;
game.World[entity] |= Has.Entry;
}
}
5 changes: 5 additions & 0 deletions src/systems/sys_control_paddle.ts
Original file line number Diff line number Diff line change
@@ -15,6 +15,11 @@ function update(game: Game, entity: Entity) {
let transform = game[Get.Transform2D][entity];
let control = game[Get.ControlPaddle][entity];

// game.Add({
// ...get_blu_tail(100, 20, "red"),
// Translation: [...transform.Translation] as [number, number],
// });

let x = transform.Translation[0] + game.InputEvent.mouse_x;
if (x < control.Width / 2) {
transform.Translation[0] = control.Width / 2;
5 changes: 4 additions & 1 deletion src/systems/sys_draw2d.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,8 @@ const QUERY = Has.Transform2D | Has.Draw;

export function sys_draw2d(game: Game, delta: number) {
game.Context2D.resetTransform();
game.Context2D.clearRect(0, 0, game.ViewportWidth, game.ViewportHeight);
game.Context2D.fillStyle = game.ClearColor;
game.Context2D.fillRect(0, 0, game.ViewportWidth, game.ViewportHeight);

for (let i = 0; i < game.World.length; i++) {
if ((game.World[i] & QUERY) == QUERY) {
@@ -31,6 +32,8 @@ export function sys_draw2d(game: Game, delta: number) {
}

function draw_rect(game: Game, draw: DrawRect) {
game.Context2D.globalAlpha = draw.Alpha;
game.Context2D.fillStyle = draw.Color;
game.Context2D.filter = draw.Filter;
game.Context2D.fillRect(-draw.Width / 2, -draw.Height / 2, draw.Width, draw.Height);
}
40 changes: 40 additions & 0 deletions src/systems/sys_entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {get_blu_tail} from "../blueprints/blu_tail.js";
import {Get, Has} from "../components/com_index.js";
import {Entity, Game} from "../game.js";
import {Vec2} from "../math/index.js";
import {lerp} from "../math/vec2.js";

const QUERY = Has.Transform2D | Has.Entry;

export function sys_entry(game: Game, delta: number) {
for (let i = 0; i < game.World.length; i++) {
if ((game.World[i] & QUERY) == QUERY) {
update(game, i, delta);
}
}
}

function update(game: Game, entity: Entity, delta: number) {
let entry = game[Get.Entry][entity];
let transform = game[Get.Transform2D][entity];
let collide = game[Get.Collide][entity];

if (entry.CurrentTime <= entry.Time) {
let time = entry.Easing(entry.CurrentTime / entry.Time);
transform.Translation = lerp([0, 0], entry.Initial, entry.Final, time);
entry.CurrentTime += delta;
transform.Dirty = true;
game.Add({
...get_blu_tail(100, 20, "green"),
Translation: [...transform.Translation] as Vec2,
});

if (collide) {
collide.New = true;
}
} else {
transform.Translation = [...entry.Final] as [number, number];
game.World[entity] &= ~Has.Entry;
// collide.New = true;
}
}
28 changes: 28 additions & 0 deletions src/systems/sys_fade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {DrawRect} from "../components/com_draw.js";
import {Get, Has} from "../components/com_index.js";
import {Entity, Game} from "../game.js";

const QUERY = Has.Transform2D | Has.Fade;

export function sys_fade(game: Game, delta: number) {
for (let i = 0; i < game.World.length; i++) {
if ((game.World[i] & QUERY) == QUERY) {
update(game, i, delta);
}
}
}

function update(game: Game, entity: Entity, delta: number) {
let fade = game[Get.Fade][entity];
let draw = game[Get.Draw][entity] as DrawRect;
let transform = game[Get.Transform2D][entity];
if (draw.Alpha > 0) {
draw.Alpha -= fade.Step;
transform.Scale = [Math.max(0, draw.Alpha), Math.max(0, draw.Alpha)];
transform.Dirty = true;

if (draw.Alpha <= 0) {
game.Destroy(entity);
}
}
}
34 changes: 34 additions & 0 deletions src/systems/sys_shake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Get, Has} from "../components/com_index.js";
import {Entity, Game} from "../game.js";

const QUERY = Has.Transform2D | Has.Shake;

export function sys_shake(game: Game, delta: number) {
for (let i = 0; i < game.World.length; i++) {
if ((game.World[i] & QUERY) == QUERY) {
update(game, i, delta);
}
}
}

function update(game: Game, entity: Entity, delta: number) {
let shake = game[Get.Shake][entity];

if (shake.Duration > 0) {
shake.Duration -= delta;

let transform = game[Get.Transform2D][entity];
transform.Translation = [
shake.Strength - Math.random() * (shake.Strength * 2),
shake.Strength - Math.random() * (shake.Strength * 2),
];
transform.Dirty = true;
game.ClearColor = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() *
255})`;
if (shake.Duration <= 0) {
shake.Duration = 0;
transform.Translation = [0, 0];
game.ClearColor = `black`;
}
}
}
36 changes: 21 additions & 15 deletions src/worlds/wor_stage.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import {ball_blueprint} from "../blueprints/blu_ball.js";
import {get_ball_blueprint} from "../blueprints/blu_ball.js";
import {create_brick} from "../blueprints/blu_brick.js";
import {paddle_blueprint} from "../blueprints/blu_paddle.js";
import {get_paddle_blueprint} from "../blueprints/blu_paddle.js";
import {shake} from "../components/com_shake.js";
import {Game} from "../game.js";

export function world_stage(game: Game) {
game.World = [];

game.Add({
Translation: [game.ViewportWidth / 2, game.ViewportHeight - 20],
...paddle_blueprint,
});

game.Add({
Translation: [game.ViewportWidth / 2, game.ViewportHeight - 100],
...ball_blueprint,
});
game.ClearColor = "black";

let col_count = 5;
let row_count = 5;
@@ -25,14 +17,28 @@ export function world_stage(game: Game) {
let top_left_x = (game.ViewportWidth - brick_width * col_count - padding * (col_count - 1)) / 2;
let top_left_y = 100;

let bricks = [];
for (let row = 0; row < row_count; row++) {
let y = top_left_y + row * (brick_height + padding) + brick_height / 2;
for (let col = 0; col < col_count; col++) {
let x = top_left_x + col * (brick_width + padding) + brick_width / 2;
game.Add({
Translation: [x, y],
...create_brick(brick_width, brick_height),
bricks.push({
Translation: [x, y] as [number, number],
...create_brick(brick_width, brick_height, x, y, 0.5 + Math.random()),
});
}
}

game.Camera = game.Add({
Using: [shake(0, 10)],
Children: [
{
...get_paddle_blueprint(game),
},
{
...get_ball_blueprint(game),
},
...bricks,
],
});
}