'opóźniona cykliczność po wciśnięciu klawisza'

0

Robię ping ponga i mam problem z płynnością ruchu paletki. Czy mogę coś zrobić, by po wciśnięciu klawisza nie było tej krótkiej przerwy po pierwszym poruszeniu, tylko żeby chodziła ona płynnie?

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const cw = canvas.width;
const ch = canvas.height;
const ballSize = 20;
let ballX = cw / 2 - ballSize / 2;
let ballY = ch / 2 - ballSize / 2;
window.alert("Witaj w ping pongu! Uzyj klawiszy w i s by poruszac swoja paletka (po lewo). Twoim celem jest niedopuszczenie pilki na swoj kraniec planszy. Wygrywasz jesli zdobedziesz 21 punktow przed przeciwnikiem.");

const paletkaH = 100;
const paletkaW = 20;

const graczX = 10;
const aiX = 970;

const graczY = 200;
let aiY = 200;

const lineWidth = 6;
const lineHeight = 16;

let ballVx = 4;
let ballVy = 4;

let punkty1, punkty2;
punkty1 = punkty2 = 0;

const aiV = 3;

const paletka1 = {x:graczX, y:graczY, width:paletkaW, height:paletkaH};

paletka1.draw = function() {
	ctx.fillStyle = 'red';
	ctx.fillRect(this.x, this.y, this.width, this.height);
};

document.addEventListener('keydown', function(e){		//funkcja pozwalająca poruszać paletką
	e.preventDefault();
	if(e.code == "KeyW") paletka1.y -=8;
	else if(e.code == "KeyS") paletka1.y +=8;
	if (paletka1.y >= ch - paletkaH) {			//warunki, żeby paletka nie wychodziła poza stol
		paletka1.y = ch - paletkaH;
	}

	if (paletka1.y <= 0) {
		paletka1.y = 0;
	}
});

function ai() {							
	ctx.fillStyle = 'blue';
	ctx.fillRect(aiX, aiY, paletkaW, paletkaH);
	}

function reset(){				//przywraca stół do stanu początkowego
	ballX = cw / 2 - ballSize / 2;
	ballY = ch / 2 - ballSize / 2;
	paletka1.y = 200;
	aiY = 200;
	ballVx = -ballVx;
	if (ballVx < 0){
		ballVx = -4;
	}else{
		ballVx = 4;
	}
	ballVy = -ballVy;
	if (ballVy < 0){			//dodaje trochę różnorodności do rozgrywki
		ballVy += 4;
		if (ballVy > -1 && ballVy < 1)ballVy += 4; 
	}else{
		ballVy -= 4;
		if (ballVy > -1 && ballVy < 1)ballVy -= 4;
	}
}

function ball() {						//funckja generująca piłkę
	ctx.fillStyle = '#ffffff';
	ctx.fillRect(ballX, ballY, ballSize, ballSize);

	ballX += ballVx;
	ballY += ballVy;

	if (ballY <= 0 || ballY + ballSize >= ch) {		//piłka odbija sie od górnej i dolnej krawędzi
		ballVy = -ballVy;
		przyspiesz();
	}
	if (ballX <= graczX + paletkaW && ballY + ballSize >= paletka1.y && ballY <= paletka1.y + paletkaH){	//piłka odbija się od paletek
		ballVx = -ballVx;										
		przyspiesz();
	}
	if (ballX + ballSize >= aiX && ballY + ballSize >= aiY && ballY <= aiY + paletkaH){
		ballVx = -ballVx;
		przyspiesz();
	}
	if (ballX <= graczX + paletkaW && (ballY + ballSize < paletka1.y || ballY > paletka1.y + paletkaH)){	//plansza się resetuje i przeciwnik zdobywa punkt
		punkty2++;
		reset();
	}
	if (ballX + ballSize >= aiX && (ballY + ballSize < aiY || ballY > aiY + paletkaH)){			//plansza się resetuje i gracz zdobywa punkt
		punkty1++;
		reset();
	}
}

function stol() {				//rysuje stół do gry
	ctx.fillStyle = 'black';
	ctx.fillRect(0, 0, cw, ch);

	for (let linePosition = 20; linePosition < ch; linePosition += 30) {			//rysuje siatke na środku
        	ctx.fillStyle = "gray"
        	ctx.fillRect(cw / 2 - lineWidth / 2, linePosition, lineWidth, lineHeight)
	}

}


function przyspiesz() {					//przyspieszanie piłki po odbiciu
	if (ballVx > 0 && ballVx < 16) {
		ballVx += .08;

	} else if (ballVx < 0 && ballVx > -16) {
		ballVx -= .08;
	}

	if (ballVy > 0 && ballVy < 16) {
		ballVy += .08;

	} else if (ballVy < 0 && ballVy > -16) {
		ballVy -= .08;
	}

    }

function aiPozycja() {					//funkcja poruszająca przeciwnikiem
	if(aiY + paletkaH / 2 < ballY){			//jeśli piłeczka jest nad środkiem paletki przeciwnika,
		aiY += aiV;				// paletka porusza się w górę i na odwrót
	}else{
		aiY -= aiV;
	}
	if (aiY >= ch - paletkaH) {			//żeby przeciwnik nie wychodził poza stół
		aiY = ch - paletkaH
	}

	if (aiY <= 0) {
		aiY = 0;
	}
}

function game() {					//funkcja wywołująca naszą grę
	stol();
	ball();
	paletka1.draw();
	ai();
	aiPozycja();
	ctx.font = '45px serif';			//wyświetlanie wyników
	ctx.fillStyle = 'white';
	ctx.fillText(punkty1, 250, 80);
	ctx.fillText(punkty2, cw - 250, 80);
	if (punkty1 === 21){				//kto pierwszy dojdzie do 21 punktów wygrywa
		window.alert("Wygrales!");
		punkty1 = punkty2 = 0;
	}
	if (punkty2 === 21){
		window.alert("Przegrales!");
		punkty1 = punkty2 = 0;
	}
}

setInterval(game, 1000 / 60);				//odtwarzanie gry 60 klatek na sekunde
```js
1

Po wykryciu keydown odczytaj klawisz u ustaw sobie flagę kierunku, w którym przesuwa się paletka.
Zwiększanie / zmniejszanie paletka1.y realizuj sobie w ramach setInterval, najlepiej chyba w ramach funkcji game.
Po wykryciu keyup zeruj flagę kierunku.

1

requestAnimationFrame zamiast setInterval.

1 użytkowników online, w tym zalogowanych: 0, gości: 1