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{
|
||||
background: #121D29;
|
||||
background: black;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -25,6 +25,8 @@ canvas {
|
||||
background-color: gray;
|
||||
position: fixed;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.control-set {
|
||||
@@ -33,6 +35,7 @@ canvas {
|
||||
border: 10px;
|
||||
border-color: black;
|
||||
background-color: lightgray;
|
||||
max-width: 100%;
|
||||
/* height: 100%; */
|
||||
}
|
||||
|
||||
@@ -50,14 +53,22 @@ canvas {
|
||||
|
||||
#hyperparameters {
|
||||
grid-column: 2;
|
||||
grid-row: 1 / 2;
|
||||
/* background-color: green; */
|
||||
grid-row: 1 / 3;
|
||||
|
||||
}
|
||||
|
||||
#powers {
|
||||
#abilities {
|
||||
grid-column: 3;
|
||||
grid-row: 1 / 2;
|
||||
grid-row: 1 / 3;
|
||||
/* 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>
|
||||
</div>
|
||||
|
||||
<div id='powers' class='control-set'>
|
||||
<h2>Powers</h2>
|
||||
<div id='abilities' class='control-set'>
|
||||
<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>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const CellTypes = {
|
||||
mover: 5,
|
||||
killer: 6,
|
||||
armor: 7,
|
||||
colors: ['#121D29', 'green', 'black', 'orange', 'white', 'blue', 'red', 'purple'],
|
||||
colors: ['#121D29', 'green', 'gray', 'orange', 'white', 'blue', 'red', 'purple'],
|
||||
getRandomLivingType: function(){
|
||||
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 Modes = require("./ControlModes");
|
||||
const CellTypes = require("./CellTypes");
|
||||
|
||||
class ControlPanel {
|
||||
constructor(engine) {
|
||||
this.engine = engine;
|
||||
this.defineEngineSpeedControls();
|
||||
this.defineHyperparameterControls();
|
||||
this.defineModeControls();
|
||||
this.fps = engine.fps;
|
||||
this.organism_record=0;
|
||||
this.env_controller = this.engine.env.controller;
|
||||
}
|
||||
|
||||
defineEngineSpeedControls(){
|
||||
@@ -21,14 +25,14 @@ class ControlPanel {
|
||||
}.bind(this);
|
||||
$('#pause-button').click(function() {
|
||||
if ($('#pause-button').text() == "Pause" && this.engine.running) {
|
||||
$('#pause-button').text("Play")
|
||||
$('#pause-button').text("Play");
|
||||
this.engine.stop();
|
||||
}
|
||||
else if (!this.engine.running){
|
||||
$('#pause-button').text("Pause")
|
||||
$('#pause-button').text("Pause");
|
||||
console.log(this.fps)
|
||||
this.engine.start(this.fps);
|
||||
}
|
||||
console.log()
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
@@ -57,6 +61,28 @@ class ControlPanel {
|
||||
}.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) {
|
||||
this.engine.stop();
|
||||
this.engine.start(change_val)
|
||||
@@ -70,7 +96,7 @@ class ControlPanel {
|
||||
if (org_count > this.organism_record)
|
||||
this.organism_record = org_count;
|
||||
$('#org-record').text("Highest count: " + this.organism_record);
|
||||
|
||||
// this.env_controller.performModeAction();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
const Environment = require('./Environment');
|
||||
const ControlPanel = require('./ControlPanel');
|
||||
|
||||
const render_speed = 60;
|
||||
|
||||
class Engine{
|
||||
constructor(){
|
||||
this.fps = 0;
|
||||
this.fps = 60;
|
||||
this.env = new Environment(5);
|
||||
this.controlpanel = new ControlPanel(this);
|
||||
this.env.OriginOfLife();
|
||||
@@ -21,7 +23,7 @@ class Engine{
|
||||
this.fps = fps;
|
||||
this.game_loop = setInterval(function(){this.update();}.bind(this), 1000/fps);
|
||||
this.running = true;
|
||||
if (this.fps >= 45) {
|
||||
if (this.fps >= render_speed) {
|
||||
if (this.render_loop != null) {
|
||||
clearInterval(this.render_loop);
|
||||
this.render_loop = null;
|
||||
@@ -39,7 +41,7 @@ class Engine{
|
||||
|
||||
setRenderLoop() {
|
||||
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,9 +50,12 @@ class Engine{
|
||||
this.delta_time = Date.now() - this.last_update;
|
||||
this.last_update = Date.now();
|
||||
this.env.update(this.delta_time);
|
||||
this.env.render();
|
||||
this.actual_fps = 1/this.delta_time*1000;
|
||||
this.controlpanel.update();
|
||||
if(this.render_loop == null){
|
||||
this.env.render();
|
||||
this.controlpanel.update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class Environment{
|
||||
var to_remove = [];
|
||||
for (var i in this.organisms) {
|
||||
var org = this.organisms[i];
|
||||
if (!org.update()) {
|
||||
if (!org.living || !org.update()) {
|
||||
to_remove.push(i);
|
||||
}
|
||||
}
|
||||
@@ -42,9 +42,9 @@ class Environment{
|
||||
OriginOfLife() {
|
||||
var center = this.grid_map.getCenter();
|
||||
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.producer, 0, 0);
|
||||
// org.addCell(CellTypes.mouth, 1, -1);
|
||||
this.addOrganism(org);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
var Modes = require("./ControlModes");
|
||||
const CellTypes = require("./CellTypes");
|
||||
|
||||
class EnvironmentController{
|
||||
constructor(env, canvas) {
|
||||
@@ -7,21 +9,15 @@ class EnvironmentController{
|
||||
this.mouse_y;
|
||||
this.mouse_c;
|
||||
this.mouse_r;
|
||||
this.mouse_down = false;
|
||||
this.left_click = false;
|
||||
this.right_click = false;
|
||||
this.cur_cell = null;
|
||||
this.cur_org = null;
|
||||
this.mode = Modes.None;
|
||||
this.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 => {
|
||||
var prev_cell = this.cur_cell;
|
||||
var prev_org = this.cur_org;
|
||||
@@ -43,7 +39,67 @@ class EnvironmentController{
|
||||
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
|
||||
//check nearby locations (is there room and a direct path)
|
||||
var org = new Organism(0, 0, this.env, this);
|
||||
if (Math.random() * 100 <= this.mutability) {
|
||||
if (Math.random() * 100 <= 3) {
|
||||
org.mutate();
|
||||
}
|
||||
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_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.r = new_r;
|
||||
this.env.addOrganism(org);
|
||||
@@ -125,13 +125,13 @@ class Organism {
|
||||
// add cell
|
||||
var type = CellTypes.getRandomLivingType();
|
||||
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 growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
|
||||
var c = branch.loc_col+growth_direction[0];
|
||||
var r = branch.loc_row+growth_direction[1];
|
||||
return this.addCell(type, c, r);
|
||||
}
|
||||
// }
|
||||
}
|
||||
else if (choice == 1){
|
||||
// change cell
|
||||
@@ -211,7 +211,7 @@ class Organism {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user