第二个是书中的源代码给出了一个Collision类,其中的block方法可以实现两个物体之间的碰撞检测。
有趣的是,Collsion.block方法有两个参数,第一个是被阻碍物,第二个是障碍物,在这个演示中,山上有两块石板。
对于左边的石板,石板是被阻碍物,小猪是障碍物,产生的效果就是小猪可以推着石板走。
对于右边的石板,小猪是被阻碍物,石板是障碍物,产生的效果就是小猪撞到墙上就不能动了,很有意思。
http://bbs.9ria.com/viewthread.php?tid=88769&extra=page%3D1%26amp%3Borderby%3Ddateline%26amp%3Bfilter%3D2592000
| package |
| { |
| import flash.display.MovieClip; |
| import flash.geom.Point; |
| |
| public class Collision |
| //0.2 (March 20, 2009) |
| { |
| public function Collision() |
| { |
| } |
| |
| //Block objects |
| static public function block(objectA:MovieClip, objectB:MovieClip):void |
| { |
| var objectA_Halfwidth:Number = objectA.width / 2; |
| var objectA_Halfheight:Number = objectA.height / 2; |
| var objectB_Halfwidth:Number = objectB.width / 2; |
| var objectB_Halfheight:Number = objectB.height / 2; |
| var dx:Number = objectB.x - objectA.x; |
| var ox:Number = objectB_Halfwidth + objectA_Halfwidth - Math.abs(dx); |
| if (ox > 0) |
| { |
| var dy:Number = objectA.y - objectB.y; |
| var oy:Number = objectB_Halfheight + objectA_Halfheight - Math.abs(dy); |
| if (oy > 0) |
| { |
| if (ox < oy) |
| { |
| if (dx < 0) |
| { |
| //Collision on right |
| oy = 0; |
| } |
| else |
| { |
| //Collision on left |
| oy = 0; |
| ox *= -1; |
| } |
| } |
| else |
| { |
| if (dy < 0) |
| { |
| //Collision on Top |
| ox = 0; |
| oy *= -1; |
| } |
| else |
| { |
| //Collision on Bottom |
| ox = 0; |
| } |
| } |
| |
| //Use the calculated x and y overlaps to |
| //Move objectA out of the collision |
| |
| objectA.x += ox; |
| objectA.y += oy; |
| } |
| } |
| } |
| |
| //General purpose method for testing Axis-based collisions. Returns true or False |
| static public function test(objectA:Object,objectB:Object):Boolean |
| { |
| var objectA_Halfwidth=objectA.width/2; |
| var objectA_Halfheight=objectA.height/2; |
| var objectB_Halfwidth=objectB.width/2; |
| var objectB_Halfheight=objectB.height/2; |
| var dx=objectB.x-objectA.x; |
| var ox=objectB_Halfwidth+objectA_Halfwidth-Math.abs(dx); |
| if (0<ox) |
| { |
| var dy=objectA.y-objectB.y; |
| var oy=objectB_Halfheight+objectA_Halfheight-Math.abs(dy); |
| if (0<oy) |
| { |
| return true; |
| } |
| } |
| else |
| { |
| return false; |
| } |
| return false; |
| } |
| |
| //Collisions between the player and platform |
| static public function playerAndPlatform(player:MovieClip, platform:MovieClip, bounce:Number, friction:Number):void |
| { |
| //This method requires the following getter and |
| //setter properties in the player object: |
| //objectIsOnGround:Boolean, vx:Number, vy:Number, |
| //bounceX:Number, bounceY:Number |
| |
| //Decalre variables needed for the player's |
| //position and dimensions |
| var player_Halfwidth:Number; |
| var player_Halfheight:Number; |
| var player_X:Number; |
| var player_Y:Number |
| |
| //Decalre variables needed for the physics calculations |
| var bounceX:Number; |
| var bounceY:Number; |
| var frictionX:Number; |
| var frictionY:Number; |
| |
| //Find out whether the player object has a collisionArea |
| //subobject defined |
| if(player.collisionArea != null) |
| { |
| //If it does, find out its width and height |
| player_Halfwidth = player.collisionArea.width / 2; |
| player_Halfheight = player.collisionArea.height / 2; |
| |
| //Convert the collisionArea's local x,y coordinates to global coordinates |
| var player_Position:Point = new Point(player.collisionArea.x, player.collisionArea.y); |
| player_X = player.localToGlobal(player_Position).x; |
| player_Y = player.localToGlobal(player_Position).y; |
| } |
| else |
| { |
| //If there's no collisionArea subobject |
| //Use the player's main height, width, x and y |
| player_Halfwidth = player.width / 2; |
| player_Halfheight = player.height / 2; |
| player_X = player.x; |
| player_Y = player.y; |
| } |
| //Find the platform's dimensions |
| var platform_Halfwidth:Number = platform.width / 2; |
| var platform_Halfheight:Number = platform.height / 2; |
| |
| //Find the distance between the player and platfrom on the x axis |
| var dx:Number = platform.x - player_X; |
| |
| //Find the amount of overlap on the x axis |
| var ox:Number = platform_Halfwidth + player_Halfwidth - Math.abs(dx); |
| |
| //Check for a collision on the x axis |
| if (ox > 0) |
| { |
| //If the objects overlap on the x axis, a collision might be occuring |
| //Define the variables you need to check for a collision on the y axis |
| var dy:Number = player.y - platform.y; |
| var oy:Number = platform_Halfheight + player_Halfheight - Math.abs(dy); |
| |
| //Check for a y axis collision. We know a collision must be |
| //occuring if there's a collision on both the x and y axis |
| if (oy > 0) |
| { |
| //Yes, a collision is occuring! |
| //Now you need to find out on which side |
| //of the platform it's occuring on. |
| if (ox < oy) |
| { |
| if (dx < 0) |
| { |
| //Collision on right |
| oy = 0; |
| dx = 1; |
| dy = 0 |
| } |
| else |
| { |
| //Collision on left |
| oy = 0; |
| ox *= -1; |
| dx = -1; |
| dy = 0 |
| } |
| } |
| else |
| { |
| if (dy < 0) |
| { |
| //Collision on Top |
| ox = 0; |
| oy *= -1; |
| dx = 0; |
| dy = -1; |
| //set the player's isOnGround property to |
| //true to enable jumping |
| player.isOnGround = true; |
| } |
| else |
| { |
| //Collision on Bottom |
| ox = 0; |
| dx = 0; |
| dy = 1; |
| } |
| } |
| |
| //Find the direction of the collision ("dot product") |
| var directionOfCollision:Number = player.vx * dx + player.vy * dy; |
| |
| //Calculate the new direction for the bounce ("projection") |
| var newDirection_X:Number = directionOfCollision * dx; |
| var newDirection_Y:Number = directionOfCollision * dy; |
| |
| //Find the "tangent velocity": |
| //the speed in the direction that the object is moving. |
| //It's used for calculating additional platform friction. |
| var tangent_Vx:Number = player.vx - newDirection_X; |
| var tangent_Vy:Number = player.vy - newDirection_Y; |
| |
| //Apply collision forces if the object is moving into a collision |
| if (directionOfCollision < 0) |
| { |
| //Calculate the friction |
| frictionX = tangent_Vx * friction; |
| frictionY = tangent_Vy * friction; |
| |
| //Calculate the amount of bounce |
| bounceX = newDirection_X * bounce; |
| bounceY = newDirection_Y * bounce; |
| } |
| else |
| { |
| //Prevent forces from being applied if the object is |
| //moving out of a collision |
| bounceX = 0; |
| bounceY = 0; |
| frictionX = 0; |
| frictionY = 0; |
| } |
| //Apply platform friction |
| player.vx += ox - frictionX; |
| player.vy += oy - frictionY; |
| |
| //Move the player out of the collision |
| player.x += ox; |
| player.y += oy; |
| |
| //Bounce the player off the platform |
| player.bounceX = bounceX; |
| player.bounceY = bounceY; |
| } |
| } |
| } |
| } |
| } |

本文介绍了一个Collision类,其中包含block方法用于实现两个物体间的碰撞检测。通过调整参数,可以模拟不同类型的碰撞效果,如物体间推挤或阻挡。此外,还详细解释了playerAndPlatform方法如何处理玩家与平台之间的碰撞。
400

被折叠的 条评论
为什么被折叠?



