CodeInside
@CodeInside

Где ошибка в алгоритме Arkanoid?

На jsfiddle проект почему-то не запускается (пишет "Uncaught ReferenceError: ballMoving is not defined") поэтому подгружу исходники здесь:
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="reset.CSS">
	<link rel="stylesheet" href="style.css">
	<script src="jquery-3.1.0.min.js"></script>
</head>
<body>
	<div id="wrapper">
		<div id="blocks"></div>
		<div id="platform"></div>
		<div id="ball"></div>
	</div>
	<script>
		'use strict';

		var ball = new Object();
		var platform = new Object();
		var blocks = new Object();

		var settings = new Object();

		var x = 0, y = 0;

		document.addEventListener("DOMContentLoaded", function(event) {
			blocks = document.getElementById('blocks');

			setSettings();
			createBlocks();
			setPlatformStartingPosition();
			setBallStartingPosition();

			document.addEventListener("mousemove", function(event) {
				movePlatform(event.clientX);
			});
		});

		

		function movePlatform(clientX)	{
			if(platform.width() / 2 > clientX) {
				platform.css('left', '0px');
				return;
			}

			if($(window).width() - clientX < platform.width() / 2) {
				platform.css('left', $(window).width() - $("#platform").width() + 'px');
				return;
			}

			platform.css('left', (clientX - $("#platform").width() / 2) + 'px');
		}

		function setSettings()	{
			settings.numberOfRows = 5;
			settings.bHeight = 25;
			settings.bWidth = 50;
			settings.nBlocksInRow = Math.round($(window).width() / settings.bWidth);
			settings.topMargin = Math.round($(window).height() * 0.1);	// 10% of window height
			settings.leftMargin = Math.round(($(window).width() - (settings.nBlocksInRow * settings.bWidth)) / 2);
			if(settings.nBlocksInRow * settings.bWidth > $(window).width()) {
				settings.nBlocksInRow--;
				settings.leftMargin = Math.round(($(window).width() - (settings.nBlocksInRow * settings.bWidth)) / 2);
			}

			settings.bottomMargin = Math.round($(window).height() * 0.05);	// 5% of window height
			settings.ballDiameter = 20;
			settings.angle = 225;	// degrees; starting ball direction
			settings.alpha = Math.PI * settings.angle / 180;	// converting degrees to radians
			settings.d = 3;
		};

		function createBlocks()	{
			for(var i = 0; i < settings.numberOfRows; i++)
				for(var j = 0 ; j < settings.nBlocksInRow; j++) {
					var block = document.createElement('div');
					block.className = 'block';
					block.style.top = settings.topMargin + i * settings.bHeight + "px";
					block.style.left = settings.leftMargin + j * settings.bWidth + "px";
					block.style.height = settings.bHeight + "px";
					block.style.width = settings.bWidth + "px";
					blocks.appendChild(block);
				}
			};

			function setPlatformStartingPosition()	{
				platform = $('#platform');
			platform.css('top', Math.round($(window).height() - settings.bottomMargin - 15) + "px");	// 15 - height of platform
			platform.css('left', Math.round(($(window).width() - 125) / 2) + "px");	// 125 - width of platform
		};

		function setBallStartingPosition()	{
			ball = $('#ball');
			ball.css('top', Math.round($(window).height() - settings.bottomMargin - ball.height() - 15) + "px");	// 15 - height of platform
			ball.css('left', Math.round(($(window).width() - 62.5) / 2) + "px");	// 62.5 - half of platform width

			x = ball.position().top;
			y = ball.position().left;
		};

		var ballMovingInterval = setInterval("ballMoving()", 10);

		function ballMoving()	{
			console.log("x = " + x);
			console.log("y = " + y);
			//console.log("p.top = " + platform.position().top);
			console.log("p.left = " + platform.position().left);

			if (x < 0 || x + settings.ballDiameter > $(window).width())
				settings.alpha = Math.PI - settings.alpha;

			if (y < 0 )
				settings.alpha = -(settings.alpha);

			if(	y + settings.ballDiameter >= platform.position().top &&
			 	x + settings.ballDiameter / 2 >= platform.position().left && 
			 	x + settings.ballDiameter / 2 <= platform.position().left + platform.width()) {
				settings.alpha = -(settings.alpha);
				settings.alpha = Math.PI - settings.alpha;
				console.log("------------------------------------------------");
			}
			
			if(y > $(window).height() - settings.ballDiameter)	{
				alert("Game over!");
				clearInterval(ballMovingInterval);
			}

			var dx = settings.d * Math.cos(settings.alpha);
			var dy = settings.d * Math.sin(settings.alpha);
			x += dx;
			y += dy;
			ball.css('top', x + "px");
			ball.css('left', y + "px");
		}
	</script>
</body>
</html>


body {
	background: #F2F3E1;
}

#ball {
	border-radius: 50%;
	background: #FEAB07;
	position: absolute;
	height: 20px;
	width: 20px;
}

.block {
	background: #FA365E;
	border: black solid 1px;
	box-sizing: border-box;
	position: absolute;
}

#platform {
	background: #57DBCE;
	position: absolute;
	height: 15px;
	width: 125px;
}


Проблема в том что мяч просто пролетает мимо платформы (ракетки). За то чтобы он отбивался отвечает фрагмент кода который начинается на 117 строке:
if(	y + settings.ballDiameter >= platform.position().top &&
			 	x + settings.ballDiameter / 2 >= platform.position().left && 
			 	x + settings.ballDiameter / 2 <= platform.position().left + platform.width()) {
				settings.alpha = -(settings.alpha);
				settings.alpha = Math.PI - settings.alpha;
			}


Если убираю проверку на правую границу платформы:
if(	y + settings.ballDiameter >= platform.position().top &&
			 	x + settings.ballDiameter / 2 >= platform.position().left ) {
				settings.alpha = -(settings.alpha);
				settings.alpha = Math.PI - settings.alpha;
			}

... то мяч каждый раз отбивается на разной (очень разной) высоте. Может заметили, веду лог координат мяча и платформы, но полученные данные в этом логе очень странные. Никак не могу решить эту проблему. Поможете?
  • Вопрос задан
  • 260 просмотров
Пригласить эксперта
Ответы на вопрос 1
lazalu68
@lazalu68
Salmon
1. Не ошибка, но это
var ballMovingInterval = setInterval("ballMoving()", 10);
стоит поменять на
var ballMovingInterval = setInterval(ballMoving, 10);


2. y > $(window).height() - settings.ballDiameter - условие неправильно
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы