Skip to content

Instantly share code, notes, and snippets.

@EmilyAShaw
Forked from dribnet/.block
Last active June 8, 2017 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EmilyAShaw/e60c23d4f2daf153fbc6a7e5d1410bc4 to your computer and use it in GitHub Desktop.
Save EmilyAShaw/e60c23d4f2daf153fbc6a7e5d1410bc4 to your computer and use it in GitHub Desktop.
17.1.MDDN242 PS4
license: mit
// note: this file is poorly named - it can generally be ignored.
// helper functions below for supporting blocks/purview
function saveBlocksImages(doZoom) {
if(doZoom == null) {
doZoom = false;
}
// generate 960x500 preview.jpg of entire canvas
// TODO: should this be recycled?
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 960;
offscreenCanvas.height = 500;
var context = offscreenCanvas.getContext('2d');
// background is flat white
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 960, 500);
context.drawImage(this.canvas, 0, 0, 960, 500);
// save to browser
var downloadMime = 'image/octet-stream';
var imageData = offscreenCanvas.toDataURL('image/jpeg');
imageData = imageData.replace('image/jpeg', downloadMime);
p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');
// generate 230x120 thumbnail.png centered on mouse
offscreenCanvas.width = 230;
offscreenCanvas.height = 120;
// background is flat white
context = offscreenCanvas.getContext('2d');
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 230, 120);
if(doZoom) {
// pixelDensity does the right thing on retina displays
var pd = this._pixelDensity;
var sx = pd * mouseX - pd * 230/2;
var sy = pd * mouseY - pd * 120/2;
var sw = pd * 230;
var sh = pd * 120;
// bounds checking - just displace if necessary
if (sx < 0) {
sx = 0;
}
if (sx > this.canvas.width - sw) {
sx = this.canvas.width - sw;
}
if (sy < 0) {
sy = 0;
}
if (sy > this.canvas.height - sh) {
sy = this.canvas.height - sh;
}
// save to browser
context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
}
else {
// now scaledown
var full_width = this.canvas.width;
var full_height = this.canvas.height;
context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
}
imageData = offscreenCanvas.toDataURL('image/png');
imageData = imageData.replace('image/png', downloadMime);
p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
}

PS4 MDDN 242 2017

big bang simulation

This is my big bang simultion. It represents the process of hydogen fusion, with the lightest elements right at the start of the big bang.

There are five elements, 'agents'

hyrdrogen, Lithium, Beryllium, helium, and 'plasma'(nothing).

When the hydrogens bump together there is a process called fusion, where they fuse together to make a helium nucleus. Lithium and beryllium are trace elements, which is why they are smaller, and 90% of universe today is still constructed from hyrdrogen atoms.

there is also a feature when you can 'play god'. By using mouse over you can speed up the process of hydrogen fustion.

There are two variables called 'destroy'and 'destroyer' which you can swap the agents out of, this way you can chose which element you want to change into something else, like if you want to slow the process of the big bang, fusion could be the destroy and hydrogen could be the desroyer.

I also did this kind of thing with the fusion, you can change which elements collide and turn into another with the 'turnInto' variable. Another vairable is the radius, which roughly controls how fast the bang happens. If the radius is set to one, the big bang will happen instantly (more realistic). However if it is closer to 30, it will happen very slowly and gradually.

My Z_background is a representation of the sectors of elemetents in the shape of the sun. Helium is mostly int the centre because fusion occurs uner imense pressure, but there is also helium reactions around the outside, as it does not only happen in the center, but when hydrogens collide.

As a rule, they all start off moving in a random direction, none are stationary for the purpose that the big bang is never stationary.

all agents have the collision rule, they can tell which their neighbours are. Only when hydrogen collides together and when helium collides with hydrogen does a reaction occur.

function Agent1() {
// any variables you add here are for your own internal state
this.is_alive = false;
this.was_alive = false;
// setup is run when the agent is reset
// value is a number between 0 and 100
this.setup = function(value) {
if(value > 50) {
this.is_alive = true;
}
else {
this.is_alive = false;
}
this.was_alive = this.is_alive;
}
// this happens generally on mouse over
this.activate = function() {
this.is_alive = true;
}
// decide on your next move based on neighbors (but don't do it yet)
this.step = function(neighbors) {
var num_neighbors_alive = 0;
for(var i=0; i<neighbors.length; i++) {
if(neighbors[i].agent.is_alive) {
num_neighbors_alive = num_neighbors_alive + 1;
}
}
// lonliness
if (this.is_alive && num_neighbors_alive < 2) {
this.next_alive = false;
}
// overpopulation
else if (this.is_alive && num_neighbors_alive > 3) {
this.next_alive = false;
}
// reproduction
else if (this.is_alive == false && num_neighbors_alive == 3) {
this.next_alive = true;
}
// statis
else {
this.next_alive = this.is_alive;
}
}
// execute the next move you decided on
this.update_state = function() {
this.was_alive = this.is_alive;
this.is_alive = this.next_alive;
}
this.draw = function(size) {
stroke(0);
if(this.is_alive == true && this.was_alive == true) {
fill(255, 170, 0); //hydrogen
}
else if(this.is_alive == true && this.was_alive == false) {
fill(0, 244, 0);//berillym
}
else if(this.is_alive == false && this.was_alive == true) {
fill(244, 0, 0); //lithium
}
else {
fill(0, 0, 30);
}
rect(0, 0, size, size);
}
}
function Agent2() {
// any variables you add here are for your own internal state
this.power = 0.0;
this.next_power = 0.0;
// setup is run when the agent is reset
// value is a number between 0 and 100
this.setup = function(value, agent_type) {
this.power = value;
this.agent_type = agent_type;
this.next_power = this.power;
}
// this happens generally on mouse over
this.activate = function() {
this.power = 100.0;
}
// decide on your next move based on neighbors (but don't do it yet)
this.step = function(neighbors) {
var max_power = 0;
for(var i=0; i<neighbors.length; i++) {
if((this.agent_type == 0 && neighbors[i].y < 0) || (this.agent_type ==1 && neighbors[i].y >0)) {
if(neighbors[i].agent.power > max_power) {
max_power = neighbors[i].agent.power;
}
}
}
this.next_power = 0.8 * max_power;
if(this.next_power > 100) {
this.next_power = 100;
}
}
// execute the next move you decided on
this.update_state = function() {
this.power = this.next_power;
}
this.draw = function(size) {
// var half_size = size/2;
// var low = color(255, 255, 255);
// var high = color(193, 149, 229);
// var c = lerpColor(low, high, this.power / 50.0);
// var d = lerpColor(high, low, this.power / 50.0);
// stroke(0);
// noStroke();
// fill(c);
// ellipse(half_size, half_size, size/2, size/2);
// fill(d);
// ellipse(half_size, half_size, size/8, size/4);
// ellipse(half_size, half_size, size/4, size/8);
//dribnet
var half_size = size/2;
var low, high;
if(this.agent_type == 0) {
low = color(255, 255, 255);
high = color(193, 149, 229);
}
else {
low = color(244, 244, 244);
high = color(148, 224, 197);
}
noStroke();
// fill(c);
// ellipse(half_size, half_size, size/2, size/2);
// fill(d);
// ellipse(half_size, half_size, size/8, size/4);
// ellipse(half_size, half_size, size/4, size/8);
var c = lerpColor(low, high, this.power / 100.0);
var d = lerpColor(high, low, this.power / 50.0);
noStroke();
fill(c);
//ellipse(half_size, half_size, size, size);
fill(c);
ellipse(half_size, half_size, size/2, size/2);
fill(d);
ellipse(half_size, half_size, size/8, size/4);
ellipse(half_size, half_size, size/4, size/8);
}
}
function Agent3Preload() {
}
function Agent3() {
// any variables you add here are for your own internal state
// setup is run when the agent is reset
// value is a number between 0 and 100
this.setup = function(value, agent_type) {
this.agent_type = agent_type;
}
// mouse over triggers hydrogen fusion, changing agent 2 into agent 4. Playing god.
var destroy = 2; //the element you are destroying
var destroyer = 4; //the element it turns into
this.activate = function() {
scale(0.5);
if (this.agent_type==destroy){
scale(0.5);
this.agent_type = destroyer;}
}
// decide on your next move based on neighbors (but don't do it yet)
this.step = function(neighbors, radius) {
var r = 20;
this.close = false;
if(this.agent_type >= 0) {
v = p5.Vector.random2D().mult(radius/r);
for(var i=0; i<neighbors.length; i++) {
var npos = neighbors[i].pos;
var d = npos.mag();
if ((d > 0) && (d < radius + neighbors[i].radius)) {
this.close = true;
// Calculate vector pointing away from neighbor
var move_away = npos.mult(-1);
move_away.normalize();
move_away.div(d*0.1); // Weight by distance
v.add(move_away);
}
}
return v;
}
}
var turnInTo = 4;
this.fusion = function(){
this.agent_type = turnInTo;
}
function mouseClicked(){
fill(255,0,0);
rect(0,0,960,500);
}
this.draw = function(radius) {
stroke(0);
textSize(8);
if(this.close && this.agent_type==2) {
// sound.play(); tried to get a pop sound, code kept breaking
scale(3);
this.fusion();
}
else if(this.agent_type == 0) { //created transparent 'plasma'. I did this because ititiall I had
//black to fill the 'void' as back then there was nothing, but it did not look aesthetically nice.
image(plasma,0,0,radius*2, radius*2);
}
else if(this.agent_type == 1) { //BERYLLIUM
fill(109, 181, 94); //proton color
noStroke();
ellipse(7, -3, radius/2, radius/2); //right proton
ellipse(-7, -3, radius/2, radius/2);//left proton
ellipse(0,7, radius/2, radius/2); //bottom proton
fill(150, 237, 132);
ellipse(4,4, radius/2, radius/2); //neutron
ellipse(-4,4, radius/2, radius/2); //neutron
ellipse(0,-4, radius/2, radius/2); //neutron
fill(109, 181, 94); //proton color
ellipse(0, 1, radius/2, radius/2); //middle proton
}
else if(this.agent_type == 2) { //hydrogen
scale(0.7);
fill(255, 170, 0);
noStroke();
ellipse(0, 0, radius*4, radius*4);
stroke('red');
noFill();
fill(255,0,0);
//ellipse(0,0,radius/2, radius/2);
//text("H", -4, 5);
noFill();
// ellipse(0,0,radius*2, radius*2);
fill(255, 170, 0);
}
else if(this.agent_type == 3) { //LITHIUM
fill(170, 215, 239); //neutron color
noStroke();
ellipse(7, -3, radius, radius); //right neutron
ellipse(-7, -3, radius, radius);//left neutron
ellipse(0,7, radius, radius); //bottom neutron
fill(121, 191, 229); //proton color
ellipse(4,4, radius, radius); //proton
ellipse(-4,4, radius, radius); //proton
ellipse(0,-4, radius, radius); //proton
fill(170, 215, 239); //neutron color
ellipse(0, 1, radius, radius); //middle neutron
}
else if(this.agent_type == 4) {
scale(4);
image(atomicImage, -10, -10, radius*2, radius*2); //fusion
}
}
}
function hydrogen (x,y){
ellipse(x,y, radius, radius);
}
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="agent3.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.0;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>World</td>
<td id="selector1Container"></td>
</tr>
<tr>
<td>Size</td>
<td id="selector2Container"></td>
</tr>
<tr>
<td>Speed</td>
<td id="selector3Container"></td>
</tr>
<tr>
<td></td>
<td id="playButtonContainer"></td>
</tr>
<tr>
<td></td>
<td id="clearButtonContainer"></td>
</tr>
<tr>
<td></td>
<td id="checkContainer"></td>
</tr>
</div>
</div>
</table>
</body>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="clock.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
</div>
</table>
</body>
var canvasWidth = 960;
var canvasHeight = 500;
var is_playing = false;
var show_oddball = false;
var modeSelector;
var sizeSelector;
var speedSelector;
var max_vals = [360, 100, 100];
var allAgents = [];
var numActiveAgents = 0;
var clearButton, randomButton, playButton, stepButton, stopButton;
var backgroundImage = null;
var agentLookupWidth = 1;
var agentLookupHeight = 1;
var agentLookupTable = [0];
var haveSeenMovement = false;
function preload() {
backgroundImage = loadImage("z_background.jpg");
atomicImage = loadImage("atomic.png");
plasma = loadImage("plasma.png");
//pop = loadSound("pop.mp3");
// this is called for static assets your agents need
Agent3Preload();
}
function setup() {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
modeSelector = createSelect();
modeSelector.option('grid');
modeSelector.option('hexgrid');
// modeSelector.option('vornoi');
// modeSelector.option('freestyle');
modeSelector.changed(gridTypeChanged);
modeSelector.value('hexgrid');
modeSelector.parent('selector1Container');
sizeSelector = createSelect();
sizeSelector.option('16');
sizeSelector.option('32');
sizeSelector.option('64');
sizeSelector.option('128');
sizeSelector.option('256');
sizeSelector.parent('selector2Container');
sizeSelector.value('32');
sizeSelector.changed(sizeChangedEvent);
speedSelector = createSelect();
speedSelector.option('1');
speedSelector.option('2');
speedSelector.option('5');
speedSelector.option('10');
speedSelector.option('24');
speedSelector.option('60');
speedSelector.parent('selector3Container');
speedSelector.value('10');
speedSelector.changed(speedChangedEvent);
stepButton = createButton('step');
stepButton.mousePressed(stepButtonPressedEvent);
stepButton.parent('playButtonContainer');
playButton = createButton('play');
playButton.mousePressed(playButtonPressedEvent);
playButton.parent('playButtonContainer');
// stopButton = createButton('stop');
// stopButton.mousePressed(stopButtonPressedEvent);
// stopButton.parent('playButtonContainer');
clearButton = createButton('reset');
clearButton.mousePressed(clearButtonPressedEvent);
clearButton.parent('clearButtonContainer');
randomButton = createButton('random');
randomButton.mousePressed(randomButtonPressedEvent);
randomButton.parent('clearButtonContainer');
// guideCheckbox = createCheckbox('', false);
// guideCheckbox.parent('checkContainer');
// guideCheckbox.changed(guideChangedEvent);
// setup lookup table from pixels
backgroundImage.loadPixels();
var p = backgroundImage.pixels;
agentLookupHeight = backgroundImage.height;
agentLookupWidth = backgroundImage.width;
agentLookupTable = new Array(agentLookupHeight);
for(var j=0; j<agentLookupHeight; j++) {
agentLookupTable[j] = new Array(agentLookupWidth);
for(var i=0; i<agentLookupWidth; i++) {
var ix = 4 * (j * agentLookupWidth + i);
if(p[ix] > 128 && p[ix+1] > 128 && p[ix+2] > 128) {
// white
agentLookupTable[j][i] = 0;
}
else if(p[ix] < 128 && p[ix+1] < 128 && p[ix+2] < 128) {
// black
agentLookupTable[j][i] = 1;
}
else if(p[ix] > p[ix+1] && p[ix] > p[ix+2] ) {
// red-ish
agentLookupTable[j][i] = 2;
}
else if(p[ix+1] > p[ix] && p[ix+1] > p[ix+2] ) {
// green-ish
agentLookupTable[j][i] = 3;
}
else {
agentLookupTable[j][i] = 4;
}
}
}
noLoop();
refreshGridData();
modeChangedEvent();
speedChangedEvent();
playButtonPressedEvent();
}
/*
function mouseClicked() {
if (mouseX > width/4) {
refreshGridData();
}
redraw();
}
*/
var numGridRows;
var numGridCols;
var gridValues; // row, col order
var gridOffsetX, gridOffsetY;
var gridSpacingX, gridSpacingY;
// Generate data for putting glyphs in a grid
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function getNewAgent() {
a = new Agent3();
return a;
}
function lookupAgentType(x, y, size) {
s2 = size/2;
x += s2;
y += s2;
if(x < 0 || y < 0 || x >= canvasWidth || y >= canvasHeight) {
print("ERROR");
return 0;
}
var ix = int(map(x, 0, canvasWidth, 0, agentLookupWidth));
var iy = int(map(y, 0, canvasHeight, 0, agentLookupHeight));
return agentLookupTable[iy][ix];
}
function refreshGridData() {
var mode = modeSelector.value();
var glyphSize = parseInt(sizeSelector.value(), 10);
if (mode == "hexgrid") {
if(glyphSize == 16) {
numGridCols = 58;
numGridRows = 33;
gridOffsetX = 20;
gridSpacingX = 16;
gridOffsetY = 1;
gridSpacingY = 15;
}
if(glyphSize == 32) {
numGridCols = 30;
numGridRows = 17;
gridOffsetX = 10;
gridSpacingX = 31;
gridOffsetY = 2;
gridSpacingY = 29;
}
else if(glyphSize == 64) {
numGridCols = 13;
numGridRows = 7;
gridOffsetX = 35;
gridSpacingX = 66;
gridOffsetY = 35;
gridSpacingY = 59;
}
else if(glyphSize == 128) {
numGridCols = 7;
numGridRows = 4;
gridOffsetX = 10;
gridSpacingX = 132;
gridOffsetY = 0;
gridSpacingY = 118;
}
else if(glyphSize == 256) {
numGridCols = 3;
numGridRows = 2;
gridOffsetX = 96;
gridSpacingX = 262;
gridOffsetY = 0;
gridSpacingY = 234;
}
}
else if(glyphSize == 128) {
numGridCols = 7;
numGridRows = 3;
gridOffsetX = 10;
gridSpacingX = 136;
gridOffsetY = 20;
gridSpacingY = 166;
}
else if(glyphSize == 256) {
numGridCols = 3;
numGridRows = 1;
gridOffsetX = 20;
gridSpacingX = 320;
gridOffsetY = 100;
gridSpacingY = 500;
}
else if(glyphSize == 64) {
numGridCols = 14;
numGridRows = 7;
gridOffsetX = 3;
gridSpacingX = 68;
gridOffsetY = 6;
gridSpacingY = 71;
}
else if(glyphSize == 32) {
numGridCols = 24;
numGridRows = 13;
gridOffsetX = 4;
gridSpacingX = 40;
gridOffsetY = 4;
gridSpacingY = 38;
}
else if(glyphSize == 16) {
numGridCols = 48;
numGridRows = 25;
gridOffsetX = 1;
gridSpacingX = 20;
gridOffsetY = 1;
gridSpacingY = 20;
}
// this updates the grid to account for center spacing
gridOffsetX += glyphSize/2;
gridOffsetY += glyphSize/2;
// determine active agents and reset
numActiveAgents = 0;
var hexOffset = (mode == "hexgrid");
gridValues = new Array(numGridRows);
for (var i=0; i<numGridRows; i++) {
var tweakedNumGridCols = numGridCols;
if (hexOffset && i%2 == 1) {
tweakedNumGridCols = numGridCols - 1;
}
gridValues[i] = new Array(tweakedNumGridCols);
for (var j=0; j<tweakedNumGridCols; j++) {
if(numActiveAgents >= allAgents.length) {
allAgents.push(getNewAgent());
}
gridValues[i][j] = allAgents[numActiveAgents];
numActiveAgents = numActiveAgents + 1;
}
}
// assign positions
for (var i=0; i<numGridRows; i++) {
var tweakedNumGridCols = numGridCols;
var offsetX = 0;
if (hexOffset && i%2 == 1) {
offsetX = gridSpacingX / 2;
tweakedNumGridCols = numGridCols - 1;
}
for (var j=0; j<tweakedNumGridCols; j++) {
gridValues[i][j]._x = gridOffsetX + j * gridSpacingX + offsetX;
gridValues[i][j]._y = gridOffsetY + i * gridSpacingY;
gridValues[i][j]._type = lookupAgentType(gridValues[i][j]._x, gridValues[i][j]._y, glyphSize);
if(gridValues[i][j]._type > 1) {
gridValues[i][j]._static = false;
gridValues[i][j]._size = glyphSize/4;
}
else {
gridValues[i][j]._static = true;
gridValues[i][j]._size = glyphSize/2;
}
}
}
// setup
for (var i=0; i<numActiveAgents; i++) {
var agent = allAgents[i];
agent.setup(0, agent._type);
}
// compute neighbors
computeNeighbors(glyphSize);
}
function computeNeighbors(glyphSize) {
var mode = modeSelector.value();
var hexOffset = (mode == "hexgrid");
for (var i=0; i<numActiveAgents; i++) {
allAgents[i]._neighbors = []
}
var dist_thresh = 2.0;
if(hexOffset) {
dist_thresh = 1.4;
}
for (var i=0; i<numActiveAgents; i++) {
var agent = allAgents[i];
// agent.setup(0, agent._type);
for (var j=i+1; j<numActiveAgents; j++) {
var other = allAgents[j]
var d = dist(agent._x, agent._y, other._x, other._y) / glyphSize
if (d < dist_thresh) {
var o1 = {
'distance': d,
'agent': other,
'radius': other._size,
'x': other._x - agent._x,
'y': other._y - agent._y,
'pos': createVector(other._x - agent._x, other._y - agent._y)
}
agent._neighbors.push(o1)
var o2 = {
'distance': d,
'agent': agent,
'radius': agent._size,
'x': agent._x - other._x,
'y': agent._y - other._y,
'pos': createVector(agent._x - other._x, agent._y - other._y)
}
other._neighbors.push(o2)
}
}
}
}
function speedChangedEvent() {
var speed = parseInt(speedSelector.value(), 10);
frameRate(speed)
}
function sizeChangedEvent() {
var mode = modeSelector.value();
refreshGridData();
redraw();
}
function guideChangedEvent() {
show_oddball = guideCheckbox.checked();
redraw();
}
function modeChangedEvent() {
var mode = modeSelector.value();
if (is_playing) {
playButton.elt.textContent = "pause";
stepButton.attribute('disabled','');
// stopButton.removeAttribute('disabled');
}
else {
playButton.elt.textContent = "play";
stepButton.removeAttribute('disabled');
// stopButton.attribute('disabled','');
}
if (mode === "drive") {
// disable the button
// button.attribute('disabled','');
// enable the size selector
sizeSelector.removeAttribute('disabled');
}
else {
// enable the button
// button.removeAttribute('disabled');
// enable the size selector
// sizeSelector.removeAttribute('disabled');
// refresh data
// refreshGridData();
}
if (mode === "hexgrid") {
// refresh data
// refreshGridData();
}
redraw();
}
function gridTypeChanged() {
modeChangedEvent();
refreshGridData();
redraw();
}
function clearButtonPressedEvent() {
refreshGridData();
for(var i=0; i<numActiveAgents; i++) {
var agent = allAgents[i];
agent.setup(0, agent._type);
}
redraw();
}
function randomButtonPressedEvent() {
// refreshGridData();
for(var i=0; i<numActiveAgents; i++) {
var agent = allAgents[i];
agent.setup(random(100), agent._type);
}
redraw();
}
function playButtonPressedEvent() {
if(is_playing) {
is_playing = false
noLoop();
}
else {
is_playing = true;
loop();
}
modeChangedEvent()
// refreshGridData();
redraw();
}
function stepButtonPressedEvent() {
is_playing = true;
// refreshGridData();
redraw();
is_playing = false;
}
function stopButtonPressedEvent() {
// refreshGridData();
redraw();
}
var colorBack = "rgb(232, 232, 232)"
function highlightGlyph(glyphSize) {
halfSize = glyphSize / 2.0;
stroke(0, 0, 255, 128);
noFill();
strokeWeight(4);
ellipse(halfSize, halfSize, glyphSize+4);
fill(0);
strokeWeight(1);
}
function drawGrid() {
var glyphSize = parseInt(sizeSelector.value(), 10);
background(255);
for (var i=0; i<numActiveAgents; i++) {
resetMatrix();
agent = allAgents[i];
translate(agent._x, agent._y);
agent.draw(agent._size);
resetMatrix();
if (show_oddball) {
translate(agent._x, agent._y);
highlightGlyph(glyphSize)
}
}
}
function clamp(num, min, max) {
return num <= min ? min : num >= max ? max : num;
}
function stepGrid() {
var glyphSize = parseInt(sizeSelector.value(), 10);
var radius = glyphSize / 2;
var min_x = int(0);
var min_y = int(0);
var max_x = int(canvasWidth - radius) - 1;
var max_y = int(canvasHeight - radius) - 1;
var updatedAgents = new Array(numActiveAgents);
for (var i=0; i<numActiveAgents; i++) {
// make a shallow copy of the agent
agent = allAgents[i];
var clone = Object.assign({}, agent);
agent._new_me = clone;
var movement = clone.step(clone._neighbors, clone._size);
if(typeof movement !== 'undefined') {
haveSeenMovement = true;
var new_x = clone._x + movement.x;
var new_y = clone._y + movement.y;
clone._x = clamp(new_x, min_x, max_x);
clone._y = clamp(new_y, min_y, max_y);
}
updatedAgents[i] = clone;
}
for (var i=0; i<numActiveAgents; i++) {
allAgents[i] = updatedAgents[i];
}
if(haveSeenMovement) {
// copy new version of neighbors
computeNeighbors(glyphSize);
}
else {
for (var i=0; i<numActiveAgents; i++) {
agent = allAgents[i];
var old_neighbors = agent._neighbors;
for(var j=0; j<old_neighbors.length; j++) {
if ('_new_me' in old_neighbors[j].agent) {
agent._neighbors[j].agent = agent._neighbors[j].agent._new_me;
}
}
}
// weakly check optimization assertion (not a memory leak)
for (var i=0; i<numActiveAgents; i++) {
if ('_new_me' in allAgents[i]) {
print("you flubbed the _new_me setup");
}
}
}
}
function activateGrid(x, y) {
var glyphSize = parseInt(sizeSelector.value(), 10);
for (var i=0; i<numActiveAgents; i++) {
agent = allAgents[i];
if( (agent._x <= x) && (agent._x + glyphSize > x) &&
(agent._y <= y) && (agent._y + glyphSize > y) ) {
agent.activate();
}
}
}
function mouseClicked () {
activateGrid(mouseX, mouseY);
drawGrid();
}
function draw () {
var mode = modeSelector.value();
// first do all steps
if (is_playing) {
stepGrid();
}
// then do activate
activateGrid(mouseX, mouseY);
// the do all draws
drawGrid();
resetMatrix();
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
else if (key == ' ') {
playButtonPressedEvent();
}
else if (key == 's') {
var old_value = guideCheckbox.checked();
guideCheckbox.checked(!old_value);
guideChangedEvent();
}
else if (key == '1') {
sizeSelector.value('16');
sizeChangedEvent()
}
else if (key == '2') {
sizeSelector.value('32');
sizeChangedEvent()
}
else if (key == '3') {
sizeSelector.value('64');
sizeChangedEvent()
}
else if (key == '4') {
sizeSelector.value('128');
sizeChangedEvent()
}
else if (key == '5') {
sizeSelector.value('256');
sizeChangedEvent()
}
else if (key == 'd') {
modeSelector.value('drive');
modeChangedEvent()
}
else if (key == 'g') {
modeSelector.value('grid');
gridTypeChanged()
}
else if (key == 'r') {
modeSelector.value('random');
modeChangedEvent()
}
else if (key == 'h') {
modeSelector.value('hexgrid');
gridTypeChanged()
}
}
function keyPressed() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment