The canvas is responsive to keyboard commands, however, the image remains stationary and unaffected

As I delved into the basics, incorporating canvas, CSS, and JavaScript, a question arose: should the image be housed in the HTML or the JavaScript code? Following this, I added a background color to the canvas and defined properties of the canvas in JavaScript alongside keyCodes. The image was loaded with window.onload, however, I discovered that while the canvas was moving, the image remained static.

var canvas = document.getElementById("app");
canvas.width  = document.body.clientWidth;
canvas.height = document.body.clientHeight;
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";

var keys = [];

window.addEventListener("keydown", function(e){
keys[e.keyCode] = true;
}, false);

window.addEventListener("keyup", function(e){
delete keys[e.keyCode];
}, false);

function game(){
window.onload;
update();
render();
}

function update(){
if(keys[38]) img.y--;
if(keys[40]) img.y++;
if(keys[37]) img.x--;
if(keys[39]) img.x++;
}
function render(){
ctx.fillRect(img.x, img.y);
}

window.onload = function() {
    var c=document.getElementById("app");
    var ctx=c.getContext("2d");
    var img=document.getElementById("chio");
    ctx.drawImage(img,10,10);
};

setInterval(function(){
    game();
}, 1000/30)

// > note: window.onload shows the images
#app{
background-color:#33ff00
}
<html>
<head>
<link href="app.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="app" width=300 height=640></canvas>
<img id="chio" src="chio.png"/>
<script src="app.js"></script>
</body>
</html>

I've hit a roadblock here, seeking assistance to move forward.

Answer №1

I have made some adjustments to the code in "app.js", but it's not entirely clear what you are looking for. If your intention is to move the image, here is one way to achieve that.

var canvas = document.getElementById("app");
canvas.width  = document.body.clientWidth;
canvas.height = document.body.clientHeight;
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";

var keys = [];
var ctx;
var img;
var position = {x:0,y:0};
window.addEventListener("keydown", function(e){
    keys[e.keyCode] = true;
}, false);

window.addEventListener("keyup", function(e){
    keys[e.keyCode] = false;
}, false);

function game(){
    update();
    render();
}

function update(){
    if(keys[38]) position.y--;
    if(keys[40]) position.y++;
    if(keys[37]) position.x--;
    if(keys[39]) position.x++;
}
function render(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img,position.x,position.y);
}

window.onload = function() {
    var c=document.getElementById("app");
    ctx=c.getContext("2d");
    img=document.getElementById("chio");
};

setInterval(function(){
    game();
}, 1000/30);


// > note: window.onload shows the images 

Answer №2

One major issue with the provided code is that it attempts to access DOM elements before the document has fully loaded, which can lead to errors. To fix this, it's best to ensure all DOM manipulation is done within the window.onload event listener.

Another problem arises from the inconsistent usage of variable scopes. Variables are declared locally but later treated as global variables, causing confusion and potential bugs. It's recommended to define variables in the global scope for consistency.

Additionally, trying to track an image's position by modifying its x/y attributes directly may not yield the desired results. A better approach would be to create a JavaScript object with x/y properties to manage the position tracking.

In the render() function, there seems to be an incorrect method used to draw the image on the canvas. Consider clearing the canvas and redrawing the image using the correct drawImage() method for better rendering.

To implement these improvements, here's an updated version of your JavaScript:

// Global variables
var keys = [];
var canvas;
var ctx;
var img;

// Object to track image position on canvas
var imgPos = {
    x: 0,
    y: 0
}

window.addEventListener("keydown", function(e){
    keys[e.keyCode] = true;
}, false);

window.addEventListener("keyup", function(e){
    delete keys[e.keyCode];
}, false);

function game(){
    update();
    render();
}

function update(){
    if(keys[38]) imgPos.y--;
    if(keys[40]) imgPos.y++;
    if(keys[37]) imgPos.x--;
    if(keys[39]) imgPos.x++;
}
function render(){
    // Clear canvas and redraw image at new location
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img,imgPos.x,imgPos.y);
}

window.onload = function() {
    // Initialize canvas
    canvas = document.getElementById("app");
    canvas.width  = document.body.clientWidth;
    canvas.height = document.body.clientHeight;
    canvas.style.width = canvas.width + "px";
    canvas.style.height = canvas.height + "px";

    // Draw image to canvas
    ctx=canvas.getContext("2d");
    img=document.getElementById("chio");
    ctx.drawImage(img,imgPos.x,imgPos.y);

    // Start game loop
    setInterval(function(){
        game();
    }, 1000/30);
};

You can see a working example here. I've added comments to explain the changes made for better understanding. Feel free to reach out if you have any questions or need further assistance.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error message: "Azure deployment encounters Vue CSS dependency missing issue"

I recently built a Vue app following this tutorial but without CRUD functionality: . The app was created using Vue CLI 4.3.1 with vue create. During local development, it runs smoothly with npm run serve and builds without any errors. Now, I'm atte ...

Link the ngModel input to an object within an ngFor iteration

