Simple JavaScript Game - javascript

I want to make a basic Space Invaders clone in ECMAScript/HTML5/CSS3 with the shortest and simplest code possible. I have begun implementing the controls, but they won't work. Here is the code:
<!DOCTYPE html>
<html>
<body onkeydown="javascript:move()" onkeyup=""></body>
<canvas id="myCanvas" width=800 height=800></canvas>
<script>
var context = document.getElementById('myCanvas').getContext("2d");
var img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0, 40, 40);
}
img.src = "run0.png";
function leftArrowPressed() {
img.style.left = parseInt(element.style.left) - 5 + 'px';
}
function rightArrowPressed() {
img.style.left = parseInt(element.style.left) + 5 + 'px';
}
function move(evt) {
var code = window.event.keyCode;
switch (code) {
case 37:
leftArrowPressed();
break;
case 39:
rightArrowPressed();
break;
}
};
</script>
</body>
</html>

You're not handling your keydown event in the markdown of your <body> tag. You can listen to events programatically with JavaScript, or continue as you were doing by adding the move() method to your onkeydown attribute like so:
function leftArrowPressed() {
console.log('move left');
}
function rightArrowPressed() {
console.log('move right');
}
function move(evt) {
var code = window.event.keyCode;
switch (code) {
case 37:
leftArrowPressed();
break;
case 39:
rightArrowPressed();
break;
}
};
<body onkeydown="javascript:move()" onkeyup=""></body>
In order for the above to work (inside an iframe), it must first be focused. So click the white space where the demo opens up before testing.
It should be noted that interfacing the keyboard in browsers has been historically a bit of a headache. Your best bet is to delegate the task to a good library.
I have found the Mousetrap library to be pretty extensive.

You will have a mainloop so just set some flags and attach your key events to the document, no need to worry about focus. Ship will move as long as the key is held down. Fire button will need to have a reload flag and a timer to control the repeat rate. Fire reloads at key up or if reloadTime === 0. When firing set reload to true and reloadTime to repeat rate (in frames). In the key event reload on key up by setting reload = false .
That is about as simple as you can make it.
var framesPerSecond = 30;
var shipX = 0; // ship pos
var leftKeyDown = false; // key down flags
var rightKeyDown = false;
var fireKeyDown = false;
var reloadTime = 0; // fire key needs a timer a timer/counter inbuilt keyboard repeat will take over and mess with your repeat rate.
var reload = false; // dont want the keyboard repeat to trigger shots at the wrong time so
// flag that you need to reload when the next key up
// arrives.
function mainLoop(){
if(leftKeyDown){ // move left if left key down
shipX -= 1;
}
if(rightKeyDown){ // move right if right key down
shipX += 1;
}
if(fireKeyDown && !reload){ //fire is not needing to reload and fire key down
//log("FIRE"); // sends a bullet
reload = true; // need to reload
reloadTime = 10; // number of frames till reload.
}
if(reload && reloadTime > 0){ // if needing to reload
reloadTime -= 1; // count down frames
if(reloadTime === 0){ // until time to reload.
reload = false; // then reload.
}
}
....
// game stuff.
...
// can use requestAnimationFrame if you use canvas
// requestAnimationFrame(mainLoop); // 60 frames a second
// or because you are doing it in HTML
setTimeout(mainLoop,1000 / framesPerSecond);
}
function keyEvent(event){ // handle ky up and downs.
var state = false; // assume up
if(event.type === "keydown"){ // if down
state = true; // set as down
}
if(event.keyCode === 37){ // left key
leftKeyDown = state; // set key state
}else
if(event.keyCode === 39){ // right key
rightKeyDown = state; // set key sate
}else
if(event.keyCode === 32){ // space
fireKeyDown = state;
if(!state && reload){ // reload if needed and key up
reload = false;
}
}
}
document.addEventListener('keydown', keyEvent);
document.addEventListener('keyup', keyEvent);

Related

