[HTML5]使用Box2dWeb模拟飞行箭矢
Box2d是一个2D游戏物理引擎,由Erin Catto开发,于2007年发布。很多2D游戏都用过Box2d,其中最有名的自然是愤怒的小鸟。Box2d本身是C++编写,但在不同平台都有它的衍生版本,像Flash版的Box2dFlash,JS版的Box2dJS和Box2dWeb。最近偶然看到一篇使用Box2dFlash模拟箭矢飞行效果的文章:http://www.emanueleferonato.com/2012/12/10/flying-arrows-simulation-with-box2d/很有意思,想尝试使用下Box2d。之前从没接触过Flash,选择JS版的Box2d,而Box2dJS已经很久没更新,所以使用Box2dWeb重写箭矢飞行效果。网上有不少Box2d教程,不过介绍其应用的多些。对于Box2d基本概念和原理,推荐阿蕉的博客,他将Box2d C++的系列教程译成中文。虽然C++和JS不同,但是Box2d原理是相通的,可以参考。首先下载Box2dWebhttps://code.google.com/p/box2dweb/downloads/list压缩包里只有四个文件,这里只需要Box2dWeb-2.1.a.3.min.js(也可以用Box2dWeb-2.1.a.3.js,方便了解Box2DWeb的各个函数)。按照下面的目录结构创建各个文件即可:|-js/| |-Box2dWeb-2.1.a.3.min.js| |-game.js|-arrow.html编辑arrow.html,引用javascript文件并创建一个canvas标签,代码如下:[html]<html><head><title>Box2DWeb Test</title><scripttypescripttype="text/javascript"src="js/Box2dWeb-2.1.a.3.min.js"></script><scripttypescripttype="text/javascript" src="js/game.js"></script></head><bodyonloadbodyonload="init();"><canvasidcanvasid="canvas" width="640" height="480"style="background-color:#333333;"></canvas></body></html>接下来编辑game.js。从arrow.html中可以看到,页面载入后调用init方法模拟整个过程,添加下面的代码:[javascript]function init() {// Commen code for usingBox2D object.var b2Vec2 =Box2D.Common.Math.b2Vec2;var b2AABB =Box2D.Collision.b2AABB;var b2BodyDef =Box2D.Dynamics.b2BodyDef;var b2Body =Box2D.Dynamics.b2Body;varb2FixtureDef = Box2D.Dynamics.b2FixtureDef;var b2Fixture =Box2D.Dynamics.b2Fixture;var b2World =Box2D.Dynamics.b2World;varb2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;var b2DebugDraw =Box2D.Dynamics.b2DebugDraw;/* 下文添加 */};以上代码是为了方便使用Box2d中的对象。接着就是设置全局属性,像canvas的大小、Box2d的世界参数、鼠标消息响应方法等。[javascript]// Get canvas fordrawing.var canvas =document.getElementById("canvas");var canvasPosition =getElementPosition(canvas);var context =canvas.getContext("2d");// World constants.var worldScale = 30;var dragConstant=0.05;var dampingConstant = 2;var world = newb2World(new b2Vec2(0, 10),true);document.addEventListener("mousedown",onMouseDown);debugDraw();window.setInterval(update,1000/60);设置好Box2d的世界之后就可以放置各种模型。接下来的代码创建四面墙壁来封闭区域:[javascript]// Create bottom wallcreateBox(640,30,320,480,b2Body.b2_staticBody,null);// Create top wallcreateBox(640,30,320,0,b2Body.b2_staticBody,null);// Create left wallcreateBox(30,480,0,240,b2Body.b2_staticBody,null);// Create right wallcreateBox(30,480,640,240,b2Body.b2_staticBody,null);functioncreateBox(width,height,pX,pY,type,data){var bodyDef = new b2BodyDef;bodyDef.type = type;bodyDef.position.Set(pX/worldScale,pY/worldScale);bodyDef.userData=data;var polygonShape = new b2PolygonShape;polygonShape.SetAsBox(width/2/worldScale,height/2/worldScale);var fixtureDef = new b2FixtureDef;fixtureDef.density = 1.0;fixtureDef.friction = 0.5;fixtureDef.restitution = 0.5;fixtureDef.shape = polygonShape;var body=world.CreateBody(bodyDef);body.CreateFixture(fixtureDef);}希望点击鼠标时,从左下角向鼠标点击的位置发射一支箭。所以在鼠标点击消息的响应方法中调用createArrow方法,根据传入的坐标生成一支箭,并赋给它初速度,代码如下:[javascript]function onMouseDown(e) {var evt = e||window.event;createArrow(e.clientX-canvasPosition.x,e.clientY-canvasPosition.y);}function createArrow(pX,pY) {// Set the left corner as the originalpoint.var angle = Math.atan2(pY-450, pX);// Define the shape of arrow.var vertices = [];vertices.push(new b2Vec2(-1.4,0));vertices.push(new b2Vec2(0,-0.1));vertices.push(new b2Vec2(0.6,0));vertices.push(newb2Vec2(0,0.1));var bodyDef = new b2BodyDef;bodyDef.type = b2Body.b2_dynamicBody;bodyDef.position.Set(40/worldScale,400/worldScale);bodyDef.userData = "Arrow";var polygonShape = new b2PolygonShape;polygonShape.SetAsVector(vertices,4);var fixtureDef = new b2FixtureDef;fixtureDef.density = 1.0;fixtureDef.friction = 0.5;fixtureDef.restitution = 0.5;fixtureDef.shape = polygonShape;var body = world.CreateBody(bodyDef);body.CreateFixture(fixtureDef);// Set original state of arrow.body.SetLinearVelocity(newb2Vec2(20*Math.cos(angle), 20*Math.sin(angle)));body.SetAngle(angle);body.SetAngularDamping(dampingConstant);}接下来就是系统方法,绘制物体并定时更新:[javascript]补充:web前端 , HTML 5 ,
上一个:绝对不可错过的超实用HTML5代码片段
下一个:HTML5的22个技巧
- 更多html/css疑问解答:
- div+css中关于ie浏览器中非啊元素的:hover的实现问题,哪位大神指点下啊
- css jquery代码中为什么宽度这样设定.menu li ul 150px;.menu li ul a 110px;.menu li a中padding的20px
- css 属性选择器 ie6 不支持吗?
- 用css、jquery做的选项卡效果,有一个小疑问,请高手指点,代码如下:
- 介绍本学习css的书
- wordpress多个CSS样式怎么调用?
- 这个div 的css是如何编写的
- div+css中,div的右边框小于div的高度且居中,除了用背景图片,如何实现?
- 表格立体感用CSS怎么写 我要 具体代码 写仔细 分段的 谢谢 了 兄弟 还有 下拉列表框 立体感用CSS 怎么写
- CSS 在一个大的DIV里面,另一个DIV怎么居中并置底。
- dw中html文档为什么无法链接css文档
- 设计一个小例子说明DIV+CSS的优势(例子要解释并注释)。
- 我会html css目前正在学js,打算在大三的寒假找个实习,请问应该找哪方面的实习?
- css问题,跪求大大帮忙
- 请教网页设计高手,如下图的这种css代码怎么写?