Показать сообщение отдельно
  #1 (permalink)  
Старый 20.10.2017, 23:31
Новичок на форуме
Отправить личное сообщение для igdev Посмотреть профиль Найти все сообщения от igdev
 
Регистрация: 20.10.2017
Сообщений: 7

Обработка событий
Пишу небольшую игрушку. Суть ее заключается в том, что муха "летает" по экрану пользователя (движение задается кривыми Безье),
а пользователь должен ее "прибить" мышкой при этом не давая мухе "сесть", т.е. остановить свое движение.
Если муха села, игра завершается.

Собственно, ближе к делу. Трудность возникает в том, как обработать такое событие.
Текущее координаты мухи на экране вычисляются в цыкле:
for(var i = 0; i <= shift && flag; i += step)
{
	secondFlag = true;
	var coord = formula.getPointOnCurve(i, points);
		
	context.clearRect(0, 0, 1000, 1000);		
	context.drawImage(picture, coord[0], coord[1]);
			
	canvas.addEventListener('mousemove', function(evt) 
	{
		var mousePos = getMousePos(evt);
					
						
		if (Math.abs(mousePos.x - coord[0]) <= 7 && Math.abs(mousePos.y - coord[1]) <= 7)
		{
			cancelAnimationFrame(myReq);
			context.clearRect(0, 0, 1000, 1000);
			context.drawImage(badPicture, coord[0], coord[1]);
			pushScore(score++);
			flag = false;
		}
					
	});
}


Т.е. здесь вычисляются текущее координаты мухи и координаты мышки, если они совпадают, то муху "убиваем".
Однако такой подход очень плохой, т.к. при нескольких вызовов функции полета мухи, игра начинает лагать.

Прошу помощи, совета, как можно оптимизировать данное решение, чтобы оно соответсвовало начальным требования, которые я описал выше.

Вот полностью код:
window.onload = function() {
	
	window.requestAnimationFrame = window.requestAnimationFrame
                               || window.mozRequestAnimationFrame
                               || window.webkitRequestAnimationFrame
                               || window.msRequestAnimationFrame
                               || function(f){return setTimeout(f, 1000/60)}

	window.cancelAnimationFrame = window.cancelAnimationFrame
                              || window.mozCancelAnimationFrame
                              || function(requestID){clearTimeout(requestID)} //fall back
	
	var canvas = document.getElementById('bezier');
	var context = canvas.getContext('2d');
	
	
	var formula = {};


		
	formula.getPointOnLine = function(shift,points){
		return [
			(points[1][0] - points[0][0]) * (shift / 100) + points[0][0],
			(points[1][1] - points[0][1]) * (shift / 100) + points[0][1]
		];
	};

	formula.getPointOnCurve = function(shift,points){
		if(points.length == 2){
			return this.getPointOnLine(shift,points);
		}
		var pointsPP = [];
		for(var i = 1;i < points.length;i++){
			pointsPP.push(this.getPointOnLine(shift,[
				points[i - 1],
				points[i]
			]));
		}
		return this.getPointOnCurve(shift,pointsPP);
	};

		

	function getCoordinates()
	{
		var max = 650;
		var min = -150;
			
		return Math.floor(Math.random() * (max - min + 1) + min);
	}
	
	
	var score = 0;
	var life = 3;
	var myReq;
	var flag = true;
	var secondFlag = false;
	
	var started = false;
	var running = false;
	
	
	
	function pushScore(scores)
	{
		var value = document.getElementById("sixthTd");
        value.innerHTML = "Score: " + scores;
	}
	
	function pushLife(lifes)
	{
		var value = document.getElementById("fourthTd");
		value.innerHTML = "Life: " + lifes;
	}

	
	
	
	var picture = new Image();
	picture.src = "../images/Mosca_ON.gif";
		
	var badPicture = new Image();
	badPicture.src = "../images/Mosca_OFF.gif";
	
	
	
	var points = [];
		
		function generateCoords()
		{
			var valueXPoint = Math.floor(Math.random() * (700 - 100 + 1) + 100);
			var valueYPoint = Math.floor(Math.random() * (700 - 100 + 1) + 100);
			points = [
				[valueXPoint, valueYPoint],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[getCoordinates(), getCoordinates()],
				[valueXPoint, valueYPoint]
		];
		}
		
		var shift = 0;
		var step = 1;
		
	function getMousePos(evt)
	{
		//set and store..
		priorEvt = evt = evt || priorEvt;
		//get the bounding rectangle
		var rect = canvas.getBoundingClientRect();
		//lastly, return the x and y coordinates
		if (evt)
			return {
				x: evt.clientX - rect.left,
				y: evt.clientY - rect.top
			};
		return {
			x: 0,
			y: 0
		};
	}
	
	function stop()
	{
		running = false;
		started = false;
		cancelAnimationFrame(myReq);
	}
	
	function mainLoop(timestamp) {
		if (timestamp >= 2500.0)
		{
			
			stop();
			return;
		}
		
		myReq = requestAnimationFrame(mainLoop);
	}
	
	function start()
	{
		if(!started)
		{
			started = true;
			generateCoords();
			myReq = requestAnimationFrame(function (timestamp){
				draw(1);
				running = true;
				myReq = requestAnimationFrame(mainLoop);
			});
		}
	}
	
	function newGame()
	{
		stop();
		secondFlag = false;
		flag = true;
		start();
	}
	
	function draw(timestamp)
	{
		
		context.beginPath();
			
		
		
		if(shift > 100){
			shift = 100;
		}
			
				

		for(var i = 0; i <= shift && flag; i += step)
		{
			secondFlag = true;
			var coord = formula.getPointOnCurve(i, points);
		
			context.clearRect(0, 0, 1000, 1000);		
			context.drawImage(picture, coord[0], coord[1]);
			
			canvas.addEventListener('mousemove', function(evt) 
			{
				var mousePos = getMousePos(evt);
					
						
				if (Math.abs(mousePos.x - coord[0]) <= 7 && Math.abs(mousePos.y - coord[1]) <= 7)
				{
					cancelAnimationFrame(myReq);
					context.clearRect(0, 0, 1000, 1000);
					context.drawImage(badPicture, coord[0], coord[1]);
					pushScore(score++);
					flag = false;
				}
					
				});
		}
		
		
		if (flag == false)
			newGame();
		
			
		context.stroke();	
		context.closePath();

		if(shift <= 100){
			shift += step;
		}
		
		requestAnimationFrame(draw);
		console.log(timestamp);
	
	}
	
	start();
	pushScore(score);
	pushLife(life);
}


<canvas id = "bezier" width = "700" height = "1000"></canvas>
Ответить с цитированием