-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsketch.js
163 lines (139 loc) · 4.4 KB
/
sketch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
'use strict';
// TODO add a gui menu from which user can interact
// with ruleset as json, tempo can be changed, infinity
// mode can be toggled, and midi data can be downloaded
//options (TODO make at least some of these dynamically generated based on window size)
const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;
const RADIUS = window.innerHeight / 18;
const TEMPO = 2; //bps
const FONTSIZE = window.innerHeight / 30;
const FONTSIZE_SMALL = FONTSIZE / 2;
// representation
var grid;
var gridView;
var ruleGrid;
var ruleGridView;
var defaultToast;
var notes;
var stepTimer;
var font;
// state of application
var isPaused = true;
var isRuleMaker = false;
var isloaded = false;
var isToasting = false;
var isFreePlay = false;
// load fonts and plugins before setup
function preload() {
// Ensure the .ttf or .otf font stored in the assets directory
// is loaded before setup() and draw() are called
font = loadFont('./assets/ABeeZee/ABeeZee-Regular.otf');
// load the midi soundfont
MIDI.loadPlugin({
soundfontUrl: "./soundfont/",
instrument: "acoustic_grand_piano",
onsuccess: function() {
isloaded = true;
}
});
}
// Initialize canvas and application state
function setup() {
// Create canvas and main grid
createCanvas(WIDTH,HEIGHT);
// Set text characteristics
textFont(font);
textSize(FONTSIZE);
textAlign(CENTER, CENTER);
// initialize Jammer state
grid = new HexGrid(14, 8);
gridView = new HexGridView(grid, WIDTH / 2, HEIGHT / 2, RADIUS);
notes = new NoteMap(harmonicTableMidiLayout(95))
}
function draw() {
clear();
// Display the current state of the hex grid
gridView.display();
// Show different UI elements depending on the
// state of the application
if (isPaused && !isFreePlay) {
if (isRuleMaker) {
drawRuleMakerOverlay();
ruleGridView.display();
} else {
drawPauseOverlay();
}
}
toaster(defaultToast);
}
function pause() {
isPaused = true;
window.clearInterval(stepTimer);
}
function unpause() {
isPaused = false;
stepTimer = window.setInterval(timerUp, 1000 / TEMPO);
}
function startFreePlay() {
grid.clearState()
isFreePlay = true;
}
function timerUp() {
grid.step();
notes.playNotes(grid);
}
function startRuleGui() {
// Generate state for this new rule definition grid
ruleGrid = new HexGrid(10,5);
ruleGridView = new HexGridView(ruleGrid, WIDTH / 2, (HEIGHT / 2), RADIUS * 6/5);
// Trims grid down to a single neighborhood and a next state cell
shapeRuleGrid(ruleGrid);
// Causes draw to start rule definition mode
isRuleMaker = true;
}
function saveRule() {
let neighborhood = ruleGrid.getNeighborhoodStates(3, 2);
let nextState = ruleGrid.getState(9, 2);
grid.newRule(neighborhood, nextState);
}
// Grey out the current hex grid and overlay some instructions for
// how to use the rule maker gui
// TODO display all existing rules in minimap
function drawRuleMakerOverlay() {
// grey background
fill(200, 200, 200, 220);
noStroke();
rect(0, 0, WIDTH, HEIGHT);
// title and instructions of rule maker gui
fill(65);
stroke(100)
strokeWeight(1)
textSize(FONTSIZE)
text("New Transition Rule", WIDTH / 2, HEIGHT / 16);
textSize(FONTSIZE_SMALL)
text("The complex on the left is the pattern which incites state transition, and the hex on the right represents the state to transition to.", WIDTH / 2, HEIGHT / 16 + 60);
text("Click to toggle tile states - Press Enter to save a new transition rule - Press Esc to exit the rule maker", WIDTH / 2, HEIGHT - HEIGHT / 16);
// nice little arrow showing transition direction between
// the current neighborhood and the next state
drawArrow(WIDTH * 18/32, HEIGHT / 2 - RADIUS / 2, WIDTH * 21/32, HEIGHT / 2 - RADIUS / 2);
}
// TODO make header clickable and plays one time crazy chord, or randomizes seed
// Draw the Jammer Logo at the top of page
function drawHeader() {
stroke(0);
fill(255);
strokeWeight(3);
textSize(FONTSIZE * 2)
text("JAMMER", WIDTH / 2, HEIGHT / 16);
}
// Draw the "paused" notifcation and control instructions
function drawPauseOverlay() {
stroke(100);
fill(100);
strokeWeight(1);
textSize(FONTSIZE);
text("Paused", WIDTH / 2, HEIGHT / 2);
textSize(FONTSIZE_SMALL);
text("Click to toggle tile states - Press R to define transition rules - Press Space to pause/unpause - Press P to enter free play mode", WIDTH / 2, HEIGHT - HEIGHT / 16);
}