ArrayList tiles = new ArrayList(); ArrayList moving = new ArrayList(); boolean hasWon = false; boolean allValidPositions = false; void setup() { size(480, 800); int tileSize = 80; for (int y = 0; y < height; y+=tileSize) { for (int x = 0; x < width; x+=tileSize) { //println("[" + x + "," + y + "]: " + randomRotation); Tile tmp = new Tile(x, y, tileSize); tmp.shuffle(); tiles.add(tmp); } } noStroke(); } void draw() { background(128, 128, 128); allValidPositions = true; for (Tile tile : tiles) { if (!hasWon) { tile.update(); } tile.draw(); if (tile.getRotation() != 0) { allValidPositions = false; } } if (allValidPositions) { hasWon = true; textSize(48); String message = "You Win!"; float offset = textWidth(message); float ascent = textAscent(); fill(255, 255, 255); stroke(0, 0, 0); rect(width / 4, (height / 2) - ascent * 2, width / 2, ascent *2); fill(0, 0, 0); text(message, (width - offset) / 2, (height - ascent) / 2); } } void shuffleTiles() { for (Tile tile : tiles) { tile.shuffle(); } } void mouseReleased() { if (allValidPositions && hasWon) { allValidPositions = false; hasWon = false; shuffleTiles(); } else { for (Tile tile : tiles) { if (tile.isHovering(mouseX, mouseY)) { tile.setRotationTarget(tile.getRotationTarget() + 90); moving.add(tile); } } for (Tile tile : moving) { tiles.remove(tile); tiles.add(tile); } moving.clear(); } } class Tile { private PVector position = new PVector(); private PVector size = new PVector(); private color tileColor; private int rotation; private int rotationTarget; private color lineColor; private int rotationSpeed; public Tile(int x, int y, int tileSize) { this.position.x = x; this.position.y = y; this.size.x = tileSize; this.size.y = tileSize; this.tileColor = color(255, 255, 255); this.rotation = 0; this.rotationTarget = 0; this.lineColor = color(255, 255, 0); this.rotationSpeed = 5; } public void update() { if (this.isHovering(mouseX, mouseY)) { this.setColor(color(0, 255, 0)); } else { this.tileColor = color(100, 100, 100); } if (this.isAnimating()) { this.rotation += this.rotationSpeed; this.tileColor = color(255, 0, 0); } } public void draw() { noStroke(); fill(this.tileColor); pushMatrix(); translate(this.position.x + this.size.x / 2, this.position.y + this.size.y / 2); if (this.rotation >= 360) { this.rotation = 0; } rotate(this.rotation * (PI/180)); rect(-this.size.x / 2, -this.size.y / 2, this.size.x, this.size.y); stroke(this.lineColor); line(0, 0, this.size.x / 2, 0); popMatrix(); } public boolean isHovering(int mouseX, int mouseY) { if (mouseX >= this.position.x && mouseX < this.position.x + this.size.x) { //hovering within x if (mouseY >= this.position.y && mouseY < this.position.y + this.size.y) { return true; } } return false; } public void setColor(int newColor) { this.tileColor = newColor; } public void addRotation(int newRotation) { this.rotation += newRotation; } public void setRotationTarget(int newTarget) { this.rotationTarget = newTarget; while (this.rotationTarget >= 360) { this.rotationTarget -= 360; if (this.rotationTarget <= 0) { this.rotationTarget = 0; } } } public int getRotationTarget() { return this.rotationTarget; } public boolean isAnimating() { return this.rotation != this.rotationTarget; } public int getRotation() { return this.rotation; } public void shuffle() { int randomRotation = 90 * (int)random(0, 4); this.rotation = randomRotation; this.rotationTarget = randomRotation; } }