Jquery Move Div with Arrow Keys

jQuery Move div with arrow keys

There are two things you need to do:

  1. Your <div> needs position: absolute or your top and left properties won't do anything.
  2. jQuery doesn't know what '-= 10' means but it does understand '-=10'. You might want to go all the way to '-=10px' as that's more common but the px isn't necessary.

Updated fiddle: http://jsfiddle.net/ambiguous/N5Ltt/2/

You're seeing the animation stop when you hold down an arrow key because you call .stop on each keydown and that stops the animation. The animation works using a timer and .stop stops the timer; if the keyboard's repeat rate is faster than the first iteration of the timer then no animation happens when you hold down an arrow key. You're only moving by 10px at a time so you could just do a straight non-animated move by 10px using .css:

$div.css('left', $div.offset().left - 10);

Non-animated version: http://jsfiddle.net/ambiguous/N5Ltt/3/

Continously move div with arrow keys

This could be an approach for you:

var pressed = false;
$(document).keydown(function(e) {
if(!pressed){ //only start animation once
width = $(this).width();
height = $(this).height();
switch (e.which) {
case 37:
$('div').stop().animate({
left: '-=' + width //allow the user the move the div over the whole doc
}, 2000); //left arrow key
break;
// and so on
}
}
pressed = true;
}).keyup(function(){
$('div').stop(); // stop the current animation
pressed = false;
});

perhaps you have to change the variables width and height to fit in your needs.

DEMO

how to move a div with arrow keys

var pane = $('#pane'),
box = $('#box'),
w = pane.width() - box.width(),
d = {},
x = 3;

function newv(v,a,b) {
var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
return n < 0 ? 0 : n > w ? w : n;
}

$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });

setInterval(function() {
box.css({
left: function(i,v) { return newv(v, 37, 39); },
top: function(i,v) { return newv(v, 38, 40); }
});
}, 20);
#pane {
position: relative;
width: 300px;
height: 300px;
border: 2px solid red;
}

#box {
position: absolute;
top: 140px;
left: 140px;
width: 20px;
height: 20px;
background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="pane">
<div id="box"></div>
</div>

Move elements with arrow keys

i'm not sure if you still need a solution or not but you can check this one out:
http://jsfiddle.net/ft2PD/41/

here is the html

<div id='div1'>
<input type='text' value='hello' />
</div>

<div id='div2'>
<label> World</label>
</div>

and here is the javascript:

$(document).ready(function(){
$('#div1,#div2').click(function(){
$('div.selected').removeClass('selected');
$(this).addClass('selected');

})}).keyup(function(e){
var div = $('div.selected');
console.log(div);
console.log(e.which);
switch (e.which) {
case 37:
$(div).stop().animate({
left: '-=10'
}); //left arrow key
break;
case 38:
$(div).stop().animate({
top: '-=10'
}); //up arrow key
break;
case 39:
$(div).stop().animate({
left: '+=10'
}); //right arrow key
break;
case 40:
$(div).stop().animate({
top: '+=10'
}); //bottom arrow key
break;
}
});​

and last the CSS

#div1
{
position: absolute;
width:100px;
height:100px;
margin:15px;
padding:15px;
border: thin solid #D2D2D2;
}
#div2
{
position: absolute;
width:50%;
margin:15px;
padding:15px;
border: thin solid #D2D2D2;
}
.selected
{
border: 1px dashed #cccccc !important;
}​

How to use arrow keys to move selected elements

If you use $this.position() for getting position, your code will work just fine.

