16.01.2020, 17:08
|
Новичок на форуме
|
|
Регистрация: 10.01.2020
Сообщений: 2
|
|
Тормозит requestAnimationFrame
Пишу что-то вроде движка для игры.
При использовании (30 и более секунд), анимация начинает тормозить.
Это можно увидеть если перемещать стрелками один из объектов.
Сам код:
--------Движок-----------
var D = document;
var full;
var cnv = D.createElement('canvas');
var ctx = cnv.getContext("2d");
cnv.style.padding = 0;
cnv.style.margin = 0;
cnv.style.position = "fixed";
D.getElementsByTagName('html')[0].style.width = '100%';
D.getElementsByTagName('html')[0].style.height = '100%';
D.getElementsByTagName('html')[0].style.overflow = 'hidden';
D.body.style.width = "100%";
D.body.style.height = "100%";
function Game (){
'use strict'
this.setMap = function(posx,posy,width,height,color,texture){
this.HEIGHT = height;
this.WIDTH = width;
cnv.style.top = posy+"px";
cnv.style.left = posx+"px";
this.keys = {};
if(width == full){cnv.setAttribute('width',innerWidth)}else{cnv.setAttribute('width',this.WIDTH)};
if(height == full){cnv.setAttribute('height',innerHeight)}else{cnv.setAttribute('height',this.HEIGHT)}
if(texture && !color){cnv.style.backgroundImage = "url('"+texture+"')"}
else if(!texture && color){cnv.style.backgroundColor = color};
cnv.style.background = color;
D.body.appendChild(cnv);
};
var _Game = this;
this.clear = true;
var engine = function(){
if(_Game.clear == true){if(_Game.WIDTH == full && _Game.HEIGHT != full){ctx.clearRect(0,0,innerWidth,_Game.HEIGHT)}
else if(_Game.WIDTH != full && _Game.HEIGHT == full){ctx.clearRect(0,0,_Game.WIDTH,innerHeight)}
else{ctx.clearRect(0,0,innerWidth,innerHeight)}};
_Game.update();
requestAnimationFrame(engine);
};
this.start = function(){
engine();
};
this.Rect = function(param){
this.width = param.width;
this.height = param.height;
this.x = param.x;
this.y = param.y;
this.color = param.color;
};
this.Rect.prototype = {
draw:function(){
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
}
};
this.delKey = function(name){
delete _Game.keys[name];
};
this.newKey = function(param,param2){
this.code = param;
this.name = param2;
_Game.keys[this.name] = this.code;
_Game.keys[this.name + "_isPressed"] = false;
};
this.isDown = function(name){
addEventListener('keydown',function(e){if(_Game.keys[name] == e.keyCode){_Game.keys[name+"_isPressed"] = true}},false);
addEventListener('keyup',function(e){if(_Game.keys[name] == e.keyCode){_Game.keys[name+"_isPressed"] = false}},false);
if(_Game.keys[name+"_isPressed"]==true){return true};
};
};
---------тестовое поле------------
window.onload = function(){
var game = new Game();
game.setMap(0,0,full,full,"#2F2B2B");
var cube = new game.Rect({
x:20,y:20,
width:100,
height:100,
color:"black",
});
var cube2 = new game.Rect({
x:100,y:200,
width:40,
height:40,
color:"lightblue",
});
var player = new game.Rect({
x:500,y:500,
width:30,
height:30,
color:"red",
});
var player2= new game.Rect({
x:500,y:500,
width:30,
height:30,
color:"green",
});
game.newKey(87,"W");
game.newKey(65,"A");
game.newKey(83,"S");
game.newKey(68,"D");
game.newKey(37,"left");
game.newKey(39,"right");
game.newKey(40,"down");
game.newKey(38,"up");
game.update = function(){
if(game.isDown("up")){player2.y -=2};
if(game.isDown("down")){player2.y +=2};
if(game.isDown("right")){player2.x +=2};
if(game.isDown("left")){player2.x -=2};
if(game.isDown("W")){player.y -=2};
if(game.isDown("A")){player.x -=2};
if(game.isDown("S")){player.y +=2};
if(game.isDown("D")){player.x +=2};
cube.draw();
cube2.draw();
player.draw();
player2.draw();
};
game.start();
console.log(game.keys["W_isPressed"]);
console.log(game.keys["A_isPressed"])
}
index.html - минимальный, вот:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript"src = "core.js"></script>
<script type="text/javascript"src = "test.js"></script>
</body>
</html>
управление: объект1 - W,S,A,D;
объект2 - стрелки;
подскажите пожалуйста, в чем может быть проблема.
Последний раз редактировалось AndrewMaximum, 16.01.2020 в 17:33.
|
|
17.01.2020, 07:40
|
Новичок на форуме
|
|
Регистрация: 10.01.2020
Сообщений: 2
|
|
Спасибо, очень помогли!
|
|
31.07.2022, 15:57
|
Новичок на форуме
|
|
Регистрация: 31.07.2022
Сообщений: 4
|
|
Rise,
Здаров, а что делать если допустим есть одна анимация на requestAnimationFrame, но при клике на кнопку я её пытаюсь вырубить с помощью cancel Animationframe и ниже вызываю функцию с новым requestAnimationFrame и эта функция начинает тормозить и страница зависает. Что делать?
|
|
31.07.2022, 16:00
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Andrea24000,
где код?
|
|
31.07.2022, 16:17
|
Новичок на форуме
|
|
Регистрация: 31.07.2022
Сообщений: 4
|
|
рони,
let canv = document.getElementById("canv")
ctx = canv.getContext("2d")
doc = document.documentElement
// ширина и высота canvas
wth = canv.width = 500
height = canv.height = 500
// ширина прямоугольника
x = 250
y = 440
dx = 5
dy = 5
score = 0
timeOneFps = 1/60
fpsSec = 0
xPlayer = 250
clientX = 0
colorRed = 195
colorGreen = 195
colorBlue = 189
const songPlayerRect = new Audio("song/songPlayerRect.mp3")
const songBlockCrash = new Audio("song/songBlockCrash.mp3")
let coordinateArrX = []
coordinateArrY = []
arrWth = 50
arrHeight = 15
arrClearRect = []
timeArr = []
clicker = false
btnObj = {
btn1: {
x: 190,
y: 280,
w: 160,
h: 50
},
btn2: {
x: 170,
y: 220,
w: 200,
h: 75
}
}
const arrColor = ['red', 'green', 'blue', 'yellow', 'pink', 'mangeta', 'brown', 'cian', 'orange', 'white']
function random() {
const random = Math.round((Math.random() * 10))
return random
}
let x1 = 100
y1 = 200
dx1 = 2
dy1 = 2
requestId = null
checkRequest = 0
window.addEventListener('load', () => animationStart())
function animationStart(params) {
requestAnimationFrame(start)
function start() {
console.log(111);
ctx.clearRect(0, 0, wth, height)
ctx.beginPath()
ctx.fillStyle = "black"
ctx.fillRect(0, 0, 500, 500)
ctx.fillStyle = arrColor[random()]
ctx.font = "bold 50px sans-serif"
ctx.fillText("АРКАНОИД", x1, y1)
ctx.fillStyle = "yellow"
ctx.font = "bold 40px sans-serif"
createButtonReset(btnObj.btn2.x, btnObj.btn2.y, btnObj.btn2.w, btnObj.btn2.h)
ctx.fillStyle = "yellow"
ctx.fillText(`Играть`, 205, 270)
checkBtnColl(btnObj.btn2.x, btnObj.btn2.y, btnObj.btn2.w, btnObj.btn2.h, requestId)
x1 += dx1
y1 += dy1
if (x1 > 225 || x1 < -5) {
dx1 = -dx1
}
if (y1 > 500 || y1 < 40) {
dy1 = -dy1
}
if (!checkRequest) {
requestId = requestAnimationFrame(start)
}
}
start()
}
function animationPlay() {
requestAnimationFrame(play)
let requestId1 = null
function play() {
console.log(2);
createCoordinate()
init()
ctx.clearRect(0, 0, wth, height)
playingField.color = "black"
playingField.draw()
checkCollisionBlocks()
scoreSum()
timeGame()
playerRectangle.color = "rgb(139,69,19)"
playerRectangle.draw()
function Arc(x, y, radius, zeroDeg, endDeg, rew) {
x,
y,
radius,
zeroDeg,
endDeg,
rew
ctx.beginPath()
ctx.strokeStyle = "yellow"
ctx.arc(x, y, radius, zeroDeg, endDeg, rew)
ctx.fillStyle = "red"
ctx.fill()
ctx.lineWidth = 2
ctx.stroke()
}
createArc = new Arc(x, y, 5, 0, Math.PI * 2, false)
if (y + dy < 7) {
dy = -dy
}
if (x + dx > 497) {
dx = -dx
}
if (x + dx > 500 || x + dx < 7) {
dx = -dx
}
y += dy
x += dx
function checkCollisionPlayerBlock() {
if(x + dx >= playerRectangle.x && x + dx <= playerRectangle.x + 60 &&
y + dy >= playerRectangle.y - 3 && y + dy <= playerRectangle.y + 15) {
dy = -dy
songPlayerRect.play()
}
if(x > playerRectangle.x - 0.2 && x < playerRectangle.x + playerRectangle.width + 0.2 &&
y > playerRectangle.y && y < playerRectangle.y + playerRectangle.height) {
dx = -dx
dy = +dy
}
if(x + dx == playerRectangle.x && x + dx == playerRectangle.x + 60 &&
y + dy == playerRectangle.y - 3 && y + dy == playerRectangle.y + 15) {
dy = -dy
dx = -dx
songPlayerRect.play()
}
if(x < playerRectangle.x + 60 &&
y > playerRectangle.y && y < playerRectangle.y + 5) {
dx = +dx
dy = +dy
}
}
checkCollisionPlayerBlock()
canv.addEventListener("mousemove", function(event) {
xPlayer = event.clientX - ((doc.clientWidth - 500) / 2) - 30
if (xPlayer < 0) {
xPlayer = 0
}
if (xPlayer >= 440) {
xPlayer = 440
}
})
if (y > 500) {
gameOver()
}
if (score == 400) {
gameOver()
}
/* document.addEventListener("click", () => {
if(clicker == true) {
clicker = false
}else {
clicker = false
}
console.log(clicker);
})
if (clicker == true) {
paused()
cancelAnimationFrame(requestId)
}else {
requestAnimationFrame(draw)
} */
requestId1 = requestAnimationFrame(play)
}
play()
}
function createCoordinate(x, y, wth, height) {
for (let i = 0; i < 5; i += 1) {
for (let b = 0; b < 8; b++) {
coordinateArrX.push(10 + 60 * b)
}
}
for (let i = 0; i < 5; i++) {
for (let b = 0; b < 8; b++) {
coordinateArrY.push(25 + 20 * i)
}
}
}
function init() {
// фон игры
playingField = new Rectangle(0, 0, wth, height)
// первая строка блоков
createRectangle1 = new Rectangle(coordinateArrX[0], coordinateArrY[0], arrWth, arrHeight)
createRectangle2 = new Rectangle(coordinateArrX[1], coordinateArrY[1], arrWth, arrHeight)
createRectangle3 = new Rectangle(coordinateArrX[2], coordinateArrY[2], arrWth, arrHeight)
createRectangle4 = new Rectangle(coordinateArrX[3], coordinateArrY[3], arrWth, arrHeight)
createRectangle5 = new Rectangle(coordinateArrX[4], coordinateArrY[4], arrWth, arrHeight)
createRectangle6 = new Rectangle(coordinateArrX[5], coordinateArrY[5], arrWth, arrHeight)
createRectangle7 = new Rectangle(coordinateArrX[6], coordinateArrY[6], arrWth, arrHeight)
createRectangle8 = new Rectangle(coordinateArrX[7], coordinateArrY[7], arrWth, arrHeight)
playerRectangle = new Rectangle(xPlayer, 450, 60, 15)
}
function Rectangle(x, y, width, height) {
this.color = `rgb(${colorRed}, ${colorGreen}, ${colorBlue})`
this.x = x
this.y = y
this.width = width
this.height = height
this.draw = function() {
ctx.beginPath()
ctx.fillStyle = this.color
ctx.fillRect(this.x,
this.y,
this.width,
this.height)
ctx.stroke()
}
}
function scoreSum() {
ctx.beginPath()
ctx.fillStyle = "yellow"
ctx.textBaseline = "middle"
ctx.font = "bold 25px sans-serif"
ctx.fillText(`Счёт: ${score}`, 10, 15)
}
function timeGame() {
ctx.beginPath()
ctx.fillStyle = "yellow"
ctx.textBaseline = "middle"
ctx.font = "bold 25px sans-serif"
ctx.fillText(`Время: ${Math.round(fpsSec += timeOneFps)}`, 150, 15)
}
function gameOver() {
timeArr.push(fpsSec)
ctx.beginPath()
ctx.fillStyle = "black"
ctx.fillRect(0, 0, 500, 500)
ctx.fillStyle = "yellow"
ctx.font = "bold 25px sans-serif"
ctx.fillText("Game Over!!!", 190, 200)
ctx.fillText(`Счёт: ${score}`, 215, 230)
ctx.fillText(`Время: ${Math.round(timeArr[0])}`, 215, 260)
createButtonReset(btnObj.btn1.x, btnObj.btn1.y, btnObj.btn1.w, btnObj.btn1.h)
ctx.fillStyle = "yellow"
ctx.fillText(`Обновить`, 209, 305)
checkBtnColl(btnObj.btn1.x, btnObj.btn1.y, btnObj.btn1.w, btnObj.btn1.h)
}
function createButtonReset(x, y, w, h) {
x
y
w
h
let btn = new Rectangle(x, y, w, h)
btn.color = "red"
btn.draw()
}
function checkBtnColl(x, y, w, h, requestId) {
x
y
w
h
requestId
canv.addEventListener("click", (event) => {
if (event.clientX >= x && x + w <= event.clientX &&
event.clientY >= y && y + h <= event.clientY) {
delete x
animationPlay()
ctx.clearRect(0, 0, 500, 500)
checkRequest = 1
}
})
}
function checkCollisionBlocks() {
for (let i = 0; i < coordinateArrX.length; i++) {
for (let b = 0; b < coordinateArrY.length; b++) {
if (x + dx >= coordinateArrX[i] && x + dx <= coordinateArrX[i] + arrWth &&
y + dy >= coordinateArrY[i] - 3 && y + dy <= coordinateArrY[i] + arrHeight) {
dy = -dy
delete coordinateArrX[i]
delete coordinateArrX[i]
score += 10
songBlockCrash.play()
colorRed = Math.round((Math.floor(Math.random() * 100) * 2.5))
colorGreen = Math.round((Math.floor(Math.random() * 100) * 2.5))
colorBlue = Math.round((Math.floor(Math.random() * 100) * 2.5))
}
}
}
}
|
|
31.07.2022, 16:46
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Andrea24000,
функция play 119 бесконечно ставит обработчики 202, что-то не так у вас с логикой.
плюс двойной запуск одного и того же, 117 и 238 , ещё 73 и 109.
|
|
31.07.2022, 17:39
|
Новичок на форуме
|
|
Регистрация: 31.07.2022
Сообщений: 4
|
|
рони,
202 строка, там обработчик события мыши, получает координаты мыши и заставляет платформу в арканойде двигаться за этими координатами. Не знаете что можно сделать вместо этого?
|
|
31.07.2022, 18:10
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Andrea24000,
искать canvas mousemove animation tutorial
|
|
31.07.2022, 19:20
|
Новичок на форуме
|
|
Регистрация: 31.07.2022
Сообщений: 4
|
|
рони,
Спасибо, нашёл хорошую статью по этому всему на mdn, попробую переделать
|
|
|
|