Add event API + level1

This commit is contained in:
Thibault Neveu
2018-06-08 15:02:39 +01:00
parent 3b5eaf35a8
commit ba524f28fa
11 changed files with 557 additions and 40 deletions
+17 -5
View File
File diff suppressed because one or more lines are too long
+18
View File
@@ -0,0 +1,18 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
<div class="canvas" id="canvas"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.7.1/pixi.min.js"></script>
<script src="/dist/metacar.min.js"></script>
<script type="text/javascript" src="/public/js/level1.js"></script>
</body>
</html>
+28
View File
@@ -0,0 +1,28 @@
// Get the url of the desired level
let levelUrl = metacar.level.level1;
// Create the environement (canvasID, levelUrl)
var env = new metacar.env("canvas", levelUrl);
env.load().then(() => {
// The level is loaded. Add listernes
env.addEvent("train", () => {
console.log("On train!");
});
env.addEvent("play", () => {
console.log("On play!");
});
env.addEvent("stop", () => {
console.log("On sotp!");
});
env.addEvent("reset_env", () => {
console.log("On reset env!");
});
env.addEvent("reset_agent", () => {
console.log("On reset agent");
})
env.addEvent("save", () => {
console.log("On save");
});
env.addEvent("load", (content) => {
console.log("content", content);
});
});
+17 -5
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -77,15 +77,15 @@ export class BasicMotionEngine extends MotionEngine {
}
}
turnLeft(){
turnLeft():void {
/*
Turn left
*/
this.car.rotation -= this.rotationStep*Math.PI;
this.lidar.rotation = this.car.rotation;
this.car.rotation -= this.rotationStep*Math.PI
this.lidar.rotation = this.car.rotation;
}
turnRight(){
turnRight():void {
/*
Turn right
*/
@@ -93,14 +93,14 @@ export class BasicMotionEngine extends MotionEngine {
this.lidar.rotation = this.car.rotation;
}
moveForward(){
moveForward():void {
/*
Move forward
*/
this.car.v = 1;
}
moveBackward(){
moveBackward():void {
/*
Move backward
*/
+5 -2
View File
@@ -1,11 +1,14 @@
import {fullCity} from "./embedded/level/full_city";
import {level1} from "./embedded/level/level_1";
export const embeddedUrl: any = {
fullCity: "embedded://level/fullCity"
fullCity: "embedded://level/fullCity",
level1: "embedded://level/level1"
}
export const embeddedContent: any = {
level: {
fullCity: fullCity
fullCity: fullCity,
level1: level1
}
}
+316
View File
@@ -0,0 +1,316 @@
export const level1: any = {
"cars": [
{
"mx": 5,
"my": 3,
"line": 0,
"auto": true
},
{
"mx": 5,
"my": 3,
"line": 1,
"auto": true
},
{
"mx": 5,
"my": 1,
"line": 0,
"auto": true
}
],
"tree": [
{
"x": 120,
"y": 50
},
{
"x": 86.5,
"y": 85
},
{
"x": 94.5,
"y": 135
},
{
"x": 30.5,
"y": 128
},
{
"x": 72.5,
"y": 190
},
{
"x": 23.5,
"y": 232
},
{
"x": 110.5,
"y": 242
},
{
"x": 43.5,
"y": 33
},
{
"x": 18.5,
"y": 178
},
{
"x": 305.5,
"y": 125
},
{
"x": 360.5,
"y": 122
}
],
"asset": [
{
"x": 252.5,
"y": 142
},
{
"x": 86.5,
"y": 85
},
{
"x": 94.5,
"y": 135
},
{
"x": 30.5,
"y": 128
},
{
"x": 252.5,
"y": 26
},
{
"x": 195.5,
"y": 0
},
{
"x": 307.5,
"y": 1
},
{
"x": 72.5,
"y": 190
},
{
"x": 23.5,
"y": 232
},
{
"x": 110.5,
"y": 242
},
{
"x": 43.5,
"y": 33
},
{
"x": 35.5,
"y": 185
},
{
"x": 18.5,
"y": 178
},
{
"x": 289.5,
"y": 126
},
{
"x": 337.5,
"y": 126
},
{
"x": 305.5,
"y": 125
},
{
"x": 360.5,
"y": 122
},
{
"x": 492.5,
"y": 56
},
{
"x": 503.5,
"y": 136
},
{
"x": 504.5,
"y": 58
}
],
"bench": [
{
"x": 252.5,
"y": 142
},
{
"x": 252.5,
"y": 26
}
],
"road": [
{
"x": 240,
"y": 60
},
{
"x": 240,
"y": 60
},
{
"x": 480,
"y": 0
},
{
"x": 480,
"y": 60
},
{
"x": 480,
"y": 120
},
{
"x": 480,
"y": 180
},
{
"x": 480,
"y": 240
},
{
"x": 300,
"y": 180
},
{
"x": 300,
"y": 180
},
{
"x": 360,
"y": 180
},
{
"x": 420,
"y": 180
},
{
"x": 420,
"y": 120
},
{
"x": 420,
"y": 60
},
{
"x": 360,
"y": 60
},
{
"x": 300,
"y": 60
},
{
"x": 420,
"y": 120
}
],
"house3": [
{
"x": 503.5,
"y": 136
}
],
"house": [
{
"x": 504.5,
"y": 58
}
],
"map": [
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
[
0,
0,
0,
"↱",
"↠",
"↔",
"↔",
"↰",
0,
0
],
[
0,
0,
0,
"↕",
0,
0,
0,
"↟",
0,
0
],
[
0,
0,
0,
"↳",
"↔",
"↔",
"↔",
"↲",
0,
0
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
],
"agent": {
"mx": 4,
"my": 3,
"line": 0,
"motion": {
"type": "BasicMotionEngine",
"options": {
"rotationStep": 0.5,
"actions": [
"UP",
"LEFT",
"RIGHT"
]
}
}
}
}
+9 -8
View File
@@ -60,6 +60,15 @@ export class Level {
});
}
render(val: boolean){
if (val){
this.app.ticker.start();
}
else{
this.app.ticker.stop();
}
}
createLevel(info: LevelInfo){
/*
Create the level
@@ -98,14 +107,6 @@ export class Level {
this.app.ticker.add((delta: number) => this.loop(delta));
}
render(){
/*
If the rendering has been stopped, this Method
restart the rendering.
*/
this.app.ticker.start();
}
reset(){
/*
Reset the game.
+134 -5
View File
@@ -5,6 +5,10 @@
import {Level, LevelInfo} from "./level";
import * as U from "./utils";
export interface eventLoadOptions {
computer: boolean;
}
export class MetaCar {
private isPlaying: boolean;
@@ -12,6 +16,9 @@ export class MetaCar {
private level: Level;
private canvasId: string;
private levelUrl: string;
private eventList: string[] = ["train", "play", "stop", "reset_env", "reset_agent", "save", "load"]
private eventCallback: any[];
private buttonsContainer: HTMLDivElement;
constructor(canvasId: string, levelUrl: string) {
/**
@@ -27,6 +34,23 @@ export class MetaCar {
this.isPlaying = false;
this.canvasId = canvasId;
this.levelUrl = levelUrl;
this.eventCallback = [
(fc: any) => this.onTrain(fc),
(fc: any) => this.onPlay(fc),
(fc:any) => this.onStop(fc),
(fc: any) => this.onResetEnv(fc),
(fc: any) => this.onResetAgent(fc),
(fc: any) => this.onSave(fc),
(fc: any, opt: eventLoadOptions) => this.onLoad(fc, opt)
];
// Insert the event div
var canvas = document.getElementById(canvasId);
var buttons = document.createElement('div'); // create new textarea
buttons.classList.add("metacar_buttons_container");
buttons.id = "metacar_"+ canvasId + "_buttons_container";
canvas.parentNode.insertBefore(buttons, canvas.nextSibling);
this.buttonsContainer = buttons;
}
load(level: string, agent: any): Promise<void>{
@@ -56,8 +80,8 @@ export class MetaCar {
});
document.getElementById("stop").addEventListener("click", () => {
this.isPlaying = false;
this.agent.stop();
this.level.render();
this.agent.stop();
});
document.getElementById("reset").addEventListener("click", () => {
this.level.reset();
@@ -74,12 +98,117 @@ export class MetaCar {
*/
}
render(){
private _createButton(parent: HTMLDivElement, name: string): HTMLButtonElement{
var button = document.createElement('button'); // create new textarea
button.classList.add("metacar_button_train");
button.id = "metacar_"+ this.canvasId + "_button_" + name;
// Uppercase first letter and replace _
name = name.replace(/_/g , " ");
button.innerHTML = name.charAt(0).toUpperCase() + name.slice(1);;
parent.appendChild(button);
return button
}
onTrain(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "train");
// Listen the event
button.addEventListener("click", () => {
this.render(false);
if (fc) fc();
});
}
onPlay(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "play");
// Listen the event
button.addEventListener("click", () => {
if (fc) fc();
});
}
onStop(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "stop");
// Listen the event
button.addEventListener("click", () => {
if (fc) fc();
});
}
onResetEnv(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "reset_env");
button.addEventListener("click", () => {
if (fc) fc();
});
}
onResetAgent(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "reset_agent");
button.addEventListener("click", () => {
if (fc) fc();
});
}
onSave(fc: any){
// Create the button
const button = this._createButton(this.buttonsContainer, "save");
button.addEventListener("click", () => {
if (fc) fc();
});
}
onLoad(fc: any, options: eventLoadOptions){
// Create the button
const button = this._createButton(this.buttonsContainer, "load_trained_agent");
// Create the fake input input file
var input_file = document.createElement('input'); // create new textarea
input_file.type = "file";
input_file.accept = "*/*";
input_file.style.display = "none";
input_file.classList.add("metacar_button_input_file");
input_file.id = "metacar_"+ this.canvasId + "_button_input_file";
this.buttonsContainer.appendChild(input_file);
input_file.addEventListener("change", (dump) => {
console.log("New file to handle");
U.readDump(dump, (content: any) => {
if (fc) fc(content);
});
});
button.addEventListener("click", () => {
input_file.click();
});
}
addEvent(eventName: string, fc: any, options?: eventLoadOptions):void {
/**
* eventName: Name of the event to listen
* fc: Function to call each time this event is raise
*/
const index = this.eventList.indexOf(eventName);
if (index == -1){
console.error("The environement does not support this event. Only the following are\
avaible:" + this.eventList);
}
const event = this.eventList[index];
if (event != "load"){
this.eventCallback[index](fc);
}
else{
this.eventCallback[index](fc, options);
}
}
render(val: boolean){
/*
Render the environement
again
Choose whether to render the environement.
*/
this.level.render();
this.level.render(val);
}
save(content: any, file_name: string){
+7 -9
View File
@@ -122,18 +122,16 @@ function readBuffer(buffer) {
}
*/
/*
function readDump(e, callback) {
var input = e.target;
export function readDump(dump: any, callback: any) {
var input = dump.target;
var file = input.files[0];
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = (evt) => {
reader.onload = (evt:any) => {
callback(evt.target.result);
}
}
*/
export function shuffleArray(array: number[]) {
/**
@@ -174,7 +172,7 @@ export function keyboard(keyCode: any ) {
key.isDown = true;
key.isUp = false;
}
event.preventDefault();
//event.preventDefault();
};
key.upHandler = (event: any) => {
@@ -183,9 +181,9 @@ export function keyboard(keyCode: any ) {
key.isDown = false;
key.isUp = true;
}
event.preventDefault();
//event.preventDefault();
};
//Attach event listeners
window.addEventListener(
"keydown", key.downHandler.bind(key), false