27
2018
03

Libgdx Polygon多边形碰撞检测

libgdx中Math封装了Polygon这个类,它是由多个定点进行描述实现的,在进行物体间的碰撞时,物体轮廓有时候是不规则的,这时候可以用一个多边形勾勒出其大概的轮廓,对其进行模拟。

Polygon内部自带是否包含点contains这个函数,通过这个函数我们可以判断两个多变行是否碰撞,即检测两个多边形的每个点是否在另一个多边形中。

检测代码:

public static boolean isOverlap(Polygon polygon1, Polygon polygon2){
        for(int i=0; i<polygon2.getVertices().length; i+=2){
            if( polygon1.contains(polygon2.getVertices()[i], polygon2.getVertices()[i+1]) ){
                return true;
            }
        }
        for(int i=0; i<polygon1.getVertices().length; i+=2){
            if( polygon2.contains(polygon1.getVertices()[i], polygon1.getVertices()[i+1]) ){
                return true;
            }
        }
        return false;
    }
package com.fxb.Gam003;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Polygon;
import com.badlogic.gdx.math.Vector2;

public class Lib051_Polygon extends ApplicationAdapter{

    Polygon polygon1, polygon2;
    ShapeRenderer rend;
    float[] vertices1, vertices2;
    Vector2 point = new Vector2(100, 50);
    
    InputAdapter adapter = new InputAdapter(){
        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {            
            for(int i=0; i<polygon2.getVertices().length; i+=2){
                polygon2.getVertices()[i  ] += screenX - point.x;
                polygon2.getVertices()[i+1] += Gdx.graphics.getHeight()-screenY - point.y;
            }
            polygon2.dirty();
            
            point.set(screenX, Gdx.graphics.getHeight()-screenY);
            //polygon2.setVertices(new float[]{ 100+point.x, 50+point.y, 200+point.x, 70+point.y, 300+point.x, 150+point.y, 150+point.x, 100+point.y});
                        
            return true;
        }
        
    };
    
    @Override
    public void create() {
        // TODO Auto-generated method stub
        super.create();
        
        polygon1 = new Polygon();
        vertices1 = new float[]{ 100, 100, 200, 100, 300, 300, 100, 200 };
        polygon1.setVertices(vertices1);
        
        vertices2 = new float[]{ 100, 50, 200, 70, 300, 150, 150, 100};
        polygon2 = new Polygon(vertices2);
        
        rend = new ShapeRenderer();
        Gdx.input.setInputProcessor(adapter);
    }

    
    public static boolean isOverlap(Polygon polygon1, Polygon polygon2){
        for(int i=0; i<polygon2.getVertices().length; i+=2){
            if( polygon1.contains(polygon2.getVertices()[i], polygon2.getVertices()[i+1]) ){
                return true;
            }
        }
        for(int i=0; i<polygon1.getVertices().length; i+=2){
            if( polygon2.contains(polygon1.getVertices()[i], polygon1.getVertices()[i+1]) ){
                return true;
            }
        }
        return false;
    }
    
    
    
    @Override
    public void render() {
        // TODO Auto-generated method stub
        super.render();
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        Gdx.gl.glClearColor(1, 1, 1, 1);
        
        rend.begin(ShapeType.Line);
        rend.setColor(Color.RED);
        for(int i=0; i<polygon1.getVertices().length; i+=2){
            rend.line(vertices1[i], vertices1[i+1], vertices1[(i+2)%vertices1.length], vertices1[(i+3)%vertices1.length]);
        }
        
        float[] vertices3 = polygon2.getVertices();
        for(int i=0; i<polygon2.getVertices().length; i+=2){
            rend.line(vertices3[i], vertices3[i+1], vertices3[(i+2)%vertices3.length], vertices3[(i+3)%vertices3.length]);
        }
        rend.end();
        
        //if(polygon1.contains(point.x, point.y)){
        if( isOverlap(polygon1, polygon2) ){
            rend.setColor(Color.RED);
        }else{
            rend.setColor(Color.BLUE);
        }
        rend.begin(ShapeType.Filled);
        rend.circle(point.x, point.y, 5);
        rend.end();
        
    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub
        super.dispose();
    }

}

运行结果:

  

展示了三种情况,当然,这里只是进行简单的测试,可以任意绘制多边形进行检测。


上一篇:Libgdx之正交相机 OrthographicCamera 下一篇:Java+Jquery实现转盘抽奖系统