How to create carousel using javascript and hover to prev and next image with keypress?

I want to create carousel using javascript which have an array of infinity images and after last image ends it should start from first image.On page load the first image should be selected by default and have active border on first image. When keypress right arrow or left arrow the image active border should move accordingly to next or prev image. And when press enter the active border image should get selected and opens link.
I have tried creating carousel but on keypress arrow left or right it doesn't work.
// Hover
var active = document.querySelector(".hover") || document.querySelector(".myImg a");
document.addEventListener("keydown",handler);
document.addEventListener("mouseover",handler);
function handler(e){
console.log(e.which);
active.classList.remove("hover");
switch (e.keyCode) {
case 37:
active = active.previousElementSibling || active;
break;
case 39:
active = active.nextElementSibling || active;
break;
default: active = e.target;
}
active.classList.add("hover");
}
// Carousel
var carousel = document.querySelector('.content');
var slider = document.querySelector('.slider');
var next = document.querySelector('.next');
var prev = document.querySelector('.prev');
var imagesA = document.querySelector('.carousel-img');
// var vid = document.querySelector('.videos');
var direction;
next.addEventListener('click', function () {
direction = -1;
carousel.style.justifyContent = 'flex-start';
slider.style.transform = 'translate(-20%)';
});
prev.addEventListener('click', function () {
if (direction === -1) {
direction = 1;
slider.appendChild(slider.firstElementChild);
}
carousel.style.justifyContent = 'flex-end';
slider.style.transform = 'translate(20%)';
});
slider.addEventListener('transitionend', function () {
if (direction === 1) {
slider.prepend(slider.lastElementChild);
} else {
slider.appendChild(slider.firstElementChild);
}
slider.style.transition = 'none';
slider.style.transform = 'translate(0)';
setTimeout(() => {
slider.style.transition = 'all 0.5s';
})
}, false);
It can be like we see on netflix home carousel where we have list of movies covers but instead of mouse click or mouse over i want same behaviour with Keypress.Please help.
CODE HERE : codepen.io
The keydown events are working, but probably not doing what you expected them to do. Since you already have some logic that is handling next and previous events bound to click, you should extract them as named functions and also use them on the keydown events accordingly.
next.addEventListener("click", goNext);
function goNext() {
direction = -1;
carousel.style.justifyContent = "flex-start";
slider.style.transform = "translate(-10%)";
}
prev.addEventListener("click", goPrev);
function goPrev() {
if (direction === -1) {
direction = 1;
slider.appendChild(slider.firstElementChild);
}
carousel.style.justifyContent = "flex-end";
slider.style.transform = "translate(20%)";
}
Now you have your functions ready, just use them on the switch statement you have:
function handler(e) {
console.log(e.which);
active.classList.remove("hover");
switch (e.keyCode) {
case 37:
goPrev()
break;
case 39:
goNext()
break;
default:
active = e.target;
}
active.classList.add("hover");
}
fork of your pen
There are several other things you will have to fix / improve, so you should probably come back after tweaking your code with some more specific questions.

javascript not working on IE10 / No errors. Works fine on other normal browsers

