I am making a Snake game so I'm trying to move my snake. It is moving with keys but it should move automatically on the screen. I tried doing that with while loops like in the code below but because of break; I have to press a key every time I want it to move. How can I make it move automatically? I tried removing break; an using an if statement but I didn't succeed.
Any other solutions or something else?
I'm new to programming so any advices would be helpful.
var main = function() {
var i = 0;
var j = 0;
$(document).keyup(function(event) {
var e = event.which;
while(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
while(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
while(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
while(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
//Which key is preesed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
});
};
$(document).ready(main);
I think you just have to organize a little bit your code.
First. You must put your code inside a function. You really don't need a while. You can use a simple if.
function move(i) {
if(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
if(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
if(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
if(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
}
Now you have to change the event, using keydown instead of keyup
function main() {
var interval;
$(document).keydown(function(event) {
if(interval) clearInterval(interval); // Clear the previous interval
var e = event.which;
var i;
//Which key is pressed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
interval = setInterval(function() {
move(i)
},1000); // repeat every 1 second
});
}
$(document).ready(main);
Related
I am trying to make a 2D platforming game and I am missing an essential part of it, gravity.
I have tried everything from look at questions on this website to looking at online tutorials and you-tube videos.
I really need help with getting gravity into this game as I am out of ideas.
As I said I have already tried looking at multiple tutorials and videos, including this one:
http://www.somethinghitme.com/2013/01/09/creating-a-canvas-platformer-tutorial-part-one/
but this one uses shapes created in canvas rather than images.
I already know that you have to use a velocity function as well as variable for the gravity. Then you have to put this all inside the key handler function so that it can get executed.
//spaceman variables
var sx = canvasWidth / 2; // start the spaceman in the centre
var sy = canvasHeight / 2;
var sdx = 0; // set initial speed to 0
var sdy = 0;
var sspeed = 3; // create a variable for speed
var gravity = 0.2;
var svX = 0;
var svY = (Math.random() * -10) - 5;
//set variables to use for key presses
//these are Boolean variables
//they can only be true or false
var rightPressed = false;
var leftPressed = false;
var upPressed = false;
var downPressed = false;
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
spaceman2Ready = true;
spacemanReady = false;
leftPressed = true;
} else if (e.keyCode == 38) {
upPressed = true;
} else if (e.keyCode == 40) {
downPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
sdx--;
} else if (e.keyCode == 37) {
spaceman2Ready = false;
spacemanReady = true;
leftPressed = false;
sdx--;
} else if (e.keyCode == 38) {
upPressed = false;
sdx--;
} else if (e.keyCode == 40) {
downPressed = false;
sdx--;
}
}
// add something to "listen" for an event
//an event is keypress, mouse movement, mouse click etc.
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (rightPressed == true) {
sdx = sspeed;
} else if (leftPressed == true) {
sdx = -sspeed;
} else if (upPressed == true) {
sdy = -sspeed;
} else if (downPressed == true) {
sdy = sspeed
}
if (rightPressed == false && leftPressed == false && upPressed == false && downPressed == false) {
sdx = 0;
sdy = 0;
}
sx = sx + sdx;
sy = sy + sdy;
}
if (spacemanReady) {
ctx.drawImage(spacemanImage, sx, sy);
if (spaceman2Ready) {
ctx.drawImage(spaceman2Image, sx, sy);
}
// basically the setTimeout part, but this time its requesting the function that we made at the top
requestAnimationFrame(draw);
}
// this is to get the loop for the animation to start going
window.addEventListener("load",
function() {
draw();
});
< /script>
</body >
</html>/
You should be using gravity to update your position every frame (in the draw function). This would look like:
if(sy > 0){
sdy += gravity
}
I have created a codepen with your game with gravity. I hope this helps!
I am trying to be able to control two players and make them move with a certain speed, I ain't getting any errors in the console and it writes out what it should be doing... But I see no action happening.
//control system
window.addEventListener('keydown', function (event) {
//left key
if (event.keyCode === 37) {
playerOne.x -= 1;
console.log("player 1 left");
}
//right key
else if (event.keyCode === 39) {
playerOne.x += 1;
console.log("player 1 right");
}
//up key
else if (event.keyCode === 38) {
playerOne.y -= 1;
console.log("player 1 up");
}
//down
else if (event.keyCode === 40) {
playerOne.y += 1;
console.log("player 1 down");
}
// bomb
else if (event.keyCode === 13) {
console.log("place bomb");
}
});
window.addEventListener('keydown', function (event) {
//left key
if (event.keyCode === 65) {
playerTwo.x -= 1;
console.log("player 2 left");
}
//right key
else if (event.keyCode === 68) {
playerTwo.x += 1;
console.log("player 2 right");
}
//up key
else if (event.keyCode === 87) {
playerTwo.y -= 1;
console.log("player 2 up");
}
//down
else if (event.keyCode === 83) {
playerTwo.y += 1;
console.log("player 2 down");
}
// bomb
else if (event.keyCode === 32) {
console.log("place bomb");
}
});
function movePlayers() {
"use strict";
if (keys.moveLeft) {
playerOne.x -= powerUps.speed;
if (playerOne.currentDirection != "left") {
playerOne.gotoAndPlay('left')
playerOne.currentDirection = "left";
}
}
if (keys.moveRight) {
playerOne.x += powerUps.speed;
if (playerOne.currentDirection != "right") {
playerOne.gotoAndPlay('right')
playerOne.currentDirection = "right";
}
}
if (keys.moveUp) {
playerOne.y -= powerUps.speed;
if (playerOne.currentDirection != "up") {
playerOne.gotoAndPlay('up')
playerOne.currentDirection = "up";
}
}
if (keys.moveDown) {
playerOne.y += powerUps.speed;
if (playerOne.currentDirection != "down") {
playerOne.gotoAndPlay('down')
playerOne.currentDirection = "down";
}
}
if (keys.moveLeft) {
playerTwo.x -= powerUps.speed;
if (playerTwo.currentDirection != "left") {
playerTwo.gotoAndPlay('left')
playerTwo.currentDirection = "left";
}
}
if (keys.moveRight) {
playerTwo.x += powerUps.speed;
if (playerTwo.currentDirection != "right") {
playerTwo.gotoAndPlay('right')
playerTwo.currentDirection = "right";
}
}
if (keys.moveUp) {
playerTwo.y -= powerUps.speed;
if (playerTwo.currentDirection != "up") {
playerTwo.gotoAndPlay('up')
playerTwo.currentDirection = "up";
}
}
if (keys.moveDown) {
playerTwo.y += powerUps.speed;
if (playerTwo.currentDirection != "down") {
playerTwo.gotoAndPlay('down')
playerTwo.currentDirection = "down";
}
}
}
That´s only an Tipp not an answer - but the place in comments is not enough.
I thinks that´s not an good way with your "if" construction, a sample for an easier way:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Table key´s</title>
<style>
td{width:10px;height:10px;background:#ddd;}
tr:nth-child(5) td:nth-child(5){background:#f00;}
</style>
</head>
<body>
<div id="tableContainer">
</div>
<script>
var row=col=5,max=10;
tableContainer.innerHTML = '<table>'+('<tr>'+'<td>'.repeat(max)).repeat(max)+'</table>';
window.addEventListener("keyup", function(e){
var colDiff, rowDiff;
var keyMap = new Map([[37,[-1,0]],[38,[0,-1]],[39,[1,0]],[40,[0,1]]]);
if (keyMap.has(e.keyCode)){
document.querySelector(`tr:nth-child(${row}) td:nth-child(${col})`).style.background='#ddd';
[colDiff,rowDiff]=keyMap.get(e.keyCode);
row+=rowDiff;
col+=colDiff;
row = (row>max) ? max : (row < 1) ? 1 : row;
col = (col>max) ? max : (col < 1) ? 1 : col;
document.querySelector(`tr:nth-child(${row}) td:nth-child(${col})`).style.background='#f00';
}
})
</script>
</body>
</html>
At the moment I am creating a Hangman Game and I have 26 different functions for each button on the web page. When a button is clicked its function works. What I want to do is change this so all I need is one function for all 26 buttons. Here is my HTML at the moment:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
Here is my Javascript:
function A(event) {
if (event.target.classList.contains("disabled")) {
event.preventDefault();
}
document.getElementById("A").style.opacity = "0.5";
event.target.classList.add("disabled");
for (var letter = 0; letter <= randomWord.length - 1; letter++) {
if (randomWord[letter] === "a") {
document.getElementById("letter_" + letter).innerHTML = "A";
if (oneClick === true) {
score = score + 1;
oneClick = false;
}
document.getElementById("Score").innerHTML = score;
} else if (randomWord.indexOf("a") == -1 && hasLooped === true) {
if (oneClick === true) {
score = score + 1;
oneClick = false;
}
document.getElementById("Score").innerHTML = score;
hasLooped = false;
mistakesLeft = mistakesLeft - 1;
document.getElementById("attempsLeft").innerHTML = mistakesLeft;
console.log(mistakesLeft);
if (mistakesLeft == 7) {
document.getElementById("part-1").style.display = "block";
}
else if (mistakesLeft == 6) {
document.getElementById("part-2").style.display = "block";
} else if (mistakesLeft == 5) {
document.getElementById("part-3").style.display = "block";
} else if (mistakesLeft == 4) {
document.getElementById("part-4").style.display = "block";
} else if (mistakesLeft == 3) {
document.getElementById("part-5").style.display = "block";
} else if (mistakesLeft == 2) {
document.getElementById("part-6").style.display = "block";
} else if (mistakesLeft == 1) {
document.getElementById("part-7").style.display = "block";
} else {
document.getElementById("part-8").style.display = "block";
}
}
}
}
What changes will I need to make to my HTML and Javascript so I no longer need to have 26 different functions? The stuff with in my javascript will also need to change.
Thanks
Change this a function so I can pass a id into it
Like you said, "pass an id into it"
onclick="oneFunction(event, this.id)"
function oneFunction(event, id){
// one code
}
You don't even need id. Just pass in this and you've got your element.
You can also attach the function by addEventListener something like
HTML
A
B
C
JS
var allButtons = document.getElementsByClassName('gamebutton');
//-------------as given in a tag as class----------^^^^
for(var i=0; i<allButtons.length; i++;){
allButtons[i].addEventListener('click', function (event){
//the single function by which your game would be executed
executeFunction(event, this.id);
//the id(eg:- A, B, C)----^^^-- depends
// on click is passing
})
}
So the operating system has a delay when you hold down a key. It will execute the command once, delay, then repeat. I tried to bypass this with setting a variable to true or false based on when the key has "keydown" and "Keyup." I am not sure why it is not working though. I am not sure if I am forgetting about something, but If someone could explain why my code is still not fixing the issue.
Variables
var keyPressed = {Kleft: 37, Kright: 39, Kup: 38, Kdown: 40, Kspace: 32};
key = {K37: false, K39: false, K38: false, K40: false, K32: false};
detect for key being pressed
//to detect multiple keys being pressed
$(document).keydown(function(e) {
if(keyPressed.Kleft) //left arrow
{
console.log('test');
key.K37 = true;
airplane.performAction();
}
if(keyPressed.Kright) //right arrow
{
key.K37 = true;
// airplane.performAction();
}
if(keyPressed.Kup) //up arrow
{
key.K37 = true;
// airplane.performAction();
}
if(keyPressed.Kdown) //down arrow
{
key.K37 = true;
// airplane.performAction();
}
if(keyPressed.Kspace) //space key
{
key.K37 = true;
bullet = new Bullet({x: airplane.position.x+32, y: airplane.position.y-12}, bullets_total++); //create a new bullet
bullets.push(bullet); //store the bullet in the bullets array
}
}).keyup(function(e) {
key.K37 = false; //testing just one key for now
console.log('ehhlo');
// console.log(key['K'+toString(e)]);
// key['K'+toString(e)] = false;
});
the executed function on Keypress
function MyAirplane()
{
this.performAction = function(action)
{
if(key.K37 === true){
console.log('left');
this.position.x -= 10;
}
if(key.K37 == true){
this.position.x += 10;
}
if(key.K37 == true){
this.position.y -= 10;
}
if(key.K37 == true){
this.position.y += 10;
}
}
}
Just an idea, try not automatically calling performAction.
//to detect multiple keys being pressed
$(document).keydown(function(e) {
if(keyPressed.Kleft) //left arrow
{
key.K37 = true;
}
if(keyPressed.Kright) //right arrow
{
key.K37 = true;
}
if(keyPressed.Kup) //up arrow
{
key.K37 = true;
}
if(keyPressed.Kdown) //down arrow
{
key.K37 = true;
}
if(keyPressed.Kspace) //space key
{
key.K37 = true;
bullet = new Bullet({x: airplane.position.x+32, y: airplane.position.y-12}, bullets_total++); //create a new bullet
bullets.push(bullet); //store the bullet in the bullets array
}
}).keyup(function(e) {
key.K37 = false; //testing just one key for now
console.log('ehhlo');
// console.log(key['K'+toString(e)]);
// key['K'+toString(e)] = false;
});
And create an event timer:
function MyAirplane()
{
this.performAction = function(action)
{
if(key.K37 === true){
console.log('left');
this.position.x -= 10;
}
if(key.K37 == true){
this.position.x += 10;
}
if(key.K37 == true){
this.position.y -= 10;
}
if(key.K37 == true){
this.position.y += 10;
}
}
// 60 frames per second event checker.
var eventLoop = setInterval(this.performAction.bind(this), 1000 / 60);
}
Something really odd going on here, and I have gone round in circles trying to figure out what is going on...I have a couple of input boxes, with onchange events firing for them, the event being loaded with a JS function that takes the value ( name of another item ) and actions the function accordingly. Only thing is, when the value of the string arrives at the other function, it has somehow been assigned a numeric value, specifically that of the input box.
My php that helps build the form:
$filterfield = '"p_delweek"';
print "<span class='filter'>Del Week<input class='menulink spin-button' id='weekno' type='text' value='".$weekno."' onKeyUp='doFilter($filterfield)' onChange='doFilter($filterfield)' data-filtered='0'/><input type='button' value='Clear' onClick='doUnfilter()'></span>";
$filterfield = '"p_seedweek"';
print "<span class='filter'>Sow Week<input class='menulink spin-button' id='sowweekno' type='text' value='".$weekno."' onKeyUp='doFilter($filterfield)' onChange='doFilter($filterfield)' data-filtered='0'/><input type='button' value='Clear' onClick='doUnfilter()'></span>";
Resulting HTML in source:
<span class="filter">Del Week<input style="width: 50px; height: 22px;" class="menulink spin-button smartspinner" id="weekno" value="26" onkeyup='doFilter("p_delweek")' onchange='doFilter("p_delweek")' data-filtered="0" type="text"><input value="Clear" onclick="doUnfilter()" type="button"></span><span class="filter">Sow Week<input style="width: 50px; height: 22px;" class="menulink spin-button smartspinner" id="sowweekno" value="26" onkeyup='doFilter("p_seedweek")' onchange='doFilter("p_seedweek")' data-filtered="0" type="text"><input value="Clear" onclick="doUnfilter()" type="button"></span>
Javascript function that is called:
function doFilter(filterfield) {
console.log("DoFilter:"+filterfield);
var filterInfo=[
{
fieldName : filterfield,
logic : "equal",
value : Sigma.Util.getValue("weekno")
}
]
// the next lines action the filtering
var grid=Sigma.$grid("myGrid1");
console.log("filterinfo="+filterInfo);
var rowNOs=grid.applyFilter(filterInfo);
}
It all goes fine until we get to the console.log("DoFilter:"+filterfield) , which results in DoFilter:25; 25 happens to be the value of the input box.
How is it grabbing that value? How to pass the real one?
TBH — I'm not sure if I got what you're after. However, if you must call a function inline (I recommend that you don’t), you can pass a reference to the input field as parameter and make it available in the methods’s body:
<input onchange="doFilter('p_delweek', this)" type="text">
function doFilter(filterfield, field) {
console.log(filterfield);
// field is a reference to the input field, hence
console.log(field.value);
// will print the current value for this field
}
This is not the answer, this file is the problem:
(function($) {
$.fn.extend({
spinit: function(options) {
var settings = $.extend({ min: 0, max: 100, initValue: 0, callback: doFilter, stepInc: 1, pageInc: 10, width: 50, height: 15, btnWidth: 10, mask: '' }, options);
return this.each(function() {
var UP = 38;
var DOWN = 40;
var PAGEUP = 33;
var PAGEDOWN = 34;
var mouseCaptured = false;
var mouseIn = false;
var interval;
var direction = 'none';
var isPgeInc = false;
var value = Math.max(settings.initValue, settings.min);
var el = $(this).val(value).css('width', (settings.width) + 'px').css('height', settings.height + 'px').addClass('smartspinner');
raiseCallback(value);
if (settings.mask != '') el.val(settings.mask);
$.fn.reset = function(val) {
if (isNaN(val)) val = 0;
value = Math.max(val, settings.min);
$(this).val(value);
raiseCallback(value);
};
function setDirection(dir) {
direction = dir;
isPgeInc = false;
switch (dir) {
case 'up':
setClass('up');
break;
case 'down':
setClass('down');
break;
case 'pup':
isPgeInc = true;
setClass('up');
break;
case 'pdown':
isPgeInc = true;
setClass('down');
break;
case 'none':
setClass('');
break;
}
}
el.focusin(function() {
el.val(value);
});
el.click(function(e) {
mouseCaptured = true;
isPgeInc = false;
clearInterval(interval);
onValueChange();
});
el.mouseenter(function(e) {
el.val(value);
});
el.mousemove(function(e) {
if (e.pageX > (el.offset().left + settings.width) - settings.btnWidth - 4) {
if (e.pageY < el.offset().top + settings.height / 2)
setDirection('up');
else
setDirection('down');
}
else
setDirection('none');
});
el.mousedown(function(e) {
isPgeInc = false;
clearInterval(interval);
interval = setTimeout(onValueChange, 250);
});
el.mouseup(function(e) {
mouseCaptured = false;
isPgeInc = false;
clearInterval(interval);
});
el.mouseleave(function(e) {
setDirection('none');
if (settings.mask != '') el.val(settings.mask);
}); el.keydown(function(e) {
switch (e.which) {
case UP:
setDirection('up');
onValueChange();
break; // Arrow Up
case DOWN:
setDirection('down');
onValueChange();
break; // Arrow Down
case PAGEUP:
setDirection('pup');
onValueChange();
break; // Page Up
case PAGEDOWN:
setDirection('pdown');
onValueChange();
break; // Page Down
default:
setDirection('none');
break;
}
});
el.keyup(function(e) {
setDirection('none');
});
el.keypress(function(e) {
if (el.val() == settings.mask) el.val(value);
var sText = getSelectedText();
if (sText != '') {
sText = el.val().replace(sText, '');
el.val(sText);
}
if (e.which >= 48 && e.which <= 57) {
var temp = parseFloat(el.val() + (e.which - 48));
if (temp >= settings.min && temp <= settings.max) {
value = temp;
raiseCallback(value);
}
else {
e.preventDefault();
}
}
});
el.blur(function() {
if (settings.mask == '') {
if (el.val() == '')
el.val(settings.min);
}
else {
el.val(settings.mask);
}
});
el.bind("mousewheel", function(e) {
if (e.wheelDelta >= 120) {
setDirection('down');
onValueChange();
}
else if (e.wheelDelta <= -120) {
setDirection('up');
onValueChange();
}
e.preventDefault();
});
if (this.addEventListener) {
this.addEventListener('DOMMouseScroll', function(e) {
if (e.detail > 0) {
setDirection('down');
onValueChange();
}
else if (e.detail < 0) {
setDirection('up');
onValueChange();
}
e.preventDefault();
}, false);
}
function raiseCallback(val) {
if (settings.callback != null) settings.callback(val);
}
function getSelectedText() {
var startPos = el.get(0).selectionStart;
var endPos = el.get(0).selectionEnd;
var doc = document.selection;
if (doc && doc.createRange().text.length != 0) {
return doc.createRange().text;
} else if (!doc && el.val().substring(startPos, endPos).length != 0) {
return el.val().substring(startPos, endPos);
}
return '';
}
function setValue(a, b) {
if (a >= settings.min && a <= settings.max) {
value = b;
} el.val(value);
}
function onValueChange() {
if (direction == 'up') {
value += settings.stepInc;
if (value > settings.max) value = settings.max;
setValue(parseFloat(el.val()), value);
}
if (direction == 'down') {
value -= settings.stepInc;
if (value < settings.min) value = settings.min;
setValue(parseFloat(el.val()), value);
}
if (direction == 'pup') {
value += settings.pageInc;
if (value > settings.max) value = settings.max;
setValue(parseFloat(el.val()), value);
}
if (direction == 'pdown') {
value -= settings.pageInc;
if (value < settings.min) value = settings.min;
setValue(parseFloat(el.val()), value);
}
raiseCallback(value);
}
function setClass(name) {
el.removeClass('up').removeClass('down');
if (name != '') el.addClass(name);
}
});
}
});
})(jQuery);
Why and where does this alter the passing value of a function attached to the < INPUT > ?