package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import flash.events.Event;
public class ConcaveCollisionExample extends Sprite {
private var poly1Sprite:Sprite;
private var poly2Sprite:Sprite;
private var resultTF:TextField;
// 多边形本地坐标(相对于各自Sprite)
private var poly1Local:Array = [
new Point(0, 0),
new Point(100, 0),
new Point(100, 100),
new Point(50, 50),
new Point(0, 100)
];
private var poly2Local:Array = [
new Point(0, 0),
new Point(100, 0),
new Point(100, 100),
new Point(50, 50),
new Point(0, 100)
];
public function ConcaveCollisionExample() {
createPolygons();
setupInteraction();
createResultDisplay();
updateCollision();
}
private function createPolygons():void {
// 创建并绘制红色多边形
poly1Sprite = new Sprite();
poly1Sprite.x = 100;
poly1Sprite.y = 100;
drawPolygon(poly1Sprite, poly1Local, 0xFF0000);
addChild(poly1Sprite);
// 创建并绘制蓝色多边形
poly2Sprite = new Sprite();
poly2Sprite.x = 180;
poly2Sprite.y = 150;
drawPolygon(poly2Sprite, poly2Local, 0x0000FF);
addChild(poly2Sprite);
}
private function drawPolygon(target:Sprite, points:Array, color:uint):void {
target.graphics.clear();
target.graphics.lineStyle(2, 0x000000);
target.graphics.beginFill(color, 0.5);
target.graphics.moveTo(points[0].x, points[0].y);
for (var i:int = 1; i < points.length; i++) {
target.graphics.lineTo(points[i].x, points[i].y);
}
target.graphics.lineTo(points[0].x, points[0].y);
target.graphics.endFill();
}
private function setupInteraction():void {
// 启用交互
poly1Sprite.buttonMode = true;
poly2Sprite.buttonMode = true;
// 添加事件监听
poly1Sprite.addEventListener(MouseEvent.MOUSE_DOWN, startDragPoly);
poly2Sprite.addEventListener(MouseEvent.MOUSE_DOWN, startDragPoly);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDragPoly);
}
private function createResultDisplay():void {
resultTF = new TextField();
resultTF.defaultTextFormat = new TextFormat("Arial", 20, 0x000000);
resultTF.x = 50;
resultTF.y = 300;
resultTF.width = 300;
addChild(resultTF);
}
private function startDragPoly(e:MouseEvent):void {
e.target.startDrag();
addEventListener(Event.ENTER_FRAME, updateCollision);
}
private function stopDragPoly(e:MouseEvent):void {
stopDrag();
removeEventListener(Event.ENTER_FRAME, updateCollision);
updateCollision();
}
private function updateCollision(e:Event = null):void {
// 转换本地坐标为全局坐标
var poly1Global:Array = convertLocalToGlobal(poly1Local, poly1Sprite);
var poly2Global:Array = convertLocalToGlobal(poly2Local, poly2Sprite);
// 检测碰撞
var collision:Boolean = checkCollision(poly1Global, poly2Global);
resultTF.text = "碰撞检测结果: " + collision;
}
private function convertLocalToGlobal(localPoints:Array, sprite:Sprite):Array {
var globalPoints:Array = [];
for each (var p:Point in localPoints) {
globalPoints.push(new Point(sprite.x + p.x, sprite.y + p.y));
}
return globalPoints;
}
// 以下碰撞检测方法保持不变
private function checkCollision(polyA:Array, polyB:Array):Boolean {
for (var i:int = 0; i < polyA.length; i++) {
var a1:Point = polyA[i];
var a2:Point = polyA[(i + 1) % polyA.length];
for (var j:int = 0; j < polyB.length; j++) {
var b1:Point = polyB[j];
var b2:Point = polyB[(j + 1) % polyB.length];
if (segmentsIntersect(a1, a2, b1, b2)) {
return true;
}
}
}
for each (var p:Point in polyA) {
if (isPointInPolygon(p, polyB)) return true;
}
for each (p in polyB) {
if (isPointInPolygon(p, polyA)) return true;
}
return false;
}
private function segmentsIntersect(a1:Point, a2:Point, b1:Point, b2:Point):Boolean {
var denominator:Number = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
if (denominator == 0) return false;
var ua:Number = ((b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x)) / denominator;
var ub:Number = ((a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x)) / denominator;
return ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1;
}
private function isPointInPolygon(p:Point, polygon:Array):Boolean {
var inside:Boolean = false;
for (var i:int = 0, j:int = polygon.length - 1; i < polygon.length; j = i++) {
var pi:Point = polygon[i];
var pj:Point = polygon[j];
if (((pi.y > p.y) != (pj.y > p.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) {
inside = !inside;
}
}
return inside;
}
}
}