I am currently trying to apply force to a body using a degree (a float between -90 and 90), and a forceLevel (a float between 0 and 1). Body.applyForce() only allows me to provide x and y power levels.
What I am trying to achieve:
I want to be able to drag back from a position, and have my body launch towards the other directions with the power of the launch based on how much the user dragged back.
Here is my code for getting the angle and the power level.
var cachedPosition = {
x: 0,
y: 0
};
document.addEventListener("mousedown", (e) => {
cachedPosition.x = e.clientX
cachedPosition.y = e.clientY
})
document.addEventListener("mouseup", (e) => {
var degree = "INVALID";
var difX = cachedPosition.x - e.clientX
var difY = cachedPosition.y - e.clientY
if (difX > 0 && difY < 0) {
var degree = getDegree(difX, difY)
} if (difX < 0 && difY < 0) {
var degree = -getDegree(Math.abs(difX), difY); // Negative degree if drag is towards bottom right.
}
var power = Math.sqrt(Math.pow(difX, 2)+Math.pow(difY, 2))/1000
})
I have a remote control pen as cursor (hardware).
External hardware via SDK to Javascript i receive a cursor.
Where i get x, x, y, y position and click command.
But, How to submit click on that position?
(no matter whatever Element is there on that position, i need to submit the click on that position)
if (_label == rs.cursor.GestureType.CURSOR_CLICK) {
// I have: x, x, y, y
/*
Following method works:
but i have too many buttons, how to apply dynamic click without tracking which element?
var myButton = document.getElementById("mediaplayer");
var rect = myButton.getBoundingClientRect();
if (x >= rect.left &&
x <= rect.right &&
y >= rect.top &&
y <= rect.bottom){
myButton.click();
}
*/
}
EDIT:
//
// 1 - Find Active DIV/MAP/Container?
//
var layerID = $('#layoutmain').attr('usemap');
if (_label == rs.cursor.GestureType.CURSOR_CLICK) {
//
// 2 - Loop each buttons of that container
//
$('#' + layerID).find('area').each(function(){
var onclick_function = $(this).attr('onclick') ;
var coords = $(this).attr('coords');
coords = coords.split(' ').join('');
var coords_array = coords.split(',');
console.log('>>> we have: ',
onclick_function ,
coords,
coords_array);
var rectleft = coords_array[0];
var recttop = coords_array[1];
var rectright = coords_array[2];
var rectbottom = coords_array[3];
//
// 3 - Match the RANGE of buttons with the coordinates
//
if (x >= rectleft && y >= recttop &&
x <= rectright && y <= rectbottom){
$(this).trigger('click');
}
});
}
Method 1: When the CURSOR_CLICK event is triggered, iterate all the clickable buttons and check to which button the click is "related" to.
$buttons = $('.clickable-button');
var rect;
if (_label == rs.cursor.GestureType.CURSOR_CLICK) {
$buttons.each(function(){
rect = $(this).getBoundingClientRect();
if (x >= rect.left &&
x <= rect.right &&
y >= rect.top &&
y <= rect.bottom){
$(this).click();
}
});
}
Method 2: Create an array with all the buttons on the page and their cords.
When the click event is being triggered, just compare the cords.
Advantage - Less time is being spent in the loop.
I am trying to draw straight line with pressing key "Shift".After pressing "Shift" i want to set cursor on line at 45/90 degree angle. While drawing a line on Mouse_Move event.
Diagrammatically i want like this.
For that i have written code as below:
if (isShiftKeyPressed) {
endX = evt.X;
endY = evt.Y;
var deltaX = endX -startX;
var deltaY = endY - startY;
var angleInRadian = Math.atan2(deltaY, deltaX);
var angleInDegree = angleInRadian * 180 / Math.PI;//error in this line
if (deltaX > 0 && deltaY > 0) {
if (angleInDegree > 45 && angleInDegree < 90) {
UpdateLastPosition(endX,startY);
}
if (angleInDegree < 45 && angleInDegree > 0) {
UpdateLastPosition(startX,endY);
}
}
I think you're asking how to tell if the shift key is down.
evt.shiftKey will be true if the shift key was down when the event was generated, false if it wasn't.
So your
![if (isShiftKeyPressed) {
would be
if (evt.shiftKey) {
// The shift key was down when the event was generated
}
else {
// It wasn't
}
(I assume the ! before if was a typo.)
Example (source)
I'm wondering if there's an easy way to 're-write' the value displayed by a JavaScript variable on a HTML5 canvas when the actual value of the variable has been updated by the user?
For example, I'm using the HTML5 canvas and JavaScript to write a very simple game to teach users some basic Welsh.
Currently, I have two arrays: one containing 10 .png images for the numbers 1-10, and the other containing 10 strings for the Welsh words for the numbers 1-10.
When the user views the page, the canvas displays a 'start game' button, which when clicked, draws one random element from the images array, and one random element from the words array, as well as an image of a tick and a cross.
If the image and the word represent the same number, the user should click the tick, if they do not, the user should click the cross. If the user makes the right selection- I have a currentScore variable whose value is increased by 5 (initiated at 0), if they make the wrong selection, the value of currentScore remains the same.
When I view the page in the browser, and play the game, if I click on the tick when the image and word represent the number, I can see that the value of currentScore is increased by 5 in the console, but the value of currentScore displayed on the canvas remains the same. Similarly, if I click the cross when they do not match, the score is increased in the console, but not on the canvas.
So the logic behind the code is right, and it works, I'm just not sure how I can get the value displayed for currentScore to be updated on the canvas each time its actual value is updated.
The function I'm using to do this is below:
function drawLevelOneElements(){
/*First, clear the canvas */
context.clearRect(0, 0, myGameCanvas.width, myGameCanvas.height);
/*This line clears all of the elements that were previously drawn on the canvas. */
/*Then redraw the game elements */
drawGameElements();
/*Create an array of words for numbers 1-10 */
var wordsArray = new Array();
wordsArray[0] = "Un";
wordsArray[1] = "Dau";
wordsArray[2] = "Tri";
wordsArray[3] = "Pedwar";
wordsArray[4] = "Pump";
wordsArray[5] = "Chwech";
wordsArray[6] = "Saith";
wordsArray[7] = "Wyth";
wordsArray[8] = "Naw";
wordsArray[9] = "Deg";
/*Use Math.random() to generate a random number between 1 & 10 to draw the word and image to the canvas */
var drawnImage = Math.floor(Math.random()*10);
var drawnWord = Math.floor(Math.random()*10);
/*Draw an image and a word to the canvas just to test that they're being drawn */
context.drawImage(imageArray[drawnImage], 100, 30, 30, 30);
context.strokeText(wordsArray[drawnWord], 500, 60);
/*Now draw the tick and cross to the canvas */
context.font = "30pt Calibri"; /*Set text font and size */
context.drawImage(tick, 250, 200, 50, 50);
context.drawImage(cross, 350, 200, 50, 50);
/*Add an event listener to the page to listen for a click on the tick or the cross, if the user clicks
the right one to indicate whether the image and word relate to the same number or not, increase the
user's score*/
myGameCanvas.addEventListener('click', function(e){
console.log('click: ' + e.pageX + '/' + e.pageY);
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
/*If the tick is clicked, check whether or not the image and word represent the same number, if they do,
increase the score, if not, leave the score as it is*/
if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
currentScore = currentScore + 5;
console.log('Current Score = ' + currentScore);
} else if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
currentScore = currentScore;
console.log('Current Score = ' + currentScore);
/*If the cross is clicked, check whether or not the image and word represent the same number, if they
don't, increase the score, otherwise, leave the score as it is*/
} else if((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
currentScore = currentScore + 5;
console.log('Current Score = ' + currentScore);
} else if ((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
currentScore = currentScore;
console.log('Current Score = '+ currentScore);
} else {
console.log('The click was not on either the tick or the cross.');
}
}, false);
I wouldn't have thought it would require too much code to do this, but I just can't work out how to do it. Any help would be much appreciated. Thanks!
*EDIT*
I've added the code in as you suggested, but the score displayed on the canvas is still not updated for some reason...
if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
currentScore = currentScore + 5;
context.clearRect(currentScorePositionX, currentScorePositionY, 20, 20); /*Clear the old score from the canvas */
context.strokeText(currentScore, 650, 15); /*Now write the new score to the canvas */
console.log('Current Score = ' + currentScore);
} else if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
currentScore = currentScore;
console.log('Current Score = ' + currentScore);
Any suggestions?
Something that may not have occurred to you, is that canvas elements can be transparent, and stacked on top of each other. This way, you could have a GUI only canvas, and an action canvas, and keep them separate. Absolute positioning will make this work, if you're not confident in css, and want an example, just say.
Building on what Ed Kirk said, you can detect when the score variable has changed by comparing it against itself every so often (say, 50 milliseconds for starters).
Example:
var myScore = 0;
var myOldScore = myScore;
setInterval(function() {
if(myScore != myOldScore) {
myOldScore = myScore;
// the variable has changed, write it to the canvas
}
}, 50); // will execute every 50 milliseconds
You need to clear a part or all of your canvas and redraw it in order to update the canvas display. You are already doing this in the first line of drawLevelOneElements() - you clear the whole screen. To clear just a section you can do:
context.clearRect(x, y, scoreDigitWidth, scoreDigitHeight);
x and y are the coordinate of your score digit and scoreDigitWidth and scoreDigitHeight the width and height. Then you can fill this cleared area using context.drawImage(). You could initiate the process using a continually loop updating the frame or if it doesn't need updating often just run it after line:
currentScore = currentScore;
I.e when you know the new score.
You're normally better clearing and redrawing just what has changed on the canvas instead of all of it. Here's a good article on performance. http://www.html5rocks.com/en/tutorials/canvas/performance/.
It looks like quite a simple animation, you might be better off using just html elements (divs, imgs, etc) instead of the canvas, this will allow users with browsers that don't support the canvas element to still use it, namely IE8<.
I've made a few changes to my function, and now have the follwing code:
/*Add an event listener to the page to listen for a click on the tick or the cross, if the user clicks
the right one to indicate whether the image and word relate to the same number or not, increase the
user's score*/
myGameCanvas.addEventListener('click', function(e){
console.log('click: ' + e.pageX + '/' + e.pageY);
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
/*If the tick is clicked, check whether or not the image and word represent the same number, if they do,
increase the score, if not, leave the score as it is*/
if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
currentScore = currentScore + 5;
var scorePositionX = currentScorePositionX;
var scorePositionY = currentScorePositionY;
context.clearRect(scorePositionX, scorePositionY, 30, 30); /*Clear the old score from the canvas */
context.strokeText(currentScore, 650, 50); /*Now write the new score to the canvas */
console.log('Current Score = ' + currentScore);
} else if((mouseX > 250 && mouseX < 300) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
currentScore = currentScore;
console.log('Current Score = ' + currentScore);
/*If the cross is clicked, check whether or not the image and word represent the same number, if they
don't, increase the score, otherwise, leave the score as it is*/
} else if((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage != drawnWord)){
currentScore = currentScore + 5;
context.clearRect(currentScorePositionX, currentScorePositionY, 20, 20); /*Clear the old score from the canvas */
context.strokeText(currentScore, 500, 50); /*Now write the new score to the canvas */
console.log('Current Score = ' + currentScore);
} else if ((mouseX > 350 && mouseX < 400) && (mouseY > 200 && mouseY < 250) && (drawnImage == drawnWord)){
currentScore = currentScore;
console.log('Current Score = '+ currentScore);
} else {
console.log('The click was not on either the tick or the cross.');
}
}, false);
This is now displaying the current score, and updating it every time the user correctly selects the tick or the cross, however, when drawing the new score to the canvas each time, rather than removing the previous drawing of the score and writing the new score in its place, it simply writes it over the top, so both the old score and the new score are displayed in the same location- which is a bit of a mess, and makes it hard to read.
Also, the location and font & size of the score are not where I had intended- I had intended that it be displayed in my 'score bar' as previously mentioned, however, it is now displayed below the score bar, on the main 'display' section of the canvas. Also the font is different- the numbers are not displayed as usual characters, i.e. 5, 10, etc, but the font is larger, and is like 'bubble writing', with white space in the middle of the digits. The font is also much larger- at least twice the size of the text I have displayed in the 'score bar'.
Could someone point out to me what I'm doing wrong here? Thanks very much!