redraw textures and added new async task system
This commit is contained in:
parent
815422f8e4
commit
d1c3766c98
Binary file not shown.
Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 1.5 KiB |
@ -68,10 +68,11 @@ function setupInGameSelector() {
|
||||
// npccc.moveTo(new Point2D(getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getX(), getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getY()));
|
||||
let tile = getNavigationGridTile(t.x, t.y);
|
||||
if(tile.isObstacle) return;
|
||||
npccc.moveTo(new PointInt2D(tile.position.getX(), tile.position.getY()),
|
||||
(cb)=>{
|
||||
console.log(cb);
|
||||
});
|
||||
npccc.startTask(new PointInt2D(tile.position.getX(), tile.position.getY()));
|
||||
// npccc.moveTo(new PointInt2D(tile.position.getX(), tile.position.getY()),
|
||||
// (cb)=>{
|
||||
// console.log(cb);
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
|
447
src/Game/NPC/NPCBehavior/NPCBehavior.js
Normal file
447
src/Game/NPC/NPCBehavior/NPCBehavior.js
Normal file
@ -0,0 +1,447 @@
|
||||
import { PointInt2D } from "../../Utils/Math.utils";
|
||||
// import { findPathOnNavigationGridIfExists } from "../../World/NavigationGrid/NavigationGrid";
|
||||
import { NPCController } from "../NPCController/NPCController";
|
||||
// import { NPCProto } from "../NPCProto/NPCProto";
|
||||
|
||||
async function NPCJobFunctor(props, action) {
|
||||
return new NPCActionCallbackResult();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {NPCActionCallbackResult} lastActionResult
|
||||
*/
|
||||
function NPCActionCallback(lastActionResult) {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {NPCTaskCallbackResult} taskResult
|
||||
*/
|
||||
function NPCTaskCallback(taskResult) {}
|
||||
|
||||
export class NPCActionCallbackResult {
|
||||
/**
|
||||
* status of this action. -1 - error, 0 - waiting for execution, 1 - completed, 2 - can not be completed
|
||||
*/
|
||||
status = -1;
|
||||
statusText = "";
|
||||
/**
|
||||
* @type {NPCAction}
|
||||
*/
|
||||
action = undefined;
|
||||
|
||||
/**
|
||||
* statuses: -1 - error, 0 - waiting for execution, 1 - completed, 2 - can not be completed
|
||||
* @param {Number} status
|
||||
* @param {String} text
|
||||
* @param {NPCAction} action
|
||||
*/
|
||||
constructor(status, text = "", action = undefined) {
|
||||
this.status = status;
|
||||
this.statusText = text;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new NPCActionCallbackResult(this.status, this.statusText, this.action);
|
||||
}
|
||||
}
|
||||
|
||||
export class NPCTaskCallbackResult {
|
||||
/**
|
||||
* status of this task. -1 - error, 0 - completed, 1 - can not be completed, 2 - reset
|
||||
*/
|
||||
status = -1;
|
||||
statusText = "";
|
||||
/**
|
||||
* @type {NPCActionCallbackResult}
|
||||
*/
|
||||
lastActionCallbackResult;
|
||||
/**
|
||||
* @type {NPCTask}
|
||||
*/
|
||||
task = undefined;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} status
|
||||
* @param {String} statusText
|
||||
* @param {NPCActionCallbackResult} lastActionCallbackResult
|
||||
* @param {NPCTask} task
|
||||
*/
|
||||
constructor(status, statusText, lastActionCallbackResult, task) {
|
||||
this.status = status;
|
||||
this.statusText = statusText;
|
||||
this.lastActionCallbackResult = lastActionCallbackResult;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
clone()
|
||||
{
|
||||
return new NPCTaskCallbackResult(this.status, this.statusText, this.lastActionCallbackResult, this.task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NPC Action is the smallest part of NPC's behavior.
|
||||
* There are 2 types of actions:
|
||||
* 0: move to tile
|
||||
* 1: do something
|
||||
*/
|
||||
export class NPCAction {
|
||||
//invalid action type by default
|
||||
type = -1;
|
||||
//target position
|
||||
targetPosition = new PointInt2D();
|
||||
/**
|
||||
* target job function
|
||||
* @type {NPCJobFunctor}
|
||||
*/
|
||||
targetJob;
|
||||
/**
|
||||
* these props will passed to job function on it's execution
|
||||
*/
|
||||
targetJobProps;
|
||||
/**
|
||||
* status of this action. -1 - error, 0 - waiting for execution, 1 - completed, 2 - can not be completed
|
||||
*/
|
||||
status = -1;
|
||||
/**
|
||||
* @type {NPCProto}
|
||||
*/
|
||||
owner = null;
|
||||
/**
|
||||
* will this task block chain of execution
|
||||
*/
|
||||
skipToNextIgnoringStatus = false;
|
||||
|
||||
usePause = false;
|
||||
pauseTime = 0;
|
||||
|
||||
/**
|
||||
* NPC Action is the smallest part of NPC's behavior.
|
||||
* There are 2 types of actions:
|
||||
* 0: move to tile
|
||||
* 1: do something
|
||||
* @param {Number} type
|
||||
* @param {PointInt2D} pos
|
||||
* @param {NPCJobFunctor} job
|
||||
* @param {any} jobProps
|
||||
* @param {NPCController} owner
|
||||
* @param {Boolean} skipToNext
|
||||
* @param {Boolean} usePause
|
||||
* @param {Number} pauseTime
|
||||
*/
|
||||
constructor(type, pos, job, jobProps = {}, owner = null, skipToNext = false, usePause = false, pauseTime = 0) {
|
||||
this.type = type;
|
||||
this.targetPosition = pos;
|
||||
this.targetJob = job;
|
||||
this.targetJobProps = jobProps;
|
||||
this.status = 0;
|
||||
this.owner = owner;
|
||||
this.skipToNextIgnoringStatus = skipToNext;
|
||||
this.usePause = usePause;
|
||||
this.pauseTime = pauseTime;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NPC Task is a container with NPC Actions. It is like a timeline with frames (frames are NPC Actions)
|
||||
*/
|
||||
export class NPCTask {
|
||||
/**
|
||||
* @type {Array<NPCAction>}
|
||||
*/
|
||||
actionsContainer = [];
|
||||
_currentIndex = 0;
|
||||
_startIndex = 0;
|
||||
/**
|
||||
* @type {NPCController}
|
||||
*/
|
||||
owner = null;
|
||||
//is task active and will execute actions
|
||||
active = false;
|
||||
//will task start again after completion
|
||||
loop = false;
|
||||
onPause = false;
|
||||
|
||||
_lastActionCompleted = false;
|
||||
/**
|
||||
* @type {NPCActionCallbackResult}
|
||||
*/
|
||||
_lastActionCallbackResult;
|
||||
|
||||
/**
|
||||
* @type {NPCActionCallback}
|
||||
*/
|
||||
actionCallback;
|
||||
/**
|
||||
* @type {NPCTaskCallback}
|
||||
*/
|
||||
taskCallback;
|
||||
|
||||
_pauseTimeout;
|
||||
|
||||
/**
|
||||
* @param {Array<NPCAction>} actions
|
||||
* @param {NPCController} owner
|
||||
* @param {boolean} loop
|
||||
* @param {NPCActionCallback} actionCallback
|
||||
* @param {NPCTaskCallback} taskCallback
|
||||
*/
|
||||
constructor(actions, owner = null, loop = false, actionCallback = undefined, taskCallback = undefined) {
|
||||
this.actionsContainer = actions;
|
||||
this.owner = owner;
|
||||
this.loop = loop;
|
||||
this.actionCallback = actionCallback;
|
||||
this.taskCallback = taskCallback;
|
||||
}
|
||||
|
||||
startTask() {
|
||||
if (!this.owner || this._lastActionCompleted) return false;
|
||||
this._currentIndex = this._startIndex;
|
||||
this.active = true;
|
||||
return this._pushNewAction();
|
||||
}
|
||||
|
||||
resetTask() {
|
||||
this.active = false;
|
||||
this.onPause = false;
|
||||
this._resetAllActions();
|
||||
this._currentIndex = this._startIndex;
|
||||
clearTimeout(this._pauseTimeout);
|
||||
this.taskCallback(new NPCTaskCallbackResult(2, "reset", this._lastActionCallbackResult.clone(), this));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* set owner for all actions and this task
|
||||
* @param {NPCController} owner
|
||||
*/
|
||||
setOwnerToAll(owner) {
|
||||
this.owner = owner;
|
||||
for (const action of this.actionsContainer) {
|
||||
action.owner = owner;
|
||||
}
|
||||
}
|
||||
|
||||
handleTaskTick(ticker) {
|
||||
if (!this.active || this.onPause) return;
|
||||
if (this._lastActionCompleted) {
|
||||
this._lastActionCompleted = false;
|
||||
this.actionCallback(this._lastActionCallbackResult.clone());
|
||||
if (!this.active) return;
|
||||
if (!this.actionsContainer[this._currentIndex].skipToNextIgnoringStatus) {
|
||||
if (this._lastActionCallbackResult.status !== 1) {
|
||||
this.taskCallback(new NPCTaskCallbackResult(1, "chain blocked by action status", this._lastActionCallbackResult.clone(), this));
|
||||
this.resetTask();
|
||||
return;
|
||||
}
|
||||
}
|
||||
//pay attention in timeout logic
|
||||
if (this.actionsContainer[this._currentIndex].usePause) {
|
||||
this.onPause = true;
|
||||
clearTimeout(this._pauseTimeout);
|
||||
let thisCopy = this;
|
||||
this._pauseTimeout = setTimeout(() => {
|
||||
thisCopy.onPause = false;
|
||||
thisCopy._currentIndex++;
|
||||
if (thisCopy._currentIndex >= thisCopy.actionsContainer.length) {
|
||||
if (thisCopy.loop) {
|
||||
thisCopy._currentIndex = thisCopy._startIndex;
|
||||
thisCopy._resetAllActions();
|
||||
thisCopy._pushNewAction();
|
||||
} else thisCopy.active = false;
|
||||
} else {
|
||||
thisCopy._pushNewAction();
|
||||
}
|
||||
}, this.actionsContainer[this._currentIndex].pauseTime);
|
||||
return;
|
||||
}
|
||||
//
|
||||
this._currentIndex++;
|
||||
if (this._currentIndex >= this.actionsContainer.length) {
|
||||
if (this.loop) {
|
||||
this._currentIndex = this._startIndex;
|
||||
this._resetAllActions();
|
||||
this._pushNewAction();
|
||||
} else {
|
||||
this.active = false;
|
||||
this.taskCallback(new NPCTaskCallbackResult(0, "finished", this._lastActionCallbackResult.clone(), this));
|
||||
}
|
||||
} else {
|
||||
this._pushNewAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_pushNewAction() {
|
||||
switch (this.actionsContainer[this._currentIndex].type) {
|
||||
case 0:
|
||||
this.owner.moveTo(this.actionsContainer[this._currentIndex].targetPosition, (r) => {
|
||||
this._handleMovementResult(r);
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
this.actionsContainer[this._currentIndex].targetJob(this.actionsContainer[this._currentIndex].targetJobProps, this.actionsContainer[this._currentIndex]).then((r) => {
|
||||
this._handleJobResult(r);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_resetAllActions() {
|
||||
for (const action of this.actionsContainer) {
|
||||
action.status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NPCActionCallbackResult} resultFromMoving
|
||||
*/
|
||||
_handleMovementResult(resultFromMoving) {
|
||||
this.actionsContainer[this._currentIndex].status = resultFromMoving === 0 ? 1 : resultFromMoving === -1 ? -1 : 2;
|
||||
this._lastActionCompleted = true;
|
||||
this._lastActionCallbackResult = new NPCActionCallbackResult(resultFromMoving === 0 ? 1 : resultFromMoving === -1 ? -1 : 2, "", this.actionsContainer[this._currentIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NPCActionCallbackResult} resultFromJob
|
||||
*/
|
||||
_handleJobResult(resultFromJob) {
|
||||
this._lastActionCallbackResult = resultFromJob;
|
||||
this._lastActionCompleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NPCTask} task
|
||||
*/
|
||||
function TaskChanger(task) {}
|
||||
|
||||
export class NPCBehaviorCallbackResult {
|
||||
/**
|
||||
* 0 - action callback
|
||||
* 1 - task callback
|
||||
* @type {Number}
|
||||
*/
|
||||
type;
|
||||
/**
|
||||
* status of the callback (see more in taskCallback or actionCallback)
|
||||
* @type {Number}
|
||||
*/
|
||||
status;
|
||||
/**
|
||||
* @type {String}
|
||||
*/
|
||||
statusText;
|
||||
/**
|
||||
* @type {NPCTaskCallbackResult}
|
||||
*/
|
||||
taskCallbackResult;
|
||||
/**
|
||||
* @type {NPCActionCallbackResult}
|
||||
*/
|
||||
actionCallbackResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} type
|
||||
* @param {Number} status
|
||||
* @param {String} statusText
|
||||
* @param {NPCTaskCallbackResult} taskCallbackResult
|
||||
* @param {NPCActionCallbackResult} actionCallbackResult
|
||||
*/
|
||||
constructor(type, status, statusText, taskCallbackResult, actionCallbackResult) {
|
||||
this.type = type;
|
||||
this.status = status;
|
||||
this.statusText = statusText;
|
||||
this.taskCallbackResult = taskCallbackResult;
|
||||
this.actionCallbackResult = actionCallbackResult;
|
||||
}
|
||||
}
|
||||
|
||||
export class NPCBehavior {
|
||||
/**
|
||||
* @type {Map<String, NPCTask>}
|
||||
*/
|
||||
taskMap = new Map();
|
||||
owner = undefined;
|
||||
isTaskInProgress = false;
|
||||
currentTask = "";
|
||||
behaviorCallback = undefined;
|
||||
|
||||
/**
|
||||
* @param {NPCController} owner
|
||||
*/
|
||||
constructor(owner, behaviorCallback) {
|
||||
this.owner = owner;
|
||||
this.behaviorCallback = behaviorCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} key
|
||||
* @param {NPCTask} task
|
||||
*/
|
||||
addTask(key, task) {
|
||||
task.setOwnerToAll(this.owner);
|
||||
task.actionCallback = this._handleActionCallback.bind(this);
|
||||
task.taskCallback = this._handleTaskCallback.bind(this);
|
||||
this.taskMap.set(key, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} key
|
||||
*/
|
||||
startTask(key) {
|
||||
if (this.isTaskInProgress) return false;
|
||||
if (this.taskMap.get(key).startTask()) {
|
||||
this.currentTask = key;
|
||||
this.isTaskInProgress = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
abortCurrentTask() {
|
||||
if (this.taskMap.get(this.currentTask)?.resetTask()) {
|
||||
this.isTaskInProgress = false;
|
||||
this.currentTask = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {TaskChanger} changer
|
||||
*/
|
||||
changeTask(key, changer) {
|
||||
changer(this.taskMap.get(key));
|
||||
}
|
||||
|
||||
handleNPCBehaviorTick(ticker) {
|
||||
this.taskMap.get(this.currentTask)?.handleTaskTick(ticker);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {NPCTaskCallbackResult} result
|
||||
*/
|
||||
_handleTaskCallback(result) {
|
||||
this.isTaskInProgress = false;
|
||||
this.behaviorCallback(new NPCBehaviorCallbackResult(1, result.status, result.statusText, result.clone(), undefined));
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {NPCActionCallbackResult} result
|
||||
*/
|
||||
_handleActionCallback(result) {
|
||||
this.behaviorCallback(new NPCBehaviorCallbackResult(0, result.status, result.statusText, undefined, result.clone()));
|
||||
console.log(result);
|
||||
}
|
||||
}
|
@ -2,12 +2,19 @@ import { GameObject } from "../../GameObject/GameObject";
|
||||
import { PointInt2D } from "../../Utils/Math.utils";
|
||||
import { NavigationPath, PathFinder } from "../../Utils/PathFinding.utils";
|
||||
import { findPathOnNavigationGridIfExists } from "../../World/NavigationGrid/NavigationGrid";
|
||||
import { NPCAction, NPCActionCallbackResult, NPCBehavior, NPCTask } from "../NPCBehavior/NPCBehavior";
|
||||
import { NPCProto } from "../NPCProto/NPCProto";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} result
|
||||
*/
|
||||
function NavigationCallbackFunctor(result) {}
|
||||
|
||||
/**
|
||||
* NPCController defines NPC behavior. Many NPC can have same NPCController for the same behavior.
|
||||
*/
|
||||
export class NPCController extends GameObject
|
||||
{
|
||||
export class NPCController extends GameObject {
|
||||
/**
|
||||
* NPC controlled by this controller
|
||||
* @type NPCProto
|
||||
@ -20,39 +27,65 @@ export class NPCController extends GameObject
|
||||
navigationPathQueue = new Array();
|
||||
navigationInProgress = false;
|
||||
navigationFollowMidPoint = false;
|
||||
navigationCallback = ()=>{};
|
||||
navigationCallback = () => {};
|
||||
|
||||
constructor(tickAble = true)
|
||||
{
|
||||
taskInstanceRef = new NPCTask(
|
||||
[
|
||||
new NPCAction(0, new PointInt2D(0, 0), undefined, undefined, undefined, false, true, 1000),
|
||||
new NPCAction(
|
||||
1,
|
||||
undefined,
|
||||
async (myOwner, action) => {
|
||||
console.log(myOwner);
|
||||
return new NPCActionCallbackResult(1, "", action);
|
||||
},
|
||||
"Привет!",
|
||||
undefined,
|
||||
false,
|
||||
false,
|
||||
0
|
||||
),
|
||||
],
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
|
||||
behavior = new NPCBehavior(this, () => {});
|
||||
|
||||
constructor(tickAble = true) {
|
||||
super(tickAble);
|
||||
this.behavior.addTask("MoveToCursor", this.taskInstanceRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* moves NPC to position
|
||||
* moves NPC to position. callback contains result status: -1 - error happened; 0 - success; 1 - unreachable
|
||||
* @param {PointInt2D} position
|
||||
* @param {Function} callback
|
||||
* @param {NavigationCallbackFunctor} callback
|
||||
*/
|
||||
moveTo(position, callback)
|
||||
{
|
||||
moveTo(position, callback) {
|
||||
// let pf = new PathFinder();
|
||||
// let nPath = pf.findPathIfExist(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
||||
let nPath = findPathOnNavigationGridIfExists(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position);
|
||||
nPath.then((r)=>{
|
||||
if(r.error)
|
||||
{
|
||||
callback("failed");
|
||||
let nPath = findPathOnNavigationGridIfExists(
|
||||
new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()),
|
||||
position
|
||||
);
|
||||
nPath.then((r) => {
|
||||
if (r.error) {
|
||||
this.controlledNPC.isMoving = false;
|
||||
callback(-1); //error
|
||||
return;
|
||||
} else if (r.state === 0) {
|
||||
this.controlledNPC.isMoving = false;
|
||||
callback(1); //unreachable
|
||||
return;
|
||||
}
|
||||
else if (r.result.path.length < 2)
|
||||
{
|
||||
callback("success");
|
||||
return;
|
||||
}
|
||||
for (let i = r.result.path.length-1; i > 0; i--) {
|
||||
this.navigationPathQueue = [];
|
||||
for (let i = r.result.path.length - 1; i > 0; i--) {
|
||||
this.navigationPathQueue.push(r.result.path[i]);
|
||||
}
|
||||
this.navigationCallback = callback;
|
||||
this.navigationInProgress = true;
|
||||
this.controlledNPC.isMoving = true;
|
||||
});
|
||||
// console.log("boba");
|
||||
// console.log(nPath);
|
||||
@ -60,42 +93,37 @@ export class NPCController extends GameObject
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {NavigationPath} pathToFollow
|
||||
* @param {Function} callback
|
||||
* @param {PointInt2D} pos
|
||||
*/
|
||||
_moveByPath(pathToFollow, callback)
|
||||
{
|
||||
|
||||
startTask(pos) {
|
||||
this.behavior.abortCurrentTask();
|
||||
this.behavior.changeTask("MoveToCursor", (task)=>{
|
||||
task.actionsContainer[0].targetPosition = pos;
|
||||
});
|
||||
this.behavior.startTask("MoveToCursor");
|
||||
}
|
||||
|
||||
tick(ticker)
|
||||
{
|
||||
if(this.navigationInProgress)
|
||||
{
|
||||
if(!this.navigationFollowMidPoint)
|
||||
{
|
||||
tick(ticker) {
|
||||
this.taskInstanceRef.handleTaskTick(ticker);
|
||||
if (this.navigationInProgress) {
|
||||
if (!this.navigationFollowMidPoint) {
|
||||
let target = this.navigationPathQueue.pop();
|
||||
if(!target)
|
||||
{
|
||||
if (!target) {
|
||||
this.navigationInProgress = false;
|
||||
this.navigationCallback("success");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.controlledNPC.isMoving = false;
|
||||
this.navigationCallback(0); //success
|
||||
} else {
|
||||
this.controlledNPC.worldPosition = target;
|
||||
this.navigationFollowMidPoint = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(
|
||||
} else {
|
||||
if (
|
||||
Math.abs(this.controlledNPC.drawObject.x - this.controlledNPC.worldPosition.getX()) < 0.5 &&
|
||||
Math.abs(this.controlledNPC.drawObject.y - this.controlledNPC.worldPosition.getY()) < 0.5
|
||||
)
|
||||
{
|
||||
) {
|
||||
this.navigationFollowMidPoint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { Rectangle } from "../../../pixi/pixi.mjs";
|
||||
import { SceneObject } from "../../SceneObjects/SceneObject";
|
||||
import { Point2D, interpolate } from "../../Utils/Math.utils";
|
||||
import { getSpriteFromAtlas } from "../../Utils/Sprites.utils";
|
||||
import { getNavigationGridTile } from "../../World/NavigationGrid/NavigationGrid";
|
||||
import { NPCController } from "../NPCController/NPCController";
|
||||
|
||||
export class NPCProto extends SceneObject
|
||||
@ -13,6 +14,7 @@ export class NPCProto extends SceneObject
|
||||
controller = null;
|
||||
|
||||
_positionInterpolationSpeed = 30;
|
||||
_basicPositionInterpolationSpeed = 30;
|
||||
|
||||
/**
|
||||
* path to NPC spritesheet
|
||||
@ -24,6 +26,8 @@ export class NPCProto extends SceneObject
|
||||
*/
|
||||
frame = new Rectangle();
|
||||
|
||||
isMoving = false;
|
||||
|
||||
/**
|
||||
* creates new NPC object
|
||||
* @param {Boolean} tickAble
|
||||
@ -43,7 +47,15 @@ export class NPCProto extends SceneObject
|
||||
|
||||
tick(ticker)
|
||||
{
|
||||
if(this.isMoving)
|
||||
{
|
||||
let gridTile = getNavigationGridTile(this.worldPosition.getX(), this.worldPosition.getY());
|
||||
if(gridTile && !gridTile.isObstacle)
|
||||
{
|
||||
this._positionInterpolationSpeed = this._basicPositionInterpolationSpeed / gridTile.movementCost;
|
||||
}
|
||||
this._positionInterpolation(ticker.deltaMS / 1000 * this._positionInterpolationSpeed);
|
||||
}
|
||||
};
|
||||
|
||||
_positionInterpolation(delta)
|
||||
|
@ -45,22 +45,22 @@ export class NavigationPath {
|
||||
|
||||
export class NavigationResult {
|
||||
/**
|
||||
* @type Boolean
|
||||
* @type {Boolean}
|
||||
*/
|
||||
error;
|
||||
/**
|
||||
* @type String
|
||||
* @type {String}
|
||||
*/
|
||||
errorText;
|
||||
/**
|
||||
* @type NavigationPath | undefined
|
||||
* @type {NavigationPath | undefined}
|
||||
*/
|
||||
result;
|
||||
/**
|
||||
* 0 - point is unreachable
|
||||
* 1 - path found
|
||||
* 2 - error
|
||||
* @type Int
|
||||
* @type {Number}
|
||||
*/
|
||||
state;
|
||||
|
||||
@ -194,14 +194,14 @@ export class PathFinder {
|
||||
*/
|
||||
_reconstructPath(cameFrom, current) {
|
||||
let totalPath = [current.position];
|
||||
console.log(cameFrom);
|
||||
// console.log(cameFrom);
|
||||
let keys = [...cameFrom.keys()];
|
||||
while (keys.includes(current.id)) {
|
||||
if (current.id === cameFrom.get(current.id).id) break;
|
||||
current = cameFrom.get(current.id);
|
||||
totalPath.push(current.position);
|
||||
}
|
||||
return totalPath.reverse();
|
||||
return totalPath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@ import { RGBColor, RGBCue } from "../Utils/DataTypes.utils";
|
||||
let timeElapsed = PRNG() * 37992648739;
|
||||
|
||||
// ex: scaling = 10; 1 game minute = 6 real seconds;
|
||||
let timeScaling = 300.0;
|
||||
let timeScaling = 100.0;
|
||||
|
||||
const gameSecondsInGameMinute = 60;
|
||||
const gameMinutesInGameHour = 60;
|
||||
@ -14,7 +14,7 @@ const gameDaysInGameWeek = 7;
|
||||
const gameWeeksInGameMonth = 4;
|
||||
const gameMonthsInGameYear = 12;
|
||||
|
||||
let dayColor = new RGBColor(255, 255, 255);
|
||||
// let dayColor = new RGBColor(255, 255, 255);
|
||||
let currentColor = new RGBColor(0, 0, 0);
|
||||
|
||||
let dayColorsCue = new RGBCue(
|
||||
|
@ -131,7 +131,7 @@ async function _findPathAsync(start, goal)
|
||||
export async function findPathOnNavigationGridIfExists(start, goal) {
|
||||
let r0 = await _findPathAsync(goal, start);
|
||||
if(!r0.error){
|
||||
r0.result.path.reverse();
|
||||
// r0.result.path.reverse();
|
||||
return r0;
|
||||
}
|
||||
let r1 = await _findPathAsync(start, goal);
|
||||
|
@ -17,10 +17,10 @@ const WorldChunksStorage = new Map();
|
||||
|
||||
/* #### REWRITE PART START ####*/
|
||||
const terrainSpriteList = {
|
||||
0: { x: 21, y: 21 }, //water
|
||||
1: { x: 2, y: 21 }, //sand
|
||||
0: { x: 20, y: 20 }, //water
|
||||
1: { x: 2, y: 20 }, //sand
|
||||
2: { x: 2, y: 2 }, //grass
|
||||
3: { x: 21, y: 2 }, //stone
|
||||
3: { x: 20, y: 2 }, //stone
|
||||
};
|
||||
const terrainTypeList = {
|
||||
0: "ter_water", //water
|
||||
@ -30,9 +30,9 @@ const terrainTypeList = {
|
||||
};
|
||||
const terrainNavigationCostList = {
|
||||
0: 100000000000, //water
|
||||
1: 3, //sand
|
||||
2: 2, //grass
|
||||
3: 1, //stone
|
||||
1: 1.7, //sand
|
||||
2: 1, //grass
|
||||
3: 1.5, //stone
|
||||
};
|
||||
const grassVegetationSpriteList = {
|
||||
0: { x: 10, y: 11 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user