How do I get a winning picture in a slide puzzle? - javascript

I make a slide puzzle game. When the puzzle is solved "won" should be displayed and the timer should stop.
I hope you can help me. Thanks.
Here is a link to the web editor for my puzzle link
Here is the part of the code but it doesn´t work:
function draw() {
if (isSolved()) {
console.log('SOLVED');
timerValue = 0;
text('Won', width/2, height/2);
}
}
function isSolved() {
for (let i = 0; i < plate.length - 1; i++) {
if (plate[i] !== tiles[i].index) {
return false;
}
}
return true;
}

P5JS is saying that createImage() was expecting Integer for the second parameter, received number instead. This can be solved by changing let img = createImage(w, h); tp let img = createImage(int(w), int(h));.
I'm not entirely sure if this helps, because I don't know how your puzzle works (how it's solved) so please tell me if this doesn't work and I'll investigate further.

Related

P5.Play - Collision problems

hoping someone can help me with this.
I'm trying to create a game where balloons get popped by bullet.
Sort of similar to balloons tower defence. My only problem is that the frames are drawn every 60 seconds and each loop happens once per 60 seconds meaning that the bullet getting removed happens before the balloons change.
So far I've got:
Bullet is fired.
Bullets checks whether it has hit a balloon.
If hit remove bullet and change blue balloon to red balloon.
This would be easier if there was some way of checking which bullet collides with which balloon but as far as I can tell through the P5.Play reference theres no way to do this.
Sorry if this is stupid question I feel like I've been stuck on this issue for ages :(
Thanks for the help!
Code:
Bullets:
function bulletTime() {
bullet = createSprite(player.position.x, player.position.y, 3, 10);
bullet.setSpeed(4, 270);
bullet.setCollider("rectangle", 0, -2, 3, 10);
bullet.debug = true;
bullet.addToGroup(bullets);
}
// deletes bullets when they leave the screen prevents memory overload
function bulletDelete(){
for (i = 0; i < bullets.length; i++) {
if (bullets[i].overlap(balloons)){
bullet2 = createSprite(bullets[i].position.x, bullets[i].position.y+3, 3, 10);
bullet2.addToGroup(bullets2);
bullets[i].remove();
setTimeout(bullet2.remove(),10);
}
}
}
Balloons:
// pops Balloons
function popBalloon(){
for (i = 0; i < balloons.length; i++) {
if (balloons[i].overlap(bullets2)) {
if (balloonsRed.contains(balloons[i])){
balloons[i].addImage("redPop",redPop);
balloons[i].changeAnimation("redPop");
balloons[i].remove();
score += 100;
}
if (balloonsBlue.contains(balloons[i]) ){
balloons[i].addImage("redBalloon",redBalloon);
balloons[i].changeAnimation("redBalloon");
balloons[i].addToGroup(recentlyHit);
}
}
}
}
In case anyone else has a similar issue. HardcoreGameDev had it right!
Here's the working code.
// pops Balloons
function popBalloon(){
for (j = 0; j < balloons.length; j++) {
for (i = 0; i < bullets.length; i++) {
if (bullets[i].overlap(balloons[j])){
if (balloonsRed.contains(balloons[j])){
bullets[i].remove();
balloons[j].remove();
return;
}
if (balloonsBlue.contains(balloons[j])){
print("blue")
bullets[i].remove();
balloon = createSprite(balloons[j].position.x, balloons[j].position.y, 30, 30);
balloon.addSpeed(0.5,90);
balloon.addToGroup(balloons);
balloon.debug = true;
balloon.addImage("red",redBalloon);
balloon.changeAnimation("red");
balloon.scale = 0.2;
balloon.setCollider("circle",0,0,120);
balloon.addToGroup(balloonsRed);
balloons[j].remove();
return;
}
}
}
}
}
I know the code is arbitrary at some points :)
Your issue seems to related to your step 3.
If hit remove bullet and change blue balloon to red balloon.
The bullet attempted to remove itself / delete when a collision happens.
This actually implemented as "when the bullet hit a balloon the bullet disappears", so the balloon may never detect any collisions.
Since the balloon states are triggered by bullet, the popBalloon function should be called inside bulletDelete to update the specific balloon that got hit.

