- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想实现球物理,作为新手,我调整了教程中的代码 http://adam21.web.officelive.com/Documents/JavaPhysicsTutorial.pdf .
我尽我所能地遵循它,但是我不能在代码中应用所有的物理现象,有人可以告诉我,我错在哪里或者我还在做一些愚蠢的编程错误。
当我没有调用弹跳方法并且我无法使用弹跳方法时,球正在移动并且球正在向左侧移动而不是落在地板上**,
有人可以向我推荐一些更好的方法或类似的简单紧凑的方法来完成将物理应用于两个或多个具有交互性的球的任务吗。
这是代码;
import java.awt.*;
public class AdobeBall {
protected int radius = 20;
protected Color color;
// ... Constants
final static int DIAMETER = 40;
// ... Instance variables
private int m_x; // x and y coordinates upper left
private int m_y;
private double dx = 3.0; // delta x and y
private double dy = 6.0;
private double m_velocityX; // Pixels to move each time move() is called.
private double m_velocityY;
private int m_rightBound; // Maximum permissible x, y values.
private int m_bottomBound;
public AdobeBall(int x, int y, double velocityX, double velocityY,
Color color1) {
super();
m_x = x;
m_y = y;
m_velocityX = velocityX;
m_velocityY = velocityY;
color = color1;
}
public double getSpeed() {
return Math.sqrt((m_x + m_velocityX - m_x) * (m_x + m_velocityX - m_x)
+ (m_y + m_velocityY - m_y) * (m_y + m_velocityY - m_y));
}
public void setSpeed(double speed) {
double currentSpeed = Math.sqrt(dx * dx + dy * dy);
dx = dx * speed / currentSpeed;
dy = dy * speed / currentSpeed;
}
public void setDirection(double direction) {
m_velocityX = (int) (Math.cos(direction) * getSpeed());
m_velocityY = (int) (Math.sin(direction) * getSpeed());
}
public double getDirection() {
double h = ((m_x + dx - m_x) * (m_x + dx - m_x))
+ ((m_y + dy - m_y) * (m_y + dy - m_y));
double a = (m_x + dx - m_x) / h;
return a;
}
// ======================================================== setBounds
public void setBounds(int width, int height) {
m_rightBound = width - DIAMETER;
m_bottomBound = height - DIAMETER;
}
// ============================================================== move
public void move() {
double gravAmount = 0.02;
double gravDir = 90; // The direction for the gravity to be in.
// ... Move the ball at the give velocity.
m_x += m_velocityX;
m_y += m_velocityY;
// ... Bounce the ball off the walls if necessary.
if (m_x < 0) { // If at or beyond left side
m_x = 0; // Place against edge and
m_velocityX = -m_velocityX;
} else if (m_x > m_rightBound) { // If at or beyond right side
m_x = m_rightBound; // Place against right edge.
m_velocityX = -m_velocityX;
}
if (m_y < 0) { // if we're at top
m_y = 0;
m_velocityY = -m_velocityY;
} else if (m_y > m_bottomBound) { // if we're at bottom
m_y = m_bottomBound;
m_velocityY = -m_velocityY;
}
// double speed = Math.sqrt((m_velocityX * m_velocityX)
// + (m_velocityY * m_velocityY));
// ...Friction stuff
double fricMax = 0.02; // You can use any number, preferably less than 1
double friction = getSpeed();
if (friction > fricMax)
friction = fricMax;
if (m_velocityX >= 0) {
m_velocityX -= friction;
}
if (m_velocityX <= 0) {
m_velocityX += friction;
}
if (m_velocityY >= 0) {
m_velocityY -= friction;
}
if (m_velocityY <= 0) {
m_velocityY += friction;
}
// ...Gravity stuff
m_velocityX += Math.cos(gravDir) * gravAmount;
m_velocityY += Math.sin(gravDir) * gravAmount;
}
public Color getColor() {
return color;
}
public void setColor(Color newColor) {
color = newColor;
}
// ============================================= getDiameter, getX, getY
public int getDiameter() {
return DIAMETER;
}
public double getRadius() {
return radius; // radius should be a local variable in Ball.
}
public int getX() {
return m_x;
}
public int getY() {
return m_y;
}
}
使用 adobeBall:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AdobeBallImplementation implements Runnable {
private static final long serialVersionUID = 1L;
private volatile boolean Play;
private long mFrameDelay;
private JFrame frame;
private MyKeyListener pit;
/** true means mouse was pressed in ball and still in panel. */
private boolean _canDrag = false;
private static final int MAX_BALLS = 50; // max number allowed
private int currentNumBalls = 2; // number currently active
private AdobeBall[] ball = new AdobeBall[MAX_BALLS];
public AdobeBallImplementation(Color ballColor) {
frame = new JFrame("simple gaming loop in java");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pit = new MyKeyListener();
pit.setPreferredSize(new Dimension(400, 400));
frame.setContentPane(pit);
ball[0] = new AdobeBall(34, 150, 7, 2, Color.YELLOW);
ball[1] = new AdobeBall(50, 50, 5, 3, Color.BLUE);
frame.pack();
frame.setVisible(true);
frame.setBackground(Color.white);
start();
frame.addMouseListener(pit);
frame.addMouseMotionListener(pit);
}
public void start() {
Play = true;
Thread t = new Thread(this);
t.start();
}
public void stop() {
Play = false;
}
public void run() {
while (Play == true) {
// bounce(ball[0],ball[1]);
runball();
pit.repaint();
try {
Thread.sleep(mFrameDelay);
} catch (InterruptedException ie) {
stop();
}
}
}
public void drawworld(Graphics g) {
for (int i = 0; i < currentNumBalls; i++) {
g.setColor(ball[i].getColor());
g.fillOval(ball[i].getX(), ball[i].getY(), 40, 40);
}
}
public double pointDistance (double x1, double y1, double x2, double y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
public void runball() {
while (Play == true) {
try {
for (int i = 0; i < currentNumBalls; i++) {
for (int j = 0; j < currentNumBalls; j++) {
if (pointDistance(ball[i].getX(), ball[i].getY(),
ball[j].getX(), ball[j].getY()) < ball[i]
.getRadius()
+ ball[j].getRadius() + 2) {
// bounce(ball[i],ball[j]);
ball[i].setBounds(pit.getWidth(), pit.getHeight());
ball[i].move();
pit.repaint();
}
}
}
try {
Thread.sleep(50);
} catch (Exception e) {
System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static double pointDirection(int x1, int y1, int x2, int y2) {
double H = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); // The
// hypotenuse
double x = x2 - x1; // The opposite
double y = y2 - y1; // The adjacent
double angle = Math.acos(x / H);
angle = angle * 57.2960285258;
if (y < 0) {
angle = 360 - angle;
}
return angle;
}
public static void bounce(AdobeBall b1, AdobeBall b2) {
if (b2.getSpeed() == 0 && b1.getSpeed() == 0) {
// Both balls are stopped.
b1.setDirection(pointDirection(b1.getX(), b1.getY(), b2.getX(), b2
.getY()));
b2.setDirection(pointDirection(b2.getX(), b2.getY(), b1.getX(), b1
.getY()));
b1.setSpeed(1);
b2.setSpeed(1);
} else if (b2.getSpeed() == 0 && b1.getSpeed() != 0) {
// B1 is moving. B2 is stationary.
double angle = pointDirection(b1.getX(), b1.getY(), b2.getX(), b2
.getY());
b2.setSpeed(b1.getSpeed());
b2.setDirection(angle);
b1.setDirection(angle - 90);
} else if (b1.getSpeed() == 0 && b2.getSpeed() != 0) {
// B1 is moving. B2 is stationary.
double angle = pointDirection(b2.getX(), b2.getY(), b1.getX(), b1
.getY());
b1.setSpeed(b2.getSpeed());
b1.setDirection(angle);
b2.setDirection(angle - 90);
} else {
// Both balls are moving.
AdobeBall tmp = b1;
double angle = pointDirection(b2.getX(), b2.getY(), b1.getX(), b1
.getY());
double origangle = b1.getDirection();
b1.setDirection(angle + origangle);
angle = pointDirection(tmp.getX(), tmp.getY(), b2.getX(), b2.getY());
origangle = b2.getDirection();
b2.setDirection(angle + origangle);
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AdobeBallImplementation(Color.red);
}
});
}
}
*编辑:*确定使用来自该论坛的重力新方法拆分代码:此代码也不起作用球不会落在地板上:
public void mymove() {
m_x += m_velocityX;
m_y += m_velocityY;
if (m_y + m_bottomBound > 400) {
m_velocityY *= -0.981;
// setY(400 - m_bottomBound);
m_y = 400 - m_bottomBound;
}
// ... Bounce the ball off the walls if necessary.
if (m_x < 0) { // If at or beyond left side
m_x = 0; // Place against edge and
m_velocityX = -m_velocityX;
} else if (m_x > m_rightBound) { // If at or beyond right side
m_x = m_rightBound - 20; // Place against right edge.
m_velocityX = -m_velocityX;
}
if (m_y < 0) { // if we're at top
m_y = 1;
m_velocityY = -m_velocityY;
} else if (m_y > m_bottomBound) { // if we're at bottom
m_y = m_bottomBound - 20;
m_velocityY = -m_velocityY;
}
}
非常感谢任何更正和帮助。
吉比
最佳答案
目前我无法运行 java,因此无法测试您的代码,但我注意到几件事:
编辑:
这个重力代码是错误的:
if (m_y + m_bottomBound > 400) {
m_velocityY *= -0.981;
// setY(400 - m_bottomBound);
m_y = 400 - m_bottomBound;
}
首先,您将 400 用作“魔数(Magic Number)”;说不清代表什么。然后你将效果限制在屏幕顶部附近的区域,原因尚不清楚。在函数的末尾,您以一种毫无意义的方式更改了 m_y
。并且(也许)最糟糕的是,重力反转并倍增垂直速度,这不是重力的工作原理。
试试这个:
// You will have to adjust this. Start with a small value and increase it until
// you see an effect.
final static double GRAVITY = 0.1;
// Note that +y is down, so accelerating downward means increasing vY
m_velocityY += GRAVITY;
关于java - Java 中的简单物理模拟不起作用。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3851540/
我一直在寻找游戏/模拟解决方案,以便在时间流逝时寻找距离,但这不是我要找的。 我正在寻找一个 O(1) 公式来计算(0 或 1 或 2)时钟时间,其中两个圆圈彼此之间的距离恰好为 r1+r2。负时间是
我究竟做错了什么? > crossprod(1:3,4:6) [,1] [1,] 32 根据本网站:http://onlinemschool.com/math/assistance/ve
嗨,我目前正在为类开发一个迷你游戏(第一次做这样的事情),我根本不知道如何开始碰撞检测。好吧,我正在创建的游戏是一款在冰冷的圆形竞技场上自上而下的相扑格斗游戏,您可以四处移动以获得动力和速度,并尝试击
这段代码取自使用 XNA 框架构建的游戏。我想从三角学和物理学的角度解释一下它是如何工作的。 ball.velocity = new Vector2((float)Math.Cos(cannon.ro
因此,我正在努力自学 Canvas (HTML5) 并编写了大部分简单的游戏引擎代码。它是空间场景(行星、恒星、天体等)的二维表示。我的默认“Sprite”类有一个像这样的帧监听器: “baseCla
这个问题在这里已经有了答案: Are the physical memory addresses of an array also stored in order like the virtual o
我正在尝试阅读英特尔软件开发人员手册以了解操作系统的工作原理,这四个寻址术语让我感到困惑。以上是我的理解,如有不对请指正。 线性地址 : 对一个孤立的程序来说,似乎是一长串以地址0开头的内存。该程序的
我尝试在 AndEngine 示例包中复制并粘贴物理示例。 没有出现错误,但当我运行它时,模拟器显示“不幸的是,PhysicsActivity 已停止”。 模拟器使用 API 15,GPU 已开启,磁
当我运行此代码时,第一行 CollisionWithplayer 给了我一个错误的指令错误。该错误不会每次都会出现,只是偶尔出现一次,并且没有类似的条件来确定导致该错误的原因。 func didBeg
您好,我有以下 Canvas 应用程序:http://dev.driz.co.uk/canvas/ 正如您将看到的,它渲染了一堆球。我遇到的问题是当应用程序首次启动时,球被 Canvas 边缘切断。他
我有两个 3d 物理 vector ,带有 (x,y,z) 和方向。我想对它们做一些操作。但我有一些问题: 我应该如何在 C++ 中表示这个 vector ?换句话说,我在下面写了类,但我不知道如何表
我有一个有 body 的 Sprite 。我想通过路径移动 Sprite 。我已经尝试使用 PathModifier 执行此操作, Sprite 会按原样移动,但它的 body 不会跟随 Sprite
我开发了类似投币推土机的游戏。为了硬币的平稳移动,我为每个硬币添加了一种物理 Material ,但这样做之后我的游戏速度非常慢。有没有其他选择,或者我如何在不使用物理 Material 的情况下使硬
我正在开发一款简单的平台游戏,例如 super 马里奥。我将 Java 与 LibGdx 引擎一起使用。我的物理问题与帧率无关。在我的游戏中,角色可以跳跃,跳跃高度显然取决于帧率。 在我的桌面上,游戏
我正在开发一个可能包含数学、物理和化学符号的问答应用程序,因为这是一个实时游戏应用程序,每次问题将从服务器下载并针对特定主题显示。它需要是一个原生的 Android 应用程序,并且性能非常重要(两人游
我的任务是编写一个对象,该对象可以接收不同类型的路径/url,并返回它是什么类型的路径/url。例如路径可以是 1. [drive]:\Temp 2. \\Temp 3. Temp (assuming
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
注意:当我提到层时,我指的是物理层。此站点上与“层”相关的许多问题都指的是逻辑层,这不是我要问的。 我正在设计一个使用标准“3 层”架构的应用程序,包括表示层、业务逻辑 (BLL) 层和数据访问层 (
如何检查设备上的屏幕或物理/电容式导航按钮 最佳答案 您可以使用 ViewConfiguration.get(context).hasPermanentMenuKey() 仅适用于 API 级别 14
我在我的 android 游戏中使用 AndEngine,我从 github 下载了主 AndEngine,但是没有主的 Physics Box2D 扩展。我不知道在哪里下载它或我可以使用它的哪个版本
我是一名优秀的程序员,十分优秀!