mirror of
https://github.com/wassname/metacar.git
synced 2026-09-17 12:30:24 +08:00
header github
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
var fs = require('fs');
|
||||
const express = require('express');
|
||||
var path = require("path");
|
||||
var cors = require('cors');
|
||||
|
||||
function fromDir(startPath,filter){
|
||||
var files_list = [];
|
||||
@@ -22,6 +23,7 @@ function get_path(file){
|
||||
}
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
|
||||
app.use("/dist", express.static(path.join(__dirname, "dist/")));
|
||||
app.use("/public", express.static(path.join(__dirname, "webapp/public/")));
|
||||
|
||||
Vendored
+9
-9
File diff suppressed because one or more lines are too long
@@ -9,6 +9,7 @@
|
||||
"author": "Thibault Neveu",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.4",
|
||||
"express": "^4.16.3",
|
||||
"pixi.js": "^4.8.1"
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ if (levelObject){
|
||||
}
|
||||
|
||||
// Create the editor (canvasID, levelUrl)
|
||||
var editor = new metacar.editor("editor", levelToLoad);
|
||||
var editor = new metacar.editor("editor", "http://localhost:3000/public/levels/levelGet.json");
|
||||
editor.load().then(() => {
|
||||
editor.addEvent("save", (content) => {
|
||||
console.log(content);
|
||||
// Put the object into storage
|
||||
localStorage.setItem('mylevel.json', JSON.stringify(content));
|
||||
window.open("/test_editor.html");
|
||||
}, {download: false, name: "level0.json"});
|
||||
|
||||
}, {download: false, name: "level.json"});
|
||||
});
|
||||
@@ -3,9 +3,7 @@ let levelUrl = metacar.level.level0;
|
||||
// Create the environement (canvasID, levelUrl)
|
||||
var env = new metacar.env("canvas", levelUrl);
|
||||
|
||||
console.log(env);
|
||||
|
||||
env.setAgentMotion(metacar.motion.BasicMotion, {rotationStep: 0.1});
|
||||
env.setAgentMotion(metacar.motion.BasicMotion, {rotationStep: 0.25});
|
||||
env.setAgentLidar({pts: 2, width: 1, height: 1, pos: 1});
|
||||
env.carsMoving(false);
|
||||
|
||||
@@ -17,12 +15,19 @@ env.loop(() => {
|
||||
displayState("realtime_viewer", state, 200, 200);
|
||||
let scores = agent.getStateValues(state);
|
||||
let reward = env.getLastReward();
|
||||
//displayScores("realtime_viewer", scores, reward, ["Top", "Left", "Right"]);
|
||||
})
|
||||
displayScores("realtime_viewer", scores, reward, ["Top", "Left", "Right"]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
env.load().then(() => {
|
||||
|
||||
// The level is loaded. Add listernes
|
||||
env.addEvent("train", () => agent.train());
|
||||
env.addEvent("train", () => {
|
||||
let train = confirm("The training process will freeze the tab during 1 minutes. Do you want to continue? You can also load the pre trained agent.");
|
||||
if (train)
|
||||
agent.train();
|
||||
});
|
||||
env.addEvent("play", () => agent.play());
|
||||
env.addEvent("stop");
|
||||
env.addEvent("reset_env", () => {
|
||||
@@ -30,9 +35,11 @@ env.load().then(() => {
|
||||
});
|
||||
env.addEvent("save", () => agent.save());
|
||||
env.addEvent("load", (content) => {
|
||||
agent.restore(content);
|
||||
displayQTable("q_table", agent.stateList, agent, ["Top", "Left", "Right"]);
|
||||
} , {local: true});
|
||||
loadJSON("http://localhost:3000/public/models/qtable/qtable.json", (content) => {
|
||||
agent.restore(content);
|
||||
displayQTable("q_table", agent.stateList, agent, ["Top", "Left", "Right"]);
|
||||
});
|
||||
});
|
||||
env.addEvent("custom", () => {
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ let levelUrl = metacar.level.level1;
|
||||
// Create the environement (canvasID, levelUrl)
|
||||
var env = new metacar.env("canvas", levelUrl);
|
||||
|
||||
env.setAgentMotion(metacar.motion.BasicMotion, {rotationStep: 0.1});
|
||||
|
||||
// Create the Policy agent
|
||||
var agent = new PolicyAgent(env);
|
||||
|
||||
@@ -16,7 +18,13 @@ env.loop(() => {
|
||||
|
||||
env.load().then(() => {
|
||||
// The level is loaded. Add listernes
|
||||
env.addEvent("train", () => agent.train());
|
||||
|
||||
env.addEvent("train", () => {
|
||||
let train = confirm("The training process takes some time and might slow this tab. Do you want to continue? \
|
||||
You can also load a pre-trained model");
|
||||
if (train)
|
||||
agent.train();
|
||||
});
|
||||
env.addEvent("play", () => agent.play());
|
||||
env.addEvent("stop", () => agent.stop());
|
||||
env.addEvent("reset_env", () => {
|
||||
|
||||
@@ -22,7 +22,7 @@ class PolicyAgent {
|
||||
Build the Value function
|
||||
@weights (Object) Weights for the layer
|
||||
*/
|
||||
const LEARNING_RATE = 0.05;
|
||||
const LEARNING_RATE = 0.01;
|
||||
const value_optimizer = tf.train.adam(LEARNING_RATE);
|
||||
/*
|
||||
-----------------------
|
||||
@@ -59,7 +59,7 @@ class PolicyAgent {
|
||||
Build the policy network
|
||||
@weights (Object) Weights for the layer
|
||||
*/
|
||||
const LEARNING_RATE = 0.05;
|
||||
const LEARNING_RATE = 0.01;
|
||||
this.policy_optimizer = tf.train.adam(LEARNING_RATE);
|
||||
/*
|
||||
-----------------------
|
||||
@@ -160,7 +160,7 @@ class PolicyAgent {
|
||||
// Maximum number of step per episode
|
||||
this.nb_step = 800;
|
||||
this.mini_batch_size = 200;
|
||||
this.episodeNb = 100;
|
||||
this.episodeNb = 200;
|
||||
}
|
||||
|
||||
save(env){
|
||||
@@ -175,14 +175,8 @@ class PolicyAgent {
|
||||
/*
|
||||
Restore the weights of the network
|
||||
*/
|
||||
if (window.location.href.indexOf("localhost") == -1){
|
||||
this.valueModel = await tf.loadModel('https://metacar-project.com/public/models/policy/value-model-policy-agent.json');
|
||||
this.policyModel = await tf.loadModel("https://metacar-project.com/public/models/policy/policy-model-policy-agent.json");
|
||||
}
|
||||
else{
|
||||
this.valueModel = await tf.loadModel('http://localhost:3000/public/models/policy/value-model-policy-agent.json');
|
||||
this.policyModel = await tf.loadModel("http://localhost:3000/public/models/policy/policy-model-policy-agent.json");
|
||||
}
|
||||
this.valueModel = await tf.loadModel('https://metacar-project.com/public/models/policy/value-model-policy-agent.json');
|
||||
this.policyModel = await tf.loadModel("https://metacar-project.com/public/models/policy/policy-model-policy-agent.json");
|
||||
}
|
||||
|
||||
play(){
|
||||
@@ -258,6 +252,9 @@ class PolicyAgent {
|
||||
st.dispose();
|
||||
// Step in the environement with this action
|
||||
reward = this.env.step(action);
|
||||
if (reward == -1){
|
||||
reward = -10;
|
||||
}
|
||||
}
|
||||
// Size of the next batches && minibatches
|
||||
const batch_size = rewards.length;
|
||||
|
||||
@@ -14,9 +14,7 @@ class QTableAgent {
|
||||
|
||||
save(){
|
||||
let save_content = JSON.stringify(this.Q);
|
||||
console.log(save_content);
|
||||
this.env.save(save_content, "mc_agent.json");
|
||||
console.log("Q table saved");
|
||||
this.env.save(save_content, "qtable.json");
|
||||
}
|
||||
|
||||
stringStateToState(state){
|
||||
@@ -37,7 +35,6 @@ class QTableAgent {
|
||||
restore(content){
|
||||
this.Q = {};
|
||||
this.stateList = [];
|
||||
content = JSON.parse(content);
|
||||
for (const key in content){
|
||||
var nStateToPush = this.stringStateToState(key);
|
||||
var st = key.toString();
|
||||
@@ -53,9 +50,6 @@ class QTableAgent {
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(this.Q);
|
||||
console.log(this.stateList);
|
||||
console.log("Q table loaded");
|
||||
}
|
||||
|
||||
play(){
|
||||
@@ -103,14 +97,14 @@ class QTableAgent {
|
||||
}
|
||||
|
||||
train(){
|
||||
let episode = 10000;
|
||||
let episode = 2000;
|
||||
let eps = 1.0;
|
||||
let eps_decrease = 0.99;
|
||||
|
||||
let mean_reward = [];
|
||||
for (let ep = 0; ep < episode; ep++) {
|
||||
if (ep % 50 == 0){
|
||||
eps = Math.max(0.1, eps*eps_decrease);
|
||||
if (ep % 10 == 0){
|
||||
eps = Math.max(0.05, eps*eps_decrease);
|
||||
console.log("episode=", ep, "eps=", eps, "mean_reward", mean(mean_reward));
|
||||
}
|
||||
mean_reward = [];
|
||||
@@ -128,11 +122,15 @@ class QTableAgent {
|
||||
act2 = this.pickAction(st2, 0.);
|
||||
this.createStateIfNotExist(st2);
|
||||
this.createStateIfNotExist(st);
|
||||
this.Q[st][act] = this.Q[st][act] + 0.05*(reward + (gamma*this.Q[st2][act2]) - this.Q[st][act]);
|
||||
this.Q[st][act] = this.Q[st][act] + 0.01*(reward + (gamma*this.Q[st2][act2]) - this.Q[st][act]);
|
||||
st = st2;
|
||||
}
|
||||
this.env.randomRoadPosition();
|
||||
}
|
||||
this.env.render(true);
|
||||
for (let s=0; s < this.stateList.length; s++){
|
||||
this.stateList[s] = this.stringStateToState(this.stateList[s]);
|
||||
}
|
||||
displayQTable("q_table", this.stateList, this, ["Top", "Left", "Right"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,26 @@ function argMax(array) {
|
||||
return Math.floor(Math.random()*array.length);
|
||||
}
|
||||
return array.map((x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r))[1];
|
||||
}
|
||||
|
||||
/*
|
||||
File with some usefull methods
|
||||
*/
|
||||
function loadJSON(url, callback) {
|
||||
/*
|
||||
Utils method to load a json on the server
|
||||
@url: Url to the json file to load
|
||||
@callback: Method to call when the json file is loaded
|
||||
*/
|
||||
var xobj = new XMLHttpRequest();
|
||||
xobj.overrideMimeType("application/json");
|
||||
xobj.open('GET', url, true); // Replace 'my_data' with the path to your file
|
||||
xobj.onreadystatechange = function () {
|
||||
if (xobj.readyState == 4 && xobj.status == 200) {
|
||||
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
|
||||
console.log(xobj.responseText);
|
||||
callback(JSON.parse(xobj.responseText));
|
||||
}
|
||||
};
|
||||
xobj.send(null);
|
||||
}
|
||||
@@ -43,17 +43,16 @@ function displayScores(id, score, reward, labels){
|
||||
container.appendChild(textContainer);
|
||||
}
|
||||
|
||||
console.log(score);
|
||||
var text = "";
|
||||
for (let c = 0; c < score.length; c++){
|
||||
text += labels[c] + ": <b>" + Number((parseFloat(score[c])).toFixed(2)) + "</b><br>";
|
||||
text += labels[c] + ": <b>" + ((score[c])).toFixed(2) + "</b><br>";
|
||||
}
|
||||
|
||||
if (reward){
|
||||
if (reward < 0)
|
||||
text += "<br><p style='color: #ee4c32'>Reward: <b>" +Number((parseFloat(reward)).toFixed(2)) + "</b></p>"
|
||||
if (reward != null){
|
||||
if (reward <= 0)
|
||||
text += "<br><p style='color: #ee4c32'>Reward: <b>" + ((reward)).toFixed(2) + "</b></p>"
|
||||
else
|
||||
text += "<br><p style='color: #80bf3e'>Reward: <b>" +Number((parseFloat(reward)).toFixed(2)) + "</b></p>"
|
||||
text += "<br><p style='color: #80bf3e'>Reward: <b>" + ((reward)).toFixed(2) + "</b></p>"
|
||||
}
|
||||
|
||||
textContainer.innerHTML = text;
|
||||
|
||||
Vendored
+9
-9
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
+1
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "metacar",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"main": "dist/metacar.min.js",
|
||||
"author": "Thibault Neveu",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
@@ -13,7 +13,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/pixi.js": "^4.7.5",
|
||||
"express": "^4.16.3",
|
||||
"pixi.js": "^4.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -326,7 +326,6 @@ export class AssetManger {
|
||||
file.map = map;
|
||||
// If the agent exist
|
||||
if (this.level.agent){
|
||||
console.log("enter here to create egent....");
|
||||
file.agent = {
|
||||
"mx": this.level.agent.core.mx,
|
||||
"my": this.level.agent.core.my,
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ export class Car {
|
||||
this.motion.setUp(this.core, this.lidar);
|
||||
this.core.rotationStep = 0.5;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
this.core.rotationStep = 0.5;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ export const fullCity: any = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"↠",
|
||||
"↟",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@@ -200,7 +200,7 @@ export const fullCity: any = {
|
||||
"↦",
|
||||
"↔",
|
||||
"↔",
|
||||
"↟",
|
||||
"↠",
|
||||
"↔"
|
||||
],
|
||||
[
|
||||
@@ -245,11 +245,11 @@ export const fullCity: any = {
|
||||
[
|
||||
0,
|
||||
0,
|
||||
"↠",
|
||||
"↟",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"↠",
|
||||
"↟",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
@@ -1,31 +1,5 @@
|
||||
export const level0: any = {
|
||||
"cars": [
|
||||
{
|
||||
"mx": 3,
|
||||
"my": 2,
|
||||
"line": 0
|
||||
},
|
||||
{
|
||||
"mx": 1,
|
||||
"my": 2,
|
||||
"line": 0
|
||||
},
|
||||
{
|
||||
"mx": 2,
|
||||
"my": 3,
|
||||
"line": 0
|
||||
},
|
||||
{
|
||||
"mx": 3,
|
||||
"my": 1,
|
||||
"line": 0
|
||||
},
|
||||
{
|
||||
"mx": 1,
|
||||
"my": 1,
|
||||
"line": 0
|
||||
}
|
||||
],
|
||||
"cars": [],
|
||||
"house": [
|
||||
{
|
||||
"x": 263,
|
||||
|
||||
+2
-1
@@ -13,7 +13,8 @@ export const Graphics = PIXI.Graphics;
|
||||
export const Container = PIXI.Container;
|
||||
|
||||
// Main server
|
||||
export const URL = window.location.href.indexOf("localhost") == -1 ? "https://metacar-project.com/" : "http://localhost:3000/";
|
||||
//export const URL = window.location.href.indexOf("localhost") == -1 ? "https://metacar-project.com/" : "http://localhost:3000/";
|
||||
export const URL = "https://metacar-project.com/";
|
||||
|
||||
// Textures files
|
||||
export const JSON_TEXTURES = URL + "public/textures/textures.json";
|
||||
|
||||
+25
-6
@@ -28,6 +28,7 @@ export class Level extends World {
|
||||
|
||||
public isCarsMoving: boolean = true;
|
||||
private lastReward: number = 0;
|
||||
private rewardFunction: any = null;
|
||||
|
||||
constructor(levelContent: LevelInfo, canvasId: string) {
|
||||
/*
|
||||
@@ -39,6 +40,18 @@ export class Level extends World {
|
||||
this.am = new AssetManger(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom reward function
|
||||
* The @fc will be called with three parameters and should return one number.
|
||||
* *agentCollisions: A list with all current collisions
|
||||
* *onRoad: Is the car on the road
|
||||
* *action: The last action took by the car
|
||||
* @fc The reward function to call
|
||||
*/
|
||||
public setRewardFunction(fc: any) {
|
||||
this.rewardFunction = fc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose whether other cars move or stay fixed.
|
||||
* This method should be called before to called 'load'.
|
||||
@@ -93,7 +106,7 @@ export class Level extends World {
|
||||
*/
|
||||
this.agent.reset();
|
||||
for (var c = 0; c < this.cars.length; c++) {
|
||||
this.cars[c].reset();
|
||||
//this.cars[c].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +118,11 @@ export class Level extends World {
|
||||
if (action == 0 || this.agent.core.v == 1)
|
||||
reward += 0.5;
|
||||
if (agent_col.length > 0){
|
||||
reward = -10;
|
||||
reward = -1;
|
||||
}
|
||||
else if (!on_road){
|
||||
reward = -10;
|
||||
reward = -1;
|
||||
}
|
||||
this.lastReward = reward;
|
||||
return reward;
|
||||
}
|
||||
|
||||
@@ -132,12 +144,19 @@ export class Level extends World {
|
||||
for (var c = 0; c < this.cars.length; c++) {
|
||||
if (this.cars[c].lidar && !this.cars[c].core.agent) // If this car can move
|
||||
this.cars[c].step(delta);
|
||||
}
|
||||
}
|
||||
// Move the agent
|
||||
if (this.agent){
|
||||
let {agentCollisions, onRoad} = this.agent.step(delta, action);
|
||||
// Get the reward
|
||||
let reward = this.setReward(agentCollisions, onRoad, action);
|
||||
let reward;
|
||||
if (this.rewardFunction){
|
||||
reward = this.rewardFunction(agentCollisions, onRoad, action);
|
||||
}
|
||||
else {
|
||||
reward = this.setReward(agentCollisions, onRoad, action);
|
||||
}
|
||||
this.lastReward = reward;
|
||||
return reward;
|
||||
}
|
||||
return 0;
|
||||
|
||||
+42
-28
@@ -46,34 +46,17 @@ export class MetaCar {
|
||||
this.canvasId = canvasId;
|
||||
this.levelToLoad = levelToLoad;
|
||||
}
|
||||
|
||||
/*
|
||||
Load the environement with the parameters passed in the constructor.
|
||||
*/
|
||||
public load(): Promise<void>{
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof this.levelToLoad == "string"){
|
||||
U.loadCustomURL(<string>this.levelToLoad, (content: LevelInfo) => {
|
||||
this.level = new Level(content, this.canvasId);
|
||||
this.level.setAgentMotion(this.agentMotionEngine, this.agentMotionOptions);
|
||||
this.level.setAgentLidar(this.agentLidarInfo);
|
||||
this.level.carsMoving(this.isCarsMoving);
|
||||
this._setEvents();
|
||||
this.level.load((delta: number) => this._loop(delta));
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.level = new Level(<LevelInfo>this.levelToLoad, this.canvasId);
|
||||
this.level.setAgentMotion(this.agentMotionEngine, this.agentMotionOptions);
|
||||
this.level.setAgentLidar(this.agentLidarInfo);
|
||||
this.level.carsMoving(this.isCarsMoving);
|
||||
this._setEvents();
|
||||
this.level.load((delta: number) => this._loop(delta));
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Set a custom reward function
|
||||
* The @fc will be called with three parameters and should return one number.
|
||||
* *agentCollisions: A list with all current collisions
|
||||
* *onRoad: Is the car on the road
|
||||
* *action: The last action took by the car
|
||||
* @fc The reward function to call
|
||||
*/
|
||||
public setRewardFunction(fc: any): void {
|
||||
this.level.setRewardFunction(fc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,4 +240,35 @@ export class MetaCar {
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
Load the environement with the parameters passed in the constructor.
|
||||
*/
|
||||
public load(): Promise<void>{
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof this.levelToLoad == "string"){
|
||||
U.loadCustomURL(<string>this.levelToLoad, (content: LevelInfo) => {
|
||||
this.level = new Level(content, this.canvasId);
|
||||
this.level.setAgentMotion(this.agentMotionEngine, this.agentMotionOptions);
|
||||
this.level.setAgentLidar(this.agentLidarInfo);
|
||||
this.level.carsMoving(this.isCarsMoving);
|
||||
this._setEvents();
|
||||
this.level.load((delta: number) => this._loop(delta)).then(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.level = new Level(<LevelInfo>this.levelToLoad, this.canvasId);
|
||||
this.level.setAgentMotion(this.agentMotionEngine, this.agentMotionOptions);
|
||||
this.level.setAgentLidar(this.agentLidarInfo);
|
||||
this.level.carsMoving(this.isCarsMoving);
|
||||
this._setEvents();
|
||||
this.level.load((delta: number) => this._loop(delta)).then(() => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-1
@@ -12,7 +12,7 @@ export class MetaCarEditor {
|
||||
private canvasId: string;
|
||||
private levelToLoad: string|Object;
|
||||
private event: UIEvent;
|
||||
private eventList: string[] = ["save"]
|
||||
private eventList: string[] = ["save"];
|
||||
private eventCallback: any[];
|
||||
|
||||
/**
|
||||
@@ -62,6 +62,18 @@ export class MetaCarEditor {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Usefull method to save/download a string as file.
|
||||
* @content The content of the file
|
||||
* @file_name The name of the file
|
||||
*/
|
||||
public save(content: string, file_name: string): void{
|
||||
/*
|
||||
Save the agent
|
||||
*/
|
||||
U.saveAs(content, file_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to add button under the canvas. When a
|
||||
* click is detected on the window, the associated @fc is called.
|
||||
|
||||
+3
-4
@@ -15,7 +15,7 @@ export function loadJSON(url: string, callback: any) {
|
||||
xobj.onreadystatechange = function () {
|
||||
if (xobj.readyState == 4 && xobj.status == 200) {
|
||||
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
|
||||
callback(xobj.responseText);
|
||||
callback(JSON.parse(xobj.responseText));
|
||||
}
|
||||
};
|
||||
xobj.send(null);
|
||||
@@ -40,9 +40,8 @@ export function loadCustomURL(url: string, callback: any):void {
|
||||
*/
|
||||
const customCall: any = {
|
||||
"embedded:": loadEmbeddedURL,
|
||||
"http://": loadJSON,
|
||||
"https://": loadJSON,
|
||||
"localstorage://": loadLocalStorageURL
|
||||
"http:": loadJSON,
|
||||
"https:": loadJSON
|
||||
}
|
||||
const split = url.split("//");
|
||||
customCall[split[0]](url, callback);
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ export class World {
|
||||
document.getElementById(this.canvasId).appendChild(this.app.view);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
Loader.add([JSON_TEXTURES, JSON_IMAGE]).load(() => {
|
||||
Loader.add([JSON_TEXTURES, JSON_IMAGE], {crossOrigin: true}).load(() => {
|
||||
this._setup(info); // Set up the level (Add assets)
|
||||
resolve();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user