基于 Android 和 JBox2D 的简单小游戏

以下是一个基于 Android 和 JBox2D 的简单小游戏开发示例,实现一个小球在屏幕上弹跳的效果:

1. 添加 JBox2D 依赖

在项目的 build.gradle 文件中添加 JBox2D 的依赖:

复制代码
dependencies {
    implementation 'org.jbox2d:jbox2d-library:2.3.1'
}

2. 创建物理世界和刚体

创建一个类 JBoxImpl,用于封装 JBox2D 的逻辑:

复制代码
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.EdgeShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.*;

public class JBoxImpl {
    private World world;
    private float widthWorld = 10f; // 世界宽度
    private float heightWorld = 10f; // 世界高度
    private float ratioForBox2dToScreen; // 屏幕与世界的比例

    public JBoxImpl() {
        world = new World(new Vec2(0f, -10f)); // 重力向下
    }

    public void onSizeChanged(int width, int height) {
        ratioForBox2dToScreen = width / widthWorld;
        initEdges(width, height);
    }

    private void initEdges(int width, int height) {
        // 创建边界
        float widthScreen = width;
        float heightScreen = height;
        float widthWorld = widthScreen / ratioForBox2dToScreen;
        float heightWorld = heightScreen / ratioForBox2dToScreen;

        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.STATIC;

        EdgeShape edgeShape = new EdgeShape();
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = edgeShape;
        fixtureDef.density = 1f;
        fixtureDef.restitution = 1f; // 完全弹性碰撞

        // 创建四个边界
        Body groundBody = world.createBody(bodyDef);
        edgeShape.set(new Vec2(0, 0), new Vec2(widthWorld, 0));
        groundBody.createFixture(fixtureDef);

        edgeShape.set(new Vec2(widthWorld, 0), new Vec2(widthWorld, heightWorld));
        groundBody.createFixture(fixtureDef);

        edgeShape.set(new Vec2(widthWorld, heightWorld), new Vec2(0, heightWorld));
        groundBody.createFixture(fixtureDef);

        edgeShape.set(new Vec2(0, heightWorld), new Vec2(0, 0));
        groundBody.createFixture(fixtureDef);
    }

    public Body createBall(float x, float y, float radius) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DYNAMIC;
        bodyDef.position.set(x / ratioForBox2dToScreen, y / ratioForBox2dToScreen);

        CircleShape circleShape = new CircleShape();
        circleShape.m_radius = radius / ratioForBox2dToScreen;

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circleShape;
        fixtureDef.density = 1f;
        fixtureDef.restitution = 1f; // 完全弹性碰撞

        Body ballBody = world.createBody(bodyDef);
        ballBody.createFixture(fixtureDef);
        return ballBody;
    }

    public void step() {
        world.step(1f / 60f, 8, 3); // 更新物理世界
    }

    public World getWorld() {
        return world;
    }

    public float getRatioForBox2dToScreen() {
        return ratioForBox2dToScreen;
    }
}

3. 创建自定义 View 进行绘制

创建一个自定义 View,用于绘制小球:

复制代码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class JBoxView extends View {
    private JBoxImpl jBoxImpl;
    private Paint paint;

    public JBoxView(Context context, AttributeSet attrs) {
        super(context, attrs);
        jBoxImpl = new JBoxImpl();
        paint = new Paint();
        paint.setColor(0xFFFF0000); // 红色
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        jBoxImpl.onSizeChanged(w, h);
        jBoxImpl.createBall(w / 2, h / 2, 50); // 创建一个小球
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        jBoxImpl.step(); // 更新物理世界

        for (Body body = jBoxImpl.getWorld().getBodyList(); body != null; body = body.getNext()) {
            if (body.getType() == BodyType.DYNAMIC) {
                float x = body.getPosition().x * jBoxImpl.getRatioForBox2dToScreen();
                float y = body.getPosition().y * jBoxImpl.getRatioForBox2dToScreen();
                float radius = ((CircleShape) body.getFixtureList().get(0).getShape()).m_radius * jBoxImpl.getRatioForBox2dToScreen();
                canvas.drawCircle(x, y, radius, paint);
            }
        }
        invalidate(); // 重绘
    }
}

4. 在布局中使用自定义 View

在布局文件中添加自定义 JBoxView

复制代码
<com.example.jbox2dgame.JBoxView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

5. 运行效果

运行程序后,你将看到一个小球在屏幕上弹跳。

相关推荐
柚鸥ASO优化1 分钟前
一篇讲透安卓ASO!开发者千万别只盯着iOS了
android·ios·aso优化
木易 士心2 分钟前
compileSdkVersion、minSdkVersion 和 targetSdkVersion —— Android 三个核心的 SDK 版本配置
android
人道领域3 分钟前
为什么iPhone微信聊天记录搜不到“?“,而安卓可以。
android·微信·iphone
火山上的企鹅1 小时前
Codex实战:APP远程升级服务搭建(四)Node 服务端自动识别 APK 信息
android·服务器·git·github·qgc
JohnnyDeng941 小时前
【Android】ViewModelScope 与协程生命周期管理:告别内存泄漏,掌控异步边界
android·kotlin·mvvm·协程
私人珍藏库2 小时前
【Android】瞬净ins版-无水印解析-无水印视频保存
android·app·工具·软件·多功能
Maxwellhang2 小时前
Termux 安装 Claude Code + 配置 DeepSeek API
android·智能手机
百度搜知知学社2 小时前
一键装裱照片,相框APP内置滤镜与贴纸编辑器
android·编辑器·滤镜·图片编辑·贴纸·相框
AFinalStone3 小时前
Android12 U盘插拔链路源码全解析(四):Framework层(上) —— UsbHostManager
android·frameworks
qq3621967053 小时前
第三方安卓应用商店安全评测 2026:Appteka、Aptoide、APKPure 等 7 家横评
android·网络·人工智能·安全·chatgpt·智能手机