The image momentarily pauses as the arrow keys are switched

I have a query regarding the movement of the main player image. While it generally moves smoothly Left or Right, there is an issue when quickly switching directions from right to left. When the left key is pressed while the right key is still held down, the image pauses momentarily before moving left.

Main.js

var getPlatF1POSX = 0;
var getPlatF1POSY = 0;
var addVar = 0;
var addVar2 = 0;
var addVar3 = 0;
function initializeGame() {
    document.getElementsByTagName("DIV")[4].style.visibility = "visible";
    addEventListener('mousemove', fetchData, false);
    addEventListener('keydown', movePlayer, false);
    addEventListener('keyup', stopPlayer, false);
    movePlatform();
    movePlayerCharacter();

    document.getElementById("player").style.left = xPos + "px";
    document.getElementById("player").style.top = yPos + "px";  
}

function fetchData(gData) {

}

var thisThis = 1;
var moveBlock1 = 350;
var stLandT = 0;
var gPos = "";
var rightPos = false;
var leftPos = false;
function movePlatform() {

}

function movePlayerCharacter(mPlayer) {
    switch (mPlayer.keyCode) {
        case 39: // RIGHT
            if (stLandT == 0 && gPos == "" && rightPos == false) {
                setThis = setTimeout(landT, 500);
                thisSet = setTimeout(moveLand, 30);
                stLandT = 1;
            }
            gPos = "RIGHT";
            rightPos = true;
            leftPos = false;
        break;

        case 37: // LEFT
            if (stLandT == 0 && gPos == "" && leftPos == false) {
                setThis = setTimeout(landT, 500);
                thisSet = setTimeout(moveLand, 30);
                stLandT = 1;
            }
            gPos = "LEFT";
            rightPos = false;
            leftPos = true;
        break;

        case 38: // UP

        break;

        case 40: // DOWN

        break;
    }
}

function stopPlayer(sPlayer) {
    switch (sPlayer.keyCode) {
        case 39:
            clearTimeout(setThis);
            clearTimeout(thisSet);
            stLandT = 0;
            gPos = "";
            rightPos = false;
            leftPos = false;
        break;
        case 37:
            clearTimeout(setThis);
            clearTimeout(thisSet);
            stLandT = 0;
            gPos = "";
            rightPos = false;
            leftPos = false;
        break;
    }
}

Move Land And Player

var cTAdd = 0;
var setThis = 1;
var GAPlayer = 3;
function landT() {
    setThis = setTimeout(landT, 500);

    if (xPos >= 500) {
        cTAdd = Math.floor(Math.random() * 100 + 1);

        var block00 = document.createElement("img");

        if (cTAdd > 0 && cTAdd < 25) {
            block00.src = "images/sep2.png";
        }
        if (cTAdd > 25 && cTAdd < 50) {
            block00.src = "images/sep1.png";
        }
        if (cTAdd > 50 && cTAdd < 100) {
            block00.src = "images/platform00.png";
        }

        document.getElementById("land01").appendChild(block00);

        var block01 = document.createElement("img");
        var getB = block01.getBoundingClientRect();


        if (cTAdd > 0 && cTAdd < 25) {
            block01.src = "images/platform00.png";
        }
        if (cTAdd > 25 && cTAdd < 50) {
            block01.src = "images/sep2.png";
        }
        if (cTAdd > 50 && cTAdd < 100) {
            block01.src = "images/sep1.png";
        }

        document.getElementById("land00").appendChild(block01);

        GAPlayer = GAPlayer + 2;
    }

}

var thisSet = 1;
var cPlayer = 0;
var moveSpeed = 5;
var xPos = 50;
var yPos = 300;
function moveLand() {

    thisSet = setTimeout(moveLand, 30);

    if (xPos >= 500) {
        moveBlock1 = moveBlock1 - 10;
        document.getElementById("land00").style.left = moveBlock1 + "px";
        document.getElementById("land01").style.left = moveBlock1 + "px";
    }

    cPlayer++;
    if (cPlayer >= 4) 
        cPlayer = 0;
    document.images[GAPlayer].src = gPlayer[cPlayer].src;

}

function moveP() {
    var setThis = setTimeout(moveP, 10);

    if (leftPos == false) {
        xPos = xPos + moveSpeed;
    }

    if (rightPos == false) {
        xPos = xPos - moveSpeed;
    }

    document.getElementById("player").style.left = xPos + "px";
    document.getElementById("player").style.top = yPos + "px";  

    if (xPos >= 500) {
        xPos = 500; 
    }
    if (xPos < 50) {
        xPos = 50;  
    }   
}

Answer №1

This is because the player is stopped regardless of which key is released. It is important to keep track of the last key that was pressed down, and only stop movement when that key is released.

I struggled to debug the code, so I decided to rewrite it using jQuery (but encountered similar issues):

