libGDX游戏开发之Box2D(十四)
libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm…国内用libgdx比较少,多数情况需要去官网和google找资料,相互学习的可以加我联系方式。

Box2D碰撞,可以在世界添加ContactListener,并给物体添加不同的类别用以区分玩家、障碍与敌人。可以基于此,尝试开发酷跑类游戏。

一、碰撞

初始化时:

world.setContactListener(new ContactListener() {
@Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
int de = fixtureA.getFilterData().categoryBits + fixtureB.getFilterData().categoryBits;
switch (de) {
case playerBits | groundBits:
System.out.println("玩家与地面接触");
break;
case playerBits | badlogicBits: {
System.out.println("玩家与障碍物接触");
break;
}
} // if(fixtureB.getBody()==dogBody){
// System.out.println(1);
// System.out.println(fixtureB.getType());
// } // System.out.println(fixtureA.getFilterData().categoryBits);
// System.out.println(fixtureB.getFilterData().categoryBits);
// System.out.println(fixtureA.getType());// 返回碰撞类型:圆、多边形、边等等... // 测试这个点 (6,6)世界坐标 是否与fixtureB这个形状重叠,注意是世界坐标
//fixtureB.testPoint(6,6);
} @Override
public void endContact(Contact contact) { } @Override
public void preSolve(Contact contact, Manifold oldManifold) { } @Override
public void postSolve(Contact contact, ContactImpulse impulse) { }
});

基于上一篇的完整代码:

