Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 21.05.2017, 11:17
Новичок на форуме
Отправить личное сообщение для Sasha05082002 Посмотреть профиль Найти все сообщения от Sasha05082002
 
Регистрация: 07.05.2017
Сообщений: 8

Ответ на Rise:
Я извиняюсь, Я неправильно написал. Я думаю по этой картинке всё должно быть понятно.
Изображения:
Тип файла: jpg Безымянный.jpg (8.2 Кб, 6 просмотров)
Ответить с цитированием
  #12 (permalink)  
Старый 22.05.2017, 23:01
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Sasha05082002, исправил, и система координат теперь более адекватная, нарисовал, так удобнее размышлять об углах
Изображения:
Тип файла: jpg radians.jpg (57.2 Кб, 14 просмотров)
Ответить с цитированием
  #13 (permalink)  
Старый 23.05.2017, 17:36
Новичок на форуме
Отправить личное сообщение для Sasha05082002 Посмотреть профиль Найти все сообщения от Sasha05082002
 
Регистрация: 07.05.2017
Сообщений: 8

Благодарности Risе'у
Сппппппппппааааасссиииббо оо огромное Rise!!!! Я думаю что тема закрыта, осталось тока подробнее разобрать ваш код, и вопрос как тему закрыть то?

Последний раз редактировалось Sasha05082002, 23.05.2017 в 17:42.
Ответить с цитированием
  #14 (permalink)  
Старый 28.05.2017, 04:31
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Sasha05082002, никак, вот решил еще что-то написать но вовремя остановился получилось весьма интересно, особая гордость XBOT patrol - поворот по кратчайшему пути, движение по определенному маршруту (не)определенное число раз
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>TANK</title></head>
<body>
<style>
canvas { outline: 1px solid gray; }
canvas:hover { outline-color: red; }
pre { width: 600px; font: 12px/12px monospace; outline: 1px solid gray; margin: 0; }
</style>
Control: Mouse + AWDS (click to focus)
<pre></pre>
<canvas width="600" height="300" tabindex="1"></canvas>
<script>
/* Class Tank */

