JavaScript Time Lag

Every 100 milliseconds, the PS.Tick() function is called to execute the AI function of NPCs and make them move:

PS.Tick = function ()
{
"use strict";
for (NPCid = 0; NPCid < NPCnumber; NPCid++)
{
    NPCAI(NPCid);
};
}; 

However, I wanted the NPCs to move at their own pace rather than all at once every 100 milliseconds. To achieve this, I implemented the following code:

PS.Tick = function ()
{
"use strict";
for (NPCid = 0; NPCid < NPCnumber; NPCid++)
{
    var timeout = 0;
    timeout = PS.Random (1000);
    setTimeout("NPCAI(NPCid)",timeout);
};
};

Unfortunately, the NPCs are not moving at all now. What could be causing this issue? How can I make them move at different time intervals?

Answer №1

create this

for (index = 0; index < number; index++) {
    var delay = 0;
    delay = Math.Random (1000);
    (function (identifier) {
        setTimeout(function(){functionName(identifier)},delay);
    })(index); };

Using that additional function is crucial to retaining the ID in a closure. Otherwise, only the final ID of the loop will be passed each time.

Answer №2

Why aren't they moving anymore?

There could be a few reasons for this:

  • If the variable NPCid is not defined anywhere: Your code will throw a ReferenceError.

  • If NPCid is defined but not globally: Passing a string into setTimeout won't evaluate it in the current context, causing issues with accessing NPCid. It's generally advised not to pass strings into setTimeout.

  • If NPCid is global: During execution of delayed code, all instances will see the same value of NPCid, which is its final value at the end of the loop.

To resolve this, if you're working on NodeJS (assuming from your approach), you can try:

PS.Tick = function ()
{
    "use strict";

    // (Assuming NPCid is declared; add `var NPCid;` here if needed)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random(1000);
        setTimeout(NPCAI, timeout, NPCid); // Only for NodeJS and Firefox!!
    }
};

This method works because NodeJS (and Firefox) allow passing arguments to setTimeout for the called function.

If not using NodeJS or Firefox, but having ES5's Function#bind, consider:

PS.Tick = function ()
{
    "use strict";

    // (Assuming NPCid is declared; add `var NPCid;` here if needed)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random(1000);
        setTimeout(NPCAI.bind(undefined, NPCid), timeout);
    }
};

Function#bind generates a function that calls the original function with specified this value and provided arguments.

If unavailable, create a custom bind or opt for:

PS.Tick = function ()
{
    "use strict";

    // (Assuming NPCid is declared; add `var NPCid;` here if needed)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random(1000);
        setTimeout(makeHandler(NPCid), timeout);
    }

    function makeHandler(id) {
        return function() {
            NPCAI(id);
        };
    }
};

This solution involves creating a function that, upon invocation, triggers the appropriate call to NPCAI with the provided argument value.

Answer №3

Make sure to include a function call in your setTimeout,

Here's an example:

setTimeout(function(){ NPCAI(NPCid); }, timeout);

Alternatively, consider using set interval for each NPC separately. Keep in mind that relying too heavily on timeouts and intervals can lead to inefficiency and potential lag issues.

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

The code is malfunctioning on this site (yet functions perfectly on a different website)

So I have a question that may seem silly, but it's worth asking. I'm attempting to create a sticky div element that stays in place when you scroll past a certain point on the page. This is the script I have: <script type="text/javascript"> ...

jQuery cannot access a hidden CSS property

I'm working on a form for my new project and have assigned the same class to all input fields. In my CSS file, I've set the text to be capitalized and it displays correctly. However, when I use jQuery's .val() to get the value of the field, ...

Guide on updating a variable to the following string within an array

Snippet: months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October&apos ...

Working with HTTPS in Angular: A guide to using $http

Can anyone provide guidance on how to handle https + cross-domain URL using $http? I managed to solve my issue using $.ajax, but I prefer using $http because I have an $http interceptor set up to automate certain processes. I've checked out related ...

Is there a way to customize the ripple effect color on a Button?

As I'm exploring the API (v3.9.2), I have noticed a reference to TouchRippleProps for ButtonBase on https://material-ui.com/api/button-base/ The code for my button is as follows: <Button variant="text" size={"large"} ...

