Skip to content

Commit

Permalink
Merge pull request #8 from flo-bit/main
Browse files Browse the repository at this point in the history
stuff
  • Loading branch information
flo-bit authored Jul 26, 2024
2 parents bbf040b + dfb5455 commit ae8613d
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 73 deletions.
33 changes: 10 additions & 23 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Enemy, { CrossEnemy } from './enemy.js';

import Stats from 'stats.js';

import { AdvancedBloomFilter } from 'pixi-filters';
import { AdvancedBloomFilter, OldFilmFilter } from 'pixi-filters';
import PlayerManager from './player-manager.js';
import ProjectileManager, { ProjectileData } from './projectile-manager.js';

Expand All @@ -20,6 +20,7 @@ import { WaveManager } from './wave.js';
import { Item, ItemOptions } from './item.js';
import { ItemManager } from './item-manager.js';
import { LightManager } from './light-manager.js';
import { createNoiseSprite } from './helper.js';

export default class Game {
container: PIXI.Container;
Expand All @@ -46,7 +47,7 @@ export default class Game {

debug: boolean = false;

showStats: boolean = false;
showStats: boolean = true;

stats?: Stats;

Expand All @@ -65,8 +66,6 @@ export default class Game {
minWidth = 700;
minHeight = 1000;

lightPlaced = false;

constructor() {
this.setup();

Expand Down Expand Up @@ -160,7 +159,12 @@ export default class Game {
this.mainContainer.scale.set(this.scale);
});

//this.container.scale.set(this.scale);
let noise = createNoiseSprite(2000, 2000);
noise.anchor.set(0.5);
noise.scale.set(1);
noise.alpha = 0.3;
noise.zIndex = 100;
this.mainContainer.addChild(noise);

app.ticker.add((ticker) => {
if (this.stats) this.stats.begin();
Expand Down Expand Up @@ -334,7 +338,6 @@ export default class Game {
update(deltaTime: number) {
// update game state here
this.playerManager?.update(deltaTime, this.keys);
if (!this.playing) return;

this.playingTime += deltaTime;
if (Math.floor(this.playingTime / 1000) !== Math.floor((this.playingTime - deltaTime) / 1000)) {
Expand All @@ -344,7 +347,7 @@ export default class Game {

this.obstacleManager.update(deltaTime);

this.enemyManager?.update(deltaTime);
if (this.playing) this.enemyManager?.update(deltaTime);

this.itemManager.update(deltaTime);

Expand All @@ -356,22 +359,6 @@ export default class Game {
}
}

if (this.keys['e']) {
let player = this.playerManager?.players[0];
if (player && !this.lightPlaced) {
this.lightManager.addLight({
color: player.color,
x: player.x,
y: player.y,
alpha: 0.2,
scale: 0.5
});
this.lightPlaced = true;
}
} else {
this.lightPlaced = false;
}

let playerManager = this.playerManager;

if (playerManager) {
Expand Down
31 changes: 31 additions & 0 deletions src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,34 @@ export function blendColors(color1: number, color2: number, blend: number): numb
// Recombine blended components into hexadecimal
return (r << 16) | (g << 8) | b;
}

import * as PIXI from 'pixi.js';

export function createNoiseSprite(width: number, height: number): PIXI.Sprite {
// Create an empty PIXI texture with the given width and height
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d')!;

// Fill the canvas with random noise
const imageData = ctx.createImageData(width, height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = Math.floor(Math.random() * 256); // Alpha
}
ctx.putImageData(imageData, 0, 0);

// Create a PIXI texture from the canvas
const texture = PIXI.Texture.from(canvas);
// Create a sprite from the texture
const sprite = new PIXI.Sprite(texture);

// remove canvas
canvas.remove();

return sprite;
}
25 changes: 20 additions & 5 deletions src/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export class Item {

life: number = 0;

light?: PIXI.Sprite;

constructor(game: Game, options: ItemOptions) {
this.game = game;

Expand All @@ -43,14 +45,15 @@ export class Item {

this.lifetime = options.lifetime ?? 10000;

this.shape = new PIXI.Graphics().rect(0, 0, this.size, this.size).fill(this.color);
this.shape = new PIXI.Graphics().circle(0, 0, this.size / 2).fill(this.color);

this.shape.x = options.x;
this.shape.y = options.y;
this.shape.pivot.set(this.size / 2, this.size / 2);

game.container.addChild(this.shape);

this.addGlow();

const rigidBodyDesc = RAPIER()
.RigidBodyDesc.dynamic()
.setTranslation(this.shape.x, -this.shape.y);
Expand All @@ -67,6 +70,18 @@ export class Item {
this.rigidBody.userData = this;
}

async addGlow() {
const texture = await PIXI.Assets.load('./light.png');
this.light = PIXI.Sprite.from(texture);
this.light.tint = this.color;
this.light.anchor.set(0.5);
this.light.scale.set(0.1);
this.light.zIndex = -1;
this.light.alpha = 0.2;

this.shape.addChild(this.light);
}

pickup(player: Player) {
this.game.spawnParticles(this.shape.x, this.shape.y, 5, this.color);

Expand All @@ -82,7 +97,7 @@ export class Item {
this.destroy();
return;
}

/*
let closestPlayer = this.game.lightManager?.getClosestLight({
x: this.shape.x,
y: this.shape.y
Expand All @@ -91,9 +106,9 @@ export class Item {
if (closestPlayer) {
let dist = Math.hypot(closestPlayer.x - this.shape.x, closestPlayer.y - this.shape.y);
this.shape.alpha = 1 - dist / (closestPlayer.scale * 300);
}
}*/

this.shape.alpha *= 1 - this.life / this.lifetime;
this.shape.scale.set(1 - this.life / this.lifetime + 0.2);
}

destroy() {
Expand Down
39 changes: 25 additions & 14 deletions src/light-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,34 @@ export class LightManager {
position: { x: number; y: number },
maxDist: number | undefined = undefined
): Light | undefined {
let closestLight: Light | undefined;
let closestDistance = Infinity;
position.y = -position.y;
let solid = true;

for (let light of this.lights) {
if (light.destroyed) continue;
console.log(light);
const distance = Math.hypot(light.x - position.x, light.y - position.y);
if (distance < closestDistance) {
closestDistance = distance;
closestLight = light;
}
}
let proj = this.game.world.projectPoint(position, solid, undefined, 0x10001000);

if (proj) {
let light = proj.collider.parent()?.userData as Light;

if (!maxDist || closestDistance < maxDist) {
return closestLight;
return light;
}

return undefined;
// let closestLight: Light | undefined;
// let closestDistance = Infinity;

// for (let light of this.lights) {
// if (light.destroyed) continue;
// console.log(light);
// const distance = Math.hypot(light.x - position.x, light.y - position.y);
// if (distance < closestDistance) {
// closestDistance = distance;
// closestLight = light;
// }
// }

// if (!maxDist || closestDistance < maxDist) {
// return closestLight;
// }

// return undefined;
}
}
40 changes: 37 additions & 3 deletions src/light.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as PIXI from 'pixi.js';
import { RAPIER } from './rapier';
import Game from './app';
import { RigidBody } from '@dimforge/rapier2d';
// import 'pixi.js/advanced-blend-modes';

export type LightOptions = {
x?: number;
Expand All @@ -11,6 +13,10 @@ export type LightOptions = {
lifetime?: number;

alpha?: number;

detail?: number;

flicker?: boolean;
};

export class Light {
Expand All @@ -34,6 +40,10 @@ export class Light {

flicker: boolean = true;

rigidBody?: RigidBody;

detail: number = 120;

constructor(game: Game, options: LightOptions) {
this.game = game;

Expand All @@ -52,6 +62,8 @@ export class Light {
this.lifetime = options.lifetime;
}
if (options.alpha) this.alpha = options.alpha;
if (options.detail) this.detail = options.detail;
if (options.flicker !== undefined) this.flicker = options.flicker;

this.createLight();

Expand All @@ -63,13 +75,17 @@ export class Light {
}
set x(value) {
this.lightContainer.x = value;

this.rigidBody?.setTranslation({ x: value, y: -this.y }, true);
}

get y() {
return this.lightContainer.y;
}
set y(value) {
this.lightContainer.y = value;

this.rigidBody?.setTranslation({ x: this.x, y: -value }, true);
}

get scale() {
Expand Down Expand Up @@ -107,14 +123,27 @@ export class Light {

this.lightContainer.addChild(this.light);

// this.lightContainer.blendMode = 'add';

this.light.mask = this.shadow;

const rigidBodyDesc = RAPIER()
.RigidBodyDesc.kinematicPositionBased()
.setTranslation(this.x, -this.y)
.lockRotations();
this.rigidBody = this.game.world.createRigidBody(rigidBodyDesc);

const colliderDesc = RAPIER().ColliderDesc.cuboid(10, 10).setCollisionGroups(0x10001000);
this.game.world.createCollider(colliderDesc, this.rigidBody);

this.rigidBody.userData = this;
}

drawShadow() {
// ray cast around the player to create a shadow
this.shadow.clear();

const rays = 360;
const rays = this.detail;

const angleStep = (Math.PI * 2) / rays;
const rayLength = 100000;
Expand Down Expand Up @@ -158,8 +187,12 @@ export class Light {
this.drawShadow();

if (this.flicker && this.light) {
this.light.alpha = this._alpha + Math.random() * 0.01;
this.light.scale.set(this._scale + Math.random() * 0.05);
this.light.alpha = this._alpha + (Math.random() - 0.5) * 0.03;
this.light.scale.set(this._scale + Math.random() * 0.1);

if (Math.random() < 1 / deltaTime) {
this.light.alpha = this._alpha * 0.5;
}
}
}

Expand All @@ -168,5 +201,6 @@ export class Light {

this.destroyed = true;
this.lightContainer.destroy();
if (this.rigidBody) this.game.world.removeRigidBody(this.rigidBody);
}
}
Loading

0 comments on commit ae8613d

Please sign in to comment.