Javascript: Moving an Object with Arrow Keys - javascript

Im making a simple Tetris game. So far I have a Tetris piece that rotates when the space bar is clicked.
The next step for me is to move the objects left and right using the arrow keys. From looking at other Stack Questions I found that this was possible by changing the margins.
var angle = 0;
var obj = document.getElementById('image')
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '32') {
rotate();
}
else if (e.keyCode == '37') {
moveLeft();
}
else if (e.keyCode == '39') {
moveRight();
}
}
function rotate() {
angle = angle + 90;
console.log(angle)
obj.className = "image" + angle;
console.log(obj.className)
if (angle == 360) {
angle = 0;
}
}
function moveLeft() {
obj.style.left = parseInt(obj.style.left) - 5 + 'px';
}
function moveRight() {
obj.style.left = parseInt(obj.style.left) + 5 + 'px';
}
For some reason this isn't working for me.
I've also re-created my code in a JSFiddle using a banana instead of a Tetris piece.

The problem is not with your Javascript, but with your styles. You need to absolutely position your image (banana in this case), and set an initial "left" value. The position: absolute; can be set either in the HTML or CSS, but the left: 0; must be set in the HTML style attribute. Here is an updated jsfiddle with the changes.

Related

Three.js Set relative position to another Object

Recently, I've been working on a video game with Three.js and I want the up arrow key to go forward relative to the camera.
Here is my code for the arrow key.
var x = 0;
var rotx = 0;
setInterval(function() {
if (x == 1){
camera.position.z += 0.05
}
}
document.addEventListener("keydown", function(event){
if (event.key == "ArrowUp"){
x = 1
}
});
document.addEventListener("keyup", function(event){
if (event.key == "ArrowUp"){
x = 0
}
});
Many times I've been searching for the answer. Usually coming across both
object.localToWorld();
object.worldToLocal();
but I can't seem to understand how to use this method.

Key code based event listener doesn’t move box correctly, using margins

I am having a problem with a script that I made to allow elements with the ID me to move based on arrow keys, but whenever it’s told to go left it goes right, when told to go right it goes right, when told to go up or down it doesn’t move.
Here is the script:
document.onkeydown = function(event) {
var kc = event.keyCode;
var me = document.getElementById('me');
me.innerHTML = kc;
var XPos = me.offsetLeft;
var YPos = me.offsetTop;
if (kc == '39') {
me.style.marginLeft = XPos++ + 'px';
}
if (kc == '37') {
me.style.marginLeft = XPos-- + 'px';
}
if (kc == '38') {
me.style.marginTop = YPos-- + 'px';
}
if (kc == '40') {
me.style.marginTop = YPos++ + 'px';
}
};
A demo is on this website.
There are two mistakes in your code:
You are trying to set the position of the box with marginLeft / marginTop – this adds, as the name implies, margins to the div, i.e. additional space around it, thus moving it in the opposite direction that you intend; you should simply use left and top
By using e.g. XPos++, you are getting the old value of XPos, and then you increase its value; you should use ++XPos instead, this way, the value is increased before you use it
Here's an updated, working version of your code:
document.onkeydown = function(event) {
var kc = event.keyCode;
var me = document.getElementById('me');
me.innerHTML = kc;
var XPos = me.offsetLeft;
var YPos = me.offsetTop;
if (kc == '39') {
me.style.left = ++XPos + 'px';
}
if (kc == '37') {
me.style.left = --XPos + 'px';
}
if (kc == '38') {
me.style.top = --YPos + 'px';
}
if (kc == '40') {
me.style.top = ++YPos + 'px';
}
};
#me {
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 100px;
background-color: blue;
}
<div id="me"></div>
See JSFiddle: https://jsfiddle.net/pahund/sovxsh22/

Make element behave a certain way until event (Making a pacman game)

