I am developing a game in JavaScript, which consists in being able to move on the screen and create walls, by holding the left click button, while moving the cursor around on the canvas. On the other hand, by pressing right click, one bullet is created. The problem appears when one bullet is created, by right clicking, which, also, determines the window.onmousedown() function to take place. I do not want to create walls by right clicking on the screen, because the right click is only supposed to create a bullet, not a wall, as the wall should only be created by the left click.
I've tried to create a variable, called wallCannotBeCreated, which is set to false, by default. In my mind, the window.oncontextmenu() function should take place, when right click event takes place, thus wallCannotBeCreated becomes true, in order that window.onmousedown() function is becoming "unable" to create any new wall, until window.onmouseup() function takes place, where wallCannotBeCreated becomes, again, false. Unfortunatelly, it doesn't seem to work, as, always, window.onmousedown() function occurs before window.oncontextmenu() function.
var wallCannotBeCreated = false;
window.oncontextmenu = function (e)
{
//alert("right click was pressed");
// a new bullet must be created
bullets[++counterBullets] = new Bullet(player.x + player.r / 2, player.y, e.x, e.y);
wallCannotBeCreated = true;
console.log(wallCannotBeCreated);
}
window.onmousedown = function()
{
console.log(wallCannotBeCreated);
if(wallCannotBeCreated == false)
{
//console.log("mouse is being pressed");
Keys.click = true;
// one wall must be created
walls[++wallNumber] = new Wall();
walls[wallNumber].timerStart();
}
}
window.onmouseup = function()
{
//console.log("mouse was released");
Keys.click = false;
wallCannotBeCreated = false;
}
Related
I created some objects with fabric js and added different cursors for them if the user hovers with his mouse over the object. i want to add a function which changes the cursor for the whole canvas and all its objects and then changes it back to its default values (so the cursor settings for the objects and the canvas).
is there a way to do this simple? or do i have to set the cursor for every object manually?
I got a small jsFiddle for this: https://jsfiddle.net/bxgox7cr/14/
If you click on the button "change Cursor", the cursor is changed to a crosshair, but when you move your mose over the lines or circles, it is changed to their settings. I want the cursor to stay as a crosshair. After pressing "default Cursor" all the settings should be set back, so the cursor should use the special settings for lines and circles.
the main functionality is in this 2 functions:
$('#button').click(function() {
canvas.defaultCursor = 'crosshair';
});
$('#button2').click(function() {
canvas.defaultCursor = 'default';
});
I might save the default values for every object and then change them back after the click of button2, but this seems to be a difficult solution, so I'm hoping there might be an easier way.
Just add to your code this event:
canvas.on('mouse:over', function(event){
if (event.target != null)
event.target.hoverCursor = canvas.defaultCursor;
}
});
On each object you will reset 'hover' cursor what you set for whole canvas.
Updated:
If you need reset to default you have to keep track of original cursors for each object. You need something like this:
$('#button').click(function() {
changeCursor('crosshair');
});
$('#button2').click(function() {
resetCursor();
});
var cursors = {canvasDefault: canvas.defaultCursor,
canvasDefault: 'default',
object:[
{objectType: 'circle',
hoverCursor: 'move'},
{objectType: 'line',
hoverCursor: 'ns-resize'}
]
};
function changeCursor(cursor){
canvas.forEachObject(function(obj){
for (var i in cursors.object){
if (cursors.object[i].objectType == obj.type){
obj.hoverCursor = cursor;
}
}
canvas.defaultCursor = cursor;
});
}
function resetCursor(){
canvas.forEachObject(function(obj){
for (var i in cursors.object){
if (cursors.object[i].objectType == obj.type){
obj.hoverCursor = cursors.object[i].hoverCursor;
}
}
canvas.defaultCursor = cursors.canvasDefault;
});
}
I'm building a little fantasy game. In the game, the player has a endurance limit. For each click at the map, the endurance bar is increased:
angular.element('.click').click(function() {
var endurance_click = angular.element('.progressbar').height();
angular.element('.progressbar').css('height', endurance_click-20);
});
The thing I want to accomplish is that if you click around at the map, and stops before you have run out of endurance, and wait for 2sec, I want to fire an function that restores you endurance. When you decide to move on, I want to stop the function.
I have tried setInterval, but the function just keeps running.
Here is my code:
//Call a function that should restore the endurance
d = window.setInterval(restoreEndurance2, 2000);
function restoreEndurance2()
{
var endurance_restore = angular.element('.progressbar').height();
angular.element('.progressbar').css('height', endurance_restore+20);
if(endurance_restore >= 320) //If it's restored
{
alert(endurance_restore);
clearInterval(d);
}
}
How can I make the function stop when I start navigate through the map?
I am currently working on a battle system.
The health gets calculated every 200ms, and I'm using a Interval. It works pretty good, until I start the game - the Interval again. It doesn't stop anymore.
It is a lot of code - I have also an online live demo here http://wernersbacher.de/pro/coinerdev/
Like I said - works the first, but not the second.
So, just the main code:
var frameStop;
// Draws Startscreen
function showStartRaid(name) {
playerBTC = btc;
playerBTCs = btcs;
playerName = nick;
// Sets stats for called level
enemyBTC = dun[name]["buyer"]["btc"];
enemyBTCs = dun[name]["buyer"]["btcs"];
enemyName = dun[name]["buyer"]["label"];
enemyNum = dun[name]["meta"]["base"];
/* Reset everything in html */
}
var battle = false;
$(".raid_building").click(function() {
//Draws level
showStartRaid(name);
//Sets start BTC as fighting stats (they will decrease during battle)
fplayerBTC = playerBTC;
fenemyBTC = enemyBTC;
//Click on "Start"
$("#startRaid").click(function() {
function raiden() {
//Calculates fighting
fenemyBTC -= playerBTCs/frameMinus;
fplayerBTC -= enemyBTCs/frameMinus;
/*Draws stats and health here in html */
if(fplayerBTC >= 0 && fenemyBTC >= 0)
console.log("battle goes on")
else {
//If battle is over, stop it
clearInterval(frameStop);
}
}
//Start battle
frameStop = setInterval(raiden, frameRaid);
});
});
Thanks for any help, I'm helpless.
With your code, every time .raid_building is clicked, you hook up a new handler for clicks on #startRaid. So that means, if .raid_building is clicked twice, you'll have two handlers for clicks on #startRaid, both of which start a new interval timer. Your frameStop variable will only contain the handle of one of them; the other will continue. And of course, a third click will compound the problem (you'll have three click handlers, each of which fires up a new interval timer). And so on...
Move the code hooking click on #startRaid outside the click handler on .raid_building.
I can determine where on a globe the user has clicked.
When the user first clicks the mouse button down, I can store where they have clicked; lets call it the pin.
Then, as they drag the mouse around, I want to put the pin under the mouse cursor.
Here is some code that seems to roughly keep the pin under the mouse pointer, but doesn't correctly maintain the globe; it flickers and spins randomly. Sometimes it flips the axis entirely so the globe is momentarily back-to-front.
function evtPos(evt) {
if(!scene.ortho) return null;
var x = lerp(scene.ortho[0],scene.ortho[1],evt.clientX/canvas.width),
y = lerp(scene.ortho[3],scene.ortho[2],evt.clientY/canvas.height), // flipped
sqrd = x*x+y*y;
return (sqrd > 1)?
null:
mat4_vec3_multiply(mat4_inverse(scene.mvMatrix),[x,y,Math.sqrt(1-sqrd)]);
}
function onMouseDown(evt) {
pin = evtPos(evt);
}
function onMouseMove(evt,keys,isMouseDown) {
if(!isMouseDown) return;
var pt = evtPos(evt);
if(pin == null) pin = pt;
if(pt == null) return;
var d = vec3_sub(pt,pin),
rotx = Math.atan2(d[1],d[2]),
roty = (d[2] >= 0)?
-Math.atan2(d[0] * Math.cos(rotx),d[2]):
Math.atan2(d[0] * Math.cos(rotx),-d[2]),
rotz = Math.atan2(Math.cos(rotx),Math.sin(rotx)*Math.sin(roty));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotx,[1,0,0]));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(roty,[0,1,0]));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotz,[0,0,1]));
}
function onMouseUp(evt) {
pin = null;
}
Also, over time, an error seems to build up and the pin drifts further and further from the mouse pointer. I presume I should somehow compute the mvMatrix completely rather than by lots of samll increments each event?
I want the user to be able to drag the globe around to navigate naturally. All code to spin globes that I've found uses fixed speeds e.g. arrow keys, rather than 'pinning' the globe under a mouse pointer. Unity has a function Quaternion.FromToRotation(fromPos,toPos) which seems very promising but the source is not available.
One of the approaches for doing this is the arcBall algorithm. There are even JavaScript implementations available so you don't need to roll your own.
I'm learning javascript by using the easeljs library to make a simple game, for school lessons.
I want to make a crosshair give some feedback to the player by showing a small animation while you are pointing at your target, using a hittest I made.
However, when the crosshair touches the target, the animation (should be two little triangles pointing to the middle of the crosshair) seems to be stuck on it's first frame.
Here is a bit of my code, I put both of these functions inside a ticker function. The functions do what they're supposed to do (I checked by sending a message to the console.log), but I think the animation is reset as soon as the variable "hitTestControle" is set to true, at every tick.
If you want to check out all of the code, here is a link to the "game":
http://athena.fhict.nl/users/i279907/achtergrond/achtergrond.html
function hitTest() {
if(distance(crossHair, block) < 60) {
hitTestControle = true;
} else {
hitTestControle = false;
console.log(hitTestControle);
}
}
function hitTestControl() {
if(hitTestControle == true) {
crossHair.gotoAndPlay("move");
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
}
}
PS: There also seems to be something wrong with this hittest I used.
function distance() {
var difx = blok.x - crossHair.x;
var dify = blok.y - crossHair.y;
return Math.sqrt( (difx * difx) + (dify * dify) );
}
It looks like you're starting the animation... setting it to the first frame and starting it... every time hitTestControle is true. Since hitTestControle will be true as long as you're hovering over the target, the animation will never reach the second frame.
What you need to do is start the animation when you transition from hitTestControle = false to hitTestControle = true, but once that happens you just let it play automatically.
Try changing your hitTestControl() function to something like this:
function hitTestControl() {
if(hitTestControle == true && alreadyOverHit == false) {
crossHair.gotoAndPlay("move");
alreadyOverHit = true;
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
alreadyOverHit = false;
}
}
In other words, only start the animation once, during the first frame you're detecting a hit, and then don't touch it unless you move off the target and back on.