1

I am trying to create combination dial lock, which can be turned when mouseMoved, it works perfectly when I assign the value of each key equals to mouseX or mouseY's coordinate, but not working when I assign the value to plus/subtract a number from itself every time when mouseMoved.

The simplified question is, what's the difference between the following 2 codes:

///////////--------code 1,works as expected-------------///////////
var keyA=0;
keyA=mouseY;
keyA=min(keyA,9);
//////////------code 2,doesn't work as expected---------////////
var keyA=0;
keyA-=3;
keyA=min(keyA,9);

For code 1, keyA won't go above 9, while for code 2, keyA can go above 9. They are both circle dial lock.

I've enclosed the complete code and Canvas output below for a better understanding:

//declare the variables

var keyA;
var keyB;
var keyC;
var keyD;

function setup() {
    createCanvas(512,512);

    //initialise the variables
    keyA = 0;
    keyB = 0;
    keyC = 0;
    keyC = 0;
    keyD = 0;
}

///////////////////EVENT HANDLERS///////////////////
function mouseMoved(){
    //only keyB and keyC work incorrectly,the min() max() methods not working here
    //Decrement keyB by 3, use the 'min' function to prevent keyB from going above 9
    keyB-=3;
    keyB=min(keyB,9);

    //Increment keyC by 1, use the 'max' function to prevent keyC from falling below 5
    keyC+=1;
    keyC=max(keyC,5);

    //keyA and keyD work correctly, I included here in order to contrast the difference
    //keyA equal to the value of mouseY, use 'min' function to prevent keyA from going above 16
    keyA=mouseY;
    keyA=min(16,keyA);

    //Make keyD equal to value of mouseY, use 'min' function to prevent keyD from going above 76
    keyD=mouseY;
    keyD=min(keyD,76);

    //the output value seems fine, for all 4 keys, they all heading to positive or negative infinite.
    console.log('B is '+keyB);
}

///////////////Draw the cobination dials and door lever///////////////////

function draw() {
    //Draw the safe door
    background(10);
    noStroke();
    fill(129,110,16);
    rect(26,26,width-52,width-52);

    //Draw the combination dials
    //keyA
    push();
    translate(120,170);
    drawDial(140,keyA, 21);
    pop();
    //keyB
    push();
    translate(120,380);
    drawDial(140,keyB, 14);
    pop();
    //keyC
    push();
    translate(280,380);
    drawDial(140,keyC, 13);
    pop();

    //keyD, the lever
    push();
    translate(width - 225,136);
    drawLever(keyD);
    pop();

    //put text next to each key, so we know which key is which
    fill(0);
    text('A',35,200);
    text('B',35,400);
    text('C',355,400);
    text('D',395,200);
}

//drawDial function
function drawDial(diameter,num,maxNum) {
    //the combination lock
    var r = diameter * 0.5;
    var p = r * 0.6;

    stroke(0);
    fill(255,255,200);
    ellipse(0,0,diameter,diameter);
    fill(100);
    noStroke();
    ellipse(0,0,diameter*0.66,diameter*0.66);
    fill(150,0,0);
    triangle(
        -p * 0.4,-r-p,
        p * 0.4,-r-p,
        0,-r-p/5
    );

    noStroke();

    push();
    var inc = 360/maxNum;

    rotate(radians(-num * inc));
    for(var i = 0; i < maxNum; i++) {
        push();
        rotate(radians(i * inc));
        stroke(0);
        line(0,-r*0.66,0,-(r-10));
        noStroke();
        fill(0);
        text(i,0,-(r-10));
        pop();
    }

    pop();
}

//drawLever function
function drawLever(rot) {
    push();
    rotate(radians(-rot))
    stroke(0);
    fill(100);
    rect(-10,0,20,100);
    ellipse(0,0,50,50);
    ellipse(0,100,35,35);
    pop();
}

And here is the Canvas output: canvas output

I've also uploaded a zip file to weTransfer with html and js files included if it helps: (file size is 198KB) https://wetransfer.com/downloads/1a3c130909e542992e0b8b8f661a8f2720181104133922/a58a78

The code was written based on p5.js library.

Sorry to post such a long question, I've been working on this bug for a month, if anyone can point me to a direction that which part goes wrong, I think might be in drawDial function, or we just simply can't decrease 0 and limit it from going above 9 logically. Any help is appreciate

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
WWL
  • 155
  • 2
  • 9

1 Answers1

0

Pay attention to the information that you're printing to the console. You'll see stuff like this:

B is -600 
B is -603 
B is -606 
B is -609 
B is -612 
B is -615 
B is -618 
B is -621 
B is -624 
B is -627 
B is -630

This tells you that keyB is not becoming greater than 9. It's simply becoming very small. (Or very large negatively, depending on how you look at it.)

And this makes sense with your code:

keyB -= 3;
keyB = min(keyB, 9);

Here you subtract 3 from keyB whenever the mouse moves, and then you take the smaller value: keyB or 9. Note that values like -3, -6, and -300 are all less than 9. In other words, the second line here doesn't really do anything.

I'm not sure how you want your code to work: you could either limit your values so they stay above 0, or you could wrap them around using an if statement.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • yep I agree, the outcome I'm looking for is, I've drawn a circled combination lock on Canvas, I want it works like a real safebox lock, you can turn it clockwise or anti-clockwise. If we take keyB for example, I drew 14 number on the lock, 0-13, the lock does spin between 0-13, no matter what value of keyB is shown in console.log, this part does work. The only problem is, I want to limit/restrict the lock going above 9, which means I don't want people to be able to turn the lock between 10-13, like in real life, the lock is stucked or rusted, you can only turn it between 0-9. – WWL Nov 04 '18 at 20:56
  • The reason I was aksing the difference between 'keyA=mouseY' and 'keyA-=3' is, if I use keyA=mouseY, it works, the lock spins and I can restrict the value, but once I use -=, the lock also spins, but unable to restrict the value. Although we can use keyB+=3; min(keyB,9), or constrain, or let keyB=mouseY. The thing is I am not allowed to use those, have to work out which part went wrong, since keyB does spin between 0-13 wiile console showing negative value, there might be someway to work out how to restrict the value, I think there may be an error in my code somewhere, still looking for it – WWL Nov 04 '18 at 21:13
  • @WWL The reason `keyA=mouseY` works is because those values are already restricted to be between `0` and `height`. Like I mentioned in my answer, you're going to have to decide what you want to do with negative numbers. – Kevin Workman Nov 04 '18 at 21:56
  • ok, got it. I guess it just won't work logically while keyB-=3, combined with min() function. Thanks for the help – WWL Nov 05 '18 at 11:10
  • @WWL I think you can make it work logically. Right now you're capping its maximum value. What happens if you also cap its minimum value? Or you could wrap the value around so that if it goes below a certain value, it starts over at a different value. – Kevin Workman Nov 05 '18 at 18:30
  • emmm thx, I will try let the value starts over when it reaches a certain nunber. When I cap its minimum value, such as keyB-=3; max(keyB,-5), so it stops at 9, then I can start over. The thing is I'm not allowed to use max() or if() statement for keyB. The logic is quite weird, why would I want to prevent a negative value from going above 9? That's exactly what I was asked to do and the reason I think I may have some errors at the lower part of the code, instead of in the mouseMoved event handler. – WWL Nov 05 '18 at 22:34