var depth = 0;
var moving = false;
var answers = new Array();
var qNo = 0;
var rangeCarousel;
var productCarousel;
var ih, iw, orient;
var sidebarOpen = false;
var focused = "range";
var currentRange = 0;
$(document).ready(function () {
document.getElementById('intro').addEventListener('click', clickHandler);
document.getElementById('q1').addEventListener('click', clickHandler);
document.getElementById('q2').addEventListener('click', clickHandler);
document.getElementById('q3').addEventListener('click', clickHandler);
document.getElementById('q4').addEventListener('click', clickHandler);
document.getElementById('intro').addEventListener('webkitTransitionEnd', transitionEnd);
document.getElementById('intro').addEventListener('transitionend', transitionEnd);
document.getElementById('intro').addEventListener('transition', transitionEnd);
});
function clickHandler(e) {
if ((qNo < 4) && (e.target.id != 'intro')) {
qNo++;
if (!moving) {
depth -= 100;
document.getElementById('intro').style.top = (depth + '%');
document.getElementById('q1').style.top = (depth + '%');
document.getElementById('q2').style.top = (depth + '%');
document.getElementById('q3').style.top = (depth + '%');
document.getElementById('q4').style.top = (depth + '%');
moving = true;
}
} else if (qNo == 4) {
var c = e.target.parentNode.classList[0];
switch (c) {
case 'one':
window.open("test.html","_self");
break;
case 'two':
window.open("test.html","_self");
break;
case 'three':
window.open("test.html","_self");
break;
case 'four':
window.open("test.html","_self");
break;
}
}
}
function transitionEnd() {
moving = false;
}
i m trying to create a quiz where users clicks on the images then loads the answer. It works fine on ie11 but i also need to make it work on ie10. I cant see any errors or anything to show me whats wrong
Any help or suggestion will be great
Some old IE does not support target property. You can use e.srcElement which is an alias of target as an alias of target
((e.target || e.srcElement).id) === "intro"
& also use it to find the parentNode
Side Note :As mentioned in comment section you can use jquery as which will also reduce the number of lines in your code beside efficiently handling events
You can also use jquery multiple selector instead of writing same lines of code for attaching event to every selector.
$('sel1 ,selector2 , selector 3 ...').click(function(event){.. rest of code})

simple game using CSS, jQuery and HTML

