added mouse controls
This commit is contained in:
25
dist/bundle.js
vendored
25
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
21
dist/css/style.css
vendored
21
dist/css/style.css
vendored
@@ -1,5 +1,5 @@
|
|||||||
body{
|
body{
|
||||||
background: #121D29;
|
background: black;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,8 @@ canvas {
|
|||||||
background-color: gray;
|
background-color: gray;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-template-rows: repeat(2, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-set {
|
.control-set {
|
||||||
@@ -33,6 +35,7 @@ canvas {
|
|||||||
border: 10px;
|
border: 10px;
|
||||||
border-color: black;
|
border-color: black;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
|
max-width: 100%;
|
||||||
/* height: 100%; */
|
/* height: 100%; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,14 +53,22 @@ canvas {
|
|||||||
|
|
||||||
#hyperparameters {
|
#hyperparameters {
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
grid-row: 1 / 2;
|
grid-row: 1 / 3;
|
||||||
/* background-color: green; */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#powers {
|
#abilities {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
grid-row: 1 / 2;
|
grid-row: 1 / 3;
|
||||||
/* background-color: yellow; */
|
/* background-color: yellow; */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.control-mode-button {
|
||||||
|
border-color: gray;
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#none-button {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
8
dist/html/index.html
vendored
8
dist/html/index.html
vendored
@@ -38,8 +38,12 @@
|
|||||||
<input type="checkbox" id="fixed-ratio" name="scales" checked>
|
<input type="checkbox" id="fixed-ratio" name="scales" checked>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='powers' class='control-set'>
|
<div id='abilities' class='control-set'>
|
||||||
<h2>Powers</h2>
|
<h2>Control Mode</h2>
|
||||||
|
<button class='control-mode-button' id='food-button' value='Inset Border'>Drop Food</button>
|
||||||
|
<button class='control-mode-button' id='wall-button'>Drop Wall</button>
|
||||||
|
<button class='control-mode-button' id='kill-button'>Kill Organism</button>
|
||||||
|
<button class='control-mode-button' id='none-button'>None</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const CellTypes = {
|
|||||||
mover: 5,
|
mover: 5,
|
||||||
killer: 6,
|
killer: 6,
|
||||||
armor: 7,
|
armor: 7,
|
||||||
colors: ['#121D29', 'green', 'black', 'orange', 'white', 'blue', 'red', 'purple'],
|
colors: ['#121D29', 'green', 'gray', 'orange', 'white', 'blue', 'red', 'purple'],
|
||||||
getRandomLivingType: function(){
|
getRandomLivingType: function(){
|
||||||
return Math.floor(Math.random() * 5) + 3;
|
return Math.floor(Math.random() * 5) + 3;
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/ControlModes.js
Normal file
8
src/ControlModes.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
const Modes = {
|
||||||
|
None: 0,
|
||||||
|
FoodDrop: 1,
|
||||||
|
WallDrop: 2,
|
||||||
|
ClickKill: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Modes;
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
var Hyperparams = require("./Hyperparameters");
|
var Hyperparams = require("./Hyperparameters");
|
||||||
|
var Modes = require("./ControlModes");
|
||||||
|
const CellTypes = require("./CellTypes");
|
||||||
|
|
||||||
class ControlPanel {
|
class ControlPanel {
|
||||||
constructor(engine) {
|
constructor(engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.defineEngineSpeedControls();
|
this.defineEngineSpeedControls();
|
||||||
this.defineHyperparameterControls();
|
this.defineHyperparameterControls();
|
||||||
|
this.defineModeControls();
|
||||||
this.fps = engine.fps;
|
this.fps = engine.fps;
|
||||||
this.organism_record=0;
|
this.organism_record=0;
|
||||||
|
this.env_controller = this.engine.env.controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineEngineSpeedControls(){
|
defineEngineSpeedControls(){
|
||||||
@@ -21,14 +25,14 @@ class ControlPanel {
|
|||||||
}.bind(this);
|
}.bind(this);
|
||||||
$('#pause-button').click(function() {
|
$('#pause-button').click(function() {
|
||||||
if ($('#pause-button').text() == "Pause" && this.engine.running) {
|
if ($('#pause-button').text() == "Pause" && this.engine.running) {
|
||||||
$('#pause-button').text("Play")
|
$('#pause-button').text("Play");
|
||||||
this.engine.stop();
|
this.engine.stop();
|
||||||
}
|
}
|
||||||
else if (!this.engine.running){
|
else if (!this.engine.running){
|
||||||
$('#pause-button').text("Pause")
|
$('#pause-button').text("Pause");
|
||||||
|
console.log(this.fps)
|
||||||
this.engine.start(this.fps);
|
this.engine.start(this.fps);
|
||||||
}
|
}
|
||||||
console.log()
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +61,28 @@ class ControlPanel {
|
|||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineModeControls() {
|
||||||
|
var self = this;
|
||||||
|
$('.control-mode-button').click( function() {
|
||||||
|
switch(this.id){
|
||||||
|
case "food-button":
|
||||||
|
self.env_controller.mode = Modes.FoodDrop;
|
||||||
|
break;
|
||||||
|
case "wall-button":
|
||||||
|
self.env_controller.mode = Modes.WallDrop;
|
||||||
|
break;
|
||||||
|
case "kill-button":
|
||||||
|
self.env_controller.mode = Modes.ClickKill;
|
||||||
|
break;
|
||||||
|
case "none-button":
|
||||||
|
self.env_controller.mode = Modes.None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$(".control-mode-button" ).css( "background-color", "lightgray" );
|
||||||
|
$("#"+this.id).css("background-color", "darkgray");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
changeEngineSpeed(change_val) {
|
changeEngineSpeed(change_val) {
|
||||||
this.engine.stop();
|
this.engine.stop();
|
||||||
this.engine.start(change_val)
|
this.engine.start(change_val)
|
||||||
@@ -70,7 +96,7 @@ class ControlPanel {
|
|||||||
if (org_count > this.organism_record)
|
if (org_count > this.organism_record)
|
||||||
this.organism_record = org_count;
|
this.organism_record = org_count;
|
||||||
$('#org-record').text("Highest count: " + this.organism_record);
|
$('#org-record').text("Highest count: " + this.organism_record);
|
||||||
|
// this.env_controller.performModeAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
const Environment = require('./Environment');
|
const Environment = require('./Environment');
|
||||||
const ControlPanel = require('./ControlPanel');
|
const ControlPanel = require('./ControlPanel');
|
||||||
|
|
||||||
|
const render_speed = 60;
|
||||||
|
|
||||||
class Engine{
|
class Engine{
|
||||||
constructor(){
|
constructor(){
|
||||||
this.fps = 0;
|
this.fps = 60;
|
||||||
this.env = new Environment(5);
|
this.env = new Environment(5);
|
||||||
this.controlpanel = new ControlPanel(this);
|
this.controlpanel = new ControlPanel(this);
|
||||||
this.env.OriginOfLife();
|
this.env.OriginOfLife();
|
||||||
@@ -21,7 +23,7 @@ class Engine{
|
|||||||
this.fps = fps;
|
this.fps = fps;
|
||||||
this.game_loop = setInterval(function(){this.update();}.bind(this), 1000/fps);
|
this.game_loop = setInterval(function(){this.update();}.bind(this), 1000/fps);
|
||||||
this.running = true;
|
this.running = true;
|
||||||
if (this.fps >= 45) {
|
if (this.fps >= render_speed) {
|
||||||
if (this.render_loop != null) {
|
if (this.render_loop != null) {
|
||||||
clearInterval(this.render_loop);
|
clearInterval(this.render_loop);
|
||||||
this.render_loop = null;
|
this.render_loop = null;
|
||||||
@@ -39,7 +41,7 @@ class Engine{
|
|||||||
|
|
||||||
setRenderLoop() {
|
setRenderLoop() {
|
||||||
if (this.render_loop == null) {
|
if (this.render_loop == null) {
|
||||||
this.render_loop = setInterval(function(){this.env.render();}.bind(this), 1000/45);
|
this.render_loop = setInterval(function(){this.env.render();this.controlpanel.update();}.bind(this), 1000/render_speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +50,14 @@ class Engine{
|
|||||||
this.delta_time = Date.now() - this.last_update;
|
this.delta_time = Date.now() - this.last_update;
|
||||||
this.last_update = Date.now();
|
this.last_update = Date.now();
|
||||||
this.env.update(this.delta_time);
|
this.env.update(this.delta_time);
|
||||||
this.env.render();
|
|
||||||
this.actual_fps = 1/this.delta_time*1000;
|
this.actual_fps = 1/this.delta_time*1000;
|
||||||
|
if(this.render_loop == null){
|
||||||
|
this.env.render();
|
||||||
this.controlpanel.update();
|
this.controlpanel.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Engine;
|
module.exports = Engine;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Environment{
|
|||||||
var to_remove = [];
|
var to_remove = [];
|
||||||
for (var i in this.organisms) {
|
for (var i in this.organisms) {
|
||||||
var org = this.organisms[i];
|
var org = this.organisms[i];
|
||||||
if (!org.update()) {
|
if (!org.living || !org.update()) {
|
||||||
to_remove.push(i);
|
to_remove.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,9 +42,9 @@ class Environment{
|
|||||||
OriginOfLife() {
|
OriginOfLife() {
|
||||||
var center = this.grid_map.getCenter();
|
var center = this.grid_map.getCenter();
|
||||||
var org = new Organism(center[0], center[1], this);
|
var org = new Organism(center[0], center[1], this);
|
||||||
org.addCell(CellTypes.mouth, -1, -1);
|
|
||||||
org.addCell(CellTypes.producer, 0, 0);
|
|
||||||
org.addCell(CellTypes.mouth, 1, 1);
|
org.addCell(CellTypes.mouth, 1, 1);
|
||||||
|
org.addCell(CellTypes.producer, 0, 0);
|
||||||
|
// org.addCell(CellTypes.mouth, 1, -1);
|
||||||
this.addOrganism(org);
|
this.addOrganism(org);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
var Modes = require("./ControlModes");
|
||||||
|
const CellTypes = require("./CellTypes");
|
||||||
|
|
||||||
class EnvironmentController{
|
class EnvironmentController{
|
||||||
constructor(env, canvas) {
|
constructor(env, canvas) {
|
||||||
@@ -7,21 +9,15 @@ class EnvironmentController{
|
|||||||
this.mouse_y;
|
this.mouse_y;
|
||||||
this.mouse_c;
|
this.mouse_c;
|
||||||
this.mouse_r;
|
this.mouse_r;
|
||||||
this.mouse_down = false;
|
this.left_click = false;
|
||||||
|
this.right_click = false;
|
||||||
this.cur_cell = null;
|
this.cur_cell = null;
|
||||||
this.cur_org = null;
|
this.cur_org = null;
|
||||||
|
this.mode = Modes.None;
|
||||||
this.defineEvents();
|
this.defineEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
defineEvents() {
|
defineEvents() {
|
||||||
this.canvas.addEventListener('mousedown', e => {
|
|
||||||
this.mouse_down=true;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.canvas.addEventListener('mouseup', e => {
|
|
||||||
this.mouse_down=false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.canvas.addEventListener('mousemove', e => {
|
this.canvas.addEventListener('mousemove', e => {
|
||||||
var prev_cell = this.cur_cell;
|
var prev_cell = this.cur_cell;
|
||||||
var prev_org = this.cur_org;
|
var prev_org = this.cur_org;
|
||||||
@@ -43,7 +39,67 @@ class EnvironmentController{
|
|||||||
this.env.renderer.highlightCell(this.cur_cell, true);
|
this.env.renderer.highlightCell(this.cur_cell, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.performModeAction();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.canvas.addEventListener('mouseup', function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this.left_click=false;
|
||||||
|
this.right_click=false;
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
this.canvas.addEventListener('mousedown', function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
if (evt.button == 0) {
|
||||||
|
this.left_click = true;
|
||||||
|
}
|
||||||
|
if (evt.button == 2)
|
||||||
|
this.right_click = true;
|
||||||
|
this.performModeAction();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
this.canvas.addEventListener('contextmenu', function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.canvas.addEventListener('mouseleave', function(){
|
||||||
|
this.right_click = false;
|
||||||
|
this.left_click = false;
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
performModeAction() {
|
||||||
|
var mode = this.mode;
|
||||||
|
var right_click = this.right_click;
|
||||||
|
var left_click = this.left_click;
|
||||||
|
if (mode != Modes.None && (right_click || left_click)) {
|
||||||
|
var cell = this.cur_cell;
|
||||||
|
if (cell == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(mode) {
|
||||||
|
case Modes.FoodDrop:
|
||||||
|
if (left_click && cell.type == CellTypes.empty){
|
||||||
|
this.env.changeCell(cell.col, cell.row, CellTypes.food, null);
|
||||||
|
}
|
||||||
|
else if (right_click && cell.type == CellTypes.food){
|
||||||
|
this.env.changeCell(cell.col, cell.row, CellTypes.empty, null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Modes.WallDrop:
|
||||||
|
if (left_click && (cell.type == CellTypes.empty || cell.type == CellTypes.food)){
|
||||||
|
this.env.changeCell(cell.col, cell.row, CellTypes.wall, null);
|
||||||
|
}
|
||||||
|
else if (right_click && cell.type == CellTypes.wall){
|
||||||
|
this.env.changeCell(cell.col, cell.row, CellTypes.empty, null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Modes.ClickKill:
|
||||||
|
if (this.cur_org != null)
|
||||||
|
this.cur_org.die();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class Organism {
|
|||||||
//produce mutated child
|
//produce mutated child
|
||||||
//check nearby locations (is there room and a direct path)
|
//check nearby locations (is there room and a direct path)
|
||||||
var org = new Organism(0, 0, this.env, this);
|
var org = new Organism(0, 0, this.env, this);
|
||||||
if (Math.random() * 100 <= this.mutability) {
|
if (Math.random() * 100 <= 3) {
|
||||||
org.mutate();
|
org.mutate();
|
||||||
}
|
}
|
||||||
if (Math.random() <= 0.5)
|
if (Math.random() <= 0.5)
|
||||||
@@ -107,7 +107,7 @@ class Organism {
|
|||||||
|
|
||||||
var new_c = this.c + (direction_c*this.cells.length*2) + (direction_c*offset);
|
var new_c = this.c + (direction_c*this.cells.length*2) + (direction_c*offset);
|
||||||
var new_r = this.r + (direction_r*this.cells.length*2) + (direction_r*offset);
|
var new_r = this.r + (direction_r*this.cells.length*2) + (direction_r*offset);
|
||||||
if (org.isClear(new_c, new_r)){// && org.isStraightPath(new_c, new_r, this.c, this.r, this)){
|
if (org.isClear(new_c, new_r) && org.isStraightPath(new_c, new_r, this.c, this.r, this)){
|
||||||
org.c = new_c;
|
org.c = new_c;
|
||||||
org.r = new_r;
|
org.r = new_r;
|
||||||
this.env.addOrganism(org);
|
this.env.addOrganism(org);
|
||||||
@@ -125,13 +125,13 @@ class Organism {
|
|||||||
// add cell
|
// add cell
|
||||||
var type = CellTypes.getRandomLivingType();
|
var type = CellTypes.getRandomLivingType();
|
||||||
var num_to_add = Math.floor(Math.random() * 3) + 1;
|
var num_to_add = Math.floor(Math.random() * 3) + 1;
|
||||||
for (var i=0; i<num_to_add; i++){
|
// for (var i=0; i<num_to_add; i++){
|
||||||
var branch = this.cells[Math.floor(Math.random() * this.cells.length)];
|
var branch = this.cells[Math.floor(Math.random() * this.cells.length)];
|
||||||
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
|
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
|
||||||
var c = branch.loc_col+growth_direction[0];
|
var c = branch.loc_col+growth_direction[0];
|
||||||
var r = branch.loc_row+growth_direction[1];
|
var r = branch.loc_row+growth_direction[1];
|
||||||
return this.addCell(type, c, r);
|
return this.addCell(type, c, r);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else if (choice == 1){
|
else if (choice == 1){
|
||||||
// change cell
|
// change cell
|
||||||
@@ -211,7 +211,7 @@ class Organism {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isPassableCell(cell, parent){
|
isPassableCell(cell, parent){
|
||||||
return cell.type == CellTypes.empty || cell.owner == this || cell.owner == parent;
|
return cell != null && (cell.type == CellTypes.empty || cell.owner == this || cell.owner == parent || cell.type == CellTypes.food);
|
||||||
}
|
}
|
||||||
|
|
||||||
isClear(col, row) {
|
isClear(col, row) {
|
||||||
|
|||||||
Reference in New Issue
Block a user