我们都玩过愤怒的小鸟,该游戏一大特点是,两物体碰撞后,它会模拟现实世界物体碰撞后的反弹效果,因此游戏特别具有体感和逼真感,本节我们利用物理引擎Box2D,制作一个类似愤怒小鸟类型的碰撞游戏。

游戏的基本玩法是,用鼠标点击小球,移动鼠标选择小球的发射方向,松开鼠标按钮后,小球按照鼠标指向的方向发射出去,一旦小球与障碍物碰撞后,它会像现实世界那样反复弹跳,如果一系列碰撞后,小球能停留在木架上,游戏就算过关,基本场景如下:

它类似于投篮,选定箭头方向,让小球发射后落入到绿色方块中。这个游戏的开发特点在于,我们充分利用物理引擎的帮助来实现像现实世界中的碰撞效果,如果没有引擎,我们必须自己计算小球各个方向的加速度,摩擦力,碰撞后的相互作用力等,那是非常复杂的。有了物理引擎,我们完全可以把各种复杂的细节交给引擎来控制。

接下来我们开始基本场景的设计,先把以前我们准备好的VUE项目复制一份,并改名为BallShooting,同时把相关开发库,例如createjs,Box2D等放入到static目录下:

相关的开发库会附带在云课堂的代码附件里。我们进入到根目录,打开index.html,先把各个要用到的第三方库加载进来,代码修改如下:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimal-ui"><meta name="apple-mobile-web-app-capable" content="yes"><script type="text/javascript" src="./static/tweenjs-0.5.1.min.js"></script><script type="text/javascript" src="./static/easeljs-0.7.1.min.js"></script><script type="text/javascript" src="./static/movieclip-0.7.1.min.js"></script><script type="text/javascript" src="./static/Box2dWeb-2.1.a.3.min.js"></script><script type="text/javascript" src="./static/preloadjs-0.4.1.min.js"></script><script type="text/javascript">window.createjs = createjs</script><title>Shooting A Ball</title></head><body><div id="app"></div><!-- built files will be auto injected --></body>
</html>

接着进入src/目录,修改App.vue,将内容修改如下:

<template><div id="app"><game-container></game-container></div>
</template><script>
import GameContainer from './components/gamecontainer'
export default {name: 'app',components: {GameContainer}
}
</script><style>
#app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

我们在主入口组件中引入了一个GameContainer组件,接下来我们就实现该组件,组件的作用是搭建游戏的基本场景,进入components/目录,在里面生成一个gamecontainer.vue文件,然后添加如下内容:

<template><div><header><div class="row"><h1>Let shoot the Ball</h1></div></header><div><game-scene></game-scene></div></div>
</template><script>import GameScene from './GameSceneComponent'export default {components: {GameScene}}
</script><style scoped>body, h1, h2, p {margin: 0;padding: 0;}</style>

该组件搭建了游戏的html框架后,引入gameSceneComponent组件,我们几乎大部分游戏的逻辑设计都会实现在该组件里。同理在当前目录下新建一个文件,名为gamescenecomponent.vue,然后添加如下内容:

<template><section id="game" class="row"><canvas id="debug-canvas" width="480" height="360"></canvas><canvas id="canvas" width="480" height="360"></canvas></section>
</template>

我们在里面设置两个画布组件,其中一个用来调试,另一个用来显示游戏画面,一旦所有设计调试通过后,我们就可以把调试画布组件给去除,留下第二个画布组件。接着我们在组件初始化代码中,将物理引擎中用到的组件都获取到,代码如下:


