Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- =================
- === App Class ===
- =================
- import { Application, Assets } from 'pixi.js';
- import { Viewport } from './Viewport';
- export class App extends Application {
- static instance = null;
- constructor() {
- if (App.instance) return App.instance;
- super();
- App.instance = this;
- Assets.addBundle('characters', [
- { alias: 'man', src: '/man.json' },
- { alias: 'peep', src: '/peep.json' }
- ]);
- this.mouseLocation;
- this.viewport = null;
- }
- async startApp(options) {
- await this.init(options);
- await Assets.init({ manifest });
- const textures = await Assets.loadBundle('characters');
- this.mouseLocation = this.renderer.events.pointer.global;
- this.viewport = new Viewport({ app: this });
- this.stage.addChild(this.viewport);
- return {
- textures
- };
- }
- addChild(child) {
- if (!child.update) return;
- if (!this.ticker) return;
- if (!this.viewport) return;
- console.log(child);
- this.viewport.addChild(child);
- this.ticker.add((e) => child.update(e));
- }
- destroy() {
- this.destroy();
- App.instance = null;
- }
- }
- const manifest = {
- bundles: [
- {
- name: 'characters',
- assets: [
- {
- alias: 'man',
- src: '/man.json'
- },
- { alias: 'peep', src: '/peep.json' }
- ]
- }
- ]
- };
- ====================
- === Parent Class ===
- ====================
- import { AnimatedSprite, Assets, Container } from 'pixi.js';
- import { App } from './App';
- import { Vector2D } from './Vector2D';
- export class Entity extends AnimatedSprite {
- static children = [];
- constructor({ textures, variant = 'peep', index }) {
- super(textures[variant].animations['stand-down/tile']);
- this.app = new App();
- this.skin = textures[variant]; // Get textures from bundle
- this.index = index || Entity.children.length;
- this.origin = new Vector2D();
- this.coordinates = new Vector2D();
- this.direction = Vector2D.random();
- this.velocity = new Vector2D();
- this.acceleration = new Vector2D();
- this.anchor.set(0.5);
- Entity.children.push(this);
- this.app.addChild(this);
- }
- setPosition(x = 0, y = 0) {
- this.x = x;
- this.y = y;
- this.coordinates.set(x, y);
- }
- setPosFromObject(v) {
- this.setPosition(v.x, v.y);
- }
- moveTowards(target) {
- this.direction = target.sub(this.coordinates).normalize();
- this.velocity.setFromObject(direction);
- }
- // Add methods for changing animation based on movement here, e.g.,
- setAnimation(animationName) {
- if (!this.skin.animations[animationName]) return;
- if (this.textures === this.skin.animations[animationName]) return;
- this.textures = this.skin.animations[animationName];
- this.play();
- }
- }
- =======================
- === Inherited Class ===
- =======================
- import { AnimatedSprite, Point, Graphics, Color, loadImageBitmap } from 'pixi.js';
- import { Entity } from './Entity';
- import { Vector2D } from './Vector2D';
- export class Peep extends Entity {
- CURSOR_RADIUS = 100;
- constructor({ textures }) {
- super({ textures });
- // === State management ===
- this.origin.set(Math.random() * this.app.screen.width, Math.random() * this.app.screen.height);
- this.setPosition(this.origin.x, this.origin.y);
- this.state = 'repel'; // Current state (idle, wander, pause)
- this.animationMap = {
- motion: {
- stand: 'stand-',
- run: 'walk-'
- },
- direction: {
- right: 'right/tile',
- left: 'left/tile',
- down: 'down/tile',
- up: 'up/tile'
- }
- };
- this.directionSet = ['left', 'down', 'right', 'up'];
- this.revDirectionSet = ['right', 'up', 'left', 'down'];
- }
- update(e) {
- // console.log(this.texture.label, this.currentFrame);
- switch (this.state) {
- case 'wander':
- this.wanderUpdate(e.deltaTime);
- break;
- case 'follow':
- this.followUpdate(e.deltaTime);
- break;
- case 'repel':
- this.repelUpdate(e.deltaTime);
- break;
- case 'return':
- this.returnToOrigin(e.deltaTime);
- break;
- case 'pause':
- this.stand();
- break;
- default:
- break;
- }
- this.zIndex = Math.floor(this.y);
- }
- // TODO: Implement this and include animation updates
- switchState(newState) {
- this.state = newState;
- return;
- // this.origin = { x: this.x, y: this.y };
- }
- // wanderUpdate(elapsed) {
- // // Update direction with some randomness
- // if (elapsed > 16.5) {
- // this.direction += (Math.random() - 0.5) * 0.5; // Change direction slightly
- // this.lastDirectionChange = elapsed;
- // }
- // // Assuming speed is in pixels-per-second:
- // const dx = (Math.cos(this.direction) * this.speed * elapsed) / 1000;
- // const dy = (Math.sin(this.direction) * this.speed * elapsed) / 1000;
- // // Optimized animation selection
- // const dominantDirection =
- // Math.abs(dx) > Math.abs(dy) ? (dx > 0 ? 'right' : 'left') : dy > 0 ? 'down' : 'up';
- // this.x = Math.max(0, Math.min(this.app.screen.width, this.x + dx));
- // this.y = Math.max(0, Math.min(this.app.screen.height, this.y + dy));
- // this.setAnimation(this.animationMap.direction[dominantDirection]);
- // }
- // followUpdate(mouseLocation, elapsed) {
- // const mouseCoords = new Vector2D.fromData(mouseLocation);
- // const delta = mouseCoords.subtract(this);
- // const dx = mouseLocation.x - this.x;
- // const dy = mouseLocation.y - this.y;
- // const distance = Math.sqrt(dx * dx + dy * dy);
- // if (distance > 100) {
- // } else {
- // const moveFactor = Math.min(distance / 100, (this.speed * elapsed) / 10000);
- // this.x += (dx + 1 / distance) * moveFactor;
- // this.y += (dy + 1 / distance) * moveFactor;
- // if (!this.animationSpeed) this.animationSpeed = 0.09;
- // }
- // let dominantDirection = (Math.abs(dy) > Math.abs(dx) && (dy > 0 ? 'down' : 'up')) || '';
- // dominantDirection += (Math.abs(dx) > Math.abs(dy) && (dx > 0 ? 'right' : 'left')) || '';
- // this.setAnimation(this.animationMap.direction[dominantDirection]);
- // }
- repelUpdate(elapsed) {
- const mouseCoords = Vector2D.fromObject(this.app.mouseLocation);
- if (!mouseCoords.multiply(1).magnitude()) mouseCoords.set(-200, -200);
- const deltaFromMouse = Vector2D.subtract(mouseCoords, this.coordinates);
- const distanceFromMouse = deltaFromMouse.magnitude();
- const distanceFromOrigin = Vector2D.subtract(this.origin, this.coordinates).magnitude();
- const quadrantFromMouse = Vector2D.quadrant(deltaFromMouse);
- const directionQuadrant = Vector2D.quadrant(this.direction);
- let motion = 'stand';
- let dominantDirection = this.directionSet[directionQuadrant];
- /*
- ================================
- ======== MOVEMENT LOGIC ========
- ================================
- If entity is farther than CURSOR_RADIUS (100)
- from mouse, it stands.
- If the mouse between CURSOR_RADIUS + 100
- and CURSOR RADIUS away from the entity,
- it looks at the cursor. (e.g. 200 > distance >= 100)
- */
- if (distanceFromOrigin >= 10 && distanceFromMouse > this.CURSOR_RADIUS + 200) {
- this.switchState('return');
- this.velocity.set(0, 0);
- return;
- } else if (
- distanceFromMouse < this.CURSOR_RADIUS + 100 &&
- distanceFromMouse >= this.CURSOR_RADIUS
- ) {
- this.direction.setFromObject(deltaFromMouse.normalize());
- dominantDirection = this.directionSet[quadrantFromMouse];
- } else if (distanceFromMouse < this.CURSOR_RADIUS) {
- this.direction.setFromObject(deltaFromMouse.normalize());
- dominantDirection = this.revDirectionSet[quadrantFromMouse];
- if (this.velocity.magnitude() > 0) motion = 'walk';
- this.velocity.setFromObject(this.direction.multiply(elapsed));
- const target = Vector2D.subtract(this.coordinates, this.velocity);
- this.setPosition(target.x, target.y);
- }
- this.setAnimation(`${motion}-${dominantDirection}/tile`);
- }
- returnToOrigin(elapsed) {
- const mouseCoords = Vector2D.fromObject(this.app.mouseLocation);
- const deltaFromOrigin = Vector2D.subtract(this.origin, this.coordinates);
- const distanceFromMouse = Vector2D.subtract(mouseCoords, this.coordinates).magnitude();
- const distanceFromOrigin = deltaFromOrigin.magnitude();
- const directionQuadrant = Vector2D.quadrant(this.direction.angle());
- const originQuadrant = Vector2D.quadrant(deltaFromOrigin);
- let motion = 'walk';
- let dominantDirection = this.directionSet[directionQuadrant];
- if (distanceFromOrigin <= 10 || distanceFromMouse < this.CURSOR_RADIUS) {
- this.switchState('repel');
- this.velocity.set(0, 0);
- return;
- }
- this.velocity.setFromObject(Vector2D.multiply(this.direction, elapsed));
- this.direction.setFromObject(deltaFromOrigin.normalize());
- const target = Vector2D.add(this.coordinates, this.velocity);
- dominantDirection = this.directionSet[originQuadrant];
- this.setPosition(target.x, target.y);
- this.setAnimation(`${motion}-${dominantDirection}/tile`);
- }
- stand() {
- if (this.state === 'pause') return;
- this.animationSpeed = 0;
- this.state = 'pause';
- }
- resume() {
- if (this.state !== 'pause') return;
- this.animationSpeed = 0.09;
- this.state = 'follow'; // Resume wandering by default
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement