We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I've been using the Sprites library S4P_Jigsaw_Player example to build an interactive project. I want to draw other things on top of the jigsaw puzzle, but I can't figure out where in the code I can superimpose something in the void draw section. I've been testing it out by trying to place a random image on top of the puzzle, but the closest I've gotten to making something appear is by placing it in the keyPressed command section and then the image will flash for a second. Does anyone know how to do this?
import java.io.File;
import sprites.utils.*;
import sprites.maths.*;
import sprites.*;
final int SPLASH = 0;
final int TRANSITION_FROM_SPLASH = 1;
final int SOLVE_PUZZLE = 2;
final int VIEW_PIC = 4;
int mode = SPLASH;
int colBoard, colEdge;
ArrayList<Jigsaw> jigs;
int jSelect = 0;
int nextZ;
Jigsaw jigsaw;
PFont font;
String splashText = "[S] solve this one";
String inPlayText = "[N] New jigsaw puzzle : [V] View solution";
String viewSolutionText = "[B] Back to solving the puzzle";
int splashTextX, inPlayTextX, viewSolutionTextX;
float timeToSpread = 2.5f;
StopWatch sw = new StopWatch();
PImage horse;
void setup() {
size(800, 800);
//cursor(CROSS);
rectMode(CORNER);
colBoard = color(255);
colEdge = color(0, 0, 48);
font = createFont("Arial Black", 24);
textFont(font, 24);
splashTextX = (width - (int) textWidth(splashText))/2;
inPlayTextX = (width - (int) textWidth(inPlayText))/2;
viewSolutionTextX = (width - (int) textWidth(viewSolutionText))/2;
// Get a list of jigsaws
File data = new File(dataPath(""));
File[] jjigs = data.listFiles();
jigs = new ArrayList<Jigsaw>();
for(File f : jjigs){
if(f.isDirectory()){
String folder = f.getName();
if(folder.startsWith("JSP_"))
jigs.add(new Jigsaw(folder, width, height));
}
}
jSelect = 0;
jigsaw = jigs.get(jSelect);
sw.reset();
horse = loadImage("horse.jpg");
}
void draw() {
float elapsedTime = (float) sw.getElapsedTime();
background(255);
switch(mode) {
case SPLASH:
drawSplash();
break;
case TRANSITION_FROM_SPLASH:
drawSolutionTable();
S4P.updateSprites(elapsedTime);
S4P.drawSprites();
if (sw.getRunTime() >= timeToSpread) {
for (int p = 0; p < jigsaw.nbrPieces; p++) {
jigsaw.pieces[p].setVelXY(0, 0);
jigsaw.solved[p] = false;
}
mode = SOLVE_PUZZLE;
}
break;
case SOLVE_PUZZLE:
drawSolutionTable();
float inPlace = jigsaw.progress();
if (inPlace > 0) {
fill(128, 0, 0);
rect(0, 0, width * inPlace, 36);
fill(255);
text(nf(100 * inPlace, 2, 1) + "% solved", 5, 26);
}
fill(0);
text(inPlayText, inPlayTextX, height - 30);
S4P.drawSprites();
break;
case VIEW_PIC:
drawSolutionTable();
fill(0);
text(viewSolutionText, viewSolutionTextX, height - 30);
imageMode(CORNER);
image(jigsaw.picture, jigsaw.offX, jigsaw.offY);
break;
}
}
void drawSolutionTable() {
background(colBoard);
noStroke();
fill(colEdge);
rect(jigsaw.offX-10, jigsaw.offY-10, jigsaw.jWidth+20, jigsaw.jHeight+20);
fill(128);
rect(jigsaw.offX, jigsaw.offY, jigsaw.jWidth, jigsaw.jHeight);
}
void drawSplash() {
imageMode(CORNER);
int fx = (width - (int) textWidth(jigsaw.title))/2;
fill(255);
text(jigsaw.title, fx, 100);
image(jigsaw.picture, jigsaw.offX, jigsaw.offY);
fill(0);
text(splashText, splashTextX, height -40);
}
void keyPressed() {
if (mode == SPLASH) {
if (key == 's' || key == 'S') {
jigsaw.loadPieces(this);
nextZ = 3000;
mode = TRANSITION_FROM_SPLASH;
prepareToSplitJigsaw();
sw.reset();
}
}
else if (mode == SOLVE_PUZZLE) {
if (key == 'n' || key == 'N') {
jigsaw.unloadPieces();
mode = SPLASH;
}
else if (key == 'v' || key == 'V') {
mode = VIEW_PIC;
}
}
//HERE'S WHERE I'VE PLACED THE HORSE CURRENTLY
else if (mode == VIEW_PIC) {
if (key == 'b' || key == 'B') {
mode = SOLVE_PUZZLE;
image(horse,0, 0);
}
}
}
void prepareToSplitJigsaw() {
drawSolutionTable();
int ex, ey;
for (int p = 0; p < jigsaw.nbrPieces; p++) {
do {
ex = (int) random(12, width - 24);
ey = (int) random(12, height - 24);
}
while (get (ex, ey) != colBoard);
float velX = ((float)(ex - jigsaw.px[p])) / timeToSpread;
float velY = ((float)(ey - jigsaw.py[p])) / timeToSpread;
jigsaw.pieces[p].setVelXY(velX, velY);
jigsaw.solved[p] = false;
}
}
void handleSpriteEvents(Sprite sprite) {
if (sprite.eventType == Sprite.PRESS) {
sprite.setZorder(nextZ++); // bring to front
}
else if (sprite.eventType == Sprite.RELEASE) {
int pn = sprite.tagNo; // get piece number
int deltaX = abs(jigsaw.px[pn] - round((float) sprite.getX()));
int deltaY = abs(jigsaw.py[pn] - round((float) sprite.getY()));
if (deltaX < 3 && deltaY < 3) {
sprite.setXY(jigsaw.px[pn], jigsaw.py[pn]);
jigsaw.solved[pn] = true;
}
else {
jigsaw.solved[pn] = false;
}
}
}
class Jigsaw {
String folder;
String title;
PImage picture;
int cols, rows, nbrPieces;
int pWidth, pHeight;
int jWidth, jHeight;
int offX, offY;
Sprite[] pieces = null;
int[] px = null;
int[] py = null;
boolean[] solved; // 0 = no, 1 = yes
Jigsaw(String folder, int w, int h) {
this.folder = folder;
picture = loadImage(this.folder + "/picture.jpg");
String[] info = loadStrings(this.folder + "/info.txt");
title = info[0];
cols = Integer.parseInt(info[1]);
rows = Integer.parseInt(info[2]);
pWidth = Integer.parseInt(info[3]);
pHeight = Integer.parseInt(info[4]);
nbrPieces = rows * cols;
jWidth = cols * pWidth;
jHeight = rows * pHeight;
offX = (w - jWidth)/2;
offY = (h - jHeight)/2;
}
void loadPieces(PApplet app) {
if (pieces == null) {
String fname;
pieces = new Sprite[nbrPieces];
px = new int[nbrPieces];
py = new int[nbrPieces];
solved = new boolean[nbrPieces];
int p = 0, x, y;
y = offY + pHeight/2;
for (int r = 0; r < rows; r++) {
x = offX + pWidth/2;
for (int c = 0; c < cols; c++) {
fname = folder + "/piece_" + nf(p, 3) + ".png";
int z = (int) random(1000, 2999);
px[p] = x;
py[p] = y;
pieces[p] = new Sprite(app, fname, z);
pieces[p].tagNo = p;
pieces[p].setXY(px[p], py[p]);
solved[p] = true;
pieces[p].respondToMouse(true);
pieces[p].setDraggable(true);
x += pWidth;
p++;
}
y += pHeight;
}
}
else {
resetPieces();
}
}
void resetPieces() {
for (int p = 0; p < nbrPieces; p++) {
int z = (int) random(1000, 2999);
pieces[p].setZorder(z, false);
pieces[p].setXY(px[p], py[p]);
solved[p] = true;
pieces[p].respondToMouse(true);
pieces[p].setDraggable(true);
S4P.registerSprite(pieces[p]);
}
S4P.sortZorder();
}
void unloadPieces() {
for (int p = 0; p < nbrPieces; p++) {
pieces[p].respondToMouse(false);
pieces[p].setDraggable(false);
S4P.deregisterSprite(pieces[p]);
}
}
// Returns true if all pieces in place
boolean isSolved() {
for (boolean b : solved)
if (!b) return false;
return true;
}
float progress() {
float count = 0;
for (boolean b : solved)
if (b) count++;
return count / nbrPieces;
}
}
Answers
To make the image permanent the image has to be drawn during the execution of the draw() method.
Create a global variable called showHorse
boolean showHorse;
change lines 149-155 to
else if (mode == VIEW_PIC) { if (key == 'b' || key == 'B') { mode = SOLVE_PUZZLE; showHorse = true; } }
When the key is pressed we will be in SOLVE_PUZZLE mode so in the draw method lines 81-93 become
There are other ways to do it but the sketch design is flexible in that it is easy to add your own modes to increase fucntionality.