- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的意思是,当我与实体的侧面碰撞并想要跳跃时,我无法向右/向左移动,因为当我与右侧/左侧的实体碰撞时,我有一个标志可以防止这种情况发生,例如所以:
这是我用来检测碰撞的代码:
public void onCollision(Wrapper wrapper) {
if (horizontal_velocity == 0 && vertical_velocity == 0) {
return;
}
Entity e1 = wrapper.thisEntity; //the object we are controlling
Entity e2 = wrapper.otherEntity; //the object we are impacting with
Rectangle rect1 = wrapper.thisEntityRectangle;
Rectangle rect2 = wrapper.otherEntityRectangle;
int e1y = (int) rect1.getY(), e1x = (int) rect1.getX(), e1w = (int) rect1.getWidth(), e1h = (int) rect1.getHeight();
int e2y = (int) rect2.getY(), e2x = (int) rect2.getX(), e2w = (int) rect2.getWidth(), e2h = (int) rect2.getHeight();
e1x += e1w / 2;
e1w /= 2;
e1y += e1h / 2;
e1h /= 2;
//horizontal interaction -- x
/* ---+\\\\\\+---
* |------|
* | |
* e1 | e2 | e1
* | |
* |------|
* ---+\\\\\\+---
*/
boolean touchingSide = false;
if(e1y > e2y && e1y < e2y + e2h) {
//touchingSide = true;
if(e1x > e2x - e1w && e1x < e2x) { //going right || hitting left side
collisionsHappening.put(wrapper.otherEntity.getID(), "right");
canMoveRight = false;
horizontal_velocity = 0;
setX(e2x - e1w*2);
}
if(e1x < e2x + e2w + e1w && e1x > e2x) { //going left || hitting right side
collisionsHappening.put(wrapper.otherEntity.getID(), "left");
canMoveLeft = false;
horizontal_velocity = 0;
setX(e2x + e2w);
}
}
//vertical interaction -- y
/*
* \| e1 |\
* \+--+------+--+\
* \\\\| |\\\\
* \\\\| e2 |\\\\
* \\\\| |\\\\
* \+--+------+--+\
* \| e1 |\
*
*/
if(e1x > e2x - e1w && e1x < e2x + e2w && !touchingSide) {
if(e1y + e1h > e2y && e1y < e2y) { //going down || hitting top side
collisionsHappening.put(wrapper.otherEntity.getID(), collisionsHappening.get(wrapper.otherEntity.getID()) + "|top");
setY(e2y - e1h * 2);
vertical_velocity = 0;
//readyNextTurn = true;
isFalling = false;
onGround = true;
}
if(e1y - e1h < e2y + e2h && e1y > e2y) { //going up || hitting bottom side
collisionsHappening.put(wrapper.otherEntity.getID(), collisionsHappening.get(wrapper.otherEntity.getID()) + "|bottom");
setY(e2y + e2h + e1h);
vertical_velocity = 0;
//readyNextTurn = true;
isFalling = false;
onGround = true;
}
}
}
..代码受 canMoveRight
和 canMoveLeft
标志影响的地方:
public void key(int keyCode) {
try {
onEdge();
switch (keyList.get(keyCode)) {
...
case MOVE_RIGHT:
for(Entity e : objectsCollidingWith) { //check if still colliding, if not, reset variable canMoveLeft inorder to not impair movement
if(collisionsHappening.get(e.getID()) == "right") {
canMoveRightNextFrame = true;
}
}
canMoveLeft = true;
if (!canMoveRight && !canMoveRightNextFrame) break;
if(canMoveRightNextFrame) {
canMoveRightNextFrame = false;
System.out.println(canMoveRightNextFrame);
}
if (horizontal_velocity == 0) {
horizontal_velocity = getXDisplacement();
}
changeX(horizontal_velocity);
direction = "right";
//horizontal_velocity = 0;
break;
case MOVE_LEFT:
for(Entity e : objectsCollidingWith) { //check if still colliding, if not, reset variable canMoveLeft inorder to not impair movement
if(collisionsHappening.get(e.getID()) == "left") {
canMoveLeftNextFrame = true;
}
}
canMoveRight = true;
if (!canMoveLeft && !canMoveLeftNextFrame) {
break;
}
canMoveLeftNextFrame = canMoveLeftNextFrame ? true : false; //if true, make false
if (horizontal_velocity == 0) {
horizontal_velocity = getXDisplacement();
}
changeX(-horizontal_velocity);
direction = "left";
//horizontal_velocity = 0;
break;
case JUMP:
jump();
}
} catch (NullPointerException e) {
//ignore - a key with no action pressed
}
}
<小时/>
当我寻找冲突时 - 不会像上面的代码那样对它们使用react - 我尝试实现一个 HashMap,其中我将一个字符串 - "left"
或 "right"
- 到键 Entity.getID() ,它返回一个唯一的名称,如下所示(相关代码行之后是 // <<<
):
public Wrapper[] collisions(Entity thisEntity) {
ArrayList<Wrapper> wrappers = new ArrayList<Wrapper>();
Player p = null;
boolean isPlayer = thisEntity instanceof Player;
boolean onGround = false;
if (isPlayer) {
p = (Player) thisEntity;
}
try {
for (Entity e : getLevel().getEntities()) {
if (!thisEntity.equals(e)) {
collisionsHappening.put(e.getID(), ""); // <<<
objectsCollidingWith.add(e); // <<<
if (thisEntity.getRect().intersects(e.getRect())) {
wrappers.add(new Wrapper(thisEntity, e, thisEntity.getRect(), e.getRect(),
thisEntity.getRect().intersection(e.getRect())));
onGround = true;
//collisionsHappening.put(e.getID(), true);
//System.out.println("collision between " + e.getID() + " + " + thisEntity.getID());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (isPlayer) {
p.isTouching = onGround;
if (onGround) {
//System.out.println(onGround);
}
}
//Entity[] result = list.toArray(new Entity[1]);
return wrappers.toArray(new Wrapper[0]);
}
该系统依赖于在碰撞停止后保留标志 1 帧,以便删除代码行中的标志 canMoveRight
或 canMoveLeft
for(Entity e : objectsCollidingWith) { //check if still colliding, if not, reset variable canMoveLeft inorder to not impair movement
if(collisionsHappening.get(e.getID()) == "left") {
canMoveLeftNextFrame = true;
}
}
canMoveRight = true;
if (!canMoveLeft && !canMoveLeftNextFrame) {
break;
}
if(canMoveLeftNextFrame) {
canMoveLeftNextFrame = false; //if true, make false
}
...
...对于 canMoveRight
标志也是如此...
但是,这不起作用,并且在“抓取”实体的边缘后我仍然无法在跳跃中移动,除非我朝相反方向移动以“重置”所需方向的标志(行:case MOVE_RIGHT:
...
canMoveLeft = true;
和 case MOVE_LEFT:
...
canMoveRight = true;
),如动画所示。
所以,总结一下:
谢谢。
最佳答案
对于比贪吃蛇更高级的游戏来说,用事件驱动的方式来解决这个问题实际上是不可能的。我建议您关注更新每个实体的简单更新循环。然后每个实体更新自己的速度和位置。然后检查碰撞并处理响应。关键事件处理程序不应该有任何逻辑,而只是更改实体可以轮询的标志。
至于碰撞和响应部分,这是简单平台游戏引擎的核心所在,并且有许多不同的方法。在现成的物理引擎的现代世界中,例如Box2D,你可以简单地让物理系统处理事情。但从事情的声音来看,你并不是在寻找那个,你想要的是我所说的基于逻辑的物理学。
如果您的世界和实体由轴对齐的框组成,您可以将每个实体的水平和垂直运动分成两个离散的步骤。对于每个轴,每个对象都会尝试尽可能远地移动(取决于速度和碰撞),如果对象撞到某物,则会生成碰撞事件并将该轴上的速度设置为零。对另一个轴重复此操作,您将拥有一个简单的平台游戏引擎。对于此方法,您需要仔细处理由于 float 值误差而导致的两个对象接触的状态。我建议使用整数进行碰撞检测(以屏幕坐标的比例)。
如果您希望拥有一个不限于轴对齐框的环境和实体,那么您将必须变得更加复杂,并且不再依赖于简单地处理 X 然后 Y 移动来为您提供诸如框滑动之类的东西在地板上或墙上。在这种情况下,我建议您跟踪您的实体站立或行走的表面,以便您可以在每种状态下以不同的方式处理它们的运动。当它们在空中时,进行正常运动,但是当它们在某个表面上时,运动被限制为水平运动,并调整垂直位置以将它们保持在表面上。然后,您需要检测它们何时改变状态。
我希望您觉得这有帮助。事实证明,这对谷歌来说并不是一个容易的话题。 (更新循环、碰撞检测、运动物理、数值积分和碰撞响应的几何形状都很容易通过 Google 搜索)。大多数程序员似乎只是采取不断摆弄它直到它起作用的方法,因此它永远不会得到很好的记录。
附注隐式欧拉积分方法适用于大多数游戏。
关于java - 碰撞 - 识别物体何时停止碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28288810/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!