/**
* @author lingkang
*/
public class MyBox2D extends ApplicationAdapter {
private SpriteBatch batch;
private TextureRegion img, dog;
private OrthographicCamera camera; private World world;
private Box2DDebugRenderer debugRenderer;
private Body dogBody;
// 正常像素下物体重力现象不明显,需要对纹理进行缩小100++倍才比较明细的物理效果
private float reduce = 100;// 缩小100 倍易于观察到物理现象
private boolean isJump;
private final static short playerBits = 1;
private final static short groundBits = 2;
private final static short badlogicBits = 4; @Override
public void create() {
batch = new SpriteBatch();
// 创建一个相机, 这里缩小64倍,因为要观察的物体需要缩小100倍
camera = new OrthographicCamera();
camera.setToOrtho(false, Gdx.graphics.getWidth() / 64, Gdx.graphics.getHeight() / 64); // 图片一: 50*50 缩小100倍就是 0.5*0.5 在绘制时缩小的
dog = new TextureRegion(new Texture("dog.jpg"), 50, 50);
// 图片二: 256*256 ...
img = new TextureRegion(new Texture("badlogic.jpg"), 256, 256); // 创建一个世界,里面的重力加速度为 10
world = new World(new Vector2(0, -10), true);
// 试调渲染,可以使用这个渲染观察到我们用Box2D绘制的物体图形
debugRenderer = new Box2DDebugRenderer(); // 创建一个地面,其实是一个静态物体,这里我们叫它地面,玩家可以走在上面
BodyDef groundBodyDef = new BodyDef();
groundBodyDef.type = BodyDef.BodyType.StaticBody;// 静态的质量为0
groundBodyDef.position.x = 0;// 位置
groundBodyDef.position.y = 0;
// 创建这个地面的身体,我们对这个物体
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();// 物体的形状,这样创建是矩形的
groundBox.setAsBox(Gdx.graphics.getWidth(), 10);// 物体的宽高
FixtureDef groundFixtureDef = new FixtureDef();
groundFixtureDef.shape = groundBox;
// 配置一个碰撞的类别,用于碰撞判定是谁,
groundFixtureDef.filter.categoryBits = groundBits;
groundBody.createFixture(groundFixtureDef); // 创建一个静态物体
BodyDef badlogicBodyDef = new BodyDef();
badlogicBodyDef.type = BodyDef.BodyType.StaticBody;
badlogicBodyDef.position.x = 10;
badlogicBodyDef.position.y = 10 + 1.28f; // + 1.28是因为图片由中心绘制的 也可以写成 + 256/2/100
Body badlogicBody = world.createBody(badlogicBodyDef);
PolygonShape badlogicBox = new PolygonShape();
badlogicBox.setAsBox(256 / 2 / reduce, 256 / 2 / reduce);// 图形绘制是由中心绘制的,所以要除一半
FixtureDef badlogicFixtureDef = new FixtureDef();
badlogicFixtureDef.shape = badlogicBox;
// 配置一个碰撞的类别,用于碰撞判定是谁,
badlogicFixtureDef.filter.categoryBits = badlogicBits;
//badlogicFixtureDef.density=0;// 静态物体的质量应该设为0 默认是0
badlogicBody.createFixture(badlogicFixtureDef); // 再添加一个动态物体,可以把他看成玩家
BodyDef dogBodyDef = new BodyDef();
dogBodyDef.type = BodyDef.BodyType.DynamicBody;
dogBodyDef.position.x = 10;
dogBodyDef.position.y = 20;
dogBody = world.createBody(dogBodyDef);
PolygonShape dynamicBox = new PolygonShape();
dynamicBox.setAsBox(50 / 2 / reduce, 50 / 2 / reduce); // 给玩家添加一些属性
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicBox;// 形状
fixtureDef.restitution = 0.2f; // 设置这个值后,物体掉落到地面就会弹起一点高度...
// 配置一个碰撞的类别,用于碰撞判定是谁,
fixtureDef.filter.categoryBits = playerBits;
dogBody.createFixture(fixtureDef).setUserData(this);//设置自定义数据可以从这个物体获取这个数据对象 // 上面的图形要处理掉
groundBox.dispose();
dynamicBox.dispose(); world.setContactListener(new ContactListener() {
@Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
int de = fixtureA.getFilterData().categoryBits + fixtureB.getFilterData().categoryBits;
switch (de) {
case playerBits | groundBits:
System.out.println("玩家与地面接触");
break;
case playerBits | badlogicBits: {
System.out.println("玩家与障碍物接触");
break;
}
} // if(fixtureB.getBody()==dogBody){
// System.out.println(1);
// System.out.println(fixtureB.getType());
// } // System.out.println(fixtureA.getFilterData().categoryBits);
// System.out.println(fixtureB.getFilterData().categoryBits);
// System.out.println(fixtureA.getType());// 返回碰撞类型:圆、多边形、边等等... // 测试这个点 (6,6)世界坐标 是否与fixtureB这个形状重叠,注意是世界坐标
//fixtureB.testPoint(6,6);
} @Override
public void endContact(Contact contact) { } @Override
public void preSolve(Contact contact, Manifold oldManifold) { } @Override
public void postSolve(Contact contact, ContactImpulse impulse) { }
});
} @Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // 获取 物体的位置
Vector2 position = dogBody.getPosition(); // 将相机与批处理精灵绑定
camera.position.set(position.x, position.y, 0);
camera.update(); // 将绘制与相机投影绑定 关键 关键
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(img, 10 - 1.28f, 10, 0, 0, 256, 256, 0.01f, 0.01f, 0);
batch.draw(dog, position.x - 50 / 2 / reduce, position.y - 50 / 2 / reduce, // 设置位置 减少 50/2/reduce 是为了和物体的形状重合
0, 0, 50, 50, // 绘制图片的一部分,这里就是全部了
1 / reduce, 1 / reduce, // 缩小100倍
0 // 不旋转
);
batch.end(); // 获取五星的线速度
Vector2 linearVelocity = dogBody.getLinearVelocity();
if (Gdx.input.isKeyPressed(Input.Keys.D) && linearVelocity.x <= 2) { // 现在最大速度为 2,不然会放飞自我
// 施加冲动 让物体运行起来,可以看成我们推一下物体就往一边移动了
dogBody.applyLinearImpulse(new Vector2(0.1f, 0), dogBody.getWorldCenter(), true);
}
if (Gdx.input.isKeyPressed(Input.Keys.A) && linearVelocity.x >= -2) {
dogBody.applyLinearImpulse(new Vector2(-0.1f, 0), dogBody.getWorldCenter(), true);
} // 跳起来的逻辑,比较简单。但是时候这个演示
if (!isJump && Gdx.input.isKeyPressed(Input.Keys.W) && linearVelocity.y <= 4) {
dogBody.applyLinearImpulse(new Vector2(0, 4), dogBody.getWorldCenter(), true);
isJump = true;
}
if (linearVelocity.y == 0) {
isJump = false;
} // 给Box2D世界里的物体绘制轮廓,让我们看得更清楚,正式游戏需要注释掉这个渲染
debugRenderer.render(world, camera.combined); // 更新世界里的关系 这个要放在绘制之后,最好放最后面
world.step(1 / 60f, 6, 2);
}
}

二、识别碰撞边

在上面介绍了碰撞,没有说明是那边碰撞,例如超级玛丽,我们要判断是头撞砖还是脚踩蘑菇?box2d官网也介绍了如何识别那条边碰撞,大致意思就是相对物体A的一个点是否在物体B上来判断。
box2d官网说明碰撞:
https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_collision.html#autotoc_md41

那么在beginContact中的代码添加即可。

  Vector2 position = fixtureB.getBody().getPosition();
// 我们知道狗蛋是 50 * 50 并且缩小100倍,position 为狗蛋的中心位置:图形绘制从中心绘制的
// 那么 position.y - (52/2 / reduce) 则是狗蛋下方的一点,通过判断该点是否与物体重合,从而知道那个位置撞上对方了
// box2d官网有很好的说明 https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_collision.html#autotoc_md41
// You can perform a couple geometric queries on a single shape. 您可以对单个形状执行几个几何查询。
if (fixtureA.testPoint(position.x, position.y - (52/2 / reduce))) {
System.out.println("狗蛋踩到了障碍物体");
}

