游戏人工智能-自治可移动智能体设计--seek

以下代码改编自《游戏人工智能编程案例精粹(修订版)》([美]Mat buckland,人民邮电出版社,2012)。将其C++代码改为javascript实现

<!DOCTYPE html>
<html>
<head>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="mySteerbehavior_seek.js"></script>
<style>
#world{
text-align:left;
background-color:white;
}
</style>
</head>
<body>
<canvas id='world' ></canvas>
</body>
</html>
//mysteerbehavior_seek.js
$(document).ready(function () {
	var Vector2 = {
		Length: function (v) {
			return Math.sqrt(v.x * v.x + v.y * v.y);
		},
		Vector2Normal: function (v) {
			var d = Math.sqrt(v.x * v.x + v.y * v.y);

			return {
				x: v.x / d,
				y: v.y / d
			};
		},
		Vector2Add: function (a, b) {
			return {
				x: a.x + b.x,
				y: a.y + b.y
			};
		},
		Vector2Sub: function (a, b) {
			return {
				x: a.x - b.x,
				y: a.y - b.y
			};
		},
		Vector2Mul: function (a, b) {
			return {
				x: a.x * b,
				y: a.y * b
			};
		},
		Vector2Div: function (a, b) {
			return {
				x: a.x / b,
				y: a.y / b
			};
		},
	};
	var mySteeringBehavior = {
		Vechile: {},
		Seek: function () {
			var DesiredVelocity = Vector2.Vector2Sub(this.Vechile.m_targetPos, this.Vechile.m_Pos);
			
			return Vector2.Vector2Sub(DesiredVelocity, this.Vechile.m_Velocity);
		},
		Calculate: function () {
			var p = this.Seek();
			
			return p;
		},
	};
	var Model = {
		m_Pos: {
			x: 100,
			y: 100
		},
		m_Velocity: {
			x: 0,
			y: 0
		},
		m_Heading: {
			x: 0,
			y: 0,
			angle: 0,
		},
		m_Mass: 1,
		m_MaxSpeed: 100,
		m_MaxForce: 10,
		m_targetPos: {
			x: 60,
			y: 60
		},
		setTargetPos: function (pos) {
			this.m_targetPos.x = pos.x;
			this.m_targetPos.y = pos.y;
		},
		time: 0,
		m_Steering: {},
		Init: function () {
			this.time = (new Date()).getTime();
			mySteeringBehavior.Vechile = Model;

		},

		Update: function () {
			var currentTime = (new Date()).getTime();
			var time_elapsed = currentTime - Model.time;
			this.time = currentTime;
			time_elapsed /= 1000;
			var force = mySteeringBehavior.Calculate();
			var acceleration = Vector2.Vector2Div(force, Model.m_Mass);
			var dVelocity = Vector2.Vector2Mul(acceleration, time_elapsed);
			Model.m_Velocity = Vector2.Vector2Add(Model.m_Velocity, dVelocity);
			var len = Vector2.Length(Model.m_Velocity);
			if (len > Model.m_MaxSpeed) {
				Model.m_Velocity = Vector2.Vector2Mul(Vector2.Vector2Normal(Model.m_Velocity), Model.m_MaxSpeed);
			}
			var dPos = Vector2.Vector2Mul(Model.m_Velocity, time_elapsed);
			Model.m_Pos = Vector2.Vector2Add(Model.m_Pos, dPos);
			len = Vector2.Length(Model.m_Velocity);
			if (len > 0.1) {
				Model.m_Heading.angle = Math.atan2(Model.m_Velocity.y, Model.m_Velocity.x);
				console.log("change-" + Model.m_Heading.angle);
			}
			console.log(":" + len);

		},

	};
	var View = {
		world: null,
		canvas: null,
		world_width: 0,
		world_height: 0,
		Init: function () {
			this.world = document.getElementById("world");
			this.world_width = document.documentElement.clientWidth;
			this.world_height = document.documentElement.clientHeight;

			this.world.width = document.documentElement.clientWidth;
			this.world.height = document.documentElement.clientHeight;

			this.canvas = this.world.getContext("2d");

		},
		Show_Info: function (info) {
			this.canvas.font = "30px Arial";
			this.canvas.fillText(info.info, info.x, info.y);
		},
		draw_car: function () {
			this.canvas.strokeStyle = "rgb(0,0,255)";
			var pos = Model.m_Pos;
			var angle = Model.m_Heading.angle;
			this.canvas.translate(pos.x, pos.y);
			this.canvas.rotate(angle);
			View.canvas.clearRect(-35, -35, 70, 70);

			this.canvas.beginPath();
			this.canvas.moveTo(0, -10);
			this.canvas.lineTo(30, 0);
			this.canvas.lineTo(0, 10);
			this.canvas.closePath();
			this.canvas.stroke();
			this.canvas.rotate(-angle);
			this.canvas.translate(-pos.x, -pos.y);
		},
		draw_cross: function () {
			this.canvas.strokeStyle = "rgb(255,0,0)";
			var pos = Model.m_targetPos;
			this.canvas.translate(pos.x, pos.y);
			//View.canvas.clearRect(-10, 10, 20, 20);
			this.canvas.beginPath();
			this.canvas.moveTo(-10, 0);
			this.canvas.lineTo(10, 0);
			this.canvas.moveTo(0, -10);
			this.canvas.lineTo(0, 10);
			this.canvas.arc(0, 0, 6, 0, 2 * Math.PI, false);
			this.canvas.stroke();
			this.canvas.translate(-pos.x, -pos.y);
		},
		View: function () {
			this.draw_car();
			this.draw_cross();

		},
	};
	var Controller = {
		timer: null,
		Init: function () {
			Model.Init();
			View.Init();
			$("#world").mousedown(Controller.click);
			Controller.timer = setInterval(function () {
					Controller.Update();
				}, 40);
		},
		Update: function () {
			Model.Update();
			View.View();
		},
		click: function (e) {
			Model.setTargetPos({
				x: e.offsetX,
				y: e.offsetY
			});
			View.canvas.clearRect(0, 0, View.world_width, View.world_height);
		},
	};
	Controller.Init();
});

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值