// constructor
function Tank(config) {
	for (var prop in config) {
		this[prop] = config[prop];
	}
}
// public members
Tank.prototype = {
	constructor: Tank,
	// default properties
	name: 'TANK',
	crew: 'empty',
	status: 1,
	pivotX: 100,
	pivotY: 100,
	headWidth: 50,
	headHeight: 40,
	headArrow: 10,
	headColor: '#aaaaaa',
	headAngle: 0,
	bodyWidth: 100,
	bodyHeight: 60,
	bodyArrow: 10,
	bodyColor: '#cccccc',
	bodyAngle: 0,
	stepAngle: Math.PI / 180,
	stepFactor: 1,
	// move methods
	bodyForward: function () {
		this.pivotX += Math.cos(this.bodyAngle) * this.stepFactor;
		this.pivotY += Math.sin(this.bodyAngle) * this.stepFactor;
		return this;
	},
	bodyBackward: function () {
		this.pivotX -= Math.cos(this.bodyAngle) * this.stepFactor;
		this.pivotY -= Math.sin(this.bodyAngle) * this.stepFactor;
		return this;
	},
	bodyLeft: function () {
		var angle = this.bodyAngle - this.stepAngle;
		this.bodyAngle = (angle < 0) ? angle + 2 * Math.PI : angle;
		return this;
	},
	bodyRight: function () {
		var angle = this.bodyAngle + this.stepAngle;
		this.bodyAngle = (angle < 2 * Math.PI) ? angle : angle - 2 * Math.PI;
		return this;
	},
	headLeft: function () {
		var angle = this.headAngle - this.stepAngle;
		this.headAngle = (angle < 0) ? angle + 2 * Math.PI : angle;
		return this;
	},
	headRight: function () {
		var angle = this.headAngle + this.stepAngle;
		this.headAngle = (angle < 2 * Math.PI) ? angle : angle - 2 * Math.PI;
		return this;
	},
	// frame methods
	update: function () {
		Tank.crew[this.crew].call(this);
		return this;
	},
	render: function () {
		var x1, y1, x2, y2;
		// body
		Context.save();
		Context.translate(this.pivotX, this.pivotY);
		Context.rotate(this.bodyAngle);
		Context.translate(-this.pivotX, -this.pivotY);
		x1 = this.pivotX - this.bodyWidth / 2;
		y1 = this.pivotY - this.bodyHeight / 2;
		x2 = x1 + this.bodyWidth;
		y2 = y1 + this.bodyHeight;
		// body polygon
		Context.beginPath();
		Context.moveTo(x1, y1);
		Context.lineTo(x2, y1);
		Context.lineTo(x2 + this.bodyArrow, this.pivotY);
		Context.lineTo(x2, y2);
		Context.lineTo(x1, y2);
		Context.fillStyle = this.bodyColor;
		Context.fill();
		Context.restore();
		// head
		Context.save();
		Context.translate(this.pivotX, this.pivotY);
		Context.rotate(this.headAngle);
		Context.translate(-this.pivotX, -this.pivotY);
		x1 = this.pivotX - this.headWidth / 2;
		y1 = this.pivotY - this.headHeight / 2;
		x2 = x1 + this.headWidth;
		y2 = y1 + this.headHeight;
		// head polygon
		Context.beginPath();
		Context.moveTo(x1, y1);
		Context.lineTo(x2, y1);
		Context.lineTo(x2 + this.headArrow, this.pivotY);
		Context.lineTo(x2, y2);
		Context.lineTo(x1, y2);
		Context.fillStyle = this.headColor;
		Context.fill();
		Context.restore();
		// status text
		if (this.status) {
			Context.fillText(this.name + '(' + this.crew + ')', this.pivotX, this.pivotY);
		}
		return this;
	},
	inform: function (x, y, Context) {
		Context.fillText(this.name + ':' +
			' X ' + this.pivotX.toFixed(2) +
			' Y ' + this.pivotX.toFixed(2) +
			' bA ' + this.bodyAngle.toFixed(5) +
			' hA ' + this.headAngle.toFixed(5) +
			' sA ' + this.stepAngle.toFixed(5) +
			' sF ' + this.stepFactor.toFixed(5), x, y);
		return this;
	}
};
// static members
// array of instances
Tank.base = [];
// crew methods
Tank.crew = {
	empty: function () {
		//console.log(this.name, this.crew);
	},
	player: function () {
		// input control
		if (Input.keys.left) {
			this.bodyLeft();
		}
		if (Input.keys.forward) {
			this.bodyForward();
		}
		if (Input.keys.right) {
			this.bodyRight();
		}
		if (Input.keys.backward) {
			this.bodyBackward();
		}
		// mouse control
		if (Mouse.follow) {
			Mouse.angle = Tank.math.hypotAngle(Mouse.x - this.pivotX, Mouse.y - this.pivotY);
			var angle = Tank.math.deltaAngle(Mouse.angle, this.headAngle);
			if (angle < 0) {
				this.headLeft();
			} else {
				this.headRight();
			}
			if (Math.abs(angle) - this.stepAngle < 0) {
				Mouse.follow = 0;
			}
		}
	},
	patrol: function () {
		// states: stop 0, init 1, turn 2, move 3
		if (this.routeState == 0) {
			//console.log('state', 0);
			if (this.routeIndex < this.routeArray.length) {
				this.routeState = 1;
			} else if (this.routeRound) {
				if (this.routeRound > 0) {
					this.routeRound--;
				}
				this.routeIndex = 0;
			}
		} else if (this.routeState == 1) {
			//console.log('state', 1);
			this.routePoint = this.routeArray[this.routeIndex++];
			var deltaX = this.routePoint[0] - this.pivotX;
			var deltaY = this.routePoint[1] - this.pivotY;
			this.routeHypot = Tank.math.hypot(deltaX, deltaY);
			this.routeAngle = Tank.math.hypotAngle(deltaX, deltaY);
			this.routeState = 2;
		} else if (this.routeState == 2) {
			//console.log('state', 2);
			var angle = Tank.math.deltaAngle(this.routeAngle, this.bodyAngle);
			if (angle < 0) {
				this.bodyLeft().headLeft();
			} else {
				this.bodyRight().headRight();
			}
			if (Math.abs(angle) - this.stepAngle < 0) {
				this.routeState = 3;
			}
		} else if (this.routeState == 3) {
			//console.log('state', 3);
			this.bodyForward();
			this.routeHypot -= this.stepFactor;
			if (this.routeHypot < 0) {
				this.routeState = 0;
			}
		} else {
			this.routeIndex = 0;
			this.routeState = 0;
		}
	}
};
// math methods
Tank.math = {
	hypot: function (deltaX, deltaY) {
		return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
	},
	hypotAngle: function (deltaX, deltaY) {
		// delta = point - pivot
		var angle = Math.atan2(deltaY, deltaX);
		if (angle < 0) {
			angle += 2 * Math.PI;
		}
		return angle;
	},
	deltaAngle: function (hypotAngle, pivotAngle) {
		var angle;
		if (hypotAngle < pivotAngle) {
			angle = pivotAngle - hypotAngle;
			if (angle < Math.PI) {
				angle = -angle;
			}
		} else {
			angle = hypotAngle - pivotAngle;
			if (angle > Math.PI) {
				angle = -angle;
			}
		}
		// -angle - left, +angle - right, |angle| - delta
		return angle;
	}
};

/* Input & Mouse & Output */