libGDX游戏开发之Box2D碰撞(十五)的更多相关文章

  1. Unity游戏开发之“分层碰撞”

    有没有同学遇到过这样的情况:在游戏开发3D游戏中非经常见,比方让一个物体能穿过一个物体 而还有一个物体不能穿过这个物体,并且3个物体都不能穿过地面.在unity中这样的情况的处理是通过分层碰撞来解决的 ...

  2. iOS游戏开发之UIDynamic

    iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ...

  3. Cocos2d-x 3.x游戏开发之旅

    Cocos2d-x 3.x游戏开发之旅 钟迪龙 著   ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x ...

  4. 【转载】浅谈游戏开发之2D手游工具

    浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android  程序设计: 其它  编程语言:   引擎/SDK ...

  5. [整理]Unity3D游戏开发之Lua

    原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...

  6. Cocos2d—X游戏开发之CCToggle(菜单标签切换)CCControlSwitch(开关切换)

    Cocos2d—X游戏开发之CCToggle(菜单标签切换) 首先继承子CCMenu,是菜单标签中的一种.‘ class CC_DLL CCMenuItemToggle : public CCMenu ...

  7. [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读

    ---------------------------------------------------------------------------------------------------- ...

  8. [Unity3D]Unity3D游戏开发之从Unity3D到Eclipse

    ---------------------------------------------------------------------------------------------------- ...

  9. [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)

    ---------------------------------------------------------------------------------------------------- ...

  10. Cocos2d—X游戏开发之CCScrollView(滑动视图)(十二)

    CCScrollView在Cocos2d-X引擎中主要使用在图片尺寸远大于屏幕尺寸的时候使用. 总体来说,使用起来比较简单. 一个是CCScrollView控件本身,一个是CCScrollViewDe ...

随机推荐

  1. Nacos启动报错:Please set the JAVA_HOME variable in your environment, We need java(x64) jdk8 or later

    可能原因: 1.JDK版本过低(应不低于1.8) 2.未设置jdk环境变量(可能性低) 3.jdk环境变量设置不适配nacos(博主就是这个原因) 解决方案: 1.直接在startup.cmd文件中设 ...

  2. 在线问诊 Python、FastAPI、Neo4j — 生成 Cypher 语句

    目录 构建节点字典 构建Cypher CQL语句 Test 这边只是为了测试,演示效果和思路,实际应用中,可以通过NLP构建CQL 接上一篇的问题分类 question = "请问最近看东西 ...

  3. Apollo2.1.0+Springboot使用OpenApI

    依赖管理 <!-- bootstrap最高级启动配置读取 --> <dependency> <groupId>org.springframework.cloud&l ...

  4. Django框架——Web应用、基于SOCKET写一个web应用、 手撸简单web框架、http协议、Web框架(手撸自己的Web框架)、django简介以及简单使用

    文章目录 1 Web应用 一 Web应用程序是什么 1.1 Web应用程序的优点 1.2 Web应用程序的缺点 1.3 B/S架构优点 二 基于SOCKET写一个web应用 2.1 main.py 2 ...

  5. python系列:argparse详解 外部传参给python的库

    一.argparse简介 argparse 模块是 Python 内置的用于命令项选项与参数解析的模块,argparse 模块可以让人轻松编写用户友好的命令行接口,能够帮助程序员为模型定义参数. ar ...

  6. Android历史版本

    目录 [隐藏]  1 测试版 2 版本列表 2.1 Android 1.0 2.2 Android 1.1 2.3 Android 1.5 Cupcake 2.4 Android 1.6 Donut ...

  7. 人工智能AI绘画全攻略(AI绘画教程分享)

    在过去的三个月一直在研究人工智能生成绘画这个方向,3 月份的时候参加了小红书的小航海,也因为这个方向的选择正好对应到了趋势,小红书在一个半月做到了 1 万粉.我为什么看好这个方向? 主要是从三个方面: ...

  8. Termius for macOS or Windows Download ssh

    mac电脑   苹果系统 window 系统 链接  服务器,访问 ecs ,ssh链接 工具 下载地址:http://pgyd.online/?website/53.html Termius for ...

  9. APIO 2023 游记

    真心话大冒险很有趣. rand 一个房间去敲门加 QQ 很有趣.这么看社恐猫好像也没那么社恐. 面到了 zpl pcq iee dx.单方面认识了很多神仙. 比赛只会写暴力,评测 queue 害人不浅 ...

  10. List、Set与 Map

    目录 1. List接口和常用方法 1.1 List接口基本介绍 1.2 List接口的三种遍历方式 2. ArrayList 2.1 注意事项 2.2 ArrayList的底层操作机制源码分析(重点 ...