var game = {
    settings: {
    moveSpeed: 5, // 5 milliseconds, 200fps  
        moveBy: 2 // 2 pixels
    },
    land: null,
    landWidth: null,
    landLeft: null,
    viewport: null,
    viewportWidth: null,
    landMinLeft: null,
    init: function() {
        game.land = $('.land');
        game.landWidth = game.land.width();
        game.landLeft = game.land.position().left;
        game.viewport = $('.viewport');
        game.viewportWidth = game.viewport.width();
        game.landMinLeft = -(game.landWidth-game.viewportWidth);
    },
    movingInterval: null,
    lastKey: null,
    keyDown: function (e) {
switch (e.keyCode) {
        case 39: // RIGHT
                game.lastKey = e.keyCode;
                clearInterval( game.movingInterval );
                game.movingInterval = setInterval( function() {
                    game.move('right');
                }, game.settings.moveSpeed);
                break;
            case 37: // LEFT
                game.lastKey = e.keyCode;
                clearInterval( game.movingInterval );
                game.movingInterval = setInterval( function() {
                    game.move('left');
                }, game.settings.moveSpeed);
                break;
        }
    },
    keyUp: function(e) {
        if( e.keyCode==game.lastKey ) {
        game.stopMoving();
        };
    },
    move: function( direction ) {
    switch( direction ) {
            case 'left':
                var newLeft = game.land.position().left+game.settings.moveBy;
                if( newLeft>0 ) newLeft=0;
                game.land.css({
                   'left': newLeft+'px' 
                });
                break;
            case 'right':
                var newLeft = game.land.position().left-game.settings.moveBy;
                if( newLeft<game.landMinLeft ) newLeft=game.landMinLeft;
                game.land.css({
                   'left': newLeft+'px' 
                });
                break;
        };
    },
    stopMoving: function() {
    clearInterval( game.movingInterval );
    }
};
game.init();
$(window).on('keydown', game.keyDown);
$(window).on('keyup', game.keyUp);
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body, html, .viewport {
    width: 100%;
    height: 100%;
}
.viewport {
    position: relative;
    overflow: hidden;
}
.land {
    position: absolute;
    left: 0;
    top: 0;
    width: 2300px;
    height: 200px;
    background: url('//dummyimage.com/2300x400/000/fff&text=Mario+is+great!+Mario+is+our+hero!+We+love+you+mario!') no-repeat center center;
    background-size: cover;
    will-change: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="viewport">
    <div class="land"></div>
</div>

Check it out on the Playground.

Answer №2

This is a simple demonstration of implementing game logic using Javascript/HTML5.

File: theGame.js

var getPlatF1POSX = 0;
var getPlatF1POSY = 0;
var addVar = 0;
var addVar2 = 0;
var addVar3 = 0;

var thisThis = 1;
var moveBlock1 = 350;
var stLandT = 0;

var moveRight = false;
var moveLeft = false;
var movePL = 0;
var movePR = 0;

// Function to load the game and set key event listeners
function loadGame() {
    document.getElementsByTagName("DIV")[4].style.visibility = "visible";
    addEventListener('mousemove', getData, false);
    addEventListener('keydown', movePlayer, false);
    addEventListener('keyup', stopPlayer, false);
    moveP();

    document.getElementById("player").style.left = xPos + "px";
    document.getElementById("player").style.top = yPos + "px";  
}

function getData(gData) {

}

// Function to handle key down events for player movement
function movePlayer(mPlayer) {
    switch (mPlayer.keyCode) {
        case 39: // RIGHT
            if (stLandT == 0) {
                setThis = setTimeout(landT, 500);
                thisSet = setTimeout(moveLand, 30);
                stLandT = 1;    
            }

                movePL = 0;
                movePR = 1;

        break;

        case 37: // LEFT
            if (stLandT == 0) {
                setThis = setTimeout(landT, 500);
                thisSet = setTimeout(moveLand, 30);
                stLandT = 1;    
            }

                movePL = 1;
                movePR = 0;

        break;

        case 38: // UP

        break;

        case 40: // DOWN

        break;
    }
}

// Function to handle key up events for stopping player movement
function stopPlayer(sPlayer) {
    if (sPlayer.keyCode == 39) {
        clearTimeout(setThis);
        clearTimeout(thisSet);
        stLandT = 0;
        movePR = 0;
    }

    if (sPlayer.keyCode == 37) {
        clearTimeout(setThis);
        clearTimeout(thisSet);
        stLandT = 0;
        movePL = 0;
    }
}

File: landThis.js (Move Player and Platforms)

var cTAdd = 0;
var setThis = 1;
var GAPlayer = 3;

// Function to show platforms and move them
function landT() {
    setThis = setTimeout(landT, 500);

    if (xPos >= 500) {
        // Logic for platform generation
    }

}

// Function to move platforms
var thisSet = 1;
var cPlayer = 0;
var moveSpeed = 5;
var xPos = 50;
var yPos = 300;
function moveLand() {

    thisSet = setTimeout(moveLand, 30);

    if (xPos >= 500) {
        // Code to move platforms
    }

}

// Function to move the player
var setP = 1;
function moveP() {
    setP = setTimeout(moveP, 10);

    // Player movement logic
}

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

Ways to align text within a table cell on a background using CSS

I'm attempting to print jukebox strips with designated corner markings. The code I have written generates the HTML page for displaying the strips, allowing users to then print them. Jukeboxes typically feature selection buttons labeled ABCDEFGHJK and ...

What is the best method for choosing the parent elements?

I am attempting to create a sidebar that saves the last clicked link in local storage and still displays the collapsed links after the page is reloaded. $(".clickedLink").parent().parent().css('background-color', 'green'); Ca ...

I am unable to incorporate added height into the component

In my current project using react.js, material-ui, and sass, I had the task of creating a ChatBit component. After writing it, here is the code: customComponent.js file. // @flow import * as React from 'react'; import { useState } f ...

Ajax returns with a successful response, yet the specified action is never executed

Currently assisting with a plugin build on Wordpress and facing an issue with a basic ajax call. I am attempting to pass an object through the method 'grab_object_from_ajax_call,' but the method is not executing as expected. Below is the JavaScri ...

Where is the best place to implement HTML form validation: on the frontend or backend?

Is it important to validate all values before submitting the form to the backend server, as mentioned in the title? ...

Next.js app experiencing issues with Chakra UI not transitioning to dark mode

After attempting to incorporate Chakra UI into my Next.js application, I carefully followed every step outlined in their documentation: Despite setting the initialColorMode to "dark" for the ColorModeScript prop, it seems that the dark mode is not being a ...

Enabling Video Autoplay in HTML5

When my index.html page starts, it plays a full-screen video. Once the video ends, a button appears on the screen. Clicking the button redirects to another page. However, I am facing an issue with the "autoplay muted" property as it mutes the audio. I wa ...

ReactJS input range issue: Cannot preventDefault within a passive event listener invocation

I've been encountering some issues with the react-input-range component in my React App. It functions perfectly on larger viewports such as PCs and desktops, but on smaller devices like mobile phones and tablets, I'm seeing an error message "Unab ...

JavaScript Lightbox for Full Page Content (or near full page)

One option to consider is always jQuery. I am in search of a lightbox that provides a "full screen" effect. Not necessarily filling the entire screen, but rather covering most of the content on the page. The lightboxes I have come across either only displ ...

Slightly puzzled by the declaration of `var app = express()`

After going over the documentation, I'm still struggling to grasp why we store express() inside an app variable. I attempted to call methods using express().get and .post directly, but was unsuccessful. Why is that? Why doesn't it function in t ...

Using AJAX to search through paginated pages is quite simple and effective

Currently, I have developed a JavaScript script that filters names within a list. However, a problem has arisen with pagination - as the list paginates, I am unable to retrieve names without refreshing the page. Is there a way to use AJAX to access and dis ...

Stylish CSS animation enhancing an image

Can a flash effect like the one in this image be created using only CSS? I attempted to use -webkit-filter, but it did not produce satisfactory results. https://i.sstatic.net/Eg49c.jpg ...

Are you utilizing content loaded through jquery load in your work?

I have successfully utilized jQuery's .load() function to retrieve the contents of a table from another webpage and insert it into the current page, which is functioning properly. However, when I try to run scripts afterwards that manipulate the newly ...

potential issues with memory leakage and browser crashes in three.js

Currently working on an app that features a spherical panorama photo with a jpg size of around 4Mb. Throughout the development process, I find myself constantly refreshing the page to see changes and browsing through various three.js example pages for insp ...

Discovering the Secrets of Accessing and Modifying Item Values in BIRT

Is it feasible to create using only Javascript without utilizing any Java functions? Is there a way to access values from elements like labels, tables, or charts by calling them from an HTML button? I am currently working with Openlayers and BIRT. I need ...

How can I modify the container to prevent the Bootstrap dropdown from being clipped by overflow:hidden settings?

With bootstrap, I encountered a situation where dropdown menus are being clipped by my <div> with overflow: hidden. How can I address this issue without incurring high costs? One potential solution might be to change the container of all dropdowns wi ...

An HTML webpage that automatically refreshes but does't display the iframe content when the underlying HTML page is being updated

I have a script that updates a text file with completed tasks, creating log files in the process. I then use another script to format these logs with HTML code for tables, headings, banners, etc., saving the formatted version as Queue.html. To display this ...

What is the best way to display a red cross on a button?

Could you please help me add a red cross (font awesome icon) to the button? I attempted to implement the code on JSFiddle. However, I still need: UPDATE Initially, I found Kiranvj's answer suitable for its simplicity and applicability to all r ...

What is the best .scss file to use for updating the site?

Currently in the process of learning SASS and Bootstrap 4, I have set up some .scss partial files and imported them into my site.scss file as required. Making changes to Bootstrap involved modifying my _my-theme.scss file. But now, I'm wondering about ...

I am interested in creating a ranking system in JavaScript using JSON data based on points

I have a desire to create the following: var users = {jhon: {name: 'jhon', points: 30}, markus:{name: 'Markus', points: 20}}; // I want it to return like this 1. Jhon with number of points: 30 // 2. Markus with number of points: 20 ...