Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.01.2020, 17:08
Новичок на форуме
Отправить личное сообщение для AndrewMaximum Посмотреть профиль Найти все сообщения от AndrewMaximum
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 17.01.2020, 04:26
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Утечка памяти. У тебя addEventListener() в бесконечном цикле находится. При том, что addEventListener() не заменяет предыдущий обработчик, а прибавляет следующий:
for (var i = 0; i < 3; i++) addEventListener('click', function(e) { alert(e.type) });
document.body.click();

requestAnimationFrame() вызывается около 60 раз в секунду, вот и считай, 60 раз вызывается game.update(), 8 раз вызывается game.isDown(), 2 раза вызывается addEventListener(), за 30 секунд это 30 * 60 * 8 * 2 = 28800 обработчиков событий добавлено.

Последний раз редактировалось Rise, 17.01.2020 в 04:39.
Ответить с цитированием
  #3 (permalink)  
Старый 17.01.2020, 07:40
Новичок на форуме
Отправить личное сообщение для AndrewMaximum Посмотреть профиль Найти все сообщения от AndrewMaximum
 
Регистрация: 10.01.2020
Сообщений: 2

Спасибо, очень помогли!
Ответить с цитированием
  #4 (permalink)  
Старый 17.01.2020, 16:12
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

AndrewMaximum,
Есть еще косяки.
1. строки 6-14 бессмысленны, достаточно только body margin 0.
2. full это строка наверное, значит так 'full'.
3. строки 34-35 cnv.setAttribute('width',...) можно просто так cnv.width = ....
4. строки 37-39 color и texture можно объединить в слово background и назначить его в cnv.style.background.
5. строки 50-52 надо всего лишь написать if (_Game.clear) ctx.clearRect(0,0,cnv.width,cnv.height).
6. строки 90-106 наверно не нужны кроме 104-105 которые перенести куда-нибудь, попутно можно сократить:
- addEventListener('keydown',function(e){_Game.keys[e.code] = true});
- addEventListener('keyup',function(e){_Game.keys[e.code] = false});
потом проверяется так if(game.keys.KeyW){...}, if(game.keys.ArrowLeft){...}.

Последний раз редактировалось Rise, 17.01.2020 в 16:22.
Ответить с цитированием
  #5 (permalink)  
Старый 31.07.2022, 15:57
Новичок на форуме
Отправить личное сообщение для Andrea24000 Посмотреть профиль Найти все сообщения от Andrea24000
 
Регистрация: 31.07.2022
Сообщений: 4

Rise,
Здаров, а что делать если допустим есть одна анимация на requestAnimationFrame, но при клике на кнопку я её пытаюсь вырубить с помощью cancel Animationframe и ниже вызываю функцию с новым requestAnimationFrame и эта функция начинает тормозить и страница зависает. Что делать?
Ответить с цитированием
  #6 (permalink)  
Старый 31.07.2022, 16:00
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Andrea24000,
где код?
Ответить с цитированием
  #7 (permalink)  
Старый 31.07.2022, 16:17
Новичок на форуме
Отправить личное сообщение для Andrea24000 Посмотреть профиль Найти все сообщения от Andrea24000
 
Регистрация: 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))
            }
        }
        
    }
}
Ответить с цитированием
  #8 (permalink)  
Старый 31.07.2022, 16:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Andrea24000,
функция play 119 бесконечно ставит обработчики 202, что-то не так у вас с логикой.

плюс двойной запуск одного и того же, 117 и 238 , ещё 73 и 109.
Ответить с цитированием
  #9 (permalink)  
Старый 31.07.2022, 17:39
Новичок на форуме
Отправить личное сообщение для Andrea24000 Посмотреть профиль Найти все сообщения от Andrea24000
 
Регистрация: 31.07.2022
Сообщений: 4

рони,
202 строка, там обработчик события мыши, получает координаты мыши и заставляет платформу в арканойде двигаться за этими координатами. Не знаете что можно сделать вместо этого?
Ответить с цитированием
  #10 (permalink)  
Старый 31.07.2022, 18:10
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Andrea24000,
искать canvas mousemove animation tutorial
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Тормозит неактивный кусок кода. kuksha Общие вопросы Javascript 6 25.03.2015 12:38
Nodejs v0.10.15 тормозит под Windows 8 devataatman AJAX и COMET 0 14.08.2013 22:24
как узнать какой скрипт тормозит Артем125 Events/DOM/Window 4 22.09.2012 02:32
JavaScript на Яндекс.Фотки - почему тормозит браузеры? ZavFirefox Javascript под браузер 23 27.09.2009 19:24
тормозит в IE olgatcpip Internet Explorer 6 08.07.2009 01:29