Skip to content

Commit

Permalink
GH-40 Create canvasTexture to track fog changes
Browse files Browse the repository at this point in the history
- Creates a `CanvasTexture` that contains the updates to the fog of war, based on both gameObject logic & cached old positions
  • Loading branch information
amaccann committed Apr 9, 2020
1 parent 78f3db4 commit aa1a154
Show file tree
Hide file tree
Showing 19 changed files with 707 additions and 47 deletions.
9 changes: 9 additions & 0 deletions packages/phaser3-fog-of-war/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
nvmrc=~/.nvm/nvm.sh
if [ -e $nvmrc ]; then
source $nvmrc
nvm install
fi

PATH_add node_modules/.bin

export NODE_ENV=dev
5 changes: 5 additions & 0 deletions packages/phaser3-fog-of-war/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea
node_modules
coverage
dist
yarn-error.log
4 changes: 4 additions & 0 deletions packages/phaser3-fog-of-war/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
src/
webpack/
public/
.idea/
1 change: 1 addition & 0 deletions packages/phaser3-fog-of-war/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v13.6.0
8 changes: 8 additions & 0 deletions packages/phaser3-fog-of-war/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"useTabs": false,
"printWidth": 160,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5",
"jsxBracketSameLine": true
}
3 changes: 2 additions & 1 deletion packages/phaser3-fog-of-war/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1",
"webpack-merge": "^4.2.2"
}
},
"dependencies": {}
}
8 changes: 7 additions & 1 deletion packages/phaser3-fog-of-war/src/demo/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Phaser from 'phaser';
import { DragSelectPlugin } from '@pixelburp/phaser3-drag-select';
import { GameObjectEnginePlugin } from '@pixelburp/phaser3-game-object-engine';

