I'm looking for a way to have an element shift in a particular direction only when two keys are pressed simultaneously

Having trouble moving a square diagonally when two keys are pressed simultaneously. Trying to create an if statement that detects both key presses at the same time and triggers the movement. However, all attempts have failed so far, leaving uncertainty about whether the x and y translations of the square will function properly. Additional information can be provided upon request.

JavaScript

// Function for handling key press events
function pressed() {
    let squarePosY = 0;
    let squarePosX = 0;
    
    // Event listener for keydown
    document.addEventListener("keydown", (event) => {
        if (event.keyCode === 87) {
            // Change background color to yellow
            document.getElementById("w-key").style.backgroundColor = "yellow";
            squarePosY -= 5;
            anime({
                targets: '#square',
                translateY: squarePosY
            });
        } else if (event.keyCode === 83) {
            document.getElementById("s-key").style.backgroundColor = "yellow";
            squarePosY += 5;
            anime({
                targets: '#square',
                translateY: squarePosY
            });
        } else if (event.keyCode === 65) {
            document.getElementById("a-key").style.backgroundColor = "yellow";
            squarePosX -= 5;
            anime({
                targets: '#square',
                translateX: squarePosX
            });
        } else if (event.keyCode === 68) {
            document.getElementById("d-key").style.backgroundColor = "yellow";
            squarePosX += 5;
            anime({
                targets: '#square',
                translateX: squarePosX
            });
        } else if (event.keyCode == 87 && event.keyCode == 65) {
            squarePosX += 5;
            squarePosY += 5;
            anime({
                targets: '#square',
                translateX: squarePosX,
                translateY: squarePosY
            });
            alert("worked");
        }
    });
    
    // Event listeners for keyup to reset background color
    document.addEventListener("keyup", (event) => {
        if (event.keyCode === 87 ) {
            document.getElementById("w-key").style.backgroundColor = "white";
        }
    });
    document.addEventListener("keyup", (event) => {
        if (event.keyCode === 83 ) {
            document.getElementById("s-key").style.backgroundColor = "white";
        }
    });
    document.addEventListener("keyup", (event) => {
        if (event.keyCode === 65 ) {
            document.getElementById("a-key").style.backgroundColor = "white";
        }
    });
    document.addEventListener("keyup", (event) => {
        if (event.keyCode === 68 ) {
            document.getElementById("d-key").style.backgroundColor = "white";
        }
    });
}

// Start the animation
function startAnim() {
    pressed();
}

CSS

#square {
    width: 10px;
    height: 10px;
    background-color: black;
    left: 50%;
    bottom: 50%;
    position: absolute;
}

.squareStartPos {
    width: 8px;
    height: 8px;
    border: 1px solid black;
    left: 50%;
    bottom: 50%;
    position:absolute;
}

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="html.js"></script>
    <link rel="stylesheet" href="css.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js" integrity="sha512-aNMyYYxdIxIaot0Y1/PLuEu3eipGCmsEUBrUq+7aVyPGMFH8z0eTP0tkqAvv34fzN6z+201d3T8HPb1svWSKHQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body onload="startAnim()">
    <div id="keyboard">
        <div class="top-row"></div>
        <div class="button-key button" id="w-key"></div>
        <div id="bottom-row">
            <div class="button-key button" id="a-key"></div>
            <div class="button-key button" id="s-key"></div>
            <div class="button-key button" id="d-key"></div>
        </div>
    </div>

    <div class="square" id="square"></div>
    <div class="squareStartPos"></div>
</body>
</html>

Attempted to combine keyCodes using '&&' in the if statement without success.

Answer №1

Here's a more efficient and organized approach that can also allow for the addition of speed, acceleration, and time control in the future. Integrating the anime.js library may introduce some complexity to the basic logic.

The concept involves using a time interval to monitor which keys are being pressed by referencing a global dictionary object that is updated whenever a key is pressed or released.

// Function to handle key press events 
function detectKeyPress() {
  let squarePosY = 0;
  let squarePosX = 0;
  var speedX = 0
  var speedY = 0

  const keysPressed = {};

  function keyDownEventHandler(event) {
    keysPressed[event.keyCode] = true;
  }

  function keyUpEventHandler(event) {
    delete keysPressed[event.keyCode];
  }

  document.addEventListener('keydown', keyDownEventHandler);
  document.addEventListener('keyup', keyUpEventHandler);

  updateMovement()


  function updatePosition() {
    document.getElementById("w-key").classList.toggle("pressed", keysPressed[87] === true);
    document.getElementById("s-key").classList.toggle("pressed", keysPressed[83] === true);
    document.getElementById("a-key").classList.toggle("pressed", keysPressed[65] === true);
    document.getElementById("d-key").classList.toggle("pressed", keysPressed[68] === true);


    if (keysPressed[87]) {
      squarePosY -= 5;
    }
    if (keysPressed[83]) {
      squarePosY += 5
    }
    if (keysPressed[65]) {
      squarePosX -= 5;
    }
    if (keysPressed[68]) {
      squarePosX += 5;
    }

    anime({
      targets: '#square',
      translateY: squarePosY,
      translateX: squarePosX,
    })

  }

  function movementUpdateLoop() {
    updatePosition();
    requestAnimationFrame(movementUpdateLoop);
  }


}



function startAnimation() {
  detectKeyPress()
}
#square {
  width: 10px;
  height: 10px;
  background-color: black;
  left: 50%;
  bottom: 50%;
  position: absolute;
}

.squareStartPos {
  width: 8px;
  height: 8px;
  border: 1px solid black;
  left: 50%;
  bottom: 50%;
  position: absolute;
}

.button-key {
  width: 20px;
  height: 20px;
  border: 1px solid red;
  float: left;
  background: white;
}

.pressed {
  background: yellow;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="html.js"></script>
  <link rel="stylesheet" href="css.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js" integrity="sha512-aNMyYYxdIxIaot0Y1/PLuEu3eipGCmsEUBrUq+7aVyPGMFH8z0eTP0tkqAvv34fzN6z+201d3T8HPb1svWSKHQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body onload="startAnimation()">
  <!-- Div container for the keyboard keys -->
  <div id="keyboard">
    <div class="top-row"></div>
    <div class="button-key button" id="w-key">w</div>
    <div id="bottom-row">
      <div class="button-key button" id="a-key">a</div>
      <div class="button-key button" id="s-key">s</div>
      <div class="button-key button" id="d-key">d</div>
    </div>
  </div>
  <!-- Element representing the controllable square -->
  <div class="square" id="square"></div>
  <div class="squareStartPos"></div>
</body>

</html>

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

Endless cycle of Facebook login prompts

Currently, I am utilizing the Facebook JavaScript SDK for a login button on my website. The functionality is working correctly, but there are two specific use cases where I seem to be encountering some issues. One issue arises when the Facebook cookie is ...

Ajax sending numerous requests to the API

Recently, I began my journey of learning Javascript and decided to interact with my Django API through Ajax requests. To achieve this, I created a search bar that triggers the API call after a one-second delay following a keyup action. input.addEventListe ...

Issue with displaying a vTable component in VueJS / Vuetify

I am struggling with this basic HTML/Vue/Vuetify code snippet below, and I can't seem to get it functioning as intended. const { createApp, computed, ref, reactive } = Vue; const { createVuetify } = Vuetify; const ...

Exploring the process of creating a interactive rectangular border on an image with JavaScript

I'm currently working on a project that requires me to draw multiple bounding boxes interactively within an image displayed on a web browser. After drawing the bounding boxes, I will need to extract their coordinates. Are there any suggestions for a J ...

Parenting and Child Components: Keeping the State in Sync

I am currently diving into my initial React project which focuses on a basic expense tracker for credit cards. While I'm still in the learning phase, I hope you can decipher the intent behind my code. My current roadblock involves mapping the state an ...

Increasing the grid size in React Bootstrap 5 for added flexibility

Customizing React Bootstrap Sizes WPW Container Max-Width sx < 576px - none sm > 567px - 540px md > 768px - 720px lg > 992px - 960px xl > 1200px - 1140px xxl > 1400px - 1320px Desiring a New Size Category: I am interested in ad ...

No response from jQuery's $.getJSON() function

I'm currently experimenting with jQuery by using a script that I wrote. As a beginner in learning jQuery, I am trying to read data from a .json file and display it in a div. function jQuerytest() { $.getJSON( "books/testbook/pageIndex.json", func ...

Ways to deactivate the Bootstrap collapse feature

In my accordion FAQs, I am facing an issue where Question 1 is automatically opened when the page loads. Additionally, when I click on Question 2, it closes instead of staying open. I would like to address these problems and make sure that each question st ...

problems with using array.concat()

I am attempting to reverse a stream of data using a recursive call to concatenate a return array. The instructions for this problem are as follows: The incoming data needs to be reversed in segments that are 8 bits long. This means that the order of thes ...

Combining Multiple Optional Async AJAX Calls

In my Angular 1.5.8 app, I have different views that require various combinations of the same 3 ajax requests. Some views need data from all three endpoints, while others only need data from one or two. To efficiently manage the retrieval of this data, I ...

Problems with radio button serialization in jQuery form plugin

I've created a basic form: <form class="dataform" method="post" id="settings" action="/"> <input type="radio" name="shareSetting" value="n"/> <input type="radio" name="shareSetting" value="y"/> <input type="button" na ...

Guide on transferring the td id value to a different page

document.getElementById('scdiv').innerHTML=Quantity <td id="scdiv"> </td> document.getElementById('quantitydiv').innerHTML=mrp <td id="quantitydiv"> </td> I am currently facing an issue where the code is being d ...

Unable to retrieve AJAX response

I've been working on a page where I'm using AJAX to fetch data based on the selection of radio buttons. The three options available are 'Unapproved', 'Approved' and 'All'. My goal is to display the corresponding user ...

A technique, such as regular expressions, can be used to detect the quantity of newline characters in the text entered by the user in a text area

I'm trying to figure out how to count the number of newline characters (or whatever is inserted when the user presses the return key) in a textarea's value. I believe I should be using a regular expression for this task, but I'm not very ski ...

Django's Implementation of Real-Time WebSocket Notifications

Currently, I am encountering an issue while integrating web socket notifications into my Django project. The problem arises when attempting to pass the user's unread notification count to them. To address this challenge, my initial solution involved ...

The calculation of Value Added Tax does not involve the use of jQuery

My form setup is as follows: <form method="post" action="" id="form-show"> <table class="table table-bordered table-striped table-hover" id='total' style="width:100%;"> ...

GeoJson with timestamp and marked directional indicator

I am looking to create an animation of a boat traveling along a specific route. Currently, I am able to display the route as a line and the boat as a circle using TimestampedGeoJson: # circle with following line features = [ { 'type': ...

Using JavaScript, retrieve the ID of a child element by utilizing details about the parent element

I have implemented a JavaScript function that creates a div element. Within this div, there are multiple checkboxes as child elements. My goal is to use a loop to extract the ids of all these checkboxes. The div has been assigned to a variable named: o ...

Preventing event bubbling/propagation in custom events: a step-by-step guide

Incorporating a module-project from Github into my Angular project, I am able to resize the DOM elements that are displayed on top of a div functioning as a drawing board. To configure my initial rectangles, I am utilizing a combination of mouseDown - mou ...

Issues with implementing AddEventListener in InAppBrowser on IONIC 2

I am currently working on implementing AddeventListener to listen for 'Exit' and 'LoadStart' events in InAppBrowser within IONIC2. Here is my HTML: <button (click)="browsersystem('https://www.google.com')" > Visit URL& ...