'Smoother' JavaScript 键盘输入?



所以我正在制作这个JetPack JoyRide的仿制品,我希望精灵在我按住空格键时向上移动,然而,当我开始按住它时会有一个滞后,它会向上移动并暂停几分钟,然后它才开始向上飞,

function playerInput (e)//keydown
{
//if (e.repeat) return;
if (e.keyCode == "32")
{
if(!(hitTop() || pause))
{
player.y -= 10;
flying = true;
}
}
}
function playerInput2(e){//keyup
if(e.keyCode == "32"){
if(!pause){
flying = false;
}

}
}

以下是整个JS代码:

let canvas;
let ctx;
let buffer;
let flying = false;
let player;
let gravity = 5;
let acc = 0.1;
let scrollspeed = 5;
let backx = 0;
let pause = false;
class Player {
constructor(x, y, imageSource){
this.x = x;
this.y = y;
this.ship = new Image();
this.ship.src = imageSource;
}
}
class MovingBack {
constructor(x, y, imageSource){
this.x = x;
this.y = y;
this.back = new Image();
this.back.src = imageSource;
}
}


function initBackground(){
//set backround color of canvas to gray
ctx.fillStyle = 'silver';
}
function initElements(){
//create canvas element
canvas = document.createElement("canvas");
//set canvas size
canvas.width = 1280;
canvas.height = 720;
//get context of canvas
ctx = canvas.getContext("2d");
buffer = canvas.getContext("2d");
//append canvas to body
document.body.appendChild(canvas)
}
function drawBackground () {
//decorate your background
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function playerInput (e)//keydown
{
//if (e.repeat) return;
if (e.keyCode == "32")
{
if(!(hitTop() || pause))
{
player.y -= 10;
flying = true;
}
}
else if (e.keyCode == "27")
{
pause = !pause;
console.log("esc");
}
}
function playerInput2(e){//keyup
if(e.keyCode == "32"){
if(!pause){
flying = false;
}

}
}
function hitBottom(){
let rockbottom = canvas.height - 40;
if(player.y >= rockbottom){
player.y = rockbottom;
return 1;
}
else
{
return 0;
}
}
function hitTop(){
let top = 0;
if(player.y <= top){
player.y = top;
return 1;
}
else {
return 0;
}
}
function update(){
if(!hitBottom() && flying == false)
{

player.y += gravity * acc;
acc += 0.03;
}
else {
acc = 0.1;
}
backx += scrollspeed;
}
function drawPlayer () {
//draw player spaceship at current location
buffer.drawImage(player.ship, player.x-20, player.y, 40, 40)
}

function drawBackground1 (){
buffer.drawImage(backround1.back, 0 + backx,0, 1280 + backx , 720 ,  0 , 0 , 1280, 720);
}

function draw () {
//do
//  {

if(!pause)
{
update();
}

drawBackground();
drawBackground1();

drawPlayer();
//drawEnemies();

window.requestAnimationFrame(draw);

//}while(pause == false);
}
function init () {
document.addEventListener('keydown', playerInput);
document.addEventListener('keyup', playerInput2);
initElements();
initBackground();
player = new Player(canvas.width/2, canvas.height-40, "ship.png");//"https://cdn.onlinewebfonts.com/svg/img_3969.png");
backround1 = new MovingBack(0,0, "back1.jpg");
//start game

draw();



}

CCS:

canvas {
margin: auto;
display: block;
}

HTML:

<!DOCTYPE html>
<html>
<head>
<title>Simple animation example</title>
<link rel=stylesheet href="game.css">
<script src="game.js"></script>
<script src="game2.js"></script>
</head>
<body onload="init()">
</body>
</html>

一些东西一些东西

可能只是将飞行的位置更新放在更新功能中。测试一下我自己,这真的很顺利

function update(){

if(!hitBottom() && flying == false)
{

player.y += gravity * acc; 
acc += 0.03;
}
else {
player.y += gravity * acc; 
acc = -0.3;
}
backx += scrollspeed;

}

function playerInput (e)//keydown
{
//if (e.repeat) return;
if (e.keyCode == "32")
{
if(!(hitTop() || pause || flying))
{
//player.y = player.y - 10;
flying = true;
console.log("flying")
}
}
else if (e.keyCode == "27")
{
pause = !pause;
console.log("esc");
}
}
function playerInput2(e){//keyup
if(e.keyCode == "32"){
if(!pause && flying){
flying = false;
console.log("not flying")
}

}
}

将按钮状态存储在地图中

const isKeyDown = Array(255).fill(false);
onkeydown = onkeyup = (e) => {
isKeyDown[e.keyCode] = e.type === "keydown";
};

并在更一致的间隔(如requestAnimationFrame(内使用该映射来移动角色。

const RIGHT = 39;
const LEFT = 37;
const UP = 38;
const DOWN = 40;
const MAX_VELOCITY = 25;
const ACCELLERATION = 2;
const DRAG = .95;
const GRAVITY = 1;
const BOUNCE = .75;
const isKeyDown = Array(255).fill(false);
onkeydown = onkeyup = (e) => {
isKeyDown[e.keyCode] = e.type === "keydown";
// so SO doesn't start to scroll around
e.preventDefault(); 
};
let position = {
x: innerWidth / 2,
y: 0
};
let velocity = {
x: 0,
y: 0
};
const clamp = (value, min, max) => value > min ? value < max ? value : max : min;
const ball = document.querySelector(".red");
function renderLoop() {
requestAnimationFrame(renderLoop);
const width = innerWidth - ball.offsetWidth;
const height = innerHeight - ball.offsetHeight;
velocity.x = clamp(
velocity.x * DRAG + (isKeyDown[RIGHT] - isKeyDown[LEFT]) * ACCELLERATION, 
-MAX_VELOCITY,
MAX_VELOCITY
);
velocity.y = clamp(
velocity.y * DRAG + GRAVITY + (isKeyDown[DOWN] - isKeyDown[UP]) * ACCELLERATION, 
-MAX_VELOCITY,
MAX_VELOCITY
);
position.x += velocity.x;
position.y += velocity.y;
if (position.x <= 0) {
position.x = -position.x;
velocity.x *= -BOUNCE;
}
if (position.x >= width) {
position.x = 2 * width - position.x;
velocity.x *= -BOUNCE;
}
if (position.y <= 0) {
position.y = -position.y;
velocity.y *= -BOUNCE;
}
if (position.y >= height) {
position.y = 2 * height - position.y;
velocity.y *= -BOUNCE;
}
ball.style.transform = `translate(${position.x}px, ${position.y}px)`;
}
renderLoop();
window.focus();
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
h1 {
text-align: center;
}
.red {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
background: red;
border-radius: 50%;
}
<div class="red"></div>
<h1>use Arrow Keys</h1>

最新更新