<script>export default {data () {return {canvas: null,debugCanvas: null,createWorld: null}},mounted () {this.init()},methods: {init () {this.cjs = window.createjsthis.canvas = document.getElementById('canvas')this.stage = new this.cjs.Stage(this.canvas)// 导出物理引擎的各个组件this.B2Vec2 = window.Box2D.Common.Math.b2Vec2this.B2AABB = window.Box2D.Collision.b2AABBthis.B2BodyDef = window.Box2D.Dynamics.b2BodyDefthis.B2Body = window.Box2D.Dynamics.b2Bodythis.B2FixtureDef = window.Box2D.Dynamics.b2FixtureDefthis.b2Fixture = window.Box2D.Dynamics.b2Fixturethis.B2World = window.Box2D.Dynamics.b2Worldthis.B2MassData = window.Box2D.Collision.Shapes.b2MassDatathis.B2PolygonShape = window.Box2D.Collision.Shapes.b2PolygonShapethis.B2CircleShape = window.Box2D.Collision.Shapes.b2CircleShapethis.B2DebugDraw = window.Box2D.Dynamics.b2DebugDrawthis.B2MouseJointDef = window.Box2D.Dynamics.Joints.b2MouseJointDefthis.B2RevoluteJointDef = window.Box2D.Dynamics.b2RevoluteJointDef// 每30个像素点的距离对应现实世界的一米长度this.pxPerMeter = 30this.shouldDrawDebug = false}}}
</script>

接下来我们需要调用物理引擎,构造一个由引擎驱动的虚拟世界,在这个世界里,物体的碰撞效果由物理引擎来控制,我们所有游戏逻辑的设计都要基于引擎的驱动,相关代码如下:

createMyWorld () {// 设置重力加速度var gravity = new this.B2Vec2(0, 9.8)this.world = new this.B2World(gravity)// 设置两个暂时实体对象var bodyDef = new this.B2BodyDef()var fixDef = new this.B2FixtureDef()// 设置实体为静态物bodyDef.type = this.B2Body.B2_staticBodybodyDef.position.x = 100 / this.pxPerMeterbodyDef.position.y = 100 / this.pxPerMeter// 设置实体形状为多边形fixDef.shape = new this.B2PolygonShape()fixDef.shape.SetAsBox(500 / this.pxPerMeter, 500 / this.pxPerMeter)this.world.CreateBody(bodyDef).CreateFixture(fixDef)// 设置一个动态实体bodyDef.type = this.B2Body.b2_dynamicBodybodyDef.position.x = 200 / this.pxPerMeterbodyDef.position.y = 200 / this.pxPerMeterthis.world.CreateBody(bodyDef).CreateFixture(fixDef)}

我们的游戏也需要一个主循环来驱动它的运行,在主循环中,我们持续调用物理引擎的接口,让它根据物理定律不断更新页面动态,相关代码如下:

update () {this.world.Step(1 / 60, 10, 10)if (this.shouldBeDrawDebug) {this.world.DrawDebugData()}this.world.ClearForces()},// 设置用于调试目的的图形绘制showDebugDraw () {// 为了确保设计的正确性,我们可以把图形先进行调试绘制// 确定没问题后再把图形绘制到画布里this.shouldDrawDebug = truevar debugDraw = new this.B2DebugeDraw()// 设置调试画布debugDraw.SetSprite(document.getElementById('debug-canvas').getContext('2d'))debugDraw.SetFillAlpha(0.3)debugDraw.SetLineTickness(1.0)debugDraw.SetFlags(this.B2DebugDraw.e_shapeBit | this.B2Draw.e_jointBit)this.world.SetDebugDraw(debugDraw)}

我们准备了两个画布,一个画布用来调试绘制物体的原型,原型这个概念后面会深入探究,例如愤怒的小鸟它在物理引擎的世界里,对应的其实是一个正方形,而那些被攻击的猪,其原型就是圆形。

接着我们启动主循环,将实体绘制到调试画布中,并让他们运动起来:

start () {this.createMyWorld()this.showDebugDraw()this.cjs.Ticker.setFPS(60)this.cjs.Ticker.addEventListener('tick', this.stage)this.cjs.Ticker.addEventListener('tick', this.tick)},tick () {if (this.cjs.Ticker.getPaused()) {return}this.update()}

完成上面代码后,我们就完成了基本框架的搭建和物理引擎的启动以及引擎驱动的虚拟环境的构造,上面代码运行后,页面加载后情况如下:

页面启动后,在画布里会出现两个正方形,其中一个正方形会像现实世界一样做自由落体运动,它下落有一个加速度,在物理引擎的驱使下,正方形的下落与现实世界中物体的下落是一样的。

在后续章节中,我们将基于本节创建的物理引擎场景开发精美有趣的游戏。

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:

VUE,使用物理引擎Box2D设计类愤怒小鸟的击球游戏--基本架构设置相关推荐

  1. 关于2d物理引擎box2d与ape的评论

    APE不行,做点简单的撞球,台球之类游戏还行.我最开始用他实验性做了个简单的基于物理引擎的泡泡龙类游戏,发现稍微多一点的几何体堆叠在一起就会产生渗透现象,没办法只好更改最初的设计.要专注做物理游戏,还 ...

  2. cocos2dx-3.x物理引擎Box2D介绍

    原文:https://www.cnblogs.com/yyxt/p/4561410.html 理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2 ...

  3. cocos2d-x初探学习笔记(20)--物理引擎box2d(2)

    小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 由于box2d的内容比较多,它也有自己的tes ...

  4. cocos2d-x物理引擎-Box2D介绍及开发实例

    物理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2D物理引擎,而且x引擎将它们都内置在SDK中.Box2D使用较为广泛,在这里选择Box2D来 ...

  5. 计算机编程游戏设计类报考什么大学好,游戏设计专业有什么好的大学

    1. 南加州大学 南加州大学下的Viterbi工程学院提供了本科Computer Science-CSCI(Games)游戏设计专业,研究生Computer Science(Game Developm ...

  6. unity 抛物线移动(数学模拟)愤怒小鸟等射箭游戏

    using UnityEngine; using System.Collections; /// <summary> /// 弓箭轨迹模拟 /// 阿亮设计,欢迎交流经验 /// < ...

  7. 【Unity3d学习】使用物理引擎——打飞碟游戏的物理引擎改进与射箭游戏设计

    文章目录 写在前面 HitUFO的物理引擎改进版本 物理引擎的改进版本思路与实现 PhysicsAction PhysicsManager 新接口类IActionManager 动作管理器基类的变化 ...

  8. python box2d 教程_python下的Box2d物理引擎的配置

    I come back! 由于已经大四了,正在找工作 导致了至今以来第二长的时间内没有更新博客.向大家表示道歉 前言 Box2d物理引擎 Box2d是一款开源的2d物理引擎,存在很多的版本,C++,J ...

  9. Cocos2d-x学习笔记(十五)--------物理引擎

    物理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2D物理引擎,而且x引擎将它们都内置在SDK中.Box2D使用较为广泛,在这里选择Box2D来 ...

最新文章

  1. 4.7 CNN 特征可视化-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  2. [云炬python3玩转机器学习] 6-4 在线性回归模型中使用梯度下降法
  3. 科大星云诗社动态20210225
  4. 抖音很火的存钱计划,让python告诉你总共可以存到多少钱!
  5. 14_clickhouse,kafka引擎,kafka消息到ClickHouse的MergeTree引擎
  6. NoSql中的B-tree、B+tree和LSM-tree
  7. C语言文件读写(结构体文件)
  8. Linux学习总结(36)——创建、复制、剪切、重命名、清空和删除文件夹的命令
  9. 【LeetCode】【数组】题号:*54,螺旋数组
  10. OFDM中的DC subcarrier
  11. STM32CUBEIDE USB下载总是连接不上 总是USBD_BUSY
  12. html 让360浏览器兼容模式,360浏览器兼容模式怎么设置?360浏览器兼容模式设置方法介绍...
  13. MMI笔记 virtual environments, audio for virtual environments 知识点总结
  14. 服务器系统飞行模式怎么关闭,win10系统开启飞行模式之后无法关闭怎么解决
  15. 记录一次尝试修复elasticsearch Data too large问题
  16. JAVA拾遗 — JMH与8个代码陷阱
  17. 实验一 利用Excel表格进行掷硬币模拟实验
  18. Excel根据内容自动调整行高和列宽
  19. JDK8系列之Lambda表达式教程和示例
  20. 调整变速器后拨详细图文教程

热门文章

  1. 生活中计算机应用的实例,单片机应用(生活中单片机应用实例)
  2. 会计转java6_会计转行从事 IT,如何在一年时间内全职学习?
  3. Wacom将在CES 2015上发布全新旗舰版Cintiq
  4. 信息系统项目管理 - 范围管理(划重点)
  5. 互联网起源之构建在电磁波之上
  6. 使用Vue开发项目(一)
  7. 证券从业考试考试技巧
  8. Nginx 集群安装以及常用配置详解开机自启动
  9. java中的dispose函数_[转载]java中的dispose()方法
  10. LTE射频拉远单元数字中频方案(十)