Skip to content

Commit

Permalink
Added mobile controls to build
Browse files Browse the repository at this point in the history
  • Loading branch information
neki-dev committed Oct 3, 2023
1 parent a2df2ec commit e22f8ea
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 53 deletions.
Binary file added src/assets/sprites/building/icons/confirm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/sprites/building/icons/decline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/sprites/building/icons/placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/const/world/world.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const WORLD_COLLIDE_SPEED_FACTOR = 0.002;

export const WORLD_DEPTH_DEBUG = 9999;
export const WORLD_DEPTH_GRAPHIC = 9999;

export const WORLD_DEPTH_EFFECT = 9998;
153 changes: 105 additions & 48 deletions src/game/scenes/world/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import EventEmitter from 'events';

import Phaser from 'phaser';

import { WORLD_DEPTH_EFFECT } from '~const/world';
import { WORLD_DEPTH_GRAPHIC } from '~const/world';
import { DIFFICULTY } from '~const/world/difficulty';
import { BUILDINGS } from '~const/world/entities/buildings';
import { LEVEL_TILE_SIZE } from '~const/world/level';
Expand Down Expand Up @@ -32,9 +32,11 @@ export class Builder extends EventEmitter implements IBuilder {

private buildArea: Nullable<Phaser.GameObjects.Ellipse> = null;

private buildingPreview: Nullable<Phaser.GameObjects.Image> = null;
private buildPreview: Nullable<Phaser.GameObjects.Image> = null;

private buildingPlaceholder: Nullable<Phaser.GameObjects.Image> = null;
private buildPlaceholder: Nullable<Phaser.GameObjects.Image> = null;

private buildControls: Nullable<Phaser.GameObjects.Container> = null;

private buildings: Partial<Record<BuildingVariant, IBuilding[]>> = {};

Expand Down Expand Up @@ -72,9 +74,9 @@ export class Builder extends EventEmitter implements IBuilder {
public update() {
if (this.isCanBuild()) {
if (this.isBuild) {
this.updateAssumedPosition();
this.updateSupposedPosition();
this.updateBuildAreaPosition();
this.updateBuildingPreview();
this.updateBuildInstance();
} else {
this.open();
}
Expand Down Expand Up @@ -106,8 +108,8 @@ export class Builder extends EventEmitter implements IBuilder {

this.variant = variant;

if (this.buildingPreview) {
this.buildingPreview.setTexture(BuildingInstance.Texture);
if (this.buildPreview) {
this.buildPreview.setTexture(BuildingInstance.Texture);
}
}

Expand Down Expand Up @@ -217,11 +219,18 @@ export class Builder extends EventEmitter implements IBuilder {
return;
}

this.createBuildArea();
this.createBuildingPreview();

this.isBuild = true;

if (!this.scene.game.device.os.desktop) {
this.supposedPosition = this.scene.level.getFreeAdjacentTile({
...this.scene.player.positionAtMatrix,
z: 1,
}) ?? this.scene.player.positionAtMatrix;
}

this.createBuildArea();
this.createBuildInstance();

this.emit(BuilderEvents.BUILD_START);
}

Expand All @@ -230,7 +239,7 @@ export class Builder extends EventEmitter implements IBuilder {
return;
}

this.destroyBuildingPreview();
this.destroyBuildInstance();
this.destroyBuildArea();

this.isBuild = false;
Expand Down Expand Up @@ -341,7 +350,14 @@ export class Builder extends EventEmitter implements IBuilder {
this.scene.sound.play(BuildingAudio.BUILD);

if (!this.scene.game.device.os.desktop) {
this.unsetBuildingVariant(true);
const adjacentPosition = this.scene.level.getFreeAdjacentTile({
...this.supposedPosition,
z: 1,
});

if (adjacentPosition) {
this.supposedPosition = adjacentPosition;
}
}
}

Expand Down Expand Up @@ -410,7 +426,7 @@ export class Builder extends EventEmitter implements IBuilder {
this.radius * 2 * LEVEL_TILE_SIZE.persperctive,
);
this.buildArea.updateDisplayOrigin();
this.buildArea.setDepth(WORLD_DEPTH_EFFECT);
this.buildArea.setDepth(WORLD_DEPTH_GRAPHIC);
}

private updateBuildAreaPosition() {
Expand All @@ -432,24 +448,54 @@ export class Builder extends EventEmitter implements IBuilder {
this.buildArea = null;
}

private createBuildingPreview() {
private createBuildPreview() {
if (!this.variant) {
return;
}

const BuildingInstance = BUILDINGS[this.variant];

this.buildingPreview = this.scene.add.image(0, 0, BuildingInstance.Texture);
this.buildingPreview.setOrigin(0.5, LEVEL_TILE_SIZE.origin);
this.buildPreview = this.scene.add.image(0, 0, BuildingInstance.Texture);
this.buildPreview.setOrigin(0.5, LEVEL_TILE_SIZE.origin);
}

private createBuildPlaceholder() {
this.buildPlaceholder = this.scene.add.image(0, 0, BuildingIcon.PLACEHOLDER);
}

private createBuildControls() {
this.buildControls = this.scene.add.container(0, 0);

const confirm = this.scene.add.image(-16, 0, BuildingIcon.CONFIRM);

confirm.setInteractive();
confirm.on(Phaser.Input.Events.POINTER_DOWN, (pointer: Phaser.Input.Pointer) => {
pointer.reset();
this.build();
});

const decline = this.scene.add.image(16, 0, BuildingIcon.DECLINE);

decline.setInteractive();
decline.on(Phaser.Input.Events.POINTER_DOWN, () => {
this.unsetBuildingVariant();
});

this.buildControls.add([confirm, decline]);
}

private createBuildInstance() {
this.createBuildPreview();
this.createBuildPlaceholder();

if (!this.scene.game.device.os.desktop) {
this.buildingPlaceholder = this.scene.add.image(0, 0, BuildingIcon.PLACEHOLDER);
this.createBuildControls();
}

this.updateBuildingPreview();
this.updateBuildInstance();
}

private updateBuildingPreview() {
private updateBuildInstance() {
if (!this.supposedPosition) {
return;
}
Expand All @@ -459,28 +505,41 @@ export class Builder extends EventEmitter implements IBuilder {
const depth = Level.GetTileDepth(positionAtWorld.y, tilePosition.z) + 1;
const isAllow = this.isAllowBuild();

if (this.buildingPreview) {
this.buildingPreview.setPosition(positionAtWorld.x, positionAtWorld.y);
this.buildingPreview.setDepth(depth);
this.buildingPreview.setAlpha(isAllow ? 1.0 : 0.25);
if (this.buildPreview) {
this.buildPreview.setPosition(positionAtWorld.x, positionAtWorld.y);
this.buildPreview.setDepth(depth);
this.buildPreview.setAlpha(isAllow ? 1.0 : 0.25);
}

if (this.buildPlaceholder) {
this.buildPlaceholder.setPosition(positionAtWorld.x, positionAtWorld.y + LEVEL_TILE_SIZE.height * 0.5);
this.buildPlaceholder.setDepth(depth);
this.buildPlaceholder.setAlpha(isAllow ? 0.75 : 0.25);
}

if (this.buildingPlaceholder) {
this.buildingPlaceholder.setPosition(positionAtWorld.x, positionAtWorld.y + LEVEL_TILE_SIZE.height * 0.5);
this.buildingPlaceholder.setDepth(depth);
this.buildingPlaceholder.setAlpha(isAllow ? 0.75 : 0.25);
if (this.buildControls) {
const confirmBtton = <Phaser.GameObjects.Image> this.buildControls.getAt(0);

this.buildControls.setPosition(positionAtWorld.x, positionAtWorld.y + LEVEL_TILE_SIZE.height);
this.buildControls.setDepth(WORLD_DEPTH_GRAPHIC);
confirmBtton.setTexture(isAllow ? BuildingIcon.CONFIRM : BuildingIcon.CONFIRM_DISABLED);
}
}

private destroyBuildingPreview() {
if (this.buildingPreview) {
this.buildingPreview.destroy();
this.buildingPreview = null;
private destroyBuildInstance() {
if (this.buildPreview) {
this.buildPreview.destroy();
this.buildPreview = null;
}

if (this.buildingPlaceholder) {
this.buildingPlaceholder.destroy();
this.buildingPlaceholder = null;
if (this.buildPlaceholder) {
this.buildPlaceholder.destroy();
this.buildPlaceholder = null;
}

if (this.buildControls) {
this.buildControls.destroy();
this.buildControls = null;
}
}

Expand All @@ -492,7 +551,7 @@ export class Builder extends EventEmitter implements IBuilder {
: this.scene.input.pointer1;
}

private updateAssumedPosition() {
private updateSupposedPosition() {
let position: Vector2D;

if (this.scene.game.device.os.desktop) {
Expand All @@ -503,17 +562,15 @@ export class Builder extends EventEmitter implements IBuilder {
} else {
const pointer = this.getCurrentPointer();

if (!pointer.active) {
if (!pointer.active || pointer.event.target !== this.scene.sys.canvas) {
return;
}

// Using instead of pointer.worldXY
// for get actual position in camera moving state
const worldPosition = this.scene.cameras.main.getWorldPoint(pointer.x, pointer.y);
pointer.updateWorldPoint(this.scene.cameras.main);

position = {
x: worldPosition.x,
y: worldPosition.y - LEVEL_TILE_SIZE.height / this.scene.cameras.main.zoom,
x: pointer.worldX,
y: pointer.worldY - LEVEL_TILE_SIZE.height / this.scene.cameras.main.zoom,
};
}

Expand All @@ -529,19 +586,19 @@ export class Builder extends EventEmitter implements IBuilder {
}

private handlePointer() {
if (!this.scene.game.device.os.desktop) {
return;
}

this.scene.input.on(Phaser.Input.Events.POINTER_UP, (pointer: Phaser.Input.Pointer) => {
if (!this.isBuild) {
return;
}

if (this.scene.game.device.os.desktop) {
if (pointer.button === 0) {
this.build();
} else if (pointer.button === 2) {
this.unsetBuildingVariant();
}
} else if (pointer === this.getCurrentPointer()) {
if (pointer.button === 0) {
this.build();
} else if (pointer.button === 2) {
this.unsetBuildingVariant();
}
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/scenes/world/entities/npc/npc.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Phaser from 'phaser';

import { DEBUG_MODS } from '~const/game';
import { WORLD_DEPTH_DEBUG } from '~const/world';
import { WORLD_DEPTH_GRAPHIC } from '~const/world';
import { NPC_PATH_FIND_RATE } from '~const/world/entities/npc';
import { Sprite } from '~entity/sprite';
import { equalPositions } from '~lib/utils';
Expand Down Expand Up @@ -265,7 +265,7 @@ export class NPC extends Sprite implements INPC {
}

this.pathDebug = this.scene.add.graphics();
this.pathDebug.setDepth(WORLD_DEPTH_DEBUG);
this.pathDebug.setDepth(WORLD_DEPTH_GRAPHIC);

this.on(Phaser.GameObjects.Events.DESTROY, () => {
this.pathDebug?.destroy();
Expand Down
4 changes: 2 additions & 2 deletions src/game/scenes/world/entities/sprite.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Phaser from 'phaser';

import { DEBUG_MODS } from '~const/game';
import { WORLD_COLLIDE_SPEED_FACTOR, WORLD_DEPTH_DEBUG } from '~const/world';
import { WORLD_COLLIDE_SPEED_FACTOR, WORLD_DEPTH_GRAPHIC } from '~const/world';
import { Live } from '~lib/live';
import { equalPositions } from '~lib/utils';
import { Particles } from '~scene/world/effects';
Expand Down Expand Up @@ -260,7 +260,7 @@ export class Sprite extends Phaser.Physics.Arcade.Sprite implements ISprite {
}

this.positionDebug = this.scene.add.graphics();
this.positionDebug.setDepth(WORLD_DEPTH_DEBUG);
this.positionDebug.setDepth(WORLD_DEPTH_GRAPHIC);

this.on(Phaser.GameObjects.Events.DESTROY, () => {
this.positionDebug?.destroy();
Expand Down
18 changes: 18 additions & 0 deletions src/game/scenes/world/level/level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ export class Level extends TileMatrix implements ILevel {
return LEVEL_PLANETS[this.planet].BIOMES.find((biome) => (biome.data.type === type))?.data ?? null;
}

public getFreeAdjacentTile(position: Vector3D) {
const positions: Vector2D[] = [
{ x: position.x + 1, y: position.y },
{ x: position.x, y: position.y + 1 },
{ x: position.x - 1, y: position.y },
{ x: position.x, y: position.y - 1 },
{ x: position.x + 1, y: position.y - 1 },
{ x: position.x + 1, y: position.y + 1 },
{ x: position.x - 1, y: position.y + 1 },
{ x: position.x - 1, y: position.y - 1 },
];

return positions.find((p) => this.isFreePoint({
...p,
z: position.z,
})) ?? null;
}

private addTilemap() {
const data = new Phaser.Tilemaps.MapData({
width: LEVEL_MAP_SIZE,
Expand Down
3 changes: 3 additions & 0 deletions src/types/world/entities/building.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ export enum BuildingTexture {
}

export enum BuildingIcon {
CONFIRM = 'building/icons/confirm',
CONFIRM_DISABLED = 'building/icons/confirm_disabled',
DECLINE = 'building/icons/decline',
ALERT = 'building/icons/alert',
PLACEHOLDER = 'building/icons/placeholder',
UPGRADE = 'building/icons/upgrade',
Expand Down
6 changes: 6 additions & 0 deletions src/types/world/level/level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export interface ILevel extends ITileMatrix {
*/
getBiome(type: BiomeType): Nullable<LevelBiome>

/**
* Get free adjacent tile around source position.
* @param position - Source position
*/
getFreeAdjacentTile(position: Vector3D): Nullable<Vector2D>

/**
* Get data for saving.
*/
Expand Down

0 comments on commit e22f8ea

Please sign in to comment.