function getpos(e) {  return {    X: e.pageX,    Y: e.pageY  };}
function Rect(start, stop) { this.left = Math.min(start.X, stop.X); this.top = Math.min(start.Y, stop.Y); this.width = Math.abs(stop.X - start.X); this.height = Math.abs(stop.Y - start.Y);}
$(function() { var startpos; var selected = $([]), offset = { top: 0, left: 0 }; $(".designer-verticalline, .designer-rectangle, .designer-field, .designer-image").resizable();
// http://stackoverflow.com/questions/705250/is-there-a-jquery-plugin-which-combines-draggable-and-selectable#8643716 // teha: seal on ka mousedown mis andis viga, kaseda kasutada var $liigutatavad = $(".designer-verticalline, .designer-horizontalline, .designer-rectangle, .designer-field, .designer-image, .designer-label"); $liigutatavad.draggable({ start: function(event, ui) { var $this = $(this);
if ($this.hasClass("ui-selected")) { // if this is selected, attach current offset // of each selected element to that element selected = $(".ui-selected").each(function() { var el = $(this); el.data("offset", el.offset()); }); } else { // if this is not selected, clear current selection selected = $([]); $liigutatavad.removeClass("ui-selected"); } offset = $this.offset(); },
drag: function(event, ui) { // drag all selected elements simultaneously var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; selected.not(this).each(function() { var $this = $(this); var elOffset = $this.data("offset"); $this.css({ top: elOffset.top + dt, left: elOffset.left + dl }); });
// this does not fix the issue: //$(".designer-verticalline, .designer-rectangle, .designer-field, .designer-image").resizable(); } });
// ...but manually implement selection to prevent interference from draggable() $(".designer-panel-body").on("click", "div", function(e) { if ( /*!e.metaKey &&*/ !e.shiftKey && !e.ctrlKey) { // deselect other elements if meta/shift not held down $(".designer-panel-body").removeClass("ui-selected"); $(this).addClass("ui-selected"); } else { if ($(this).hasClass("ui-selected")) { $(this).removeClass("ui-selected"); } else { $(this).addClass("ui-selected"); } }
//var selectable = $("#container").data("selectable"); //selectable.refresh(); //$( ".designer-panel-body" ).data("selectable")._mouseStop(null); });
$(".designer-panel-body").selectable({ selected : function() { $(".ui-selected").first().focus(); } });

$(".designer-panel-body").keydown(function(e) { switch (e.which) { case 37: // left $(".ui-selected").each(function() { var $this = $(this); var $position = $this.position(); $this.css({ left: $position.left - 2 }); }); break;
case 38: // up $(".ui-selected").each(function() { var $this = $(this); var $position = $this.position(); $this.css({ top: $position.top - 2 }); }); break;
case 39: // right $(".ui-selected").each(function() { var $this = $(this); var $position = $this.position(); $this.css({ left: $position.left + 2 }); }); break;
case 40: // down $(".ui-selected").each(function() { var $this = $(this); var $position = $this.position(); $this.css({ top: $position.top + 2 }); }); break;
default: return; // exit this handler for other keys } e.preventDefault(); // prevent the default action (scroll / move caret) });

});
.designer-panel-body {  min-height: 1px;  overflow: hidden;  margin: 0;  padding: 0;}.panel-footer {  background-color: inherit;}.designer-panel,.designer-resetmargins {  margin: 0;  padding: 0;}.designer-verticalline,.designer-horizontalline,.designer-rectangle {  font-size: 1pt;  border: 1px solid #000000;}.designer-field {  border: 1px solid lightgray;  white-space: pre;  overflow: hidden;}.ui-selecting {  background-color: lightskyblue;  color: white;}.ui-selected {  background-color: lightskyblue;  border-color: darkblue;  color: white;}.designer-label {  white-space: pre;  /*overflow: hidden;*/}.designer-field,.designer-label {  font-family: "Times New Roman";  font-size: 10pt;  z-index: 2;}.designer-verticalline,.designer-horizontalline,.designer-rectangle,.designer-field,.designer-image,.designer-label {  position: absolute;}
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script><script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script><div class='panel designer-panel'>  <div class='panel-body designer-panel-body panel-warning' style='height:9.37cm'>
<div class='designer-field' contenteditable='true' style='top:2.30cm;left:5.84cm;width:10.24cm;height:0.63cm;font-family:Arial;font-size:14pt;font-weight:bold;'>vnimi+' '+dok.tasudok</div> <div class='designer-field' contenteditable='true' style='top:2.30cm;left:16.37cm;width:2.68cm;height:0.61cm;font-size:14pt;'>DOK.kuupaev</div> <div class='rectangle' style='border-width: 1px;background-color:#FFFFFF;top:2.99cm;left:1.34cm;width:18.05cm;height:5.29cm'></div> <div class='designer-field' contenteditable='true' style='top:3.01cm;left:1.53cm;width:9.71cm;height:0.55cm;font-size:12pt;'>m.FIRMA</div> <div class='designer-field' contenteditable='true' style='top:3.01cm;left:12.13cm;width:3.13cm;height:0.53cm;font-size:12pt;'>ise.telefon</div> <div class='designer-field' contenteditable='true' style='top:3.01cm;left:17.11cm;width:1.89cm;height:0.55cm;font-size:12pt;text-align:right;'>ise.regnr</div> <div class='designer-label' contenteditable='true' style='top:3.04cm;left:11.39cm;text-align:right;font-size:12pt;'>Tel.</div> <div class='designer-label' contenteditable='true' style='top:3.04cm;left:15.71cm;font-size:12pt;'>Reg.Nr</div> <div class='designer-field' contenteditable='true' style='top:3.62cm;left:1.55cm;width:9.45cm;height:0.55cm;font-size:12pt;'>ise.tanav</div> <div class='designer-field' contenteditable='true' style='top:3.70cm;left:15.16cm;width:3.37cm;height:0.55cm;font-size:12pt;'>ise.vatpayno</div> <div class='designer-label' contenteditable='true' style='top:3.72cm;left:12.89cm;text-align:right;font-size:12pt;'>KMKR nr</div> <div class='designer-field' contenteditable='true' style='top:4.30cm;left:1.58cm;width:9.08cm;height:0.55cm;font-size:12pt;'>rtri(ise.postiindek)+' '+rtri(ise.piirkond)</div> <div class='designer-field' contenteditable='true' style='top:4.30cm;left:14.66cm;width:4.34cm;height:0.55cm;font-size:12pt;text-align:right;'>aarve(dok.arvekonto, 'konto.arveldusar')</div> <div class='designer-label' contenteditable='true' style='top:4.33cm;left:13.89cm;font-size:12pt;'>A/A</div> <div class='designer-horizontalline' style='border-width: 1px;top:4.96cm;left:1.34cm;width:18.03cm;height:0.00cm'></div> <div class='designer-field' contenteditable='true' style='top:5.04cm;left:17.13cm;width:1.89cm;height:0.55cm;font-size:12pt;text-align:right;'>klient.regnr</div> <div class='designer-field' contenteditable='true' style='top:5.06cm;left:4.18cm;width:12.71cm;height:0.55cm;font-size:12pt;'>klient.nimi</div> <div class='designer-label' contenteditable='true' style='top:5.06cm;left:15.74cm;font-size:12pt;'>Reg.Nr</div> <div class='designer-label' contenteditable='true' style='top:5.09cm;left:1.63cm;font-size:12pt;'>Maksja</div> <div class='designer-field' contenteditable='true' style='top:5.72cm;left:1.53cm;width:11.68cm;height:0.55cm;font-size:12pt;'>klient.tanav</div> <div class='designer-field' contenteditable='true' style='top:5.72cm;left:15.18cm;width:3.37cm;height:0.55cm;font-size:12pt;'>klient.vatpayno</div> <div class='designer-label' contenteditable='true' style='top:5.75cm;left:12.92cm;text-align:right;font-size:12pt;'>KMKR nr</div> <div class='designer-field' contenteditable='true' style='top:6.38cm;left:1.53cm;width:11.84cm;height:0.55cm;font-size:12pt;'>rtri(klient.postiindek)+' ' +rtri(klient.piirkond)</div> <div class='designer-field' contenteditable='true' style='top:6.38cm;left:13.47cm;width:3.37cm;height:0.55cm;font-size:12pt;'>sql("sele transfld('nimetus', 'riik', rapopref()) from riik where kood=klient.riik2", '' )</div> <div class='designer-field' contenteditable='true' style='top:6.99cm;left:3.71cm;width:12.16cm;height:1.16cm;font-size:12pt;'>klient.aadress</div> <div class='designer-label' contenteditable='true' style='top:7.01cm;left:1.45cm;text-align:right;font-size:12pt;'>Postiaadress</div> <div class='designer-field' contenteditable='true' style='top:8.33cm;left:3.95cm;width:2.11cm;height:0.55cm;font-size:12pt;'>dok.tasukuup</div> <div class='designer-field' contenteditable='true' style='top:8.33cm;left:6.08cm;width:8.05cm;height:0.55cm;font-size:12pt;'>eval( 'maksetin.' +left(rapopref()+'tingimus',10))</div> <div class='designer-label' contenteditable='true' style='top:8.35cm;left:1.45cm;font-size:12pt;'>Maksetähtaeg</div> <div class='designer-field' contenteditable='true' style='top:8.91cm;left:1.45cm;width:13.66cm;height:0.45cm;'>iif(!empty(dok.saaja), IR("Saaja: ")+sql('sele rtri(nimi)+" "+rtri(tanav)+" "+rtri(piirkond)+" "+rtri(postiindek) from klient where kood=dok.saaja',''),'')</div> </div> <div class='bg-warning'> <div class='panel-footer'><i class='glyphicon glyphicon-chevron-up'></i> GroupHeader 1: str(dokumnr)+str(koopia,2)</div> </div></div>

How to move selected elements using arrow keys

This is an example of how to "drag" DOM elements with arrow key's without using jQuery UI draggable.

In this example jQuery .before() and .after() functions are used to place elements to a new location.

$('.el').click(function(){        $('.el').removeClass('active');       $(this).addClass('active');  });
$('body').on('keyup',function(e){
switch(e.which) { case 37: // left var tmp_id = $('.el.active').prev().attr('id'); $('#' + tmp_id).animate({ opacity: 0 }, 100, function(){ $('.el.active').after($('.el.active').prev()); }); $('#' + tmp_id).animate({ opacity: 1 }, 300); break;
case 38: // up var active_index = $('.el.active').index(); var index_min = $('.el.active').parent().children().first().index(); var index_max = $('.el.active').parent().children().last().index(); var next_element = $('.el.active').parent().prev().children(':eq('+active_index+')'); if(index_min === active_index){ var prev_el = next_element.next(); $('.el.active').before(next_element); $(prev_el).before($('.el.active')); } if(index_max === active_index || (active_index > index_min && active_index < index_max )){ var prev_el = next_element.prev(); $('.el.active').before(next_element); $(prev_el).after($('.el.active')); } break;
case 39: // right var tmp_id = $('.el.active').next().attr('id'); $('#' + tmp_id).animate({ opacity: 0 }, 100, function(){ $('.el.active').before($('.el.active').next()); }); $('#' + tmp_id).animate({ opacity: 1 }, 300); break;
case 40: // down var active_index = $('.el.active').index(); var index_min = $('.el.active').parent().children().first().index(); var index_max = $('.el.active').parent().children().last().index(); var next_element = $('.el.active').parent().next().children(':eq('+active_index+')'); var prev_el = next_element.prev(); if(index_min === active_index){ var prev_el = next_element.next(); $('.el.active').before(next_element); $(prev_el).before($('.el.active')); } if(index_max === active_index || (active_index > index_min && active_index < index_max )){ var prev_el = next_element.prev(); $('.el.active').before(next_element); $(prev_el).after($('.el.active')); } break;
default: return; // exit this handler for other keys } e.preventDefault();
});
.container{  width: 100%;    }
div[id^="el-wr"]{ width: 280px; margin: 0 auto; }
.el{ width: 60px; height: 60px; background-color: #aaa; margin: 5px; float: left; cursor: pointer; text-align: center; line-height: 60px; font-size: 28px; color: white;}
.active{ background-color: #525252; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div id="el-wr0">
<div class="el" id="index1">1</div>
<div class="el" id="index2">2</div>
<div class="el" id="index3">3</div> <div class="el" id="index4">4</div>
</div> <div id="el-wr1">
<div class="el" id="index5">5</div>
<div class="el" id="index6">6</div>
<div class="el" id="index7">7</div> <div class="el" id="index8">8</div>
</div> <div id="el-wr2">
<div class="el" id="index9">9</div>
<div class="el" id="index10">10</div>
<div class="el" id="index11">11</div> <div class="el" id="index12">12</div>
</div>


</div>

Moving element with arrow keys jquery

Assuming the problem is that the element does not move (you don't really make the problem clear in your question), the reason is that the element is not positioned correctly.

Add position: absolute or position: relative to your CSS.

Here's an updated fiddle.

Navigate into layer using arrow key

Here's a workaround to get your goal achieved :

Q1 : "When you arrow down the window also scrolls down with it even though I added prevent default"

A : a long answer that can be applied (parts of it) to the other question. That's the logic behavior to occur when pressing arrow keys and you have attached a keyup listener but that event can't be undone as the key is already pressed :

  • keyup can catch arrow keys but can't be undone ==> not an option.

  • keypress can be undone but can't catch arrow keys ==> not an option.

  • keydown can catch arrow keys and can be undone ==> what we need, perfect.

    So keydown is the qualified event but so let's assume you changed the events to keydown :

  • imagine you have focused the textarea#searchTerm and pressed the down arrow to start navigating in the autocomplete box, the event won't trigger (due to preventDefault call).

  • we can't even start navigating with arrow keys after calling preventDefault.

A solution is to think a bit wisely :

  • attach a keydown handler to the window that checks if the current focused element in the page ($(document.activeElement)) is either the form#searchForm or one of its children (like the autocomplete items) and the key that being pressed is the up/down arrow then we prevent that event thus no scrolling down when scrolling into the autocomplete list.
  • attach a keydown handler to the form#searchForm that sees if the key pressed isn't up/down arrow then stop the event propagation to prevent getting bubbled to the window thus allowing us to write and navigate in the autocomplete list (remember we have preventDefault called in the handler for the window that can prevent us from writing).
  • a final handler for keydown attached to textarea#searchTerm (even though an input[type="text"] seems to be more suitable preventing line breaks, that may appear in a textarea, at least) that has a simple and important task which is while focusing (writing in) the field and the up arrow gets pressed we don't allow the autocomplete list last item to be selected.

the ordering when adding these handlers is very important : first attch form#searchForm handler, textarea#searchTerm's and then the handler for the window.

Q2 : "When you get to the end of the list it loops back round. It needs to stop at the end"

A : in the Navigate function we see if the displayBoxIndex variable (that tracks which item to be selected) has reached the last item and the down arrow was pressed then we just return to quit the function.

Q3 : "When you go back to the first element in the list - then the next UP action - should take you back into the input box"

A : also in the Navigate function we check if displayBoxIndex variable is at the first item and the up arrow was pressed then we trigger focus for the text field, remove the selected class from the autocomplete items, reset displayBoxIndex variable to -1 (ensuring we start from the first item when the down arrow gets pressed while typing) and finally return to halt the function.

this line displayBoxIndex += diff must appear after the above two condition in order to get correct calculation for which element we're selecting and the next one to be selected.

So, here's a demo to illustrate, it contains a wealth of helpful comments that may assist you while reading, also some covers some changes made into the code that I didn't cover above :

const form = $('#searchForm'),
searchTerm = $('#searchTerm'),
autoc = $('#autoComplete'),
jqWin = jQuery(window),
oBoxCollection = jQuery('.ac-list'),
cssClass = 'selected',
Navigate = diff => {
/** focus the text field when in the first item and the up arrow was pressed **/
if (displayBoxIndex === 0 && diff === -1) {
searchTerm.trigger('focus');
oBoxCollection.removeClass(cssClass);
displayBoxIndex = -1;
return;
}
/** prevent looping back when reached the last item in the autocomplete box **/
if (displayBoxIndex === oBoxCollection.length - 1 && diff == 1) return;

/** make the navigation **/
displayBoxIndex += diff;
oBoxCollection.removeClass(cssClass)
.eq(displayBoxIndex)
.addClass(cssClass)
.children('a')
.focus();
};

let displayBoxIndex = -1;

/** attaching events with respect of ordering **/

/** 1: keydown listener on the form **/
form.on('keydown', e => {
const upOrDown = [38, 40].indexOf(e.which) != -1;
/** is it the up/down key **/
!upOrDown && (e.stopPropagation());
/** if no (another key) just stop the event propagation so the one attached to the window won't be fired **/
upOrDown && (Navigate(e.which == 40 ? 1 : -1));
/** if yes we call we call Navigate (if we gets here to the ternary operator the e.which is either 40 or 38) **/
e.which == 27 && (autoc.slideUp(400, () => {
searchTerm.blur();
displayBoxIndex = -1;
oBoxCollection.removeClass(cssClass);
}));
});

/** 2: keydown listener on the text field **/

/** prevent going to the list box bottom when pressing up arrow **/
searchTerm.on({
keydown: e => {
e.which == 38 && (e.stopPropagation());
},
focus: e => {
/** show the autocomplete box if is hidden **/
autoc.is(':hidden') && (autoc.slideDown(400));
displayBoxIndex = -1;
} /** reset navigation position (resets to the first item in the autocomplete box) when the text field is focus **/
});

/** 3: keydown listener on the window **/
jqWin.on('keydown', e => {
const focus = $(document.activeElement);
/** get the current focused element in the page **/
[38, 40].indexOf(e.which) != -1 && (focus.is('#searchForm') ||
form.has(focus).length) && (e.preventDefault());
/** prevent scroll when navigating in the autocomplete box (the scrolling you asked about in your first question) **/
});
/** basic styling to appear like a real autocomplete box. Doesn't affect the main functionality required **/

* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
height: 300vh;
}

.wrapper {
position: relative;
display: flex;
width: 250px;
justify-content: center;
align-items: flex-start;
margin: 15px auto;
}

.wrapper textarea {
display: block;
width: 100%;
height: 35px;
padding: 8px 4px;
border: 2px solid #181818;
resize: none;
transition: all .4s 0s ease;
}

.wrapper textarea:focus {
background-color: #ccc;
}

.wrapper #autoComplete {
position: absolute;
width: 100%;
max-height: 150px;
overflow-y: auto;
top: 100%;
left: 0;
box-shadow: 0 8px 25px -8px rgba(24, 24, 24, .6);
}

.wrapper ul {
list-style-type: none;
background-color: #181818;
}

.wrapper ul li {
display: block;
margin-bottom: 4px;
transition: all .4s 0s ease;
}

.wrapper ul li:last-child {
margin-bottom: 0;
}

.wrapper ul li:hover,
.selected {
background-color: #f00;
}

.wrapper ul li a {
display: block;
padding: 4px 15px;
color: #fff;
text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- added a wrapper div in the form just to simplify the styling it has nothing related to the functionality -->
<form id="searchForm">
<div class="wrapper">
<textarea placeholder="Enter search terms..." id="searchTerm" name="searchTerm"></textarea>
<div id="autoComplete">
<ul>
<li class="ac-list"><a href="#">autocomplete item 1</a></li>
<li class="ac-list"><a href="#">autocomplete item 2</a></li>
<li class="ac-list"><a href="#">autocomplete item 3</a></li>
<li class="ac-list"><a href="#">autocomplete item 4</a></li>
<li class="ac-list"><a href="#">autocomplete item 5</a></li>
<li class="ac-list"><a href="#">autocomplete item 6</a></li>
<li class="ac-list"><a href="#">autocomplete item 7</a></li>
<li class="ac-list"><a href="#">autocomplete item 8</a></li>
<li class="ac-list"><a href="#">autocomplete item 9</a></li>
<li class="ac-list"><a href="#">autocomplete item 10</a></li>
</ul>
</div>
</div>
</form>

How do I enable arrow navigation on keyboard for a list of Div using jQuery

You need to bind keyboard events keyup/keydown and then change the css accordingly to give a feel of move up or move down :

use keyup if you want a single move even on a key press no matter the key is long pressed.

use keydown if you want to move in a cycle fashion as long as user holds the key.

$("#search").keyup(function(e) 
{
if (e.keyCode == 40)
{
Navigate(1);
}
if(e.keyCode==38)
{
Navigate(-1);
}

});

Check complete code @fiddle: http://jsfiddle.net/MKZSE/77/

Move a div within another div with arrow keys

I have tested the code and found that when you are near the borders it's not working properly (Perhaps this was the original question?). On this i tested another simpler solution: I just changed your moveSquare function to only do work when you are inside your bounds (I mean, you shouldn't be always incrementing/decrementing position and then check if you are out of bounds to correct it).



Related Topics



Leave a reply



Submit