Game Maker Language: place_meeting doesn't seem to work - game-maker

I'm making a Pac-Man-like game and I wanted to recreate the Pac-Man maze, but I wanted to make it easier for myself, so that when I change the wall placement it would automatically change the way the wall looks. My pac-man sprite as well as my wall sprites are 16px*16px. Here are the wall sprite images: Imgur . Here is the room inside the room editor: Imgur . And here is how it looks in-game: Imgur .
Here is my code inside the create event of obj_wall:
image_speed = 0;
//see where we have blocks
up = place_meeting(x, y - 16, obj_wall);
upright = place_meeting(x + 16, y - 16, obj_wall);
right = place_meeting(x + 16, y, obj_wall);
downright = place_meeting(x + 16, y + 16, obj_wall);
down = place_meeting(x, y + 16, obj_wall);
downleft = place_meeting(x - 16, y + 16, obj_wall);
left = place_meeting(x - 16, y, obj_wall);
upleft = place_meeting(x - 16, y - 16, obj_wall);
//determine how should the wall look
if(up && upright && right && downright && down && downleft && left && upleft)
{
image_index = 3;
}
if( (down && up && !left) || (down && up && !right) )
{
image_index = 1;
}
if( (right && left && !up) || (right && left && !down) )
{
image_index = 1;
image_angle = 90;
}
if( (right && down && !downright) || (right && down && !upleft && !left && !up) )
{
image_index = 2;
}
if( (up && left && !upleft) || (up && left && !downright && !right && !down) )
{
image_index = 2;
image_yscale = -1;
image_xscale = -1;
}
if( (up && right && !upright) || (up && right && !downleft && !left && !down) )
{
image_index = 2;
image_yscale = -1;
}
if( (down && left && !downleft) || (down && left && !upright && !up && !right) )
{
image_index = 2;
image_xscale = -1;
}
I'm using Game Maker Studio 1.4

Never mind I solved it. Since in the third 'if' I change the image_angle I should undo it in all other 'if's

Related

Uncaught SyntaxError: expected expression, got keyword 'var' on she-header.js