Extreme Novice needing assistance with mousePressed() event

I am VERY new to P5.js/processing (taking programming for artists). I am trying to make a crude game where an image (Jar Jar) bounces across the screen and another image (lightsaber) that moves with the mouse and when the mouse attached image goes over the bouncing image then the lightsaber will be mirrored and activate a sound. If this at all makes sense...
I have the bouncing image part down so far, but I am unable to make the mousePressed() function work. like I mentioned, I need the "lightsaber.png" to flip when the mouse is pressed. Also, when the mouse is pressed and is directly over the JarJar image, how would I add a score count and sound event?
Thank you!
here is my code so far:
let jarJar;
let jarJarX=5;
let jarJarY=5;
let xspeed;
let yspeed;
let lightSaber;
function preload() {
jarJar = loadImage('jarjar.png');
lightSaber= loadImage ('lightSaber.png');
}
function setup() {
createCanvas(700,700);
xspeed=random (15,22);
yspeed=random (15,22);
}
function draw() {
background(0);
image (lightSaber,mouseX,mouseY,100,100);
image(jarJar,jarJarX,jarJarY, 140, 200);
jarJarX= jarJarX+xspeed;
if (jarJarX<=-300|| jarJarX>=width+200){
xspeed=xspeed*-1;
}
jarJarY= jarJarY+yspeed;
if (jarJarY<-200|| jarJarY>=height+200 ){
yspeed=yspeed*-1;
}
//picture mirrors when mouse pressed
if mouseClicked(){
scale(-1,1);
image(lightSaber);
}
//score counter coordinate with lightsaber hitting image
//
}
Let it be known that I'm not proficient at javaScript. This said, your question is quite simple so I can help anyway.
Some framework will have simple ways to mirror images. Processing likes to scale with a negative number. I re-coded some of your stuff to accommodate my changes. The main changes goes as follows:
I added a method to draw the lightsaber so we can "animate" it (read: flip it for a couple frames when the user clicks around).
I added a 'score' global variable to track the score, and a way for the user to see that score with the text method.
I added a method called "intersect" which isn't very well coded as it's something I did back when I was a student (please don't hurt me, it works just right so I still use it from time to time). For more details on how simple collisions works, take some time to read this answer I wrote some time ago, there are nice pictures too!
I added a mouseClicked method. This method will act like an event, which means that it will be triggered by a specific call (a left mouse button click in this case). This method contains the code to check for a collision between the squares which are the images. If there's an overlap, the score will increase and jarjar will run in another direction (this part is a bonus to demonstrate that this is the place where you can get creative about the collision).
I commented the code so you can get what I'm doing more easily:
let jarJar;
let jarJarX=5;
let jarJarY=5;
let xspeed;
let yspeed;
let lightSaber;
let flipLength;
let score = 0;
function preload() {
jarJar = loadImage('jarjar.png');
lightSaber= loadImage ('lightSaber.png');
}
function setup() {
createCanvas(700, 700);
runJarJarRun();
}
function draw() {
background(0);
drawLightSaber(); // this way I can deal with the lightsaber's appearance in a dedicated method
image(jarJar, jarJarX, jarJarY, 140, 200);
jarJarX= jarJarX+xspeed;
if (jarJarX<=-300|| jarJarX>=width+200) {
xspeed=xspeed*-1;
}
jarJarY= jarJarY+yspeed;
if (jarJarY<-200|| jarJarY>=height+200 ) {
yspeed=yspeed*-1;
}
//score counter coordinate with lightsaber hitting image
textSize(30);
fill(200, 200, 0);
text('Score: ' + score, 10, 40);
}
function drawLightSaber() {
if (flipLength) { // if the number is > 0 this will be true
flipLength--; // measure how ling the saber is flipped in frames # ~60 frames per second
push(); // isolating the translate ans scale manpulations to avoid ruining the rest of the sketch
translate(mouseX + 100, 0); // makes the coordinates so once flipped the lightsaber will still appear at the same location
scale(-1.0, 1.0); // flip x-axis backwards
image (lightSaber, 0, mouseY, 100, 100);
pop(); // ends the sequence started with 'push();'
} else {
image (lightSaber, mouseX, mouseY, 100, 100);
}
}
function runJarJarRun() {
xspeed=random (5, 10);
yspeed=random (5, 10);
}
function mouseClicked() { // this method will trigger once when the left mouse button is clicked
flipLength = 10;
if (intersect(jarJarX, jarJarY, 140, 200, mouseX, mouseY, 100, 100)) {
score++;
runJarJarRun(); // as a bonus, jarjar will run in another direction on hit
// you could totally put some more special effects, like a flash, a sound, some 'mesa ouchie bad!' text, whatever speaks to you
}
}
function intersect(x1, y1, w1, h1, x2, y2, w2, h2) {
let checkX = false;
let checkY = false;
if ( (x1<x2 && (x1+w1)>x2) || (x1<(x2+w2) && (x1+w1)>x2+w2) || (x1>x2 && (x1+w1)<(x2+w2)) ) {
checkX = true;
}
if ( (y1<y2 && (y1+h1)>y2) || (y1<(y2+h2) && (y1+h1)>y2+h2) || (y1>y2 && (y1+h1)<(y2+h2)) ) {
checkY = true;
}
return (checkX && checkY);
}
If there's something you don't understand, let me know in a comment and I'll be happy to elaborate. Good luck and have fun!
Hi and welcome to stack overflow. One thing to keep in mind when submitting here (or any forum where you're looking for help with code) is to post a minimal reproducible example. You'll be much more likely to get useful responses.
You'll also want to separate out your questions, as they each have multi-step responses.
Your first question is about how to get your sketch to display something when you press the mouse down. Your syntax isn't quite correct there. Here's a minimal example of how to check for a mouse held down.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
if (mouseIsPressed == true) {
ellipse(100, 100, 100, 100);
}
}
Just a quick note that I tried to make this as 'novice-friendly' as possible. The == true is optional and not usually included.

FabricJS - performance threading

Sorry if the title was misleading, it's the closest approximation I could come up with, haha.
Okay so I'm using FabricJS for a proof-of-concept for a fabric-printing client, and they require 300PPI images (i.e, freaking huge). Now, if you check the JsFiddle I've popped in below you'll see the tiling is done with some while loops which seem to work fine, except for the fact that the whole browser freezes while loading, meaning I can't even stick up a loader icon.
Have I done something horribly wrong, or is that just sorta how it works? The long loading times are fine as long as I can a) put up a loader and b) it doesn't, uh, "He's dead, Jim!" my Chrome. I'm getting the images with base64, if that helps at all.
Cheers everyone!
EDIT For context, here's one of the functions that creates a pattern from an uploaded file:
function renderMirror(){
showLoader();
var isFullRows = false;
var rowIndex = 0;
var totalHeight = 0;
while(isFullRows == false){
// let's start with filling up the row's columns. start the width at zero.
var totalWidth = 0;
var isFullCols = false;
var colIndex = 0;
if(rowIndex % 2){
var isRowMirrored = false;
}else{
var isRowMirrored = true;
}
while(isFullCols == false){
colIndex++
if(rowIndex == 1){
console.log('row');
}
if(totalWidth >= canvas.width){
isFullCols = true;
}
if(colIndex % 2){
var isColMirrored = false;
}else{
var isColMirrored = true;
}
canvas.add(new fabric.Rect({
left: totalWidth,
top: totalHeight,
fill: pattern,
flipX: isColMirrored,
flipY: isRowMirrored,
height: newImgHeight,
width: newImgWidth,
selectable: false
}));
totalWidth+= newImgWidth;
// safeguard
if(colIndex > 100){
isFullCols = true;
}
}
// now instantiate the row.
rowIndex++;
if(totalHeight >= canvas.height){
isFullRows = true;
}
totalHeight+= newImgHeight;
// safeguard
if(rowIndex > 100){
isFullRows = true;
}
}
hideLoader();
}
The whole thing is here, if you'd like to have a proper look?
I've experienced something similar to generate PDF at 300. I tried two different solutions:
Using webWorkers which will do the heavy work on the background and is not going to freeze the browser, however this approach was a little bit slower in my use case.
The second approach I took was create an endpoint where I get just the base 64 image and then with that data of the image I generate a PDF using imagemagick to create the PDF at 300 DPI also I create a virtual canvas with JS to generate the real size of the image from a scaled canvas in order to make it a little bit faster as well.

CreateJs - Controlling timeline playhead with click & drag

First time posting here, hope I'm doing this right :) I am trying to create a 360 spin in Adobe Animate with createJS, using a sequence of images embedded in a MovieClip. I have managed to get control of the timeline playhead using the code below:-
var start_x;
var startFrame;
var changeDistance;
var travelDistance;
this.threeSixty.addEventListener("mousedown", onMouseDown.bind(this));
this.threeSixty.addEventListener("pressup", onMouseUp.bind(this));
function onMouseDown(e) {
start_x = e.stageX;
startFrame = this.threeSixty.timeline.position;
this.threeSixty.addEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseUp(e) {
this.threeSixty.removeEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseMove(e) {
var changeDistance = e.stageX-start_x;
var travelDistance = startFrame+changeDistance;
if (travelDistance > this.threeSixty.timeline.duration){
this.threeSixty.gotoAndStop(travelDistance % this.threeSixty.timeline.duration);
}else if (travelDistance < 0){
this.threeSixty.gotoAndStop (this.threeSixty.timeline.duration + (travelDistance % threeSixty.timeline.duration));
} else {
this.threeSixty.gotoAndStop(travelDistance);
}
}
The problem is, when you click and drag the image along the X axis, the image sequence only moves forward/backwards by a single frame, as opposed to continuing the image sequence until the either mouse has stopped moving, or the mouse click is released. Any ideas where I might be going wrong here?
Thanks

How to stop other sounds until one finishes (Js, HTML)

I need to include some sound files on a website, i recorded them and used the super complicated:
<a href="seo.html" onmouseover="new Audio('sounds/seo.mp3').play()">
to play them when the user scrolls over with the mouse. There are a total of four links on the website.
The problem is, when i mouse over one of them it starts playing, and then if i mouse over another it plays that one as well. If i move the mouse really fast accross the links i end up getting Giberish because all files are being played at the same time. How do i stop this ??
Ideal would be that the others CANNOT be played until the current playing is finished :)
An approch below.
Note, untested ;-)
HTML
a sound link -
a sound link -
a sound link -
a sound link
JS
var links = document.querySelectorAll('a.onmousesound');
var currentPlayedAudioInstance = null;
var onHoverPlaySound = function(element) {
if (currentPlayedAudioInstance &&
currentPlayedAudioInstance instanceof Audio) {
// is playing ?
// http://stackoverflow.com/questions/8029391/how-can-i-tell-if-an-html5-audio-element-is-playing-with-javascript
if (!currentPlayedAudioInstance.paused && !currentPlayedAudioInstance.ended && 0 < currentPlayedAudioInstance.currentTime) {
return false;
}
}
var file = element.getAttribute('data-file');
currentPlayedAudioInstance = new Audio(file);
currentPlayedAudioInstance.play();
};
for (var i = 0; i < links.length; i++) {
link.addEventListene('onmouseover', function() {
onHoverPlaySound(links[i]);
});
};

Categories

Resources