LibGDX_7.4: 碰撞检测 与 矩形包围区域(Rectangle)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xietansheng/article/details/50188157

本文链接: http://blog.csdn.net/xietansheng/article/details/50188157

LibGDX 基础教程(总目录)

1. Rectangle 概述

Rectangle 类表示一个 2D 矩形,封装了 2D 矩形的 左下角坐标 和 宽高。通常用 Rectangle 来表示 Texture/Sprite/Actor 在舞台中的包围区域,并用 Rectangle 中的方法进行方便的碰撞检测。

2. 碰撞检测

在游戏中的碰撞非常常见,例如 主角与地板的碰撞、主角与障碍物的碰撞、主角与怪物的碰撞、子弹与怪物的碰撞等。在游戏中需要对这些碰撞实时检测,并根据检测结果做出相应的处理。

在程序中通常先获取到主角/地板/障碍物/子弹/怪物的包围矩形 Rectangle,然后在通过 Rectangle 中的方法进行碰撞关系判断。

Rectangle 类常用构造方法:

// 默认构造方法, 坐标宽高全为 0
public Rectangle();

// 通过指定的 左下角坐标点 和 宽高 创建矩形对象
public Rectangle(float x, float y, float width, float height);

Rectangle 类中主要的检测方法如下:

// 矩形是否包含指定的点(指定的点是否在矩形中)
boolean contains(float x, float y)
boolean	contains(Vector2 point)

// 矩形是否包含指定的矩形(otherRect 矩形是否完全在 this 矩形内)
boolean	contains(Rectangle otherRect)// 判断两个矩形是否相同(坐标和宽高是否都相等)
boolean	equals(Object obj) 

// 矩形是否和指定的矩形有重叠部分(是否有碰撞)
boolean overlaps(Rectangle otherRect);

3. 代码示例

这里需要前面章节中常用的两张图片(badlogic.jpglogo.png,直接放到 assets 文件夹下)。

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.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.actions.MoveToAction;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.utils.viewport.StretchViewport;

/**
 * 游戏主程序的启动入口类
 */
public class MainGame extends ApplicationAdapter {

    // 视口世界的宽高统使用 480 * 800, 并统一使用伸展视口(StretchViewport)
    public static final float WORLD_WIDTH = 480;
    public static final float WORLD_HEIGHT = 800;

    // 舞台
    private Stage stage;

    // 纹理
    private Texture badlogicTexture;
    private Texture logoTexture;

    // 演员(这里直接使用 Image 来表示演员)
    private Image badlogicActor;
    private Image logoActor;

    // 演员的包围矩形
    private final Rectangle badlogicRect = new Rectangle();
    private final Rectangle logoRect = new Rectangle();

	@Override
	public void create() {
        // 使用伸展视口(StretchViewport)创建舞台
        stage = new Stage(new StretchViewport(WORLD_WIDTH, WORLD_HEIGHT));

        // 创建纹理
        badlogicTexture = new Texture(Gdx.files.internal("badlogic.jpg"));
        logoTexture = new Texture(Gdx.files.internal("logo.png"));

        // 创建演员
        badlogicActor = new Image(badlogicTexture);
        logoActor = new Image(logoTexture);

        // 设置演员初始位置
        badlogicActor.setPosition(
                stage.getWidth() / 2 - badlogicActor.getWidth() / 2,
                stage.getHeight() / 2 - badlogicActor.getHeight() / 2
        );
        logoActor.setPosition(0, 0);

        // 添加演员到舞台
        stage.addActor(badlogicActor);
        stage.addActor(logoActor);

        // 给 logo 演员附加一个动作
        MoveToAction action = Actions.moveTo(150, 700, 5.0F);
        logoActor.addAction(action);
    }

	@Override
	public void render() {
		// 白色清屏
		Gdx.gl.glClearColor(1, 1, 1, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // 更新舞台逻辑
        stage.act();

        // 碰撞检测
        checkCollision();

        // 绘制舞台
        stage.draw();
	}

    /**
     * 碰撞检测
     */
    private void checkCollision() {
        /*
         * 获取演员的包围矩形
         *
         * 注意: 如果对演员进行了缩放旋转等变换, 需要获取的是变换后视觉上的包围矩形,
         * 后续的引擎封装中将详细介绍。
         */
        badlogicRect.set(
                badlogicActor.getX(),
                badlogicActor.getY(),
                badlogicActor.getWidth(),
                badlogicActor.getHeight()
        );
        logoRect.set(
                logoActor.getX(),
                logoActor.getY(),
                logoActor.getWidth(),
                logoActor.getHeight()
        );

        // 判断两个演员是否碰撞, 如果碰撞, 则将 badlogicActor 设置为半透明
        if (badlogicRect.overlaps(logoRect)) {
            badlogicActor.getColor().a = 0.5F;
        } else {
            badlogicActor.getColor().a = 1.0F;
        }
    }

	@Override
	public void dispose() {
		// 当应用退出时释放资源
		if (stage != null) {
            stage.dispose();
		}
        if (badlogicTexture != null) {
            badlogicTexture.dispose();
		}
        if (logoTexture != null) {
            logoTexture.dispose();
		}
	}

}

展开阅读全文

没有更多推荐了,返回首页