I'm new to this forum and am currently receiving the error Uncaught SyntaxError: expected expression, got keyword 'var' on my she-header.js beginning at console.log and ending at header height shrink. Any help would be much appreciated. I have not tried much, and the support available is not very informative about this problem.
var $j = jQuery.noConflict();
$j( document ).ready( function() {
"use strict";
// She header
sheHeader();
} );
/* ==============================================
HEADER EFFECTS
============================================== */
function sheHeader() {
var header = $j('.she-header-yes'),
container = $j('.she-header-yes .elementor-container, .she-header-yes.e-container'),
header_elementor = $j('.elementor-edit-mode .she-header-yes'),
header_logo = $j('.she-header-yes .elementor-widget-theme-site-logo .elementor-image, .she-header-yes .elementor-widget-image .elementor-image'),
data_settings = header.data('settings');
if ( typeof data_settings != 'undefined' ) {
var responsive_settings = data_settings["transparent_on"];
var width = $j(window).width(),
header_height= header.height(),
logo_width = header_logo.width(),
logo_height = header_logo.height() ;
}
// Check responsive is enabled
if( typeof width != 'undefined' && width) {
if( width >= 1025 ) {
var enabled = "desktop";
}else if (width > 767 && width < 1025 ) {
var enabled = "tablet";
}else if (width <= 767 ) {
var enabled = "mobile";
}
}
console.log($j.inArray(enabled, responsive_settings));
if ($j.inArray(enabled, responsive_settings)!='-1') {
var scroll_distance = data_settings["scroll_distance"];
var transparent_header = data_settings["transparent_header_show"];
var background = data_settings["background"];
var bottom_border_color = data_settings["custom_bottom_border_color"],
bottom_border_view = data_settings["bottom_border"],
bottom_border_width = data_settings["custom_bottom_border_width"];
var shrink_header = data_settings["shrink_header"],
data_height = data_settings["custom_height_header"],
data_height_tablet = data_settings["custom_height_header_tablet"],
data_height_mobile = data_settings["custom_height_header_mobile"];
var shrink_logo = data_settings["shrink_header_logo"],
data_logo_height = data_settings["custom_height_header_logo"],
data_logo_height_tablet = data_settings["custom_height_header_logo_tablet"],
data_logo_height_mobile = data_settings["custom_height_header_logo_mobile"];
var change_logo_color = data_settings["change_logo_color"];
var blur_bg = data_settings["blur_bg"];
var scroll_distance_hide_header = data_settings["scroll_distance_hide_header"];**
// add transparent class
if(transparent_header == "yes" ){
header.addClass('she-header-transparent-yes');
}
// header height shrink
if( typeof data_height != 'undefined' && data_height) {
if( width >= 1025 ) {
var shrink_height = data_height["size"];
}else if (width > 767 && width < 1025 ) {
var shrink_height = data_height_tablet["size"];
if(shrink_height == ''){
shrink_height = data_height["size"];
}
}else if (width <= 767 ) {
var shrink_height = data_height_mobile["size"];
if(shrink_height == ''){
shrink_height = data_height["size"];
}
}
}
// border bottom
if( typeof bottom_border_width != 'undefined' && bottom_border_width) {
var bottom_border = bottom_border_width["size"] + "px solid " + bottom_border_color;
}
// hide header on scroll
if( typeof scroll_distance_hide_header != 'undefined' && scroll_distance_hide_header) {
var mywindow = $j(window);
var mypos = mywindow.scrollTop();
mywindow.scroll(function() {
if (mypos > scroll_distance_hide_header["size"]) {
if(mywindow.scrollTop() > mypos)
{
header.addClass('headerup');
}else{
header.removeClass('headerup');
}
}
mypos = mywindow.scrollTop();
});
}
// scroll function
$j(window).on("load scroll",function(e){
var scroll = $j(window).scrollTop();
if (header_elementor) {
header_elementor.css("position", "relative");
}
if (scroll >= scroll_distance["size"]) {
header.removeClass('header').addClass("she-header");
header.css("background-color", background);
header.css("border-bottom", bottom_border);
header.removeClass('she-header-transparent-yes');
if( shrink_header == "yes" ) {
header.css({"padding-top":"0", "padding-bottom":"0", "margin-top":"0", "margin-bottom":"0"});
container.css({"min-height": shrink_height, "transition": "all 0.4s ease-in-out", "-webkit-transition": "all 0.4s ease-in-out", "-moz-transition": "all 0.4s ease-in-out"});
}
if( change_logo_color == "yes" ) {
header_logo.addClass("change-logo-color");
}
if( blur_bg == "yes" ) {
header.css({"backdrop-filter": "saturate(180%) blur(20px)", "-webkit-backdrop-filter": "saturate(180%) blur(20px)"});
}
} else {
header.removeClass("she-header").addClass('header');
header.css("background-color", "");
header.css("border-bottom", "");
if(transparent_header == "yes" ){
header.addClass('she-header-transparent-yes');
}
if( shrink_header == "yes" ) {
header.css({"padding-top":"", "padding-bottom":"", "margin-top":"", "margin-bottom":""});
container.css("min-height", "");
}
if( change_logo_color == "yes" ) {
header_logo.removeClass("change-logo-color");
}
if( blur_bg == "yes" ) {
header.css({"backdrop-filter": "", "-webkit-backdrop-filter": ""});
}
}
});
}
};

Unwanted behavior when using insidetextorientation = 'radial' in plotly sunburst

