What is the best method to control the movement of a Three JS cube using keyboard commands?

I've been experimenting with Three.js and trying to implement movement controls for a rotating cube using the WASD keys. The goal is to move the cube up, down, left, and right, as well as reset it to its original position in the middle of the screen by pressing the space bar. However, I'm facing some difficulties getting the movement functionality to work properly. As a newbie to Three.js, I would really appreciate any help or guidance. Below is the code snippet I've worked on so far:

// initial lines remain consistent
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// end template here

var geom = new THREE.BoxGeometry(10, 10, 10);
var mat = new THREE.MeshBasicMaterial({color: "red"});
var cube = new THREE.Mesh(geom, mat);

scene.add(cube);
camera.position.x = 2;
camera.position.y = 1;
camera.position.z = 20;

var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );

var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.7 );
scene.add( directionalLight );

// handling movement
document.addEventListener("keydown", onDocumentKeyDown, false);
function onDocumentKeyDown(event) {
    var keyCode = event.which;
    
    if (keyCode == 87) { // up
        cube.position.y += 1;
        
    } else if (keyCode == 83) { // down
        cube.position.y -= 1;
        
    } else if (keyCode == 65) { // left
        cube.position.x -= 1;
        
    } else if (keyCode == 68) { // right
        cube.position.x += 1;
        
    } else if (keyCode == 32) { // space
        cube.position.x = 0.0;
        cube.position.y = 0.0;
    }
    render();
};

var render = function() {
  requestAnimationFrame(render);
  cube.rotation.x += 0.03;
  cube.rotation.y += 0.02;
  cube.rotation.z += 0.01;
  renderer.render(scene, camera);
};

render();

The above code represents the JavaScript part of my project. In addition to this file, I have an HTML file that acts as the entry point. Here's how the HTML looks like:

<html><head><title>WebGL with three.js</title>
<style>
  body { margin: 0; }
  canvas { width: 100%; height: 100% }
</style>
</head><body>
<script src="three.js"></script>
<script src="Learn_Cube3.js"></script>
</body></html>

Answer №1

What are your thoughts on this? -

// Adjust these values for movement calibration
var xSpeed = 0.0001;
var ySpeed = 0.0001;

document.addEventListener("keydown", onDocumentKeyDown, false);
function onDocumentKeyDown(event) {
    var keyCode = event.which;
    if (keyCode == 87) {
        cube.position.y += ySpeed;
    } else if (keyCode == 83) {
        cube.position.y -= ySpeed;
    } else if (keyCode == 65) {
        cube.position.x -= xSpeed;
    } else if (keyCode == 68) {
        cube.position.x += xSpeed;
    } else if (keyCode == 32) {
        cube.position.set(0, 0, 0);
    }
};

To move an object, adjust the position accordingly. Make sure to customize the xSpeed and ySpeed to suit your requirements.

Answer №2

Remember to trigger your render function during the key down event:

function onKeyDown(event) {
    ...
    render();
};

The problem was that although you were updating values, ThreeJS doesn't automatically re-render the view when there are changes. You have to explicitly instruct it to re-render.

Additionally, make sure to update the position of the cube in your render method along with rotation properties for it to move as expected.

Creating separate variables like "xSpeed" and "ySpeed" might not be effective. Instead, directly adjust the position by adding or subtracting from position.x and position.y.

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

Mixing resource and non-resource techniques in Angular factory

Feeling a bit confused by what should be a simple task. I am currently working on enhancing an Angular service by adding some new methods. Initially, the service was only making a single $resource call to my API. The additional methods I am incorporating a ...

Create various designs for a section of a webpage

My goal is to create a coding playground using flex-box to position different panels. Here is an example in JSBin, with the following html code: <div class="flex-box"> <div class="col" id="html-panel"> <p>html</p> </div& ...

Guide on adding pictures to an ExpressJS server

Working on this project has been quite a challenge for me as I delve deeper into web development. As a relatively new developer, creating a one-page application with image upload functionality has proven to be quite the task, especially considering this is ...

Transform each array into individual objects

I am a beginner in javascript and I find arrays and objects to be a bit challenging. Currently, I am facing a hurdle with them. Here is the array I'm working with: [ '5', '13', '16', '22', '24' ] 1st ...

Securing uploaded documents and limiting access to approved individuals

Currently, I am utilizing Multer for file uploads and I am contemplating the ideal approach to secure access to these files post-upload. In my system, there are two user roles: admin and regular user. Users can only upload photos while only admins have ac ...

Which is better for creating hover effects: CSS3 or JavaScript?

When hovering over a link, I want to highlight a specific picture and blur the rest. Here's my HTML code: <body> <div id="back"> <div id="one"></div> <div id="two"></div> </div> ...

What is the best way to identify the ID of a clicked element?

Imagine a scenario where you have multiple HTML elements, such as a row in a table made up of <td> tags. <td id="data1">foo</td> <td id="data2">bar</td> <td id="data3">baz</td> If you wanted to retrieve the id of ...

Dynamically submitting a form generated within the AJAX success callback in CodeIgniter

After creating a form dynamically within the success function of an AJAX call, I expected it to submit like a normal form in CodeIgniter. However, upon clicking the submit button, the form data is not being picked up by the appropriate controller. The ori ...

Displaying an array result as 'object object'

Apologies if my explanation is confusing, but I am currently dealing with an array object and trying to extract the fields for output. However, all I seem to be getting is [object object] $.getJSON( "https://service1.homepro.com/smart.asmx/GetFAP_ProfileR ...

Removing Multiple Object Properties in React: A Step-by-Step Guide

Is there a way in React to remove multiple object properties with just one line of code? I am familiar with the delete command: delete obj.property, but I have multiple object properties that need to be deleted and it would be more convenient to do this i ...

Having trouble with the implementation of createContext/ useContext in React?

Struggling to figure out why my implementation of createContext and useContext is not functioning as expected in my React project. This is how I have structured my context file: // @flow import { createContext, useContext } from "react"; export ...

What is the process for using the CLI to downgrade an NPM package to a previous minor version by utilizing the tilde version tag?

I currently have Typescript version ^3.7.4 installed as a devDependency in my project's package.json: { "name": "my-awesome-package", "version": "1.0.0", "devDependencies": { "typescript": "^3.7.4" } } My goal is to downgrade Typescript ...

Making an API call in a getter function using AngularJS

Recently, I came across a project in AngularJS that had some structural issues. One of the main problems was related to fetching settings from an API endpoint. There were times when the application tried to access these settings before they were fully load ...

What is the best way to indicate that two different array positions are equal to at least one of the specified values within a conditional statement?

Can someone help me with expressing in JavaScript that if both array1[i] and array2[j] equal either "0", "O" or "Q", then array1[i] should be equal to array2[j? I've tried different approaches but it's not working. Thank you. if ((array1[i] == "0 ...

Identifying the initial directory when it is not in English

I've developed a website that supports multiple translated languages, including English, German, Spanish, French, and Italian. Currently, I have a select box on the website that allows users to choose their preferred language. However, I'm facin ...

Vue JS version 1.0.26 flips symbols on the front-end

After purchasing the Socialite Social Network Laravel Script developed by BootstrapGuru, I encountered an issue with the chat feature on my website. Upon entering text and symbols into the chat window, such as "how are you?", the displayed text appeared as ...

Notification box for displaying database information in HTML table layout

I am currently facing an issue where I have data from a database that I want to display in an HTML table inside an alert box. The problem is that the data is not appearing in the correct format within the alert box, it is simply displaying as text. Here is ...

Splitting code is not being done through React's lazy import and the use of Webpack

//webpack development configuration const common = require("./webpack.common"); const merge = require("webpack-merge"); const globImporter = require('node-sass-glob-importer'); module.exports = merge(common, { mode: "development", modul ...

Retrieving the value of a duplicated button in AngularJS

I have implemented a basic HTML table using AngularJS to display data for each item in my "names" array. Each item represents an object with various attributes such as Name, id, etc. Along with each row in the table, I have included a button. However, I am ...

Executing multiple HTTPS requests within an Express route in a Node.js application

1 I need help with a route that looks like this: router.get('/test', async(req, res)=>{ }); In the past, I have been using the request module to make http calls. However, now I am trying to make multiple http calls and merge the responses ...