I'm making a pacman game in Javascript as an exercise. What would be a good way to make the character go one direction indefinitely until another key is pressed?
function Player(){
this.left = $('#pacMan').css('left');
this.leftMove = function(){
this.left = parseInt(this.left) - 20;
$('#pacMan').animate({'left': this.left}, 100);
};
//Pressing directional keys calls appropriate methods.
$('body').keydown(function(){
if (event.which === 39){
for (i=0; i<13; i++){
pacMan.rightMove();
}
}
if (event.which === 37){
pacMan.leftMove();
}
if (event.which === 38){
pacMan.topMove();
}
if (event.which === 40){
pacMan.bottomMove();
}
});*/
How do I make it so the element keeps moving a direction until a new key is pressed, where it would go in that direction?
A general approach I tend to use for this type of problem is have your object have a changeX (vx) and a changeY (vy) variable. Then in your main game loop change the position of the object by those to variables:
this.left = parseInt(this.left) - this.vx;
this.top = parseInt(this.top) - this.vy;
In your event handler you would set the vales of vx and vy depending on where you want to move. For example setting vx = 10 and vy = 0 would make it move left by 10 units each loop.
if (event.which === 39) {
//pacMan.leftMove();
pacMan.vx = 10; pacMan.vy = 0;
}
The player would simply have a move() function that would move based on those values in the main loop:
var timer = setInterval(function () {
pacMan.move();
}, 50);
Where move() is:
this.move = function(){
this.left = parseInt(this.left) - this.vx;
$('#pacMan').css({'left': this.left})
this.top = parseInt(this.top) - this.vy;
$('#pacMan').css({'top': this.top});
}
Working Example
I recommend setTimeout function for that
setTimeout( function() {
// leftMove, topMove, bottomMove, rightMove
// if you press new key, you have to change direction
} , 1000 );
// 1000 moving delay
You could do it using window.setInterval, something like this should work
var timer;
$('body').keydown(function () {
var key = event.which;
window.clearInterval(timer);
timer = window.setInterval(function () {
switch (key) {
case 37:
pacMan.leftMove();
break;
case 38:
pacMan.topMove();
break;
case 39:
pacMan.rightMove();
break;
case 40:
pacMan.bottomMove();
break;
}
}, 100);
});

Using arrow keys to navigate grid of divs wount scroll overflown contents

Here's a solution i found on stackoverflow
this solution works for me except that when the contents of the div is overflown the contents do not scroll alongside the arrow keys, like scroll seems to be much slower after the 5 or 6 rows.
Please here's an updated jsFiddle of the answer above
var position = { x: 0, y: 0 };
var calendarMap = [];
$(document).ready(function () {
$('.row').each(function () {
calendarMap.push([]);
$('.day, .date', this).each(function () {
calendarMap[calendarMap.length - 1].push($(this));
});
});
highlightCell();
});
$(window).on('keydown', function (e) {
if (e.keyCode === 37) // left
moveLeft();
else if (e.keyCode === 38) // up
moveUp();
else if (e.keyCode === 39) // right
moveRight();
else if (e.keyCode === 40) // down
moveDown();
highlightCell();
});
function moveLeft() {
position.x--;
if (position.x < 0)
position.x = 0;
}
function moveUp() {
position.y--;
if (position.y < 0)
position.y = 0;
}
function moveRight() {
position.x++;
if (position.x >= calendarMap[0].length)
position.x = calendarMap[0].length - 1;
}
function moveDown() {
position.y++;
if (position.y >= calendarMap.length)
position.y = calendarMap.length - 1;
}
function highlightCell() {
$('.day, .date').removeClass('selected');
calendarMap[position.y][position.x].addClass('selected');
}
If I understand this, your issue is that when scrolling with arrow-keys on your keyboard, your "selected character" inside the calender moves faster than the actual scroll bar...
This is because you are both moving the "selected" object AND scrolling with your keys. Moving the "selected" object within the calender is going on simultaneously to the regular scrolling. So two behaviors are going on at the same time, independent of each other, each triggered by the arrow key.
One solution would be to add a JS behavior to add extra scrolling with arrow-key usage... but then if the user uses their mouse to scroll in the window, things will be "off" again.
You can check out this post, it might help:
JScrollPane scrolling with arrow keys

how do i make a image follow another in javascript for my game

Hey can someone show me how i can make a picture of a zombie move towards a player image.
so a zombie image would move towards zs.png at a certain speed and maybe could add health so when the zombie touches the player the player looses health
This game is for the 3ds browser so it has to be javascript and html
Also here is a link to the page im running it on Link
And could someone give me the full code because im new to javascript. Thanks
this is what i have so far.
<html>
<head>
<script type='text/javascript'>
// movement vars
var xpos = 100;
var ypos = 100;
var xspeed = 1;
var yspeed = 0;
var maxSpeed = 5;
// boundary
var minx = 0;
var miny = 0;
var maxx = 300;
var maxy = 190;
// controller vars
var upPressed = 0;
var downPressed = 0;
var leftPressed = 0;
var rightPressed = 0;
function slowDownX()
{
if (xspeed > 0)
xspeed = xspeed - 0.5;
if (xspeed < 0)
xspeed = xspeed + 0.5;
}
function slowDownY()
{
if (yspeed > 0)
yspeed = yspeed - 0.5;
if (yspeed < 0)
yspeed = yspeed + 0.5;
}
function gameLoop()
{
// change position based on speed
xpos = Math.min(Math.max(xpos + xspeed,minx),maxx);
ypos = Math.min(Math.max(ypos + yspeed,miny),maxy);
// or, without boundaries:
// xpos = xpos + xspeed;
// ypos = ypos + yspeed;
// change actual position
document.getElementById('character').style.left = xpos;
document.getElementById('character').style.top = ypos;
// change speed based on keyboard events
if (upPressed == 1)
yspeed = Math.max(yspeed - 0.1,-0.1*maxSpeed);
if (downPressed == 1)
yspeed = Math.min(yspeed + 0.1,0.1*maxSpeed)
if (rightPressed == 1)
xspeed = Math.min(xspeed + 0.1,0.1*maxSpeed);
if (leftPressed == 1)
xspeed = Math.max(xspeed - 0.1,-0.1*maxSpeed);
// deceleration
if (upPressed == 0 && downPressed == 0)
slowDownY();
if (leftPressed == 0 && rightPressed == 0)
slowDownX();
// loop
setTimeout("gameLoop()",10);
}
function keyDown(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 1;
if (code == 40)
downPressed = 1;
if (code == 37)
leftPressed = 1;
if (code == 39)
rightPressed = 1;
}
function keyUp(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 0;
if (code == 40)
downPressed = 0;
if (code == 37)
leftPressed = 0;
if (code == 39)
rightPressed = 0;
}
</script>
</head>
<body onload="gameLoop()" onkeydown="keyDown(event)" onkeyup="keyUp(event)" bgcolor='red'>
<!-- The Level -->
<div style='width:320;height:220;position:absolute;left:0;top:0;background:green;'>
</div>
<!-- The Character -->
<img id='character' src='zs.gif' style='position:absolute;left:100;top:100;height:30;width:20;'/>
</body>
</html>
Edit: Updated a few blocks of code to make them actually work(!), added note about where to put scripts and included a jsFiddle
jsFiddle Link
Edit 2: Don't just put left:100;top:100;height:30;width:20; as it isn't valid CSS and many browsers will choke on it. Add px after each number to get left:100px;top:100px;height:30px;width:20px; instead.
A little research goes a long way.
How to detect if two divs touch with jquery?
Binding arrow keys in JS/jQuery
jquery animate .css
You almost definitely want to be using jQuery for what you're doing.
Try something like the following:
$(document).ready(function(){
$(document).keydown(function(e){
var c = $("#character");
if (e.keyCode === 37) {
// left arrow pressed
c.css("left","-=10px"); // subtract 10px from the character's CSS 'left' property, although you probably want some system to add a limit to this value
}else if(e.keyCode === 38) {
// up arrow pressed
c.css("top","-=10px"); // subtract 10px from the character's CSS 'up' property
}else if(e.keyCode === 39) {
// right arrow pressed
c.css("left","+=10px"); // add 10px to the character's CSS 'left' property
}else if(e.keyCode === 40) {
// down arrow pressed
c.css("top","+=10px"); // add 10px to the character's CSS 'top' property
}
return false;
});
});
This allows the character to move by using the arrow keys.
Making the zombie image move is a little more difficult. First, add the following div tag to your document:
<div id="zombie" style="position:absolute;top:10px;left:10px;"><img src="YOUR_ZOMBIE_IMAGE.gif" /></div>
Then, add the following JavaScript above the $(document).ready(function(){ line:
var zombieFrequency = 1000; // how long (in milliseconds) it should take the zombie to move to the character's position
var easeType = "swing"; // change this to "linear" for a different kind of zombie animation
Finally, add the following into the $(document).ready(function(){ block:
setInterval(function(){
var c = $("#character");
$("#zombie").animate({"left":c.css("left"),"top":c.css("top")},zombieFrequency,easeType);
},zombieFrequency);
This should make the zombie move to the character's position every 0.6 seconds (600ms = 0.6s), although I haven't tested it myself.
Alternatively, you could consider using CSS transitions, although I doubt they'd run smoothly (or even be supported) on a Nintendo 3DS.
Pay special attention to this!
Also, you cannot put links to scripts and internal scripts in the same <script> tag, like this:
<script src="//ajax.googleapis.com/libs/jquery/1.10.2/jquery.min.js">
// some more scripting
</script>
They must be separate, like this:
<script src="//ajax.googleapis.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
// some more scripting
</script>
On a separate note, it's recommended to decide on using either single quotes ' or double quotes ", according to the W3 spec. Most people use double quotes.
Single vs Double quotes (' vs ")

Categories

Resources