当前位置: 首页 > article >正文

基于 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);}@Overrideprotected 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); // 创建一个小球}@Overrideprotected 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.JBoxViewandroid:layout_width="match_parent"android:layout_height="match_parent" />

5. 运行效果

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

http://www.lryc.cn/news/2399242.html

相关文章:

  • 传输层协议 UDP 介绍 -- UDP 协议格式,UDP 的特点,UDP 的缓冲区
  • Python try-except-else 语句详解
  • ApacheSuperset CVE-2023-27524
  • Windows Server部署Vue3+Spring Boot项目
  • malloc 是如何分配内存的?——C 语言内存分配详解
  • Opencl
  • 如何在 HTML 中添加按钮
  • 【优秀三方库研读】quill 开源库中的命名空间为什么要用宏封装
  • AlphaFold3运行错误及解决方法(1)
  • Linux--进程的程序替换
  • 调教 DeepSeek - 输出精致的 HTML MARKDOWN
  • 【笔记】Windows系统部署suna基于 MSYS2的Poetry 虚拟环境backedn后端包编译失败处理
  • GQA(Grouped Query Attention):分组注意力机制的原理与实践《一》
  • 【深度学习优化算法】02:凸性
  • JAVA国际版一对一视频交友视频聊天系统源码支持H5+APP
  • 策略公开了:年化494%,夏普比率5.86,最大回撤7% | 大模型查询akshare,附代码
  • 【C++】string类的模拟实现(详解)
  • 业界宽松内存模型的不统一而导致的软件问题, gcc, linux kernel, JVM
  • 多模态大语言模型arxiv论文略读(101)
  • 量化Quantization初步之--带量化(QAT)的XOR异或pyTorch版250501
  • Linux Maven Install
  • #Java篇:学习node后端之sql常用操作
  • 电网“逆流”怎么办?如何实现分布式光伏发电全部自发自用?
  • 如何查看电脑电池性能
  • kubernetes》》k8s》》kubectl proxy 命令后面加一个
  • 深入理解Linux系统进程切换
  • 网络安全运维实训室建设方案
  • DBeaver 连接mysql报错:CLIENT_PLUGIN_AUTH is required
  • 联通专线赋能,亿林网络裸金属服务器:中小企业 IT 架构升级优选方案
  • Web3时代的数据保护挑战与应对策略