When using insidetextorientation = 'radial', even in a very simple plotly sunburst chart, some of the labels are grossly displaced.
library(plotly)
my_labels <- c("A","B","C","AA","AB","AC","BA","BB","CA","CB","CC")
my_parents <- c("","","","A","A","A","B","B","C","C","C")
my_values <- c(15,23,7,3,5,7,6,17,1,2,4)
plot_ly(labels = my_labels,parents = my_parents,values = my_values,type = 'sunburst',
branchvalues = 'total',insidetextorientation = 'radial')
Notice the "B" and "BA" on the left are misplaced. Similar issues occur when zooming in on any of the parents and do not persist with insidetextorientation = 'auto'. Is there a way to fix this?
On the plotly community forum the same question was asked 2 years ago, but not answered.
This isn't a great answer. It works, but when you click out of a parent so that everything is showing again, the plot has to stop moving before the labels will change back to the radial angles.
I've tried a lot of different ways to improve it. I think that letting Plotly package authors know is important; short of changing the code, I don't know of a better way to make this happen. The main problem is that the SVG paths that change when you enter and leave a parent are deleted and re-calculated. Any event that's attached is deleted at that point. (I tried both Plotly events and straight JS events.)
So instead of an event, it's on an interval. Every 100 milliseconds it checks to see if the labels need to be fixed.
plot_ly(labels = my_labels, parents = my_parents,
values = my_values, type = 'sunburst',
branchvalues = 'total', insidetextorientation = 'horizontal') %>%
htmlwidgets::onRender("function() {
pc = ['B', 'A', 'C', 'BB', 'BA', 'AC', 'AB', 'AA', 'CC', 'CB', 'CA'];
rpl = [0, -64, 28, -68, 28, -32, -80, 68, 40, 16, 4];
rx = /.*rotate\\((.*)\\)/g;
function fixer(){
tx = document.querySelectorAll('g > text');
if(tx.length === 11) { /*not when clicking subgroups*/
for(i=0;i<tx.length;i++){
wh = tx[i].getAttribute('data-unformatted');
tr = tx[i].getAttribute('transform');
rot = /.*rotate\\((.*)\\)/g.exec(tr);
if(rot !== null){ /*if a text rotation is designated*/
if(rpl[pc.indexOf(wh)] !== Number(rot)) {
rot = rot[1];
if(Number(rot) !== rpl[i] && wh === pc[i]){ /*if angle does not match & label does*/
beg = /(.*)rotate/.exec(tr)[1]; /*capture translate string*/
xy = beg + 'rotate(' + rpl[i] + ')'; /*build new transform string*/
tx[i].setAttribute('transform', xy); /*replace transform string with new*/
}
}
}
if(rot === null && wh === pc[i]) { /*if no rotation is present and label matches*/
str = tr + 'rotate(' + rpl[i] + ')'; /* build new transform string */
tx[i].setAttribute('transform', str); /*replace transform string with new*/
}
}
}
}
setInterval(fixer, 100);}") # check regularly! (every 100 ms)
I basically started with onRender set to just spit out the transform attribute for every label, so that I could get the order in which the labels appear (see pc in the JS) and the angles that the labels are placed at (see rpl in the JS). This was done while insidetextorientation = 'radial'. (I actually looked at all the text options: tangential, horizontal, auto, and radial.)
From there I tried MANY things to trigger the JS function fixer. In the end the only thing that was consistent enough for me to even share my work was using setInterval.
Update; Firefox friendly!
I really did try to figure this out for my initial answer. Here is the code without static arrays for the labels or angles. Let me know if you run into issues.
plot_ly(labels = my_labels, parents = my_parents,
values = my_values, type = 'sunburst',
branchvalues = 'total', insidetextorientation = 'horizontal') %>%
htmlwidgets::onRender("function(el, x) {
/* calculates the angles for each slice */
function angler (arVal, deg){ /* array of values in order; degrees each value unit*/
results = []; /* for storing the results */
theta = 0; /* for cumulative angle */
for(k = 0; k < arVal.length; k++){
here = arVal[k] * deg; /* units times degrees */
mrot = theta + (.5 * here); /* initial text angle */
if(mrot >= 90 && mrot < 270) {
mrot = mrot - 180; /* don't put text upside down */
}
if(mrot >= 270 && mrot < 360){
mrot = mrot - 360; /* don't put text upside down */
}
results[k] = mrot;
theta = theta + here; /* for the next loop */
}
return(results);
}
par = x.data[0].parents; /* collect the necessary data*/
val = x.data[0].values;
lab = x.data[0].labels;
parI = par.reduce((a, e, i) => { /*which rows have parents?*/
if (e == '') { a.push(i); };
return a;
}, []); /*in array a, if element e at pos i equates to ''*/
parC = par.reduce((a, e, i) => { /*which rows do NOT have parents?*/
if (e != '') { a.push(i); };
return a;
}, []); /*in array a, if element e at pos i equates to ''*/
alp = lab.map((i, j) => {return [i, val[j], par[j]]}); /* combine data */
palv = alp.filter((e, i) => parI.some(j => i === j)); /*parent array*/
calv = alp.filter((e, i) => parC.some(j => i === j)); /*children array*/
pvalS = palv.sort(function(a, b) {
return((a[1] > b[1]) ? -1 : ((a[1] == b[1]) ? 0 : 1));
}) /*parents sorted by values*/
parS = pvalS.map(function(j) {return j[0];}); /*extract ordered parents*/
csort = []; /* for ordered kids array*/
for(i = 0; i < parS.length; i++){ /* sort children by parent and size*/
arr = calv.filter(j => parS[i].includes(j[2]));
arr1 = arr.map(function(w) {return w[1]}); /*get just values*/
arr2 = arr1.sort(function(a, b){ return b - a });
bld = [];
for(k = 0; k < arr2.length; k++) {
arr3 = arr.filter(j => arr2[k] == j[1]);
csort = csort.concat(arr3);
}
}
/* get the order--- in reverse*/
cvo = csort.map(function(j){return j[1]});
cvov = Object.values(cvo).reverse();
pvo = pvalS.map(function(j) {return j[1];}); /*extract ordered parents' values*/
pvov = Object.values(pvo).reverse();
ctots = cvov.reduce((a, b) => a + b, 0); /* 45 */
rotV = 360/ctots; /* 8 in this example */
kids = angler(cvov, rotV); /* collect kids angles */
parents = angler(pvov, rotV); /* collect parent angles */
kidS = csort.map(function(j) {return j[0];}); /* extract kid labels in order */
/*pc = ['B', 'A', 'C', 'BB', 'BA', 'AC', 'AB', 'AA', 'CC', 'CB', 'CA'];*/
pc = Object.values(parS).concat(Object.values(kidS));
/*rpl = [0, -64, 28, -68, 28, -32, -80, 68, 40, 16, 4];*/
rpl = parents.reverse().concat(kids.reverse());
rx = /.*rotate\\((.*)\\)/g;
function fixer(){
tx = document.querySelectorAll('g > text');
if(tx.length === 11) { /*not when clicking subgroups*/
for(i=0;i<tx.length;i++){
wh = tx[i].getAttribute('data-unformatted');
tr = tx[i].getAttribute('transform');
rot = /.*rotate\\((.*)\\)/g.exec(tr);
if(rot !== null){ /*if a text rotation is designated*/
if(rpl[pc.indexOf(wh)] !== Number(rot)) {
rot = rot[1];
if(Number(rot) !== rpl[i] && wh === pc[i]){ /*if angle does not match & label does*/
beg = /(.*)rotate/.exec(tr)[1]; /*capture translate string*/
xy = beg + 'rotate(' + rpl[i] + ')'; /*build new transform string*/
tx[i].setAttribute('transform', xy); /*replace transform string with new*/
}
}
}
if(rot === null && wh === pc[i]) { /*if no rotation is present and label matches*/
str = tr + 'rotate(' + rpl[i] + ')'; /* build new transform string */
tx[i].setAttribute('transform', str); /*replace transform string with new*/
}
}
}
}
setInterval(fixer, 100);}") # check regularly! (every 100 ms)

