简体   繁体   中英

Measuring how long a Key is pressed using p5.js and JavaScript

I am trying to do some game development project with p5.js. Its really simple. Essentially I need to be able to go ontop of an object on a map, and press the space bar. When I press the space bar, I am basically immobile. However, it should take a certain amount of seconds for me to retrieve the object. Now, I am wondering what the best way to do this be without changing the functionality. So, if I am on top of the object, I press space bar I am meant to ensure that the key remains pressed down for approximately 5 seconds. Which would mean I have to start the timer somewhere, but im still not sure how to approach this. Examples using function KeyPressed(), KeyIsDown(), KeyReleased() would be helpful. Thank you

Edit: So currently, I have been thinking of using a counter (not that effective at all but it is what it is), but then I am thinking instead of looking at having a global timer.

Example Code:

`

function setup() {
  createCanvas(400, 400);
  
}

function draw() {
  background(220);
  let PickUpRate = 0
  push()
  let x = 100
  let y = 100
  let size = 64
  fill(100,63)
  //base
  rect(x-size/2, y-size/2-20,size,10);
  //health
  fill(0,220,0)
  rect(x-size/2, y-size/2-20,size*abs(PickUpRate)/100,10);
  pop()
}

function keyPressed(event){
  console.log(event.timeStamp)
}
function keyReleased(event){
  console.log(event.timeStamp)
}

`

https://editor.p5js.org/

This is what I have to work with so far, but I have to also increment my bar somehow using the timestamp? How should this be done?

You could use timestamps and/or application time to evaluate if a certain progress has been made.

I created a little snippet to demonstrate the thought on how to do it. This might not be the best solution but it should give you a hint in the right direction.

On KeyPressed -> Get Time.

While KeyIsDown -> Check whether the time holding the Button is equal to timeToPickUp, if not calculate progress as percent and update the progress bar.

As soon as the value reaches/exceeds 100, perform action and stop drawing the progress bar.

I never worked with p5js before, therefore the code is certainly not "production ready", but you get the idea.

 let timeToPickUp = 5000; //ms of time to pick up let startOfPickUp = 0; // var to save timeStamp to let progress = 0; // var to save progress value function setup() { createCanvas(400, 400); } function draw() { background(220); let PickUpRate = 0 push() let x = 100 let y = 100 let size = 64 fill(100,63) //base rect(x-size/2, y-size/2-20,size,10); //health fill(0,220,0) rect(x-size/2, y-size/2-20,size*abs(PickUpRate)/100,10); pop() if(keyIsDown(32)) { // Check if spacebar is pressed if(startOfPickUp > 0 && progress < 100) { // Don't draw if invalid progress = (millis() - startOfPickUp) / timeToPickUp * 100; //get progress //draw progress fill(255,0,0) rect(10, 350, progress, 25) if(progress >= 100) { console.log('do whatever is supposed to happen automatically'); } } } } function keyPressed(event){ startOfPickUp = millis() // get start } function keyReleased(event){ startOfPickUp = 0; // remove values when released progress = 0; }
 <script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>

Here's a quick proof of concept implementation using setTimeout:

 // class to encapsulate the progress tracking and meter updating class Progress { constructor(elem, duration = 2000, updateInterval = 50) { // the meter DOM element this.elem = elem; // the currently active timeout id this.timeoutId = null; // when progress tracking started this.startTime = null; // how long it takes to complete this.duration = duration; // how frequently to update the meter this.updateInterval = updateInterval; } start() { if (this.startTime) { // already running return; } // track when it started this.startTime = Date.now(); // start updating this.timeoutId = setTimeout(() => this.update(), this.updateInterval); } stop() { // cancel the timeout if it exists clearTimeout(this.timeoutId); // reset the meter css this.elem.style.setProperty('--complete', '0%'); this.elem.classList.remove('complete'); // clear our internal variables this.timeoutId = null; this.startTime = null; } update() { // compute the percentage complete based on start time and current time, and cap it at 100% const percentComplete = Math.min((Date.now() - this.startTime ?? Date.now()) / this.duration, 1) * 100; // set the css property used to do the fill this.elem.style.setProperty('--complete', `${percentComplete}%`); if (percentComplete >= 100) { // if we're at 100%, add the 'complete' class to the meter this.elem.classList.add('complete'); } else { // otherwise set up the next update this.timeoutId = setTimeout(() => this.update(), this.updateInterval); } } } // create an instance of Progress for our meter element const progress = new Progress(document.getElementById('meter')); // start on keydown document.body.addEventListener('keydown', () => { progress.start(); }) // stop on keyup document.body.addEventListener('keyup', () => { progress.stop(); })
 #meter { height: 20px; max-width: 200px; margin: 2rem auto; /* use a custom property 'complete' to fill the appropriate amount of the bar */ background: linear-gradient(90deg, var(--fillColor, limegreen) var(--complete, 0%), #eee var(--complete, 0%) 100%); } /* class and animation for flashing the box shadow upon completion */ .complete { animation: .1s ready infinite alternate; } @keyframes ready { from { box-shadow: 0 0 2px 4px red; } to { box-shadow: 0 0 0 0px red; } }
 <div id="meter"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM