当前我们实现小球弹射时,会先用鼠标点击小球,然后移动鼠标,当松开鼠标时,小球会弹射向鼠标松开的位置。我们按住小球的时间越长,小球弹射的力度就越大,但有一个问题是,玩家并不知道,当前施加在小球上的推力有多大,这节我们就增加一个动画功能,当玩家在小球上点击鼠标时,小球前方会出现一个变动着的箭头,箭头的红色部分越多,表明小球被施加的推力就越大,我们实现功能后,效果如下:
屏幕快照 2018-08-03 下午5.55.02.png
当鼠标在小球身上按下时,有一个箭头出现在小球旁边,箭头的指向根据鼠标的移动来变化,箭头中的红色块根据鼠标按下的时间长短而变化,鼠标按下时间越长,红色块就越长,它表示作用在小球上面的力度就越大。
我们看看相关代码的实现,首先对canvas控件的属性做些修改:
<script>canvas { position: absolute; top: 0; left: 0; border: 1px solid black; }</script>
我们把原来在canvas前面的井号去掉,这样两个canvas控件就会重叠在一起。接着我们引入箭头的资源库,在index.html中增加如下代码:
<script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./static/assets.js"> </script> <script type="text/javascript"> window.createjs = createjs window.Box2D = Box2D window.assetsLib = lib </script>
assets.js是资源库,我们在页面上绘制的箭头就是从这个库中获得的。接下来在控件初始化时,将资源加载到页面里:
init () { ....// change 1 引入资源库 this.assetsLib = window.assetsLib this.initPowerIndicator() }
然后添加代码,实现箭头图片的显示,以及箭头能根据鼠标的移动来转动:
// change2 加载箭头图片资源 initPowerIndicator () { this.power = new this.assetsLib.PowerArrow() this.stage.addChild(this.power) this.power.visible = false }, showPowerIndicator (x, y) { this.power.visible = true this.power.x = x this.power.y = y }, hidePowerIndicator () { this.power.visible = false }, rotatePowerIndicator (rotation) { this.power.rotation = rotation }, updatePowerBar (value) { this.power.powerBar.scaleY = Math.min(30, value) } }
上面代码实现了箭头图片的加载和旋转,接着我们修改鼠标消息响应函数,让箭头在小球被点击时出现,并且跟着鼠标的移动而转动:
stageMouseDown (e) { if (!this.isPlaying) { console.log('mouse down return') return } // change 3 var position = this.ballPosition() this.showPowerIndicator(position.x, position.y) var rotation = this.launchAngle(e.stageX, e.stageY) this.rotatePowerIndicator(rotation * 180 / Math.PI) this.tickWhenDown = this.cjs.Ticker.getTicks() this.updatePowerBar(0) }, stageMouseUp (e) { if (!this.isPlaying) { return } // change 4 this.hidePowerIndicator() this.tickWhenUp = this.cjs.Ticker.getTicks() var ticksDiff = this.tickWhenUp - this.tickWhenDown this.shootBall(e.stageX, e.stageY, ticksDiff) // 发射后500毫秒再生成一个小球 setTimeout(this.spawnBall, 500) }, // change 5 stageMouseMove (e) { if (!this.isPlaying) { return } var rotation = this.launchAngle(e.stageX, e.stageY) this.rotatePowerIndicator(rotation * 180 / Math.PI) }, update () { this.world.Step(1 / 60, 10, 10) if (this.shouldDrawDebug) { this.world.DrawDebugData() } this.world.ClearForces() // change 7 var ticksDiff = this.cjs.Ticker.getTicks() - this.tickWhenDown this.updatePowerBar(ticksDiff) },
添加完上面代码后,加载页面,点击小球是就可以看到箭头动画了。接下来我们添加代码,为游戏添加一个十字架障碍物,代码如下:
// change 10 createCross (obstacle) { var bodyDef = new this.B2BodyDef() var fixDef = new this.B2FixtureDef() fixDef.density = 0.2 fixDef.friction = 0.5 fixDef.restitution = 0.2 // 绘制一个交叉十字架物体 bodyDef.type = this.B2Body.b2_dynamicBody bodyDef.position.x = obstacle.position.x / this.pxPerMeter bodyDef.position.y = obstacle.position.y / this.pxPerMeter fixDef.shape = new this.B2PolygonShape() fixDef.shape.SetAsBox(obstacle.length / this.pxPerMeter, obstacle.width / this.pxPerMeter) var cross = this.world.CreateBody(bodyDef) cross.CreateFixture(fixDef) fixDef.shape.SetAsBox(obstacle.width / this.pxPerMeter, obstacle.length / this.pxPerMeter) cross.CreateFixture(fixDef) // 在交叉处添加一个小圆圈 bodyDef.type = this.B2Body.b2_staticBody fixDef.shape = new this.B2CircleShape(10 / this.pxPerMeter) var circle = this.world.CreateBody(bodyDef) circle.CreateFixture(fixDef) console.log('create cross:', this.B2RevoluteJointDef) var revoluteJointDef = new this.B2RevoluteJointDef() revoluteJointDef.bodyA = cross revoluteJointDef.bodyB = circle revoluteJointDef.collideConnected = false revoluteJointDef.maxMotorTorque = obstacle.maxTorque revoluteJointDef.motorSpeed = obstacle.motorSpeed revoluteJointDef.enableMotor = obstacle.enableMotor this.world.CreateJoint(revoluteJointDef) }
上面代码构造了两个长方体,并将长方体交叉重叠,在交叉处再绘制一个圆形作为固定两个长方体的连接点,最后我们使用B2RevoluteJointDef类把两个长方体和一个圆形结合起来,形成一个整体,最后我们在createObstacles函数中添加调用上面函数的代码:
createObstacles (level) { .... if (o.type === 'rect') { fixDef.shape = new this.B2PolygonShape() fixDef.shape.SetAsBox(o.dimension.width / this.pxPerMeter, o.dimension.height / this.pxPerMeter) body = this.world.CreateBody(bodyDef) body.CreateFixture(fixDef) } // change 11 if (o.type === 'cross') { this.createCross(o) } }
接着我们生成用于构建十字架障碍物的关卡数据:
levels: [ .... { // change 12 hoopPosition: {x: 50, y: 160}, ballName: 'SlowBall', ballPosition: {x: 350, y: 250}, ballRandomRange: {x: 80, y: 80}, obstacles: [ { type: 'cross', graphicName: 'cross', position: {x: 165, y: 140}, length: 60, width: 10, enableMotor: true, maxTorque: 25, motorSpeed: 3.0 } ] } }
然后我们在初始化时,将currentLevel指向上面的数据就大功告成了:
init () { .... this.currentLevel = this.levels[3] }
完成上面代码后我们可以看到如下效果:
屏幕快照 2018-08-07 上午9.03.47.png
上图中红色的十字架障碍物是不断转动的。
作者:望月从良
链接:https://www.jianshu.com/p/724d4a1fe3f6
共同学习,写下你的评论
评论加载中...
作者其他优质文章