| 前言到目前为止,我们或许已经可以制作一个类似于 谷歌小恐龙 这样的小游戏了,但是,当实际操作起来的时候,我们会发现:如何检测小恐龙与障碍物之间的碰撞?不会吧?碰撞检测很复杂的,难道还要自己造轮子?不不不, libGDX 自身提供了碰撞检测的方法:使用com.badloc.gdx.math.Rectangle类。 Rectangle 碰撞检测Rectangle 类创建一个矩形,它提供了碰撞检测,它的常用构造方法如下: Rectangle() : 创建一个空的矩形,坐标宽高都为0Rectangle(Rectangle rect) : 以 rect 创建一个新的矩形Rectangle(float x,float y,float width,float height) : 创建一个(x,y)且大小 width*height 的矩形
 Rectangle de 使用Rectangle 类包含了对矩形的各种操作: 
rect.setX(x);
rect.x=x;
rect.setY(y);
rect.y=y;
rect.setPosition(x,y);
rect.setWidth(width);
rect.width=width;
rect.setHeight(height);
rect.height=height;
rect.setSize(width,height);
rect.setBounds(x,y,width,height);
 Rectangle 还有如上讲到的碰撞检测方法: 
boolean isContains=rect.contains(x,y);
isContains=rect.contains(vec2);
isContains=rect.contains(rect2);
isEquals=rect.equals(rect2);
isOverlaps=rect.overlaps(rect2);
 碰撞深度检测游戏中,很多的物体并不是一撞到就死,更多的只是拦截而已,也就是 碰撞箱,但 libGDX 并不提供碰撞箱,因此,我们需要造轮子。 碰撞箱目的是让两个物体无法重叠,因此我们只要求出两个 Rectangle 碰撞的深度,再根据深度移出某一个 Rectangle 就可以实现 碰撞箱 ,只需要两个方法: 
public float testCollisionHeight(Rectangle rect,Rectangle otherRect) {
	if(!(rect.overlaps(otherRect)))return 0;	
	
	if(rect.y>otherRect.y)
		
		return ( ( otherRect.height + otherRect.y ) - rect.y );
	else
		
		return  - ( ( rect.height + rect.y ) - otherRect.y ) ;
}
	
public float testCollisionWidth(Rectangle rect,Rectangle otherRect) {
	if(!(rect.overlaps(otherRect)))return 0;	
	
	if(rect.x>otherRect.x)
		
		return  ( ( otherRect.width + otherRect.x ) - rect.x );
	else
		
		return -( ( rect.width + rect.x ) - otherRect.x );
}
 上面两个方法返回的是 rect 应该向 x和y 移动多少(加法),也就是说,rect 是被动的,例如游戏中可以推的箱子等等,而 otherRect 是主动的,例如推箱子的角色等等。 实例:互推为测试它们是否真的有效,我们举一个实例:
 下载这张图片,命名为 badlogic.png 放在 asset 文件夹
 
  package com.libGDX.test;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
public class Test extends ApplicationAdapter {
	private SpriteBatch batch;
	
	private Texture texture;
	
	private Sprite left;
	private Sprite right;
	
	private boolean before;
	@Override
	public void create() {
		batch=new SpriteBatch();
		
		texture=new Texture(Gdx.files.internal("badlogic.png"));
		
		
		left=new Sprite(texture);
		right=new Sprite(texture);
		
		
		left.setBounds(0,200,100,100);
		right.setBounds(400,200,100,100);
		
		
		before=true;
	}
	
	@Override
	public void render() {
		
		Gdx.gl.glClearColor(1,1,1,1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		
		act(Gdx.graphics.getDeltaTime());
		
		batch.begin();
		
		left.draw(batch);
		right.draw(batch);
		batch.end();
	}
	
	
	private void act(float delta) {
		
		if(Gdx.input.justTouched())before=!before;
		
		
		left.setX(left.getX()+100*delta);
		right.setX(right.getX()-100*delta);
		
		if(before)
			
			right.setX(right.getX()+testCollisionWidth(right.getBoundingRectangle(), left.getBoundingRectangle()));
		else 
			
			left.setX(left.getX()+testCollisionWidth(left.getBoundingRectangle(),right.getBoundingRectangle()));
	}
	
	
	public float testCollisionHeight(Rectangle rect,Rectangle otherRect) {
		if(!(rect.overlaps(otherRect)))return 0;	
		
		if(rect.y>otherRect.y)
			
			return ( ( otherRect.height + otherRect.y ) - rect.y );
		else
			
			return  - ( ( rect.height + rect.y ) - otherRect.y ) ;
	}
	
	
	public float testCollisionWidth(Rectangle rect,Rectangle otherRect) {
		if(!(rect.overlaps(otherRect)))return 0;	
		
		if(rect.x>otherRect.x)
			
			return  ( ( otherRect.width + otherRect.x ) - rect.x );
		else
			
			return -( ( rect.width + rect.x ) - otherRect.x );
	}
	@Override
	public void dispose(){
		batch.dispose();
		texture.dispose();
	}
 运行结果:  
  
 
 实例 :小恐龙躲障碍学会了如此6批的东西,怎能不大展身手一番?那么,我们做一个小恐龙躲障碍(类似谷歌小恐龙)的小游戏吧!下载下面两张图片,命名为 dinasour.png 和 cacti.png ,放到 asset 文件夹
  
 
 在项目下创建 data 文件夹,再添加 scoreMax.txt: 
 package com.libGDX.test;
import java.util.Random;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.Array;
public class Test extends ApplicationAdapter {
	private SpriteBatch batch;
	
	private Texture cactiTexture;
	private Texture dinasourTexture;
	private Array<Sprite> cactis;	
	private Sprite dinasour;	
	private Random r;	
	private int time;	
	private int jump;	
	private int score;	
	private FileHandle scoreFile;	
	private BitmapFont font;	
	private int maxScore;	
	
	public final int WORLD_WIDTH=500;	
	public final int WORLD_HEIGHT=200;
	
	@Override
	public void create() {
		batch=new SpriteBatch();
		
		cactiTexture=new Texture(Gdx.files.internal("cacti.png"));
		dinasourTexture=new Texture(Gdx.files.internal("dinasour.png"));
		cactis=new Array<>();
		dinasour=new Sprite(dinasourTexture);
		
		r=new Random();
		
		
		scoreFile=new FileHandle("data/scoreMax.txt");
		String str=scoreFile.readString();
		if(str.equals(""))maxScore=0;	
		else maxScore=Integer.valueOf(str);
		
		font=new BitmapFont();
		font.setColor(Color.BLACK);
		font.getData().setScale(3);
		reset();
	}
	
	@Override
	public void render() {
		Gdx.gl.glClearColor(1,1,1,1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		act(Gdx.graphics.getDeltaTime());
		batch.begin();	
		
		for(Sprite s : cactis)
			s.draw(batch);
		
		dinasour.draw(batch);
		font.draw(batch,"UI  "+String.valueOf(maxScore)+"    "+String.valueOf(score),150,170);
		batch.end();
	}
	
	
	private void reset() {
		
		dinasour.setBounds(50,0,60,60);
		
		maxScore=Integer.valueOf(scoreFile.readString());
		
		score=0;
		
		jump=0;
		
		time=0;
		
		for(int i=cactis.size-1;i>=0;--i) {
			cactis.removeIndex(i);
		}
	}
	
	
	private void act(float delta) {
		
		time+=delta*100;
		
		if(dinasour.getY()==0&&Gdx.input.justTouched())jump=18;
		
		dinasour.setY(dinasour.getY()+jump);
		
		if(dinasour.getY()>0)jump-=delta*60;
		else {	
			dinasour.setY(0);
			jump=0;
		}
		
		
		if(time%10==0)score++;
		
		
		if(time%40==0&&r.nextInt(2)==0) {
			Sprite cacti=new Sprite(cactiTexture);
			
			cacti.setBounds(WORLD_WIDTH, 0, 50,r.nextInt(20)+40);
			
			cactis.add(cacti);
		}
		
		Sprite cacti;
		
		for(int i=cactis.size-1;i>=0;--i) {
			
			cacti=cactis.get(i);
			
			cacti.setX(cacti.getX()-500*delta);
			
			if(dinasour.getBoundingRectangle().overlaps(cacti.getBoundingRectangle())) {
				
				if(score>maxScore)scoreFile.writeString(String.valueOf(score),false);
					reset();
			}
			
			if(cacti.getX()<0-50)
				cactis.removeIndex(i);
		}
		
		
	}
	
	@Override
	public void dispose() {
		batch.dispose();
		dinasourTexture.dispose();
		cactiTexture.dispose();
	}
}
 运行结果:
  |