var Input = {
	// awds
	codes: { 65: 'left', 87: 'forward', 68: 'right', 83: 'backward' },
	// arrows
	//codes: { 37: 'left', 38: 'forward', 39: 'right', 40: 'backward' },
	keys: { left: 0, forward: 0, right: 0, backward: 0 },
	inform: function (x, y, Context) {
		Context.fillText('INPUT:' +
			' L ' + this.keys.left +
			' F ' + this.keys.forward +
			' R ' + this.keys.right +
			' B ' + this.keys.backward, x, y);
	}
};
var Mouse = {
	x: 0,
	y: 0,
	angle: 0,
	follow: 0,
	inform: function (x, y, Context) {
		Context.fillText('MOUSE:' +
			' X ' + this.x.toFixed(2) +
			' Y ' + this.y.toFixed(2) +
			' A ' + this.angle.toFixed(5) +
			' F ' + this.follow, x, y);
	}
};
var Output = {
	setContext: function (context, pre) {
		if (pre) {
			this.context = this;
			this.nodes = pre.childNodes;
			var count = 25;
			while (count--) {
				pre.appendChild(document.createTextNode(''));
			}
		} else {
			this.context = context;
		}
	},
	fillText: function (text, x, y) {
		this.nodes[y / 12].nodeValue = ' ' + text + '\n';
	}
};

/* Canvas & Context */

var Canvas = document.querySelector('canvas');
var Context = Canvas.getContext('2d');
Context.font = '12px monospace';
Context.fillText('Touch Me', Canvas.width / 2, Canvas.height / 2);

Output.setContext(Context, document.querySelector('pre'));

Canvas.addEventListener('mouseenter', onMouseenter);
Canvas.addEventListener('mouseleave', onMouseleave);
Canvas.addEventListener('mousemove', onMousemove);
Canvas.addEventListener('keydown', onKeydown);
Canvas.addEventListener('keyup', onKeyup);

/* Event Handlers */

function onMouseenter(e) {
	Canvas.focus();
	onAnimationFrame.id = requestAnimationFrame(onAnimationFrame);
}
function onMouseleave(e) {
	cancelAnimationFrame(onAnimationFrame.id);
}
function onMousemove(e) {
	Mouse.follow = 1;
	Mouse.x = e.offsetX;
	Mouse.y = e.offsetY;
}
function onKeydown(e) {
	var code = Input.codes[e.keyCode];
	if (code) {
		Input.keys[code] = 1;
	}
}
function onKeyup(e) {
	var code = Input.codes[e.keyCode];
	if (code) {
		Input.keys[code] = 0;
	}
}
function onAnimationFrame() {
	Context.clearRect(0, 0, Canvas.width, Canvas.height);
	var tank, tanks = Tank.base, index = tanks.length;
	while (index--) {
		tank = tanks[index];
		tank.update().render();
		tank.inform(5, 36 + 12 * index, Output.context);
	}
	Input.inform(5, 12, Output.context);
	Mouse.inform(5, 24, Output.context);
	onAnimationFrame.id = requestAnimationFrame(onAnimationFrame);
}

/* Tank Base Init */

Tank.base.push(
	new Tank({
		name: 'RISE',
		crew: 'player',
		pivotX: 250,
		pivotY: 150,
		headColor: '#666633',
		headAngle: 5 / 3 * Math.PI,
		bodyColor: '#999966',
		bodyAngle: 5 / 3 * Math.PI
	}),
	new Tank({
		name: 'XBOT',
		crew: 'patrol',
		pivotX: 400,
		pivotY: 200,
		headColor: '#663300',
		headAngle: 5 / 6 * Math.PI,
		bodyColor: '#996633',
		bodyAngle: 5 / 6 * Math.PI,
		// extra
		routeArray: [[500, 70], [100, 200], [520, 230]],
		routeRound: 1
	}),
	new Tank()
);
</script>
</body>
</html>
Ответить с цитированием
  #15 (permalink)  
Старый 28.05.2017, 08:53
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Rise,
Ответить с цитированием
  #16 (permalink)  
Старый 28.05.2017, 12:56
Новичок на форуме
Отправить личное сообщение для Sasha05082002 Посмотреть профиль Найти все сообщения от Sasha05082002
 
Регистрация: 07.05.2017
Сообщений: 8

Очень круто! Тока бот врезался в стенку и остановился.
Ответить с цитированием
  #17 (permalink)  
Старый 28.05.2017, 13:55
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

рони,
Sasha05082002, он не врезался, у него закончился маршрут и он остановился
Ответить с цитированием
  #18 (permalink)  
Старый 28.05.2017, 15:44
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Еще может возникнуть вопрос, почему круг (round) установлено 1, а проехал вроде как 2, на самом деле круг там один:

Первый проезд: произвольная точка -> начальная точка -> промежуточные точки -> конечная точка
Второй проезд: конечная точка -> начальная точка -> промежуточные точки -> конечная точка (round)

И еще, бесконечному числу кругов соответствует отрицательное значение.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите сделать эффект смены страниц Eugi Элементы интерфейса 6 16.07.2013 17:06
Помогите сделать список из выборки shaltay jQuery 15 03.04.2011 17:54
Помогите не могу справится... Prostenikii Работа 2 18.02.2011 10:46
Помогите сделать тестовое задание начального уровня по js makregistr Работа 1 16.12.2010 14:26
Помогите сделать sss2019 Элементы интерфейса 15 15.06.2010 15:23