Created
March 16, 2016 03:23
-
-
Save FreedomGrenade/4b17f3c1fbc7b56b1210 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PShape cube; | |
PShape hovercube; | |
Board b; | |
PVector tempMove = new PVector(); | |
boolean menuUp; | |
boolean win; | |
int newBoardSize; | |
int newLevelSize; | |
public void setup() { | |
size(1000, 1000, P3D); | |
strokeWeight(3); | |
cube = createShape(BOX, 1.0); | |
noStroke(); | |
hovercube = createShape(BOX, 1.0); // What's the equivalent of setNoStroke() ? | |
newBoardSize = 5; | |
newLevelSize = 20; | |
b = startNew(newBoardSize, newLevelSize); | |
} | |
public void draw() { | |
b.setPointingAt(mouseX, mouseY); // before drawing background as it draws over everything | |
background(45, 75, 80); | |
b.display(); | |
if (b.totalOn == 0) { | |
win = true; | |
menuUp = true; | |
} | |
if (menuUp) drawMenu(); | |
} | |
public void drawMenu() { | |
// eh.. | |
hint(DISABLE_DEPTH_TEST); | |
strokeWeight(10); | |
stroke(255); | |
fill(65, 75, 110); | |
textAlign(CENTER, CENTER); | |
rect(width*0.1, height*0.1, width*0.8, height*0.8); | |
fill(255); | |
noStroke(); | |
textSize(50*width*0.001); | |
if (win) { | |
text("YOU WIN!!!", width*0.1, height*0.1, width*0.8, height*0.1); | |
} else { | |
text("MENU", width*0.1, height*0.1, width*0.8, height*0.1); | |
} | |
textSize(30*width*0.001); | |
text("(Up, Down) Size : " + newBoardSize, width*0.1, height*0.3, width*0.8, height*0.2); | |
text("(Left, Right) Level : " + newLevelSize, width*0.1, height*0.5, width*0.8, height*0.2); | |
textSize(20*width*0.001); | |
if (!win) text("Press m to close menu", width*0.1, height*0.7, width*0.8, height*0.1); | |
text("Press Enter to Start New game", width*0.1, height*0.8, width*0.8, height*0.1); | |
hint(ENABLE_DEPTH_TEST); | |
} | |
public Board startNew(int size, int level) { | |
Board temp = new Board(size, width*0.5); | |
temp.randomize(level); | |
menuUp = true; | |
win = false; | |
return temp; | |
} | |
public class Bulb { | |
int offColor = color(0, 0, 0); | |
int onColor = color(255, 192, 64); | |
int strokeColor = color(255, 45, 45); | |
float rate = 0.05; | |
int state = 0; | |
float brightness = 0; | |
int x, y, z; | |
float xPos, yPos, zPos, size; | |
public Bulb(int x_, int y_, int z_, float xp, float yp, float zp, float s) { | |
x = x_; | |
y = y_; | |
z = z_; | |
xPos = xp; | |
yPos = yp; | |
zPos = zp; | |
size = s; | |
} | |
public void update() { | |
brightness += (state-brightness)<0 ? -rate : rate; | |
brightness = constrain(brightness, 0.0, 1.0); | |
} | |
public int toggle(boolean instant) { | |
state = 1-state; | |
if (instant) brightness = state; | |
return state*2 - 1; // state 0 return -1, state 1 return +1 (for detecting win) | |
} | |
public void display(float rotate, boolean hoverCheck) { | |
update(); | |
pushMatrix(); | |
float fc = frameCount*0.1; // make the game a little less static | |
float xoff = sin(yPos*zPos+fc)*2; | |
float yoff = sin(zPos*xPos+fc)*2; | |
float zoff = sin(xPos*yPos+fc)*2; | |
translate(xPos+xoff, yPos+yoff, zPos+zoff); | |
scale(size); | |
if (hoverCheck) { // to determine which bulb is under the cursor | |
hovercube.setFill(color(x, y, z)); | |
shape(hovercube); | |
} else { // draw normally | |
rotateX(rotate); | |
rotateZ(rotate); | |
cube.setStroke(strokeColor); | |
cube.setFill(lerpColor(offColor, onColor, brightness)); | |
shape(cube); | |
} | |
popMatrix(); | |
} | |
} | |
public class Board { | |
PVector up; // camera stuff | |
PVector pos; | |
float dist; | |
int totalOn; // lights on | |
Bulb[] bulbs; | |
int size, size2, size3; | |
float selectRotate = 0; | |
float rotateRate = 0.05; | |
float scrollMult = 10; | |
int pointingAt = -1; | |
public Board(int s, float blockSize) { | |
totalOn = 0; | |
resetCam(); | |
size = s; | |
size2 = s*s; | |
size3 = size2*size; | |
float spacingPercent = 1.5; | |
float bulbSize = blockSize / (spacingPercent*(size-1) + size); | |
float spacing = bulbSize*spacingPercent; | |
bulbs = new Bulb[size3]; | |
for (int z = 0; z < size; z++) { | |
for (int y = 0; y < size; y++) { | |
for (int x = 0; x < size; x++) { | |
int i = x*size2+y*size+z; | |
float xPos = x*(spacing+bulbSize) - blockSize*0.5 + bulbSize*0.5; | |
float yPos = y*(spacing+bulbSize) - blockSize*0.5 + bulbSize*0.5; | |
float zPos = z*(spacing+bulbSize) - blockSize*0.5 + bulbSize*0.5; | |
bulbs[i] = new Bulb(x, y, z, xPos, yPos, zPos, bulbSize); | |
} | |
} | |
} | |
} | |
public void randomize(int hits) { | |
if (hits == 0) return; | |
while (totalOn == 0) { // keep trying if this accidentally switches all the lights off again | |
for (int i = 0; i < hits; i++) { | |
press((int)random(size), (int)random(size), (int)random(size), true); | |
} | |
} | |
} | |
public void mousepress() { | |
if (pointingAt != -1) { | |
press(bulbs[pointingAt].x, bulbs[pointingAt].y, bulbs[pointingAt].z, false); | |
} | |
} | |
public void press(int x, int y, int z, boolean instant) { | |
toggle(x+1, y, z, instant); | |
toggle(x-1, y, z, instant); | |
toggle(x, y+1, z, instant); | |
toggle(x, y-1, z, instant); | |
toggle(x, y, z+1, instant); | |
toggle(x, y, z-1, instant); | |
toggle(x, y, z, instant); | |
} | |
public void toggle(int x, int y, int z, boolean instant) { // toggle bulb at x,y,z | |
if (x < 0 || y < 0 || z < 0) return; | |
if (x >= size || y >= size || z>= size) return; | |
totalOn+=bulbs[x*size2+y*size+z].toggle(instant); | |
} | |
public void resetCam() { | |
dist = height*0.866; | |
pos = new PVector(0, 0, dist); | |
up = new PVector(0, -1, 0); | |
} | |
public void rot(float xamt, float yamt) { | |
PVector center = pos.copy(); // vector from position to center center vector = 0,0,0 - pos.x,y,z | |
center.mult(-1); | |
center.normalize(); | |
PVector right = up.cross(center); // find the right --> vector | |
right.normalize(); | |
pos.add(PVector.mult(up, -yamt)); // -1 = up | |
pos.add(PVector.mult(right, xamt)); | |
pos.setMag(dist); // stick position back on sphere around puzzle | |
center.set(pos); // same as above for new position | |
center.mult(-1); | |
center.normalize(); | |
up = center.cross(right); // recreate up vector | |
up.normalize(); | |
} | |
public void zoom(int amount) { | |
dist = constrain(dist+ amount*10, height*0.5, height*2); | |
pos.setMag(dist); | |
} | |
public void display() { | |
display(false); | |
} | |
public void display(boolean hoverCheck) { | |
pushMatrix(); | |
camera(pos.x, pos.y, pos.z, 0, 0, 0, up.x, up.y, up.z); | |
for (int i = 0; i < size3; i++) { | |
bulbs[i].display(i == pointingAt ? selectRotate : 0.0, hoverCheck); // if this (i) is the one pointed at, rotate it | |
} | |
popMatrix(); | |
} | |
public void setPointingAt(int screenX, int screenY) { | |
int result = -1; // -1 = nothing selected | |
// | |
background(255); | |
display(true); | |
int pixelCol = get(screenX, screenY); // pixel color of colored overlay (each bulb is colored differently) | |
int x = ((pixelCol >> 16) & 255); | |
int y = ((pixelCol >> 8) & 255); | |
int z = ((pixelCol) & 255); | |
if (x>= 0 && y>=0 && z>=0 && x<size && y<size && z<size) { // ignore background | |
result = x*size2 + y*size + z; | |
} | |
if (result != pointingAt) { | |
selectRotate = 0; // reset rotate angle if target is different | |
} else { | |
selectRotate += rotateRate; | |
} | |
pointingAt = result; | |
} | |
} | |
public void mousePressed() { | |
if (mouseButton == LEFT) { | |
b.mousepress(); | |
} | |
} | |
public void keyPressed() { | |
if (key == ' ') b.resetCam(); | |
if (key == ENTER || key == RETURN) { | |
b = startNew(newBoardSize, newLevelSize); | |
menuUp = false; | |
return; | |
} | |
if (key == CODED) { | |
if (menuUp) { | |
if (keyCode == LEFT) newLevelSize--; | |
if (keyCode == RIGHT) newLevelSize++; | |
if (keyCode == UP) newBoardSize++; | |
if (keyCode == DOWN) newBoardSize--; | |
newLevelSize = constrain(newLevelSize, 1, 100); | |
newBoardSize = constrain(newBoardSize, 2, 6); | |
} | |
} | |
if (!win && (key == 'm' || key== 'M')) menuUp = !menuUp; | |
} | |
public void mouseWheel(MouseEvent e) { | |
b.zoom(e.getCount()); | |
} | |
public void mouseDragged() { | |
if (mouseButton == RIGHT) { | |
int mx = mouseX - pmouseX; | |
int my = mouseY - pmouseY; | |
b.rot(mx, my); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment