I have worked through the tutorial on creating a jigsaw puzzle. I am just wondering if I can extend the code to have a button that will regenerate the puzzle. I have the button (replay) with a listener. I can hide the tick that appears when the puzzle is completed, but I can't seem to regenerate the puzzle.
Here is the code, and I have attached the compressed Animate files.
If you get a moment, would you mind looking to see if this is possible.
20_bike-puzzle-zim.zip (835.7 KB)
const tick = zimify(this.tick);
tick.vis(false);
replay = zimify(this.replay)
//const puzzle;
F.loadAssets("bike.png", "pics/");
F.on("complete", () => {
const pic = new Pic("bike.png");
const puzzle = new Scrambler(chop((pic), 3, 1))
.sca(.8)
.center();
puzzle.on("complete", ()=>{
tick.vis(true);
puzzle.scramble(1, 2, 3);
});
});
replay.addEventListener("click", reset.bind(this));
function reset() {
tick.vis(false);
//puzzle.scramble(1, 2, 3);
}
You just have to make your code more modular. So instead of creating the puzzle on load complete. Wrap that in a function like makePuzzle()
. Then include a way to dispose of the puzzle then recreate it. Here is an example:
I have been able to get to the point where I can press the replay button and generate the puzzle. The one thing I cannot work out is how to get rid of the old puzzle when a new one is generated. The new one that is generated sits on top of the old one and keeps piling the puzzles on top of each other. I wonder if you can see what I have missed. I think it may have to do with the dispose(0 command, but not quite sure.
Here is the code, and I will attach the full folder to see what I mean. I am SO close!!!
const tick = zimify(this.tick);
tick.vis(false);
replay = zimify(this.replay)
let puzzle;
replay.addEventListener("click", reset.bind(this));
function reset() {
if(puzzle) puzzle.dispose();
puzzle=null;
stage.update();
tick.vis(false);
F.loadAssets("bike.png", "pics/");
F.on("complete", () => {
const pic = new Pic("bike.png");
const puzzle = new Scrambler(chop((pic), 3, 1))
.sca(.8)
.center();
puzzle.on("complete", ()=>{
tick.vis(true);
});
});
}
jigsaw1.zip (834.7 KB)
If puzzle.dispose() isn't doing it, maybe try this:
if (puzzle) {
puzzle.dispose();
puzzle.parent.removeChild(puzzle);
// or puzzle.parent?.removeChild(puzzle);
}
...alternatively if you don't care about the "if" as visual clue of replaying, drop the if...
puzzle?.dispose();
puzzle?.parent?.removeChild(puzzle);
@rodecss I see your issue. You are declaring a puzzle
variable that is accessible to child functions but in F.on(complete)
you are declaring it's own puzzle
variable which never sets your global puzzle
variable. Just remove const
.
NEW CODE:
const tick = zimify(this.tick);
tick.vis(false);
replay = zimify(this.replay)
let puzzle;
replay.addEventListener("click", reset.bind(this));
function reset() {
if(puzzle) puzzle.dispose();
puzzle=null;
stage.update();
tick.vis(false);
F.loadAssets("bike.png", "pics/");
F.on("complete", () => {
const pic = new Pic("bike.png");
puzzle = new Scrambler(chop((pic), 3, 1))
.sca(.8)
.center();
puzzle.on("complete", ()=>{
tick.vis(true);
});
});
}
1 Like
Success - thank you very much for your help.
1 Like