Highcharts dataLabels reposition on overlap

I have a Highcharts component where the user can add comments to a graph, and the comment shows up as a dataLabel in a scatter series. However, I noticed that by default the allowOverlap just removes the dataLabels that collides, and my question to this is: would it be possible to make the colliding dataLabels stack on top of each other? I'm thinking that since the allowOverlap: true can detect which ones that are colliding, there might be a way to take advantage of this?
This is how my dataLabels look now:
This is my goal:
Hope that someone can help me with a clever solution, I sure know I am out of ideas!
By the way, right now the dataLabels gets their xAxis position by dividing the xAxis :{ max: value } by 1,5. This is just to position it equally on all my graphs, which all have different min and max values. Might be worth mentioning.
It is possible to override the funciton that should be hiding the overlapping labels and adjust position of the overlapping labels like this:
$(function() {
(function(H) {
var each = H.each,
UNDEFINED;
H.Chart.prototype.hideOverlappingLabels = function(labels, rerun) {
if (rerun === UNDEFINED ||
rerun < 10) //infinity loop limit
{
var doTheRerun = false,
len = labels.length,
label, i, j, label1, label2,
isIntersecting, pos1, pos2, parent1, parent2,
padding,
intersectRect = function(x1, y1, w1, h1, x2, y2, w2, h2) {
return !(
x2 > x1 + w1 ||
x2 + w2 < x1 ||
y2 > y1 + h1 ||
y2 + h2 < y1
);
};
for (i = 0; i < len; i++) {
label = labels[i];
if (label) {
label.oldOpacity = label.opacity;
label.newOpacity = 1;
}
}
labels.sort(function(a, b) {
return (b.labelrank || 0) - (a.labelrank || 0);
});
for (i = 0; i < len; i++) {
label1 = labels[i];
for (j = i + 1; j < len; ++j) {
label2 = labels[j];
if (label1 && label2 && label1.placed && label2.placed && label1.newOpacity !== 0 && label2.newOpacity !== 0) {
pos1 = label1.alignAttr;
pos2 = label2.alignAttr;
parent1 = label1.parentGroup; // Different panes have different positions
parent2 = label2.parentGroup;
padding = 2 * (label1.box ? 0 : label1.padding); // Substract the padding if no background or border (#4333)
isIntersecting = intersectRect(
pos1.x + parent1.translateX,
pos1.y + parent1.translateY,
label1.width - padding,
label1.height - padding,
pos2.x + parent2.translateX,
pos2.y + parent2.translateY,
label2.width - padding,
label2.height - padding
);
if (isIntersecting) {
(label1.labelrank < label2.labelrank ? label1 : label2).addHeightOffset = true;
}
}
}
}
each(labels, function(label) {
var complete,
newOpacity;
if (label) {
if (label.addHeightOffset && label.placed) {
label.alignAttr.y -= label.height;
label.addHeightOffset = false;
doTheRerun = true;
}
label['attr'](label.alignAttr);
}
});
if (doTheRerun) {
rerun = (rerun || 0) + 1;
H.Chart.prototype.hideOverlappingLabels(labels, rerun);
}
}
};
}(Highcharts))
$('#container').highcharts({
series: [{
dataLabels: {
enabled: true,
format: 'The value that is important for this point is: {y}'
},
data: [1, 2, 1, 1, 2, 2, 2]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
Demo in JSFiddle: http://jsfiddle.net/ozLtvwke/1/

Hanging moving gestures (Left/normal/right/up/normal/down) using mpu9150 sensor

We tried (Arduino+mpu9150) using gestures LEFT-NORMAL-RIGHT, UP-NORMAL-RIGHT.
We can able to get these gestures, but not accurately.
Its HANGING in middle, and sometimes values are also Incorrect.
Could you please help me to fix this issue?
Please check complete code for an ++attachment.
CODE:
void guesture() {
//LEFT & RIGHT
//Starting Accelerartion condition
if ( diff_yaw < -250)
{
diff_yaw = -(360 + diff_yaw);
}
else if (diff_yaw > 250)
{
diff_yaw = 360 - diff_yaw;
}
if ((aaReal.y < -1500) && (flag1 == false) && (flag2 == false) ) {
old_time1 = new_time;
old_yaw = new_yaw;
flag1 = true;
} else if ((aaReal.y > 1000) && (flag2 == false) && (flag1 == false)) {
old_time1 = new_time;
old_yaw = new_yaw;
flag2 = true;
} else if (aaReal.z > 400 && flag11 == false) {
old_time = new_time;
flag11 = true;
} else if (aaReal.z < -400 && flag22 == false) {
old_time = new_time;
flag22 = true;
}
if ((aaReal.y > 1000) && (flag1 == true) && (flagZ1 == false)) {
flagZ1 = true;
} else if ((aaReal.y < -1500) && (flag2 == true) && (flagZ2 == false)) {
flagZ2 = true;
} else if (aaReal.z < -400 && flag11 == true) {
diff_time = new_time - old_time;
flag11 = false;
if (diff_time < 2000 ) {
flag33 = true;
old_time = new_time;
}
} else if (aaReal.z > 400 && flag22 == true) {
diff_time = new_time - old_time;
flag22 = false;
if (diff_time < 2000 ) {
flag33 = true;
old_time = new_time;
}
}
if ((aaReal.y < 1000) && (flagZ1 == true)) {
flag1 = false;
flagZ1 = false;
diff_yaw = new_yaw - old_yaw;
diff_time = new_time - old_time1;
if (diff_time < 2000)
{
flagN = true;
}
} else if ((aaReal.y > -1500) && (flagZ2 == true)) {
flag2 = false;
flagZ2 = false;
diff_yaw = new_yaw - old_yaw;
diff_time = new_time - old_time1;
if (diff_time < 2000)
{
flagN = true;
}
}
if (flagN == true) {
if (Iposition == 0 && diff_yaw > 0) { //Right
Iposition = 1;
flagR = true;
} else if (Iposition == 0 && (diff_yaw) < 0 ) { //Left
Iposition = 2;
flagL = true;
} else if (Iposition == 1 && (diff_yaw) < 0 && (diff_yaw) > -25) { //Right-Normal
Iposition = 0;
flagNL = true;
} else if (Iposition == 1 && (diff_yaw) < -25) { //Right-Left
Iposition = 2;
flagL = true;
} else if (Iposition == 2 && (diff_yaw) > 0 && diff_yaw < 25) { //Left-Normal
Iposition = 0;
flagNL = true;
} else if (Iposition == 2 && diff_yaw > 25) { //Left-Right
Iposition = 1;
flagR = true;
}
}
if (flagN == true || flag33 == true) {
if (flagR == true) {
Serial.println("POSITION : RIGHT");
flagR = false;
} else if (flagL == true) {
Serial.println("POSITION : LEFT");
flagL = false;
} else if (flagNL == true) {
Serial.println("POSITION : NORMAL");
flagNL = false;
} else if (Ipos == 0 && pO >= 20 ) {
Ipos = 1;
Serial.println("POSITION : UP");
} else if (Ipos == 0 && pO <= -20 ) {
Ipos = 2;
Serial.println("POSITION : DOWN");
} else if (Ipos == 1 && pO <= 10 && pO >= -10 ) {
Ipos = 0;
Serial.println("POSITION : NORMAL");
} else if (Ipos == 1 && pO < -5 ) {
Ipos = 2;
Serial.println("POSITION : DOWN");
} else if (Ipos == 2 && pO >= -10 && pO < 0) {
Ipos = 0;
Serial.println("POSITION : NORMAL");
} else if (Ipos == 2 && pO > 0 ) {
Ipos = 1;
Serial.println("POSITION : UP");
}
flagN = false;
flag33 = false;
}
}

Device div screens overlapping, how do I fix?

How do i change the keyboard functions to an onscreen joystick?
I am building a html5 game and Im completely lost as the how to add a joystick.
Below is the code that needs some help. Thank you very much in advance :)
function init() {
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
enemy = new Image();
enemy.src = '8bit_enemy.png';
ship = new Image();
ship.src = 'ship.png';
starfield = new Image();
starfield.src = 'starfield.jpg';
document.addEventListener('keydown', keyDown, false);
document.addEventListener('keyup', keyUp, false);
canvas.addEventListener('click', gameStart, false);
gameLoop();
}
function gameStart() {
gameStarted = true;
canvas.removeEventListener('click', gameStart, false);
}
//The main function of the game, it calls all the other functions needed to make the game run
function gameLoop() {
clearCanvas();
drawStarfield()
if (alive && gameStarted && lives > 0) {
hitTest();
shipCollision();
moveLaser();
moveEnemies();
drawEnemies();
drawShip();
drawLaser();
}
scoreTotal();
game = setTimeout(gameLoop, 1000 / 30);
}
//Checks to see which key has been pressed and either to move the ship or fire a laser
function keyDown(e) {
if (e.keyCode == 39) rightKey = true;
else if (e.keyCode == 37) leftKey = true;
if (e.keyCode == 38) upKey = true;
else if (e.keyCode == 40) downKey = true;
if (e.keyCode == 88 && lasers.length <= laserTotal) lasers.push([ship_x + 25, ship_y - 20, 4, 20]);
}
//Checks to see if a pressed key has been released and stops the ships movement if it has
function keyUp(e) {
if (e.keyCode == 39) rightKey = false;
else if (e.keyCode == 37) leftKey = false;
if (e.keyCode == 38) upKey = false;
else if (e.keyCode == 40) downKey = false;
}
window.onload = init;
You need something like this:
function doKeyDown(e){
//====================
// THE W KEY
//====================
if (e.keyCode == 87) {
clearCanvas();
y = y - 10;
canvas_context.fillRect(x, y, 50, 30);
}
//====================
// THE S KEY
//====================
if (e.keyCode == 83) {
clearCanvas();
y = y + 10;
canvas_context.fillRect(x, y, 50, 30);
}
//====================
// THE A KEY
//====================
if (e.keyCode == 65) {
clearCanvas();
x = x - 10;
canvas_context.fillRect(x, y, 50, 30);
}
//====================
// THE D KEY
//====================
if (e.keyCode == 68) {
clearCanvas();
x = x + 10;
canvas_context.fillRect(x, y, 50, 30);
}
}
function clearCanvas() {
canvas.width = canvas.width;
}
The full explanation and code examples can be found here and a demo is here

Resources