java 2D 游戏中的跳跃数学

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/923825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:23:04  来源:igfitidea点击:

The Math of a Jump in a 2D game

javamath2dphysics

提问by Pablo Albornoz

I'm working in J2ME, I have my gameloop doing the following:

我在 J2ME 中工作,我的游戏循环执行以下操作:

public void run() {
        Graphics g = this.getGraphics();
        while (running) {
            long diff = System.currentTimeMillis() - lastLoop;
            lastLoop = System.currentTimeMillis();
            input();
            this.level.doLogic();
            render(g, diff);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                stop(e);
            }
        }
    }

So it's just a basic gameloop, the doLogic()function calls for all the logic functions of the characters in the scene and render(g, diff)calls the animateCharfunction of every character on scene, following this, the animCharfunction in the Character class sets up everything in the screen as this:

所以它只是一个基本的游戏循环,该doLogic()函数调用场景中角色的所有逻辑函数并render(g, diff)调用场景animateChar中每个角色的函数,接下来,animCharCharacter 类中的函数将屏幕中的所有内容设置为:

protected void animChar(long diff) {
        this.checkGravity();
        this.move((int) ((diff * this.dx) / 1000), (int) ((diff * this.dy) / 1000));
        if (this.acumFrame > this.framerate) {
            this.nextFrame();
            this.acumFrame = 0;
        } else {
            this.acumFrame += diff;
        }
    }

