Flash/flex Study Notes (41): Collision Detection

Source: Internet
Author: User
Tags addchild

Collision detection can be divided into two categories: Collision Detection of objects and objects, and Collision Detection of objects and points.

To facilitate the test, first write a box class (generate a small rectangle)

 
Package {import flash. display. sprite; public class box extends sprite {private var W: Number; private var H: Number; private var color: uint; Public var VX: Number = 0; Public var Vy: number = 0; Public Function box (width: Number = 50, height: Number = 50, color: uint = 0xff0000) {W = width; H = height; this. color = color; Init ();} public function Init (): void {graphics. beginfill (color); graphics. drawrect (-W/2,-H/2, W, H); graphics. endfill ();}}}

The most basic object collision detection: hittestobject

Package {import flash. display. sprite; import flash. events. event; public class boxes extends sprite {private var box: box; private var boxes: array; private var gravity: Number = 0.1; Public Function boxes () {Init ();} private function Init (): void {boxes = new array (); createbox (); addeventlistener (event. enter_frame, onenterframe);} private function onenterframe (Event: Event): void {box. vy + = gravity; box. Y + = Box. vy; // such If the object falls to the bottom boundary of the stage, it will be recreated and dropped down if (box. Y + box. height/2> stage. stageheight) {box. y = stage. stageHeight-box.height/2; createbox ();} else {for (var I: uint = 0; I <boxes. length; I ++) {// Collision Detection of IF (box!) between each falling object and other objects! = Boxes [I] & box. hittestobject (boxes [I]) {box. y = Boxes [I]. y-boxes [I]. height/2-box.height/2; // If the heap is reached, stop if (box. Y <= Box. height/2) {removeeventlistener (event. enter_frame, onenterframe) ;}else {createbox () ;}}} private function createbox (): void {box = new box (math. random () * 40 + 10, math. random () * 40 + 10, math. random () * 0 xffffff); box. X = math. random () * stage. stagewidth; addchild (box); boxes. push (box );}}}

If you replace box with the ball in the previous example, it will look like the following:

Obviously: After the rectangle is changed to a ball, the collision detection becomes inaccurate. Some balls do not seem to have really crashed into other balls. Why?

 

The answer is: Flash object collision detection uses "rectangular boundary of objects" by default as the basis for detection. The two pictures above demonstrate this detail: although the first picture looks to have only two rectangles at the intersection, in the Flash view, in fact, every pair of images have been met (the second figure), so we should be able to understand why some balls will float in the air after being replaced by the ball.

Collision Detection between objects and points: hittestpoint

 
Package {import flash. display. sprite; import flash. events. event; import flash. text. textfield; public class pointhittest extends sprite {private var ball: ball; private var box: box; private var TXT: textfield = new textfield (); Public Function pointhittest () {Init ();} private function Init (): void {BALL = new ball; addchild (ball); ball. X = stage. stagewidth/2; ball. y = stage. stageheight/2; box = new box (90, 90); addchild ( Box); box. X = 100; box. y = ball. y; addeventlistener (event. enter_frame, enterframehandler); addchild (txt); TXT. selectable = false;} private function enterframehandler (Event: Event): void {If (ball. hittestpoint (mousex, Mousey) | box. hittestpoint (mousex, Mousey) {TXT. TEXT = "met! ";}Else {TXT. Text =" ";}txt. x = mousex + 15; TXT. Y = Mousey ;}}}

When you move the mouse over two objects, you can see the collision detection result between the point where the mouse is located and the rectangle and the ball. The problem also exists here: for the ball, the rectangular boundary is also used by default, so when you move the cursor to the corner of the ball, even though the ball has not been touched, it also prompts "hit". Fortunately, flash provides an optional parameter, to improve the detection accuracy, you only need to set the third optional parameter of hittestpoint to true.

If (ball. hittestpoint (mousex, Mousey) | box. hittestpoint (mousex, Mousey,True)){

Distance-based detection: checks whether the distance between the two objects between the centers is lower than the minimum distance.

VaR ball_1: ball = new ball (70, 0xff0000); var ball_2: ball = new ball (70, 0x0000ff); ball_1.x = stage. stagewidth/2; ball_1.y = stage. stageheight/2; ball_2.x = stage. stagewidth/2; ball_2.y = stage. stageheight/2; ball_1.vx = math. random () * 20-20; ball_1.vy = math. random () * 20-20; ball_2.vx = math. random () * 20-20; ball_2.vy = math. random () * 20-20; addchild (ball_1); addchild (ball_2); addeventlistener (event. enter_frame, enterframehandler); function enterframehandler (E: Event): void {ball_1.x + = ball_1.vx; ball_1.y + = balance; ball_2.x + = ball_2.vx; balance + = balance; checkboundary (ball_1 ); checkboundary (ball_2); var DX: Number = ball_1.x-ball_2.x; var DY: Number = ball_1.y-ball_2.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); If (Dist <(ball_1.radius + ball_2.radius) {var angle: Number = math. atan2 (dy, dx); ball_1.vx = DIST * Math. cos (angle) * 0.1; ball_1.vy = DIST * Math. sin (angle) * 0.1; ball_2.vx = DIST * Math. cos (angle) *-0.1; ball_2.vy = DIST * Math. sin (angle) *-0.1;} function checkboundary (B: ball) {If (B. x> stage. stageWidth-b.width/2 | B. x <= B. width/2) {B. x-= B. VX; B. VX * =-1;} If (B. y> stage. stageHeight-b.height/2 | B. Y <= B. height/2) {B. y-= B. vy; B. vy * =-1 ;}}

Obviously, this method is very accurate for circular objects, but it can only be approximate for irregular shapes.

If you combine the elastic motion mentioned in the previous two articles, you can make more complex animations:

Package {import flash. display. sprite; import flash. events. event; public class bubbles extends sprite {private var bils: array; private var numbils: Number = 10; private var centerball: ball; private var bounce: Number =-1; private var spring: Number = 0.2; Public Function bubbles () {Init ();} private function Init (): void {bballs = new array; centerball = new ball (xcccccc); addchild (centerball); centerball. X = stage. stagewidth/2; centerball. y = stage. stageheight/2; for (var I: uint = 0; I <numbils; I ++) {var ball: ball = new ball (math. random () * 40 + 5, math. random () * 0 xffffff); ball. X = math. random () * stage. stagewidth; ball. y = math. random () * stage. stageheight; ball. VX = (math. random () * 2-1) * 10; ball. vy = (math. random () * 2-1) * 10; addchild (ball); bballs. push (ball);} addeventlistener (event. enter_frame, onenterframe);} private function onenterframe (Event: Event): void {for (var I: uint = 0; I <numbils; I ++) {var ball: ball = bils [I]; move (ball); var DX: Number = ball. x-centerBall.x; var DY: Number = ball. y-centerBall.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); var mindist: Number = ball. radius + centerball. radius; If (Dist <mindist) {var angle: Number = math. atan2 (dy, dx); var TX: Number = centerball. X + math. cos (angle) * mindist; // point of the auto motion X coordinate var Ty: Number = centerball. Y + math. sin (angle) * mindist; // y coordinate ball of the auto-Moving Target point. VX + = (tx-ball.x) * spring; ball. vy + = (ty-ball.y) * spring ;}} private function move (ball: ball): void {ball. X + = ball. VX; ball. Y + = ball. vy; If (ball. X + ball. radius> stage. stagewidth) {ball. X = stage. stageWidth-ball.radius; ball. VX * = bounce;} else if (ball. x-ball.radius <0) {ball. X = ball. radius; ball. VX * = bounce;} If (ball. Y + ball. radius> stage. stageheight) {ball. y = stage. stageHeight-ball.radius; ball. vy * = bounce;} else if (ball. y-ball.radius <0) {ball. y = ball. radius; ball. vy * = bounce ;}}}}

Schematic:

Distance-based Collision Detection for multiple objects:

Package {import flash. display. sprite; import flash. events. event; public class bubbles2 extends sprite {private var bils: array; private var numbils: Number = 20; private var bounce: Number =-0.9; private var spring: Number = 0.2; private var gravity: Number = 1; Public Function bubbles2 () {Init ();} private function Init (): void {bballs = new array (); For (var I: uint = 0; I <numbils; I ++) {var ball: ball = new ball (math. random () * 30 + 20, math. random () * 0 xffffff); ball. X = math. random () * stage. stagewidth; ball. y = math. random () * stage. stageheight; ball. VX = math. random () * 6-3; ball. vy = math. random () * 6-3; addchild (ball); bils. push (ball);} addeventlistener (event. enter_frame, onenterframe);} private function onenterframe (Event: Event): void {for (var I: uint = 0; I <numbils-1; I ++) {var ball0: ball = bils [I]; for (var j: uint = I + 1; j <numbils; j ++) {var ball1: ball = bils [J]; var DX: number = ball1.x-ball0.x; var DY: Number = ball1.y-ball0.y; var Dist: Number = math. SQRT (dx * dx + dy * Dy); var mindist: Number = ball0.radius + ball1.radius; If (Dist <mindist) {/* var angle: Number = math. atan2 (dy, dx); var TX: Number = ball0.x + math. cos (angle) * mindist; var Ty: Number = ball0.y + math. sin (angle) * mindist; */var TX: Number = ball0.x + (dx/Dist) * mindist; var Ty: Number = ball0.y + (dy/Dist) * mindist; vaR ax: Number = (TX-ball1.x) * spring; var ay: Number = (ty-ball1.y) * spring; ball0.vx-= ax; ball0.vy-= Ay; ball1.vx + = ax; ball1.vy + = Ay ;}}for (I = 0; I <numbils; I ++) {var ball: ball = bils [I]; move (ball) ;}} private function move (ball: ball): void {ball. vy + = gravity; ball. X + = ball. VX; ball. Y + = ball. vy; If (ball. X + ball. radius> stage. stagewidth) {ball. X = stage. stageWidth-ball.radius; ball. VX * = bounce;} else if (ball. x-ball. radius <0) {ball. X = ball. radius; ball. VX * = bounce;} If (ball. Y + ball. radius> stage. stageheight) {ball. y = stage. stageHeight-ball.radius; ball. vy * = bounce;} else if (ball. y-ball. radius <0) {ball. y = ball. radius; ball. vy * = bounce ;}}}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.