When I try to move my object, it seems to have a mind of its own and flies off the canvas instead of staying where

I am in the process of developing a simple game for a class project. Currently, I am working on ensuring that my rectangle stays within the boundaries of the canvas as I move it using a bounce function. However, I am facing difficulties as the rectangle does not seem to be bouncing off the edges as expected. I have already implemented the bounce function and called it at the beginning of my code. Despite this, the rectangle continues to move past the canvas limits instead of rebounding off the border.

var canvas;
var ctx;
var w = 1000;
var h = 700;
 

var o1 = {
    x: 100,
    y: h/2,
    w: 100,
    h: 100,
    c: 0,
    a: 100,
    angle: 0, //changes angle that shape sits at
    distance: 10
}
 

document.onkeydown = function(e){keypress(e, o1)}
 
 
setUpCanvas();
// circle (o1);
animationLoop();
 
 
function animationLoop(){
    //clear
    clear();
    //draw
    rect(o1);
    //update
   bounce(o1)

    requestAnimationFrame(animationLoop)
 
}
 


function bounce(o){
    if(o.x+o.w/2 > w || o.x-o.w/2 < 0){ //makes shape bounce from edge instead of middle. collision detection
        o.changeX *= -1; //same as o.changeX = o.changeX = -1;
    }
 
    if(o.y+o.h/2 > h || o.y-o.h/2 <0){
        o.changeY *= -1;
    }
   
 
}
 
 
function updateData(o){
o.x += o.changeX;
o.y += o.changeY;
}



function keypress(e,o){

 
    if (e.key == "ArrowUp"){
        o.angle = 270;
        o.distance= 80;
        forward(o);
       
    }
 
    if (e.key == "ArrowDown"){
        o.angle = 90;
        o.distance= 20;
        forward(o);
        
    }
}
 
 
 
function forward(o){ //makes shape able to move
    var cx;
    var cy;
    cx = o.distance*Math.cos(o.angle);
    cy = o.distance*Math.sin(o.angle)
    o.y += cy;
 
 }
 

    function rect(o){
        var bufferx = o.x;
        var buffery = o.y
        o.x = o.x - o.w/2;
        o.y = o.y- o.h/2;
        ctx.beginPath(); //this is very important when we are changing certain ctx properties
        ctx.moveTo(o.x,o.y);
        ctx.lineTo(o.x+o.w,o.y);
        ctx.lineTo(o.x+o.w,o.y+o.h);
        ctx.lineTo(o.x, o.y+o.h);
        ctx.lineTo(o.x,o.y);
        ctx.fillStyle = "hsla("+String (o.c)+",100%,50%,"+o.a+")";
        ctx.fill();
    
        o.x = bufferx; //o.x = o.x + o.w/2;
        o.y = buffery;//o.y = o.y+ o.h/2;
    }
    
 
 
 
 
 
 
function clear(){
    ctx.clearRect(0, 0, w, h);
}
 
function randn(range){
    var r = Math.random()*range-(range/2);
    return r
}
function rand(range){
    var r = Math.random()*range
    return r
}
 
function setUpCanvas(){
    canvas = document.querySelector("#myCanvas");
    canvas.width = w;
    canvas.height = h;
    // canvas.style.width = "1000px";
    // canvas.style.height = "700px";
    canvas.style.border = "10px solid black";
    ctx = canvas.getContext("2d");
}
 
console.log("Final Assignment")

Answer №1

Ensure that you set the changeX and changeY values in o1, as they are not initialized to work with the updateData function:

changeX: initialX,
changeY: initialY,

var canvas;
var ctx;
var w = 1000;
var h = 700;
 

var o1 = {
    x: 100,
    y: h/2,
    w: 100,
    h: 100,
    c: 0,
    a: 100,
    angle: 0, //changes angle that shape sits at
    distance: 10,
    changeX: 5, // initialize with x vel
    changeY: 4, // initialize with y vel
}
 

document.onkeydown = function(e){keypress(e, o1)}
 
 
 
 
setUpCanvas();
// circle (o1);
animationLoop();
 
 
function animationLoop(){
    //clear
    clear();
    //draw
    rect(o1);
    //update
   bounce(o1)
    updateData(o1)
    requestAnimationFrame(animationLoop)
 
}
 


function bounce(o){
    if(o.x+o.w/2 > w || o.x-o.w/2 < 0){ //makes shape bounce from edge instead of middle. collision detection
        o.changeX *= -1; //same as o.changeX = o.changeX = -1;
    }
 
    if(o.y+o.h/2 > h || o.y-o.h/2 <0){
        o.changeY *= -1;
    }
   
 
}
 
 
function updateData(o){
o.x += o.changeX;
o.y += o.changeY;
}



function keypress(e,o){

 
    if (e.key == "ArrowUp"){
        o.angle = 270;
        o.distance= 80;
        forward(o);
       
    }
 
    if (e.key == "ArrowDown"){
        o.angle = 90;
        o.distance= 20;
        forward(o);
        
    }
}
 
 
 
function forward(o){ //makes shape able to move
    var cx;
    var cy;
    cx = o.distance*Math.cos(o.angle);
    cy = o.distance*Math.sin(o.angle)
    o.y += cy;
 
 }
 

    function rect(o){
        var bufferx = o.x;
        var buffery = o.y
        o.x = o.x - o.w/2;
        o.y = o.y- o.h/2;
        ctx.beginPath(); //this is very important when we are changing certain ctx properties
        ctx.moveTo(o.x,o.y);
        ctx.lineTo(o.x+o.w,o.y);
        ctx.lineTo(o.x+o.w,o.y+o.h);
        ctx.lineTo(o.x, o.y+o.h);
        ctx.lineTo(o.x,o.y);
        ctx.fillStyle = "hsla("+String (o.c)+",100%,50%,"+o.a+")";
        ctx.fill();
    
        o.x = bufferx; //o.x = o.x + o.w/2;
        o.y = buffery;//o.y = o.y+ o.h/2;
    }
    
 
 
 
 
 
 
function clear(){
    ctx.clearRect(0, 0, w, h);
}
 
function randn(range){
    var r = Math.random()*range-(range/2);
    return r
}
function rand(range){
    var r = Math.random()*range
    return r
}
 
function setUpCanvas(){
    canvas = document.querySelector("#myCanvas");
    canvas.width = w;
    canvas.height = h;
    // canvas.style.width = "1000px";
    // canvas.style.height = "700px";
    canvas.style.border = "10px solid black";
    ctx = canvas.getContext("2d");
}
 
console.log("Final Assignment")
<canvas id="myCanvas" ></canvas>

Answer №2

Your current code does not utilize the o.changeX and o.changeY functions, rendering them ineffective despite being changed by the bounce() function.

Finding a solution may prove challenging due to your reliance on angles in the assignment. While vectors simplify game movement, solving geometric problems using angles can pose significant difficulties.

(Having developed 3D game engines and a VR sculpting app, I have found no need for angles or trigonometric functions like sin / cos even for rotation matrices. Trust me, angles are best avoided.)

Edit:
Nevertheless, here is a straightforward solution: Avoid using angles altogether.
Simply update your keypress function:


//If you want the arrow key to change the direction your square is moving:

function keypress(e,o){

 
    if (e.key == "ArrowUp"){
        o.changeY = -1;
    }
 
    if (e.key == "ArrowDown"){
        o.changeY = 1;
    }
 
}
 
//If you want the arrow key to move your square, but not change the direction it was moving:

function keypress(e,o){

 
    if (e.key == "ArrowUp"){
        o.y -= 80;
       //This value is huge. Do you really want to move your square 80 pixels? It's going to shoot off the screen in a flash. I would set this to 2.
    }
 
    if (e.key == "ArrowDown"){
        o.y += 20;
    }
 
}
 

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

Show a single jQuery Validation error

I am struggling with displaying an error message at the top if validation fails, without using the errorPlacement option. Instead, I want to showcase the message in a Bootstrap alert box. Below is the HTML code snippet: <form method="POST" action="/ro ...

Issue: unable to establish a connection to [localhost:27017]

Upon executing node app.js, an error message is displayed: Failed to load c++ bson extension, using pure JS version Express server listening on port 3000 events.js:85 throw er; // Unhandled 'error' event ^ Error: failed to conn ...

Update your Electron application with the npm update command

I have recently published an app on a local npm repository, and this particular app serves as a crucial dependency for my second electron application. The electron app I am working on is structured around node_modules/my-first-app/dist/index.html. I am w ...

"Incorporating Node.js (crypto) to create a 32-byte SHA256 hash can prevent the occurrence of a bad key size error triggered by tweetnacl.js. Learn how to efficiently