What could be causing my Jquery fade effect to not function properly?

I'm new to incorporating Jquery into my website and I'm facing an issue with getting the first row of pictures to fade in (upwards) when scrolling. Despite my efforts, they are not behaving as expected. Any guidance on how to resolve this? HTML: ...

Enhancing Rails: Tailoring the flash message to suit individual needs

I am embarking on my journey with ruby on rails and could use some guidance with the following scenario. In the application.html.erb file, flash messages are configured to fade out after a few seconds by default. <div id="message" class="modal alert a ...

When on a touch screen, event.relatedTarget will be null during a focusout event

When working with a textarea, I am trying to use the focusout event to capture the value of the clicked button that triggered the focusout, so I can later click it after some processing. This solution is effective on most devices, but I am encountering iss ...

JavaScript: Selecting parent elements using getElementsByClassName

I am dealing with the following HTML code: <div class="item"> <img class="item-image" src="${item.getImage()}"/> <p>${item.getName()}</p> </div> and JavaScript: var classname = document.getElementsByClassName("item" ...

How can TypeORM be used to query a ManyToMany relationship with a string array input in order to locate entities in which all specified strings must be present in the related entity's column?

In my application, I have a User entity that is related to a Profile entity in a OneToOne relationship, and the Profile entity has a ManyToMany relationship with a Category entity. // user.entity.ts @Entity() export class User { @PrimaryGeneratedColumn( ...

Ways to show text on a donut chart when hovering with the mouse

I have been attempting to make adjustments to this sample. My goal is to display a word in the center of the donut chart upon mouseover, similar to this: https://i.sstatic.net/dCPKP.png Although I have included code for mouseover, it seems to not be func ...

You can use AJAX, JQuery, or JavaScript in PHP to upload a total of 7 files by utilizing 7 individual file input

My client has a unique request - they want to be able to upload a file in PHP without using the traditional <form> tag or a submit button. While I am familiar with file uploads in PHP, I am unsure of how to achieve this without utilizing the <for ...

Display thumbnail images in jquery-ui dropdown menu

Hello, I'm looking to display a small image (the user's thumbnail) on the jquery-ui dropdown by making an ajax call. As someone new to ajax and unfamiliar with jquery-ui, I would appreciate some guidance in the right direction. Thank you! HTML/J ...

Encountered a snag while executing Powershell with Selenium: Error message - unable to interact with

Looking to update a textarea with a value? The script below triggers an error stating "element not interactable". This occurs because the textarea is set to "display:none". However, manually removing the "NONE" word allows the script to successfully set th ...

I have a task that requires me to click on the 'OK' button within an ALERT pop-up while using Selenium on Internet Explorer

Clicking on the 'OK' button from an alert on Internet Explorer seems to be giving me trouble. I've attempted using drive.switch_to.alert().accept()/.send_keys(Keys.ENTER) with Selenium Webdriver in Python, but it doesn't seem to be work ...

choose multiple elements from an array simultaneously

Looking for help with a basic Array question and seeking the most effective solution. The scenario involves having an array: var pathArr = [element1, element2, element3, element4, element5, element6] If I want to select multiple elements from this array ...

Understanding how to deduce parameter types in TypeScript

How can I infer the parameter type? I am working on creating a state management library that is similar to Redux, but I am having trouble defining types for it. Here is the prototype: interface IModel<S, A> { state: S action: IActions<S, A&g ...

Prevent vertical scrolling on touch devices when using the Owl Carousel plugin

Is there a way to prevent vertical scrolling on Owl Carousel when dragging it horizontally on touch devices? It currently allows for up and down movement, causing the whole page to jiggle. If anyone has a solution, I can share the JavaScript file. Appreci ...

core.js:12853 Error encountered when trying to use 'ngIf' on a 'div' element that is not recognized as a valid property

I am currently utilizing Angular 9. and I am faced with a scenario where I need to load dynamic components Within one of my components, I encountered the following warning core.js:12853 Can't bind to 'ngIf' since it isn't a known pro ...

What steps are necessary to add a Contact Us form to my HTML website?

Currently, I am searching for a way to add a "Contact Us" section to my website that is completely HTML-based. I believe the best approach would involve using a PHP script to handle sending emails from a form on the Contact Us page, but I am not familiar ...