import DemoScene from './scene/demo-scene';
import FogOfWarPlugin from '../js/phaser3-fog-of-war-plugin';
Expand All @@ -9,7 +11,11 @@ const config = {
height: 1000,
parent: 'mycanvas',
plugins: {
global: [{ key: 'FogOfWarPlugin', plugin: FogOfWarPlugin }],
global: [
{ key: 'DragSelectPlugin', plugin: DragSelectPlugin },
{ key: 'GameObjectEnginePlugin', plugin: GameObjectEnginePlugin },
{ key: 'FogOfWarPlugin', plugin: FogOfWarPlugin },
],
},
physics: {
default: 'arcade',
Expand Down
156 changes: 142 additions & 14 deletions packages/phaser3-fog-of-war/src/demo/scene/demo-scene.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,112 @@
import Phaser from 'phaser';
import { forEach } from '@pixelburp/phaser3-utils';

import DemoTileMap from '../tile-map';
import { forEach } from '@pixelburp/phaser3-utils';
import DemoSprite from '../sprite/demo-sprite';
import { DEBUG_PREVIEW_COLOR, DEBUG_SELECTION_COLOR, IMAGE_DEPTH } from '../../js/lib/constants';

const { KeyCodes } = Phaser.Input.Keyboard;

export default class DemoScene extends Phaser.Scene {
myControls;
mySprites = [];
otherSprites = [];
selectedSprites = [];
tileMap;

constructor() {
super({ key: 'DemoScene', active: true });
}

onPreview = ({ items }) => {
forEach(this.children.getChildren(), sprite => {
// Ignore if already selected...
if (sprite.tintTopLeft === DEBUG_SELECTION_COLOR) {
return;
}

// If one of the sprites under the selection, set tint
if (items.includes(sprite)) {
return sprite.setTint(DEBUG_PREVIEW_COLOR);
}

// Otherwise, clear it.
if (!!sprite.input) {
sprite.setTint(0xffffff);
}
});
};

onSelect = ({ items }) => {
this.children.getChildren().forEach(s => s.input && s.setTint(0xffffff));

items.forEach(sprite => sprite.setTint(DEBUG_SELECTION_COLOR));
this.selectedSprites = items;
};

onPointerUp = pointer => {
const { cameras, otherSprites } = this;

if (!this.selectedSprites.length || pointer.button !== 2) {
return;
}

const worldPoint = pointer.positionToCamera(cameras.main);
const targetSprite = otherSprites.find(dummySprite => Phaser.Geom.Rectangle.Contains(dummySprite.getBounds(), worldPoint.x, worldPoint.y));
const wayPoint = targetSprite ? targetSprite : worldPoint;

forEach(this.selectedSprites, sprite => {
sprite.pxlEngine.addWayPoint(wayPoint);
});
};

bindMouseEvents = () => {
this.input.on('pointerup', this.onPointerUp);
};

bindKeyEvents = () => {
const { input, plugins, scene } = this;
const { keyboard } = input;

keyboard.on('keydown-R', () => {
scene.stop('DemoScene');
plugins.stop('fogOfWarPlugin');
});
};

createAutoMovingSprites() {
let i = 0;
let sprite;

this.mySprites = [];
this.otherSprites = [];

for (i; i < 10; i+= 1) {
sprite = this.add.image(i * 100, 100, 'enabled-sprite');
for (i; i < 5; i += 1) {
sprite = this.add.image(i * 200, 100, 'enabled-sprite');
this.physics.world.enable([sprite]);
sprite.body.setVelocity(-50, 100).setBounce(1, 1).setCollideWorldBounds(true);
this.mySprites.push(sprite);
sprite.body
.setVelocity(-50, 100)
.setBounce(1, 1)
.setCollideWorldBounds(true);
this.otherSprites.push(sprite);
}
}

createMySprites() {
let sprite, y, worldX, worldY;
this.mySprites = [];
let x = 1;
const length = 2;
const OFFSET = 200;

for (x; x <= length; x += 1) {
y = 1;
for (y; y <= length; y += 1) {
// Every even numbered item will be set as "interactive"
worldX = x * 250 + OFFSET;
worldY = y * 250 + OFFSET;
sprite = new DemoSprite(this, worldX, worldY);
this.mySprites.push(sprite);
}
}
}

Expand All @@ -40,35 +126,77 @@ export default class DemoScene extends Phaser.Scene {
maxSpeed: 0.5,
};

this.cameras.main.setBounds(0, 0, 1920, 1080);
this.myControls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}

createAllPlugins() {
this.dragSelect = this.plugins.start('DragSelectPlugin', 'dragSelect');
this.dragSelect.setup(this, {
camera: this.cameras.main,
onPreview: this.onPreview,
onSelect: this.onSelect,
outlineColor: 0x00ff00,
outlineWidth: 2,
rectBgColor: 0x33ff00,
rectAlpha: 0.2,
});

this.fogOfWarPlugin = this.plugins.start('FogOfWarPlugin', 'fogOfWar');
this.fogOfWarPlugin.setup({
canClearFogSelector: this.canClearFogSelector,
fogBgColor: '#333',
fogBgOpacity: 0.8,
scene: this,
viewDistanceProp: 'viewDistance',
visibleGameObjectSelector: this.visibleGameObjectSelector,
visitedFogColor: '#333',
visitedFogOpacity: 0.5,
});

this.gameObjectEnginePlugin = this.plugins.start('GameObjectEnginePlugin', 'gameObjectEnginePlugin');
this.gameObjectEnginePlugin.setup(this, this.cameras.main);
}

canClearFogSelector = gameObject => {
return true;
return gameObject instanceof DemoSprite;
};

// Is this gameObject visible under the map?
visibleGameObjectSelector = gameObject => {};

preload() {
this.load.image('ground_1x1', 'src/assets/ground_1x1.png');
this.load.image('disabled-sprite', 'src/assets/disabled-sprite-50x50.png');
this.load.image('enabled-sprite', 'src/assets/enabled-sprite-50x50.png');
}

create() {
this.tileMap = new DemoTileMap(this);
// Plugins first
this.createAllPlugins();

this.tileMap = new DemoTileMap(this);
// Now the gameObjects
this.bindMouseEvents();
this.bindKeyEvents();
this.createAutoMovingSprites();
this.createMySprites();
this.createCamera();

this.plugin = this.plugins.start('FogOfWarPlugin', 'fogOfWar');
this.plugin.setup({
scene: this
});

this.fpsText = this.add.text(10, 10, '');
this.fpsText.setScrollFactor(0);
this.fpsText.setDepth(IMAGE_DEPTH + 1);
console.warn('scene', this);
}

update(time, delta) {
this.myControls.update(time, delta);
this.physics.world.collide(this.mySprites);
this.physics.world.collide(this.otherSprites);

this.gameObjectEnginePlugin.update(time, delta);

this.plugin.update(time, delta);
this.fogOfWarPlugin.update(time, delta);

this.fpsText.setText(`FPS: ${this.game.loop.actualFps.toFixed(3)}`);
}
Expand Down
23 changes: 23 additions & 0 deletions packages/phaser3-fog-of-war/src/demo/sprite/demo-sprite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Phaser from 'phaser';
import { v4 } from 'uuid';

const TEMP_SPEED = 250;

export default class DemoSprite extends Phaser.GameObjects.Sprite {
viewDistance = 200;

constructor(scene, x, y) {
super(scene, x, y, 'enabled-sprite');
this.id = v4();

scene.gameObjectEnginePlugin.addEngineToGameObject(this, {
rotateOnMove: false,
rotateSpeed: 10,
speed: TEMP_SPEED,
gameObjectStoppingDistance: 128,
});
scene.add.existing(this);
scene.physics.world.enable(this);
this.setInteractive();
}
}
5 changes: 5 additions & 0 deletions packages/phaser3-fog-of-war/src/js/lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const DEBUG_PREVIEW_COLOR = 0x00ff00;
export const DEBUG_SELECTION_COLOR = 0xff00ff;
export const IMAGE_DEPTH = 9999;
export const BYTE_LENGTH = 255;
export const VIEW_DISTANCE_BUFFER = 10;
Loading

0 comments on commit aa1a154

Please sign in to comment.