Skip to content

Commit

Permalink
Refactor/pixi app (#1)
Browse files Browse the repository at this point in the history
* Overloading

* Making MovementMove use absolute positions

* Attempting to use PIXI.Application to make animations easier

* Fixed PIXI.Application usage
  • Loading branch information
acbabis committed Feb 19, 2017
1 parent 3ae4b50 commit a33f2ec
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 65 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"mysql": "^2.12.0",
"node-sass": "^3.13.0",
"normalize.css": "^4.1.1",
"pixi.js": "^4.3.2",
"pixi.js": "^4.3.5",
"random-js": "^1.0.8",
"sass-loader": "^4.0.0",
"sinon": "^1.17.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class GraphicalViewKeyboardController {
if(creature && creature.isEnemy(character)) {
attemptMove(new Moves.AttackMove(tile, x, y));
} else {
attemptMove(new Moves.MovementMove(tile, dx, dy));
attemptMove(new Moves.MovementMove(tile, x, y));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class GraphicalViewMouseController {
if(dx === 0 && dy === 0) {
return [new Moves.WaitMove(playerLocation)];
} else if(Math.abs(dx) <= 1 && Math.abs(dy) <= 1 && (dx !== 0 || dy !== 0)) {
return [new Moves.MovementMove(playerLocation, dx, dy)];
return [new Moves.MovementMove(playerLocation, x, y)];
} else if(playerLocation.getCreature()) {
return Pather.getMoveSequenceToward(dungeon, player, dungeon.getTile(targetX, targetY));
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/js/app/controllers/SharedUIDataController.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export default class SharedUIDataController extends Observable {
if(dx === 0 && dy === 0) {
moves = [new Moves.WaitMove(playerLocation)];
} else if(Math.abs(dx) <= 1 && Math.abs(dy) <= 1 && (dx !== 0 || dy !== 0)) {
moves = [new Moves.MovementMove(playerLocation, dx, dy)];
moves = [new Moves.MovementMove(playerLocation, x, y)];
} else if(playerLocation.getCreature()) {
moves = Pather.getMoveSequenceToward(dungeon, player, dungeon.getTile(x, y));
}
Expand Down
6 changes: 3 additions & 3 deletions src/client/js/app/entities/creatures/Creature.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,10 @@ export default class Creature extends Entity {
* Determines if the Creature can see the given tile and what's on it.
* @return {Boolean} `true` if the Creature can see the tile; false otherwise
*/
canSee(dungeon, tile) {
// TODO: Allow creature
canSee(dungeon, param) {
const tile = param instanceof Creature ? dungeon.getTile(creature) : param;
if(!(tile instanceof Tile)) {
throw new Error('Must pass a Tile to canSee');
throw new Error('Must pass a Tile or Creature');
}
const location = dungeon.getTile(this);

Expand Down
40 changes: 23 additions & 17 deletions src/client/js/app/entities/creatures/moves/MovementMove.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,41 @@ import PlayableCharacter from '../PlayableCharacter.js';
* @todo Only take two absolute coord params
*/
export default class MovementMove extends Move {
constructor(actorTile, param1, param2) {
constructor(actorTile, x, y) {
super(actorTile);
if(Number.isInteger(param1) && Number.isInteger(param2)
&& Math.abs(param1) <= 1 && Math.abs(param2) <= 1
&& (Math.abs(param1) === 1 || Math.abs(param2) === 1)) {
this._dx = param1;
this._dy = param2;
if(Number.isInteger(x) && Number.isInteger(y)) {
this._x = x;
this._y = y;
} else {
throw new Error('Must pass two integers that represent a move to an adjacent tile');
throw new Error('Must pass two integers');
}
}

getDx() {
return this._dx;
getX() {
return this._x;
}

getDy() {
return this._dy;
getY() {
return this._y;
}

getCostMultiplier() {
return 1;
}

getReasonIllegal(dungeon, creature) {
var tile = dungeon.getTile(creature);
var x = tile.getX() + this.getDx();
var y = tile.getY() + this.getDy();
const tile = dungeon.getTile(creature);
const x = this.getX();
const y = this.getY();
const adx = Math.abs(x - tile.getX());
const ady = Math.abs(y - tile.getY());
var newLocation = dungeon.getTile(x, y);
if(!newLocation) {
return `Tile [${x}, ${y}] does not exist`;
}
if(adx > 1 || ady > 1 || (adx === 0 && ady === 0)) {
return `New location [${x}, ${y}] is not an adjacent tile`;
}
if(!creature.canOccupy(newLocation)) {
return `${creature} cannot legally occupy new location [${x}, ${y}]`;
}
Expand All @@ -56,8 +62,8 @@ export default class MovementMove extends Move {
throw new Error(reason);
}
var tile = dungeon.getTile(creature);
var x = tile.getX() + this.getDx();
var y = tile.getY() + this.getDy();
var x = this.getX();
var y = this.getY();
tile.removeCreature();
dungeon.moveCreature(creature, x, y);
dungeon.fireEvent(new GameEvents.MoveEvent(dungeon, creature, x, y));
Expand All @@ -67,6 +73,6 @@ export default class MovementMove extends Move {
var actorX = this.getActorX();
var actorY = this.getActorY();
return observer.canSee(dungeon, dungeon.getTile(actorX, actorY)) ||
observer.canSee(dungeon, dungeon.getTile(actorX + this.getDx(), actorY + this.getDy()));
observer.canSee(dungeon, dungeon.getTile(this.getX(), this.getY()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ export default class FleeStrategy extends Strategy {
return d1 > d2 ? tile1 : tile2;
});

var dx = target.getX() - tile.getX();
var dy = target.getY() - tile.getY();

return new Moves.MovementMove(tile, dx, dy);
return new Moves.MovementMove(tile, target.getX(), target.getY());
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/client/js/app/entities/creatures/strategies/Pather.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,13 @@ export default module = {
var prevX = start.getX();
var prevY = start.getY();
return pathfinding.path.slice(1).map(function(location) {
// TODO: Consider making MovementMove take two tiles instead of deltas
var nextX = location.getX();
var nextY = location.getY();
var dx = nextX - prevX;
var dy = nextY - prevY;
prevX = nextX;
prevY = nextY;
return new Moves.MovementMove(dungeon.getTile(prevX, prevY), dx, dy);
return new Moves.MovementMove(dungeon.getTile(prevX, prevY), nextX, nextY);
});
} else {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class Strategy {
// TODO: Only observe events?
observeMove(dungeon, observer, actor, move) {
if(observer.isEnemy(actor)) {
if(move.getDx) {
if(move.constructor.name === 'MovementMove') {
let currentLocation = dungeon.getTile(actor);
this._lastKnownEnemyLocation = dungeon.getTile(currentLocation.getX(), currentLocation.getY());
} else if(move.getAbility && actor.getAbility(move.getIndex()).isMovementAbility()) {
Expand Down
60 changes: 26 additions & 34 deletions src/client/js/app/views/PixiDungeonView.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,31 @@ export default class PixiDungeonView {
const canvasContainer = this._canvasContainer = document.createElement('div');
canvasContainer.classList.add('canvas-container');

const renderer = this._renderer = PIXI.autoDetectRenderer();
canvasContainer.appendChild(renderer.view);
const pixiApp = this._pixiApp = new PIXI.Application();
canvasContainer.appendChild(pixiApp.view);

PIXI.loader.add('images/spritesheet.json').load(() => this.init());

function resize() {
const {clientWidth, clientHeight} = canvasContainer;
renderer.resize(clientWidth, clientHeight);
pixiApp.renderer.resize(clientWidth, clientHeight);
}

setTimeout(resize);
window.addEventListener('resize', resize);
}

getStage() {
return this._pixiApp.stage;
}

init() {
const stage = this._stage = new PIXI.Container();
const stage = this.getStage();

const entitySprites = this._entiteSprites = {};

const sharedData = this._sharedData;
const renderer = this._renderer;
const renderer = this._pixiApp.renderer;

sharedData.addObserver((event) => {
if(event instanceof Dungeon){
Expand Down Expand Up @@ -248,29 +252,25 @@ export default class PixiDungeonView {
this.updateStatBars();
this.updateRangeIndicator();
this.updateSelectedTileIndicator();
renderer.render(stage);
});

renderer.render(stage);
}

populateStage(stage) {
this.populateSprites(stage);
populateStage() {
this.populateSprites();
this.updateCreatureLocations();
this.updateItems();
this.updateVision();
this._renderer.render(stage);
}

populateSprites(stage) {
const self = this;
populateSprites() {
const stage = this.getStage();
while(stage.children.length) stage.removeChild(stage.children[0]);

const dungeon = this._sharedData.getDungeon();
const tileContainers = this._tileContainers = new Array(dungeon.getWidth()).fill(0).map(()=>[]);
const entitySprites = this._entiteSprites;

dungeon.forEachTile(function(tile, x, y) {
dungeon.forEachTile((tile, x, y) => {
const tileContainer = getTileContainer(tile);
tileContainer.x = x * (TILE_WIDTH + GAP_WIDTH);
tileContainer.y = y * (TILE_WIDTH + GAP_WIDTH);
Expand All @@ -279,24 +279,16 @@ export default class PixiDungeonView {
tileContainers[x][y] = tileContainer;

tileContainer
.on('click', function(event) {
self._clickHanders.forEach(function(handler) {
handler(x, y);
});
}).on('tap', function(event) {
self._clickHanders.forEach(function(handler) {
handler(x, y);
});
}).on('mouseover', function(event) {
setTimeout(function() { // Ensure mouseout fires first
self._mouseOverHandlers.forEach(function(handler) {
handler(x, y);
});
});
}).on('mouseout', function(event) {
self._mouseOutHandlers.forEach(function(handler) {
handler(x, y);
.on('click', (event) => {
this._clickHanders.forEach(handler => handler(x, y));
}).on('tap', (event) => {
this._clickHanders.forEach(handler => handler(x, y));
}).on('mouseover', (event) => {
setTimeout(() => { // Ensure mouseout fires first
this._mouseOverHandlers.forEach(handler => handler(x, y));
});
}).on('mouseout', (event) => {
this._mouseOutHandlers.forEach(handler => handler(x, y));
});

stage.addChild(tileContainer);
Expand Down Expand Up @@ -437,7 +429,7 @@ export default class PixiDungeonView {
rangedAttack.getRange() * TILE_WIDTH
);

this._stage.addChild(rangeIndicator);
this.getStage().addChild(rangeIndicator);
}

updateSelectedTileIndicator() {
Expand All @@ -460,14 +452,14 @@ export default class PixiDungeonView {
const y = tile.getY();
const color = getTileColor(sharedData, x, y);
const indicator = getIndicator(x, y, color);
this._stage.addChild(indicator);
this.getStage().addChild(indicator);
return indicator;
});
}

scrollToPlayer() {
const sharedData = this._sharedData;
const stage = this._stage;
const stage = this.getStage();
const dungeon = sharedData.getDungeon();
const player = dungeon.getPlayableCharacter();
const tile = dungeon.getTile(player);
Expand Down

0 comments on commit a33f2ec

Please sign in to comment.