This ensures me that everything must to move according to the time that the machine takes to go from cycle to cycle (remember it's a phone, not a gaming rig). I'm sure it's not the most efficient way to achieve this behavior so I'm totally open for criticism of my programming skills in the comments, but here my problem: When I make I character jump, what I do is that I put his dyto a negative value, say -200 and I set the boolean jumpingto true, that makes the character go up, and then I have this function called checkGravity()that ensure that everything that goes up has to go down, checkGravityalso checks for the character being over platforms so I will strip it down a little for the sake of your time:

这确保了我一切都必须根据机器从一个循环到另一个循环所需的时间移动(记住它是手机,而不是游戏装备)。我确信这不是实现这种行为的最有效方法,所以我完全可以在评论中批评我的编程技能,但这里我的问题是:当我让我角色跳跃时,我所做的是我把他的dy为负值,比如 -200,我将布尔跳转设置为 true,这使字符上升,然后我调用checkGravity()了这个函数,以确保上升的所有东西都必须下降,checkGravity还检查字符是否在在平台上,所以为了您的时间,我将把它剥离一点:

public void checkGravity() {
        if (this.jumping) {
            this.jumpSpeed += 10;
            if (this.jumpSpeed > 0) {
                this.jumping = false;
                this.falling = true;
            }
            this.dy = this.jumpSpeed;
        }
        if (this.falling) {
            this.jumpSpeed += 10;
            if (this.jumpSpeed > 200) this.jumpSpeed = 200;
            this.dy = this.jumpSpeed;
            if (this.collidesWithPlatform()) {
                this.falling = false;
                this.standing = true;
                this.jumping = false;
                this.jumpSpeed = 0;
                this.dy = this.jumpSpeed;
            }
        }
    }

So, the problem is, that this function updates the dyregardless of the diff, making the characters fly like Superman in slow machines, and I have no idea how to implement the difffactor so that when a character is jumping, his speed decrement in a proportional way to the game speed. Can anyone help me fix this issue? Or give me pointers on how to make a 2D Jump in J2ME the right way.

所以,问题是,无论diff,这个函数都会更新dy,使角色在慢速机器中像超人一样飞行,我不知道如何实现diff因子,以便当角色跳跃时,他的速度减少与游戏速度成正比的方式。谁能帮我解决这个问题?或者请教我如何以正确的方式在 J2ME 中进行 2D 跳转

采纳答案by gregd

Shouldn't you be adjusting the jumpSpeed based on the elapsed time? That is, perhaps the speed changes by -75/sec, so your diff should be a weight for the amount of change applied to the jumpSpeed.

您不应该根据经过的时间调整 jumpSpeed 吗?也就是说,速度可能会变化 -75/秒,因此您的差异应该是应用于 jumpSpeed 的变化量的权重。

So pass in diff to checkGrav and do something like... jumpSpeed += (diff * (rate_per_second)) / 1000;

因此,将 diff 传递给 checkGrav 并执行类似... jumpSpeed += (diff * (rate_per_second)) / 1000;

(assuming diff in milliseconds)

(假设差异以毫秒为单位)

(Ideally, this would make it just like real gravity :D)

(理想情况下,这将使它像真正的重力一样:D)

回答by Nosredna

Why not just scale all constants by diff?

为什么不通过 diff 缩放所有常量?

By the way, I'm embarrassed to say this, but I worked on a commercial game where gravity was twice as strong on characters going down as going up. For some reason, people preferred this.

顺便说一句,我很不好意思这么说,但我曾参与过一款商业游戏,其中角色下降的重力是上升的两倍。出于某种原因,人们更喜欢这个。

回答by Patrick Gryciuk

This seems to be more of a question about game design than the math of a jump. It is a common problem that in games running on different processors one game will be executed faster and on other games it will be executed slower (thus changing the entire speed of the game). I'm not sure what common practice is in games, but whenever I made home-brewed 2D games (they were fun to make) I would have the concept of a game-tick. On faster machines

这似乎更像是一个关于游戏设计的问题,而不是跳跃的数学。一个常见的问题是,在不同处理器上运行的游戏中,一个游戏的执行速度会更快,而其他游戏的执行速度会更慢(从而改变游戏的整体速度)。我不确定游戏中的常见做法是什么,但每当我制作自制的 2D 游戏(它们制作起来很有趣)时,我都会有游戏滴答的概念。在更快的机器上

long diff = System.currentTimeMillis() - lastLoop;
lastLoop = System.currentTimeMillis();

Would be lower. A wait time would be derived from the diff so that the game would run at the same speed on most machines. I would also have the render method in a separate thread so that the game speed isn't dependent on the graphics.

会更低。等待时间将从差异中得出,以便游戏在大多数机器上以相同的速度运行。我还将在单独的线程中使用渲染方法,以便游戏速度不依赖于图形。

回答by Konstantin

I can give a formula like this (I use it everywhere). The X is the parameter of it starting from zero and ending on the length of jump. if you want someone to jump at some Height (H) and at some Length (L), then function of the jump will look like this (and it won't' be able to ever look different):

我可以给出这样的公式(我到处都使用它)。X 是它的参数,从零开始,以跳转的长度结束。如果您希望某人以某个高度 (H) 和某个长度 (L) 跳跃,那么跳跃的功能将如下所示(并且看起来不会有任何不同):

y = minus(power(x - Length of Jump divided by two) multiply by 4 and multiply by Height of the jump) divide by power of Length and add Height of jump in the very end.

y = -(x-l/2)(x-l/2)*4*h/(l*l) + h

y = 减去(power(x - 跳跃长度除以二)乘以 4 乘以跳跃高度)除以长度的幂,最后加上跳跃高度。

y = -(xl/2)(xl/2)*4*h/(l*l) + h

And if you want the jumping object to land on something, then you can check every new X if it's approximately standing on a platform and if it is standing on something, then don't make it just stop, make it's Y position exactly equal to the Y of platform.

如果你想让跳跃的物体落在什么东西上,那么你可以检查每个新的 X 是否大约站在平台上,如果它站在什么东西上,那么不要让它停下来,让它的 Y 位置正好等于平台的Y。

If you're using something like Flash or other base which has inverted y axis, then multiply the function output by -1;

如果您使用的是 Flash 或其他具有倒 y 轴的 base 之类的东西,则将函数输出乘以 -1;