太久没有更新了,新年回来工作,突然有收到网友的邮件提问,居然还有人在关注,惭愧,找了下电脑上还有一点儿存着,顺便先发这一个番外篇吧,好歹可以看到真实的效果,等我考完英语,一定会更新下一章,“愤怒的小鸟篇”


此篇,并不是书中的篇符,而是通过希望通过结合实际的canvas 绘图库实现box2d物理引擎在各绘图库上应用,绘图库网上有很多现成的

如:createjs, pixi.js 等,Egret或者其它游戏引擎有自己的物理引擎扩展库,所以就不说了。

现在通过之前的学习,基本掌握了刚体等基础概念。那如何如何应用于现实画面中呢?

box2d只是模拟了物体,是虚拟的,如果不是通过debug是看不到任何画面的,要让用户看到画面,必须得结合canvas绘图能力,自己操作canvas绘图的原始API太麻烦,所以就有了createjs等其它流行的canvas库.

以下都以createJS代替canvas,当然你用其它库或者直接操作canvas也都可以


先上效果图

完成代码位于

https://github.com/willian12345/Box2D-for-Javascript-Games/blob/master/5-c.html

box2d呈现于createJS,贴上图的基本原理,就是将物理引擎世界中刚体的所有状态复制到createJS舞台对象!

function init() {
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2AABB = Box2D.Collision.b2AABB
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2World = Box2D.Dynamics.b2World
, b2MassData = Box2D.Collision.Shapes.b2MassData
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
, b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef
;
var worldScale = 30; // box2d中以米为单位,1米=30像素
var gravity = new b2Vec2(0, 5);
var sleep = true;
var world;
var stage,debug; function main(){
stage = new createjs.Stage("canvas");
debug = new createjs.Stage("debug"); setupPhysics(); debugDraw(); debug.on("stagemousedown", stagemousedown); createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.on("tick", function(){
stage.update();
world.DrawDebugData(); // 为了显示出createjs对象,这里不再绘制box2d对象至canvas
world.Step(1/30, 10, 10);// 更新世界模拟
world.ClearForces(); // 清除作用力
});
}
main(); function Ball(){
this.view = new createjs.Bitmap('soccer.png');
this.view.regX = this.view.regY = 50; // 创建box2d球形体
var bodyDef = new b2BodyDef();
bodyDef.position.Set(Math.random()*640 / worldScale, 0/worldScale);
bodyDef.type = b2Body.b2_dynamicBody
bodyDef.userData = 0;
var circleShape = new b2CircleShape(50 / worldScale);
var fixtureDef = new b2FixtureDef();
fixtureDef.shape = circleShape;
fixtureDef.density = 1;
fixtureDef.restitution = .4
fixtureDef.friction = .5;
this.view.body = world.CreateBody(bodyDef);
this.view.body.CreateFixture(fixtureDef); this.view.on("tick", function(){
// 让createjs的bitmap对象实时复制box2d对象的位置与旋转角度
this.x = this.body.GetPosition().x * worldScale;
this.y = this.body.GetPosition().y * worldScale;
this.rotation = this.body.GetAngle() * (180 / Math.PI);
});
} function setupPhysics(){
world = new b2World(new b2Vec2(0, 50), true);
floor();
} function stagemousedown(){
var b = new Ball();
stage.addChild(b.view); // 将产生的createjs对象添加至舞台上
} function floor(){
var bodyDef = new b2BodyDef();
bodyDef.position.Set(320/worldScale, 465/worldScale);
var polygonShape = new b2PolygonShape();
polygonShape.SetAsBox(320/worldScale, 15/worldScale);
var fixtureDef = new b2FixtureDef();
fixtureDef.shape = polygonShape;
fixtureDef.restitution = .4;
fixtureDef.friction = .5;
var theFloor = world.CreateBody(bodyDef);
theFloor.CreateFixture(fixtureDef);
} //setup debug draw
function debugDraw(){
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(debug.canvas.getContext('2d'));
debugDraw.SetDrawScale(worldScale);
debugDraw.SetFillAlpha(0.5);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
}
};

这一句

this.view = new createjs.Bitmap('soccer.png');

通过createjs的Bitmap对象读取图片,创建一个足球

this.view这个显示对象即createjs的Bitmap对象,用于显示在舞台即canvas上

this.view.on("tick", function(){
// 让createjs的bitmap对象实时复制box2d对象的位置与旋转角度
this.x = this.body.GetPosition().x * worldScale;
this.y = this.body.GetPosition().y * worldScale;
this.rotation = this.body.GetAngle() * (180 / Math.PI);
});

在Bitmap对象上侦听tick事件,tick事件可以理解为FLASH中的ENTER_FRAME事件,即每一帧调用一次,在每帧中将刚体的x,y位置属性与角度属性复制到createJS的显示对象上,就完成了结合

注释掉这一句,就可以隐藏掉box2Djs的调试状态变成一个正常的带物理效果的足球了

// debugDraw();

更多关于createJS请至官网或者搜索相关知识,你也完成可以用其它绘图库完成一样的操作,比如Pixi.js

相关系列:

HTML5之2D物理引擎 Box2D for javascript Games 系列 第一部分

注:转载请注明出处博客园:sheldon(willian12345@126.com)

https://github.com/willian12345

HTML5之2D物理引擎 Box2D for javascript Games 系列 翻外篇--如何结合createJS应用box2d.js的更多相关文章

  1. HTML5之2D物理引擎 Box2D for javascript Games 系列 第一部分

    我要的是能在H5页面上跑的javascript版的Box2D啊!!! 最近想学习Javascript版本的Box2D JS物理引擎,无奈搜了半天也没找到相对比较系统的资料 官方网站也只是简单的介绍,A ...

  2. HTML5之2D物理引擎 Box2D for javascript Games 系列 第二部分

    这是系列第二部分,之前部分在本博客中找 源码demo存放在https://github.com/willian12345/Box2D-for-Javascript-Games 向世界添加刚体 刚体(B ...

  3. HTML5之2D物理引擎 Box2D for javascript Games 系列 第三部分之创建图腾破坏者的关卡

    创建图腾破坏者的关卡 现在你有能力创建你的第一个游戏原型,我们将从创建图腾破坏者的级别开始. 为了展示我们所做事情的真实性,我们将流行的Flash游戏图腾破坏者的一关作为 我们模仿的对象.请看下面的截 ...

  4. Matter.js – 你不能错过的 2D 物理引擎

    Matter.js 是一个 JavaScript 2D 刚体物理引擎的网页.Matter.Engine 模块包含用于创建和操作引擎的方法.这个引擎是一个管理更新和渲染世界的模拟控制器. Matter. ...

  5. 制作简单的2D物理引擎(零)

    最近发现了Github上的开源物理引擎项目Matter.js,对它很感兴趣,发现源码并不算长,算上注释大约1万行左右,值得剖析一番.Matter.js实现一个最小化的2D物理引擎,性能不错,故打算用C ...

  6. 深入理解javascript作用域系列第三篇——声明提升(hoisting)

    × 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...

  7. 深入理解javascript作用域系列第三篇

    前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇——声明提升(hois ...

  8. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

  9. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

随机推荐

  1. Construct BST from given preorder traversal

    Given preorder traversal of a binary search tree, construct the BST. For example, if the given trave ...

  2. 高性能页面加载技术--BigPipe设计原理及Java简单实现

    1.技术背景 动态web网站的历史可以追溯到万维网初期,相比于静态网站,动态网站提供了强大的可交互功能.经过几十年的发展,动态网站在互动性和页面显示效果上有了很大的提升,但是对于网站动态网站的整体页面 ...

  3. 【Linux笔记】ps、kill、netstat、nohup、screen

    1.ps 命令,用于查看当前正在运行的进程,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵尸.哪些进程占用了过多的资源等等. 语法: ps [options] 示例: p ...

  4. 罗辑思维CEO脱不花:关于工作和成长,这是我的121条具体建议

    1 关于面对批评 01. 没有人对被批评感到高兴.如果有,TA撒谎. 02. 面对批评,得体的第一反应是“不急于解释,不反唇相讥”. 03. 每天,或者最长每周养成习惯,把自己存在的问题和造成的麻烦用 ...

  5. P4596 [COCI2011-2012#5] RAZBIBRIGA

    题目描述 四个等长的单词可以放在一起构成一个正方形,两个单词水平放置,两个竖直放置.水平单词只能从左往右读,竖直的单词只能从上往下读.四个角共用一个字母. 图中是由单词HLAD,NIVA,HSIN,D ...

  6. hdu1542 Atlantis (线段树+矩阵面积并+离散化)

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  7. MT【151】传球问题

    (清华2017.4.29标准学术能力测试10) 甲.乙.丙.丁四人做相互传球的游戏,第一次甲传给其他三人中的一人,第二次由拿到球的人再传给其他三人中的一人,这样的传球共进行了$4$次,则第四次球传回甲 ...

  8. BZOJ 1208 宠物收养所 | 平衡树模板题

    BZOJ 1208 宠物收养所 我犯过的错误:删除一个节点后没有update新的根节点,导致size错了! #include <cstdio> #include <cmath> ...

  9. Min Cost Climbing Stairs - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Min Cost Climbing Stairs - LeetCode 注意点 注意边界条件 解法 解法一:这道题也是一道dp题.dp[i]表示爬到第i层 ...

  10. 梯度下降法求解函数极大值-Matlab

    目录 目录题目作答1. 建立函数文件ceshi.m2. 这是调用的命令,也可以写在.m文件里3. 输出结果题外话 题目 作答 本文使用MATLAB作答 1. 建立函数文件ceshi.m functio ...