小心墙壁:
看了上面那么多代码,现在才第一次谈到hitTest(),我们在一开始的时候介绍碰撞的环境下“消失的碰撞”(where-did-my-hitTest-go )的结论,所以我们不打算运用hitTest()来检测碰撞。我们用一个更有效的方法来得知球是否碰撞了墙壁。让我们以左边的墙为例子,先检测球的位置,下面是示范:
(图4)
我们能清楚的看到,如果球半径的长度(ball._width / 2 )大于球的位置减去左墙位置的差(ball._x - Game.left),那么就碰撞了。最后的一件事是我们需要确定是当碰撞发生了会出现什么样的情形,让我们看看另一张漂亮的图片:
当然,当球碰到了墙后反弹将会发生,那么让我们创建checkWalls()方法来完成反弹,我们需要从move()中得到信息,特别是球的速度,那么我们现在就加上这些代码,我们需要的是将它做为一个参数传递。
Game = function () { // ... this.speed = 10 ; // ... } ; Game.prototype.init = function () { trace ("Init method called") ; this.drawArena () ; this.initBar () ; this.MouseListener.onMouseDown = function () { trace ("The Mouse has been pressed") ; if (! this.Game.isPlaying) { ball.move (this.Game) ; this.Game.isPlaying = true ; } } } ; MovieClip.prototype.move = function (pGame) { this.vx = pGame.speed * Math.cos (-45 * Math.PI / 180) ; this.vy = pGame.speed * Math.sin (-45 * Math.PI / 180) ; this.x = this._x ; this.y = this._y ; this.onEnterFrame = function () { this.x += this.vx ; this.y += this.vy ; this.checkWalls (pGame) ; this._x = this.x ; this._y = this.y ; } } ; MovieClip.prototype.checkWalls = function (pGame) { if (this.x < pGame.left + this._width/2) { trace ("Collision with left wall") ; this.x = pGame.left + this._width/2; this.vx *= -1; } else if (this.x > pGame.right - this._width/2) { trace ("Collision with right wall") ; this.x = pGame.right - this._width/2; this.vx *= -1; } if (this.y < pGame.up + this._height/2) { trace ("Collision with upper wall") ; this.y = pGame.up + this._height/2; this.vy *= -1; } else if (this.y > pGame.barLevel - this._height/2) { var l = bar._x - bar._width/2; var r = bar._x + bar._width/2; if (this.x > l && this.x < r) { trace ("Collision with the bar") ; this.y = pGame.barLevel - this._height/2; this.vy *= -1; } else { pGame.loseLife () ; } } } ;
很长吗?不!只要你明白了一小部分那么就可以了。 前面三个"if"条件判断应该要清晰明了,如果碰撞了其中一壁墙,那么就将球放到墙边,和改变速度的方向,最后一个"if"算最狡猾的了,它是解决球和挡板碰撞的问题。挡板碰撞的原理和碰撞墙的原理是一样的,除此之外我们还要确定球当前的位置时候在挡板的范围内,我们要精确的计算出挡板的最左边(l)和最右边(r)的坐标,如果球当前的位置在这之间,那么就表示碰撞了挡板,然后反弹
var l = bar._x - bar._width/2; var r = bar._x + bar._width/2;
因为挡板(bar)的注册点在中央,我们要减去挡板一半的宽度算出左边界的坐标,同样道理可以算出右边界的坐标。 如果碰撞了挡板,那么就和碰撞墙壁那样反弹。如果没有碰碰撞,我们就调用loseLife()方法,下面让我们定义这个方法。
Game.prototype.loseLife = function () { this.lives -- ; //生命数减1 this.isPlaying = false ; //玩家停止游戏 if (this.lives >= 0) { ball.followBar () ; //可以移动挡板和球 }else { this.endGame () ; //生命数少于0就游戏结束 } } ; Game.prototype.endGame = function () { trace ("End of the Game") ; bar.stopDrag () ; delete ball.onEnterFrame ; } ;
我们减少生命数和告诉FLASH玩家没有开始游戏,如果玩家生命数大于或等于0,就将球放到挡板上,否则就调用endGame()方法,那么就game over了!! 如果你现在测试你的游戏,你会发现你能在开始的时候拖动球,游戏开始后球发生碰撞就能作出相应的反应,(你能在pong_01.as看到以上完成的代码) 下面将会谈论砖块
出处:蓝色理想
责任编辑:qhwa
上一页 基于 as1.0 的挡板游戏 [3] 下一页 基于 as1.0 的挡板游戏 [5]
◎进入论坛Flash专栏版块参加讨论
|