gibbon.js
Version:
Actor/Component system for use with pixi.js.
154 lines • 4.77 kB
JavaScript
import { Point, Rectangle } from 'pixi.js';
import { Component } from '../core/component';
import { EngineEvent } from '../events/engine-events';
export class Camera extends Component {
/**
* Target for camera to follow.
*/
get target() { return this._target; }
set target(v) {
if (v) {
this._target = v;
this._viewRect.x = v.x - this._halfWidth;
this._viewRect.y = v.y - this._halfHeight;
this._panClip?.position.set(this._halfWidth - v.x, this._halfHeight - v.y);
}
}
/**
* Set the clip that moves to change the camera's position.
* This should be a clip that contains all game objects.
* (As opposed to static UI elements, backgrounds, etc.)
*/
get panClip() { return this._panClip; }
set panClip(v) {
this._panClip = v;
}
get minScale() { return this._minScale || 1; }
set minScale(v) { this._minScale = v; }
get maxScale() { return this._maxScale || 1; }
set maxScale(v) { this._maxScale = v; }
get viewScale() { return this._viewScale; }
set viewScale(v) {
this._viewScale = v;
this._panClip?.scale.set(v, v);
}
get x() { return -(this._panClip?.x ?? 0); }
set x(v) {
this._viewRect.x = v * this._viewScale;
if (this._panClip != null) {
this._panClip.x = -this._viewRect.x;
}
}
get y() { return -(this._panClip?.y ?? 0); }
set y(v) {
this._viewRect.y = v * this._viewScale;
if (this._panClip != null) {
this._panClip.y = -this._viewRect.y;
}
}
/**
* @property {Rectangle} Visible rectangle in the Camera's coordinate system.
*/
get viewRect() { return this._viewRect; }
get centerX() { return this._viewRect.x + this._halfWidth; }
get centerY() { return this._viewRect.y + this._halfHeight; }
get center() {
return new Point(this._viewRect.x + this._halfWidth, this._viewRect.y + this._halfHeight);
}
get left() { return this._viewRect.left; }
get right() { return this._viewRect.right; }
get top() { return this._viewRect.top; }
get bottom() { return this._viewRect.bottom; }
/**
* Target camera should track.
*/
_target = null;
_minScale = 0;
_maxScale = 0;
_viewScale = 0;
_viewRect = new Rectangle();
_panClip;
_halfWidth = 0;
_halfHeight = 0;
constructor(rect) {
super();
this.resized(rect);
}
init() {
this._target = null;
this._panClip = this.actor.clip;
this._viewScale = 1;
this._halfWidth = this._viewRect.width / 2;
this._halfHeight = this._viewRect.height / 2;
this.game.on(EngineEvent.ScreenResized, this.resized, this);
}
/**
* Call when view size has changed.
* @param rect
*/
resized(rect) {
this._viewRect.width = rect.width;
this._viewRect.height = rect.height;
this._halfWidth = rect.width / 2;
this._halfHeight = rect.height / 2;
}
/**
* Determines if an item is completely within the view.
* @param {*} it
* @returns true if item is completely onscreen, false otherwise.
*/
containsItem(it) {
throw Error("Not implemented.");
}
/**
*
* @param {*} it
* @returns true if item is within the camera view, false otherwise.
*/
itemInView(it) {
throw Error("Not implemented.");
}
/**
*
* @param p
*/
ptInView(p) {
return this._viewRect?.contains(p.x, p.y) ?? false;
}
/**
*
* @param {Rectangle} r
* @returns true if a rectangle falls within the camera view, false otherwise.
*/
rectInView(r) {
return r.x < this._viewRect.right &&
r.right > this._viewRect.x &&
r.y < this._viewRect.bottom &&
r.bottom > this._viewRect.y;
}
/**
*
* @param global
* @param dest=null
* @returns {Point}
*/
toCameraPoint(global, dest) {
return this._panClip?.toLocal(global, undefined, dest ?? new Point());
}
update() {
if (this._target === null)
return;
const targPos = this._target.position;
const destX = this._halfWidth - targPos.x;
const destY = this._halfHeight - targPos.y;
const pos = this._panClip.position;
pos.set(pos.x + (destX - pos.x) / 4, pos.y + (destY - pos.y) / 4);
//console.log('cam pos: ' + pos.x + ', '+ pos.y );
this._viewRect.x = -pos.x;
this._viewRect.y = -pos.y;
}
onDestroy() {
this.game?.off(EngineEvent.ScreenResized, this.resized, this);
}
}
//# sourceMappingURL=camera.js.map