Looking to create a dynamic form using an array that includes FieldLabel and DataModel references. I want to use the DataModel as an object reference, so when the user updates an input field, the referenced model is updated. I have searched extensively bu ...

Exploring the Power of Selenium in Python: Automating the Clicking of Expand Links Without Identifiers

Struggling to fill out a form in IE9 using Selenium and Python. The form is loaded with 'Expand/Collapse' links, all identical except for the text labels. No ID on them, just 'style' and 'onclick' attributes (though there migh ...

Is your jQuery TextEditor not functioning properly?

Having some trouble integrating the jQuery TextEditor plugin into my CodeIgniter project. I'm puzzled as to why it's not functioning properly. Just a heads up, my project also utilizes Bootstrap. Can anyone shed some light on why the plugin is fa ...

What is the best way to create a Div element that functions as a button, becoming active when clicked while deactivating all other Div elements

function toggleButton1() { $("#button1").toggleClass("button-active button-inactive"); $("#button2").toggleClass("button-inactive button-active"); $("#button3").toggleClass("button-inactive button-active"); } function toggleButton2() { $("#butto ...

Detecting button clicks in different views using Backbone.js

In my current setup, I have a main parent view called View.A which is responsible for managing two child views - View.B and View.C. Specifically, View.B contains buttons that trigger events on that view. Configuration View.A View.B view.B.template. ...

Visual Composer in WordPress is not displaying as expected

I've attempted to uninstall and reinstall Visual Composer, but I'm unable to resolve the issue. I can't edit the front end because it's not displaying properly. I'm using the Ken theme. When checking the console, I encountered this ...

Utilizing JSON data from Jade in local JavaScript: A comprehensive guide

Attempting to utilize a JSON object (the entire object, not just a portion) from Node via Jade in my local myScript.js. Here is what my Jade file looks like: span(class="glyphicon glyphicon-pencil" onclick="confirm(\"#{myJSON.taskid}\", \" ...

Methods to prevent ExtentReports from transforming HTML references in your Selenium logs into real HTML code

Having an issue with ExtentReports 4 for .Net and HTML V3 reporter. Whenever a test fails, the failure message is displayed in the report. However, if the failure message contains an HTML tag, it gets converted to actual HTML on the report, causing layout ...

Tips for Minimizing DIV Space with the Flex Property

I need some help with reducing the space between the individual content (1, 2, 3, 4) and its border in this Fiddle. As a newcomer to Flexbox, I'm unsure if there's an easy solution to this issue. Here is a visual representation of what I mean: ...

Javascript code to verify whether the page is currently positioned at the top

How can I use JavaScript to determine if the page is at scroll(0,0)? I have a full-page slider that needs to pause when the page is no longer at the top. The page may not be scrolled manually, as there are internal HTML # links that could load the page d ...

The issue I'm facing is that the "background-image" is not resizing automatically when changing orientation in CSS on

I've encountered an issue with displaying an image in the DOM that is sized based on the screen height. While this setup works flawlessly on most browsers and devices I've tested, Safari iOS 7 seems to be causing some trouble. Specifically, in S ...

Registering a function for chart.js plugins that manipulates external data

Is there a way to pass external data to the chart.plugins.register function? I'm struggling because I can't access the necessary context: Chart.plugins.register( { beforeDraw: function (chart) { //implementation } }); I attempted using ...

Loading/Adding JS script in an asynchronous manner

In my Laravel project, I am implementing templates for different pages based on a main page. Each page requires different JS scripts to function properly, so I created a template to import these scripts: <!-- jQuery 2.1.3 --> <script src="{{ URL: ...

Distributing JWT to the recipient using Express

Allow me to provide you with an overview of my application, which is quite straightforward. The main concept revolves around a user inputting their accountname and password into an html form on the /Login page like so: <form action="/Login" m ...

The drawbacks of using toJS() in React Redux: Is it really necessary in mapStateToProps()?

After reading through the Redux documentation, I came across a recommendation to not use Immutable with Redux. This advice has left me feeling confused. Why should I avoid using toJS() in the mapStateToProps function? It seems that React already uses Dee ...

Converting EDN data to a string and back in Clojure/ClojureScript

When working with JavaScript, one can convert a JavaScript data structure into a JSON string using the following code: JSON.stringify({somedata: { somesubdata: {}}}) Then, to parse it back into a JS data structure, you can use: var my_obj = JSON.parse(" ...

How can I redirect to another page when an item is clicked in AngularJS?

Here is an example of HTML code: <div class="item" data-url="link"></div> <div class="item" data-url="link"></div> <div class="item" data-url="link"></div> In jQuery, I can do the following: $('.item').click ...

Creating custom shaders in three.js that can receive shadows involves a few key steps. Let

For more information, you can visit the original post here. The task at hand seems to be quite complex due to the lack of documentation and examples on this specific topic on the three.js website. Currently, I am able to render the correct image and, with ...

"Clicking on the 'View More' button within a foreach loop is only functional for the

I am trying to iterate through a list of items using a foreach loop, and each item has a "view more" option. The intention is that when I click on this option, it should expand to show more details about the respective item. However, I am encountering an i ...