Utilizing the crypto module within node.js, I am creating a SHA256 hash as shown below: const key = crypto.createHmac('sha256', data).digest('hex'); However, when passing this key to tweetnacl's secretbox, an error of bad key siz ...

Combining Array Attributes to Create a New Property as a 'JSON String'

I'm attempting to combine the attributes of an array into a JSON-like string as a new attribute. For example: [{ { "orderNo":"1", "description":"Item 1", "note": "Note 1" }, { "orderNo":"2", "description":"Item 2", ...

How to correct header alignment in HTML for Google Table

Utilizing the google visualization table to generate a html table, I have successfully fixed the top section of the html using the stuckpart div. This ensures that regardless of how I scroll, the button remains in place. However, I now aim to fix the table ...

Updating image source dynamically with Flask

I am currently developing a face detection application using Flask. I aim to have the detected faces displayed in real-time on the HTML page. For the JavaScript aspect, I am utilizing getUserMedia to live stream camera images from the client to the server ...

Javascript Promise: managing the flow of execution

There are a series of tasks that I need to accomplish using an API. It's crucial that these functions are executed sequentially. Each of the functions mentioned below returns a valid promise. a(analyticsConfig._listConfig) .then(function() { ...

Testing for expressjs 4 using Mocha revealed unexpected behavior when attempting to spy on a function called within a promise. Despite setting up the

I have encountered a situation with some test cases structured like this: it('does stuff', function(done) { somePromise.then(function () { expect(someSpy).to.have.been.called done() }) }) When the assertion in a test case fails, it ...

What is the best way to deliver static HTML files in Nest.js?

I am encountering an issue with loading JS files from a static /dist folder located outside of my Nest project. While the index.html file loads successfully, any JS file results in a 404 error. In another Node/Express.js project, I am able to serve these ...

How to trigger a JavaScript function using a link in CakePHP?

When working with Html, <a href="some_url"> Contact Seller </a> In the realm of Cakephp, <?php echo $this->Html->link('Contact Seller', array('controller'=>'pages', 'action'=>'conta ...

Stop the loop in cypress

We have a certain situation as outlined below loop through all name elements on the webpage if(name.text() matches expName) { name.click() break out of the loop } else { createName() } How can I achieve this in Cypress? Using return false doesn't se ...

Guide to automatically dismiss calendar popup after selecting a date

After selecting a date, how can I hide the calendar? I am currently utilizing Date-time-picker by DanyelYKPan. Is there a specific function that I should be using? Here is the code snippet: <div class="col-3"> <div class="form-group calenderF ...

Steps for removing the console warning message: "The use of enableRowSelect has been deprecated. Instead, please utilize rowSelection."

) I have integrated React Data Grid from https://adazzle.github.io/react-data-grid/ multiple times in my application. One thing I noticed is that there is a console warning related to a prop called "enableRowSelect" which indicates whether the prop is bein ...

When a textbox is modified and a button is clicked in ASP.NET, triggering both client-side and server-side events

I have a popup that allows users to change an address. It contains three text boxes (Address, Province, and ZIP) and one DropDownList for the City. When the ZIP code is changed, an ajax call updates the province text box. I also want to later populate the ...

Various issues arising from a single input in Foundation Abide with AngularJS

Trying to set up a form using Foundation has proven challenging, especially when it comes to implementing more advanced error checking. If we take the example of an input field like this: <input pattern="username" required type="text" placeholder="user ...

Tracking the movement of a handheld device through GPS technology

I am interested in creating a mobile application that can track the real-time location of users who have the app installed on their devices. The concept is to allow one or more users to follow the movement of another user using GPS on a map. I plan to deve ...

MongoDB Sorting Techniques

I'm struggling to figure out how to retrieve an ordered list from MongoDB data. I need to fetch the results from a Mongo collection using return and .find(), structured like this: For instance, let's say I have one collection for cars with 10 do ...

What are the steps to add code into the Monaco Editor using Playwright?

As I explore the world of Playwright, I am faced with a challenge regarding testing a feature that involves a monaco editor. Unfortunately, my search in Playwright documentation and forums did not yield any relevant information. Here is the test scenario ...

Swapping out the main view for the partial view

Recently, I wrote some jQuery code to fetch data from an action by passing in a dashID. The expected result was to receive HTML containing the relevant information. Unfortunately, my jQuery script is not returning the desired data. Below is the JavaScript ...