added mouse controls

This commit is contained in:
MaxRobinsonTheGreat
2020-07-10 22:05:29 -06:00
parent 949d46e7c4
commit c39ece309d
10 changed files with 162 additions and 41 deletions

25
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

21
dist/css/style.css vendored
View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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
View File

@@ -0,0 +1,8 @@
const Modes = {
None: 0,
FoodDrop: 1,
WallDrop: 2,
ClickKill: 3
}
module.exports = Modes;

View File

@@ -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();
} }
} }

View File

@@ -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,9 +50,12 @@ 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;
this.controlpanel.update(); if(this.render_loop == null){
this.env.render();
this.controlpanel.update();
}
} }
} }

View File

@@ -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);
} }

View File

@@ -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();
}
}
} }

View File

@@ -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) {