I'm trying to make a game and still in the opening stages, I have the character and the code I thought would work, except when I run it nothing happens. I cant seem to find an error in it.
document.body.onkeydown = function(event){
var k = event.keyCode;
var chr = {
updown: function (){
var y = 0;
if (k==38) {
--y;
} else if (k == 40) {
++y;
}
return y;
},
leftright: function (){
var x = 0;
if (k == 37) {
--x;
} else if (k == 39) {
++x;
}
return x;
}
};
rogue.style.top = (chr.updown()) + "px";
rogue.style.left = (chr.leftright()) + "px";
}
#rogue {
position: relative;
top: 0px;
left: 0px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="jumpOPP.css">
<script src="jumpOPP.js"></script>
</head>
<body>
<img id="rogue" src="http://piq.codeus.net/static/media/userpics/piq_143310_400x400.png" >
</body>
</html>
I would appreciate any help at all.
Wrap your function like this:
document.body.onkeydown = function(event){
// Your event here
};
Take the handler off the body tag too.
JSFIDDLE
Change your function as below (its just a sample)
Suggested reading:
Retrieve the position (X,Y) of an HTML element
...
updown: function (){
var y = CURRENT_Y; // Get the current Y position of the image HERE
if (k==38) {
--y;
} else if (k == 40) {
++y;
}
return y;
},
leftright: function (){
var x = CURRENT_X; // Get the current X position of the image HERE
if (k == 37) {
--x;
} else if (k == 39) {
++x;
}
return x;
}
The logic you're using to set the top and left values is a little off. Note also that you need to parse the value to an integer so that you can add/remove from its value, and also provide a default.
Try this:
document.body.onkeydown = function(event){
var rogue = document.getElementById('rogue');
var currentY = parseInt(rogue.style.top || 0, 10);
var currentX = parseInt(rogue.style.left || 0, 10);
var speed = 3;
switch (event.keyCode) {
case 38: // up;
rogue.style.top = (currentY - speed) + 'px';
break;
case 40: // down;
rogue.style.top = (currentY + speed) + 'px';
break;
case 37: // left;
rogue.style.left = (currentX - speed) + 'px';
break;
case 39: // right;
rogue.style.left = (currentX + speed) + 'px';
break;
}
}
Example fiddle
Perfectly Working Answer: Run the Code Snippet and check
//bind an event when the user presses any key
window.onkeydown = function (e) {
if (!e) {
e = window.event;
}
//The event object will either be passed
//to the function, or available through
//window.event in some browsers.
var code = e.keyCode;
//that's the code of the key that was pressed.
//http://goo.gl/PsUij might be helpful for these.
//find our rouge image
var rouge = document.getElementById("rouge");
//get the image's current top and left position.
//rouge.style.top will find the top position out of our
//style attribute; parseInt will turn it from for example '10px'
//to '10'.
var top = parseInt (rouge.style.top, 10);
var left = parseInt (rouge.style.left, 10);
//We'll now compare the code that we found above with
//the code of the keys that we want. You can use a chart
//like the one in http://goo.gl/PsUij to find the right codes,
//or just press buttons and console.log it yourself.
if ( code == 37 ) { //LEFT
//time to actually move the image around. We will just modify
//its style.top and style.left accordingly. If the user has pressed the
//left button, we want our player to move closer to the beginning of the page,
//so we'll reduce the 'left' value (which of course is the distance from '0' left)
//by 10. You could use a different amount to make the image move less or more.
//we're also doing some very basic boundary check to prevent
//the image from getting out of the page.
if ( left > 0 ) {
rouge.style.left = left - 10 + 'px';
}
} else if ( code == 38 ) { //UP
//if we pressed the up button, move the image up.
if ( top > 0 ) {
rouge.style.top = top - 10 + 'px';
}
} else if ( code == 39 ) { //RIGHT
//move the image right. This time we're moving further away
//from the screen, so we need to 'increase' the 'left' value.
//the boundary check is also a little different, because we're
//trying to figure out if the rightmost end of the image
//will have gone
//further from our window width if we move it 10 pixels.
if ( left+rouge.width+10 < window.innerWidth ) {
rouge.style.left = left + 10 + 'px';
}
} else if ( code == 40 ) { //DOWN
if ( top+rouge.height+10 < window.innerHeight ) {
rouge.style.top = top + 10 +'px';
}
}
}
<img src="http://piq.codeus.net/static/media/userpics/piq_143310_400x400.png" id="rouge" style="position:absolute;top:0px;left:0px" />
Try this :
Create an array to hold key states : window.keyStates[];
Update the keyStates var with onkeyup / onkeydown events.
document.body.onkeydown = function (event) {
window.keyStates[event.keyCode] = true;
}
document.body.onkeyup = function (event) {
window.keyStates[event.keyCode] = false;
}
Create a loop to loop game :
var mainLoop = function () {
if (window.keyStates[38]) dostuff ();
if (window.keyStates[40]) dootherstuff ();
// etc....
}
window.setInterval(function() {mainLoop()}, 100);
The code is glitchy but you get the idea ? This way you can move your toon 2 directions at the same time too. Or manage virtually any key pressed at the same time.

loop jumps from firs if to the second with hammer.js

I want to use hammer.js pinchout option to switch images (make them larger and fade them).
I've put the images in the background of some divs and I change the css background property to make them larger and disappear. Animating all with webkit.
So far this all works. But I've tried to make a simple switch loop to change the divs one after the other. I first with if and if else and a var to act as switch and later on with the switch option.
The problem is that the the iPad ignores the brakes or pauses and just run the code repentantly from some reason. When I run the code and try to pinchout 2 images change one after the other and the alert given is x-3 (meaning the script did not stop after the first case in the switch and continue to the 3rd before even executing the second!.
please help...
here is the code:
<script type="text/javascript">
var x = 1; // position
var y = 1; // switch
var z = 90; // z-index of layer
var a = 2; // image number (start from image 3 as the first 3 are already set)
window.onload = function() {
Hammer(document.body).on("pinchout", function() {
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
switch (x)
{
case 1:
box1.style.opacity = "0";
box1.style.backgroundSize = "200% 200%";
x=x+1;
a++;
z--;
break;
case 2:
box2.style.opacity = "0";
box2.style.backgroundSize = "200% 200%";
//box1.style.backgroundImage='url("' + a +'.jpg)"';
box1.style.backgroundSize = "100% 100%";
box1.style.zIndex= z;
x++;
a++;
z--;
alert(x);
break;
case 3:
box1.style.opacity = "1";
box2.style.zIndex= z;
box3.style.opacity = "0"
box3.style.backgroundSize = "200% 200%";
x++;
a++;
z--;
break;
}
});}
</script>
ok,
got it. the pinchout event is not fire only once.
so you need to add something to check when it ends and then run your code.
like this:
var isListening = false;
var instance = Hammer(document.body);
instance.on('pinch', function(e) {
if (isListening) return;
instance.on('release', onPinchEnd);
});
function onPinchEnd(e) {
instance.off('release', onPinchEnd);
alert("here"); // do stuff on pinch end.
}

How do I listen for triple clicks in JavaScript?

If this is for a double-click:
window.addEventListener("dblclick", function(event) { }, false);
How can I capture a triple-click? This is for a pinned tab in Google Chrome.
You need to write your own triple-click implementation because no native event exists to capture 3 clicks in a row. Fortunately, modern browsers have event.detail, which the MDN documentation describes as:
A count of consecutive clicks that happened in a short amount of time, incremented by one.
This means you can simply check the value of this property and see if it is 3:
window.addEventListener('click', function (evt) {
if (evt.detail === 3) {
alert('triple click!');
}
});
Working demo: http://jsfiddle.net/L6d0p4jo/
If you need support for IE 8, the best approach is to capture a double-click, followed by a triple-click — something like this, for example:
var timer, // timer required to reset
timeout = 200; // timer reset in ms
window.addEventListener("dblclick", function (evt) {
timer = setTimeout(function () {
timer = null;
}, timeout);
});
window.addEventListener("click", function (evt) {
if (timer) {
clearTimeout(timer);
timer = null;
executeTripleClickFunction();
}
});
Working demo: http://jsfiddle.net/YDFLV/
The reason for this is that old IE browsers will not fire two consecutive click events for a double click. Don't forget to use attachEvent in place of addEventListener for IE 8.
Since DOM Level 2 you could use mouse click handler and check the detail parameter of event which should be interpreted as:
The detail attribute inherited from UIEvent indicates the number of times a mouse button has been pressed and released over the same screen location during a user action. The attribute value is 1 when the user begins this action and increments by 1 for each full sequence of pressing and releasing. If the user moves the mouse between the mousedown and mouseup the value will be set to 0, indicating that no click is occurring.
So the value of detail === 3 will give you the triple-click event.
More information in specification at http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent.
Thanks to #Nayuki https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail - a DOM3 extension which is WIP https://w3c.github.io/uievents/
Here is the real Triple click event, which triggers only when all of three clicks fired with equal interval.
// Default settings
var minClickInterval = 100,
maxClickInterval = 500,
minPercentThird = 85.0,
maxPercentThird = 130.0;
// Runtime
var hasOne = false,
hasTwo = false,
time = [0, 0, 0],
diff = [0, 0];
$('#btn').on('click', function() {
var now = Date.now();
// Clear runtime after timeout fot the 2nd click
if (time[1] && now - time[1] >= maxClickInterval) {
clearRuntime();
}
// Clear runtime after timeout fot the 3rd click
if (time[0] && time[1] && now - time[0] >= maxClickInterval) {
clearRuntime();
}
// Catch the third click
if (hasTwo) {
time[2] = Date.now();
diff[1] = time[2] - time[1];
var deltaPercent = 100.0 * (diff[1] / diff[0]);
if (deltaPercent >= minPercentThird && deltaPercent <= maxPercentThird) {
alert("Triple Click!");
}
clearRuntime();
}
// Catch the first click
else if (!hasOne) {
hasOne = true;
time[0] = Date.now();
}
// Catch the second click
else if (hasOne) {
time[1] = Date.now();
diff[0] = time[1] - time[0];
(diff[0] >= minClickInterval && diff[0] <= maxClickInterval) ?
hasTwo = true : clearRuntime();
}
});
var clearRuntime = function() {
hasOne = false;
hasTwo = false;
time[0] = 0;
time[1] = 0;
time[2] = 0;
diff[0] = 0;
diff[1] = 0;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Click button three times with equal interval
<button id="btn">Click me</button>
Also, I wrote jquery plugin TrplClick, which enables 'trplclick' event
it's very simple if you do it right, and you can even catch single, double, triple, ... clicks as you like. plain javascript, customizable click delay (timeout):
var clicks = 0;
var timer, timeout = 350;
var doubleClick = function(e) {
console.log('doubleClick');
}
var tripleClick = function(e) {
console.log('tripleClick');
}
// click timer
yourcontainer.addEventListener('click', function(e) {
clearTimeout(timer);
clicks++;
var evt = e;
timer = setTimeout(function() {
if(clicks==2) doubleClick(evt);
if(clicks==3) tripleClick(evt);
clicks = 0;
}, timeout);
});
pseudo-code:
var clicks = 0
onclick:
clicks++;
setTimer(resetClicksToZero);
if clicks == 3: tripleclickdetected(); clicks = 0;
I am working on a javascript code editor and I had to listen for triple click and here is the solution that will work for most browsers:
// Function to get mouse position
var getMousePosition = function (mouseEvent) {
var currentObject = container;
var currentLeft = 0;
var currentTop = 0;
do {
currentLeft += currentObject.offsetLeft;
currentTop += currentObject.offsetTop;
currentObject = currentObject.offsetParent;
} while (currentObject != document.body);
return {
x: mouseEvent.pageX - currentLeft,
y: mouseEvent.pageY - currentTop
}
}
// We will need a counter, the old position and a timer
var clickCounter = 0;
var clickPosition = {
x: null,
y: null
};
var clickTimer;
// The listener (container may be any HTML element)
container.addEventListener('click', function (event) {
// Get the current mouse position
var mousePosition = getMousePosition(event);
// Function to reset the data
var resetClick = function () {
clickCounter = 0;
var clickPosition = {
x: null,
y: null
};
}
// Function to wait for the next click
var conserveClick = function () {
clickPosition = mousePosition;
clearTimeout(clickTimer);
clickTimer = setTimeout(resetClick, 250);
}
// If position has not changed
if (clickCounter && clickPosition.x == mousePosition.x && clickPosition.y == mousePosition.y) {
clickCounter++;
if (clickCounter == 2) {
// Do something on double click
} else {
// Do something on triple click
resetClick();
}
conserveClick();
} else {
// Do something on single click
conserveClick();
}
});
Tested on Firefox 12, Google Chrome 19, Opera 11.64, Internet Explorer 9
This approach checks if the user has not changed cursor's position, you still can do something when you have single click or double click. Hope this solution will help everybody who will need to implement a triple click event listener :)
Configurable n-clicks event detector factory
const nClicks = (minClickStreak, maxClickInterval = 500, resetImmediately = true) => {
let timerId = 0
let clickCount = 0
let lastTarget = null
const reset = () => {
timerId = 0
clickCount = 0
lastTarget = null
}
return (originalEventHandler) => (e) => {
if (lastTarget == null || lastTarget == e.target) { // 2. unless we clicked same target
clickCount++ // 3. then increment click count
clearTimeout(timerId)
}
lastTarget = e.target
timerId = setTimeout(reset, maxClickInterval) // 1. reset state within set time
if (clickCount >= minClickStreak) {
originalEventHandler(e)
if (resetImmediately) {
clickCount = 0
}
}
}
}
Usage
table.addEventListener('click', nClicks(2)(e => { // double click
selectCell(e.target)
}))
table.addEventListener('click', nClicks(3)(e => { // triple click
selectRow(e.target)
}))

Categories