【问题标题】:Object not moving in correct direction物体没有朝着正确的方向移动
【发布时间】:2014-03-28 17:19:46
【问题描述】:

好的,我正在尝试做一些简单的对象,沿着你触摸屏幕的方向移动。

如果我直接触摸对象的西北方向,它会向触摸位置的方向移动。如果我直接触摸对象的东南方,它也会向触摸位置的方向移动。但是,如果我直接触摸物体的东北部,它会向西南方向移动。如果我直接触摸物体的西南方向,它也会向相反的方向移动到东北方向。

另外,如果我触摸物体的北边,但只是稍微向西一点,它会向西直行,向北一点点。与稍微向北触摸物体的西部相同,它会向西一点点向北直行。其他方向也一样。

真的,所有的方向都有些不正确。我也一直在做一些纸上的计算,我似乎得到了一些正确的角度,但在这一点上我完全被难住了。

有谁知道问题出在哪里?

package com.badlogic.androidgames.texasholdem;

import java.util.List;

import android.util.FloatMath;

import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Graphics;
import com.badlogic.androidgames.framework.Input.TouchEvent;
import com.badlogic.androidgames.framework.Screen;

public class MainMenuScreen extends Screen {
    public static float TO_RADIANS = (1 / 180.0f) * (float) Math.PI;
    public static float TO_DEGREES = (1 / (float) Math.PI) * 180;
    float num_x = 0; // Position of object on X axis
    float num_y = 0; // Position of object on Y axis
    float angle = 0;

    public MainMenuScreen(Game game) {
        super(game);               
    }

    public void update(float deltaTime) {
        Graphics g = game.getGraphics();
        List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
        game.getInput().getKeyEvents();       

        int len = touchEvents.size();
        for(int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if(event.type == TouchEvent.TOUCH_UP) {
                if(inBounds(event, 0, 0, g.getWidth(), g.getHeight()) ) {

                    // Calculate the angle of the direction between two points
                    angle = (float) Math.atan2(event.x - num_x, event.y - num_y) * TO_DEGREES; 
                    if (angle < 0)
                        angle += 360;

                    // This is just to give me numbers on the Math.atan2 result, angle, to/from X position, and to/from Y position
                    System.out.println("Pressed! - ATAN: " + Math.atan2(event.x - num_x, event.y - num_y)
                        + " - ANGLE:" + angle + " - POS: " + event.x + "tx/"
                        + (int)num_x + "fx " + event.y + "ty/" + (int)num_y + "fy");
                }
            }
        }
        // Moving object in direction at 1f speed
        num_x += (1f * (float) Math.cos(angle * TO_RADIANS));
        num_y += (1f * (float) Math.sin(angle * TO_RADIANS));
    }

    private boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
        if(event.x > x && event.x < x + width - 1 && 
           event.y > y && event.y < y + height - 1) 
            return true;
        else
            return false;
    }

    public void present(float deltaTime) {
        Graphics g = game.getGraphics();

        g.drawPixmap(Assets.background, 0, 0);
        g.drawPixmap(Assets.backcard, (int)num_x, (int)num_y);
    }

    public void pause() {        
        Settings.save(game.getFileIO());
    }

    public void resume() {

    }

    public void dispose() {

    }
}

【问题讨论】:

    标签: java android math libgdx


    【解决方案1】:

    如果事件 x> x 那么 x 必须是正数才能向 event.x 移动

    这里的问题是,当 event.x

    int dx,dy;
    
    
    
     dx = (1f * (float) Math.cos(angle * TO_RADIANS));
            dy = (1f * (float) Math.sin(angle * TO_RADIANS));
    
    if(event.x<x){
    dx=-dx;}
    if(event.y<y){
    dy=-dy;}
    
    
    num_x+=dx;
    num_y+=dy;
    

    这种方式更简单但不太精确....

    public void update(){
        //(find dif between item x, and touch x)
        float xdif=destx-x;
        float ydif=desty-y;
    
        if(x<destx){
    
            dx=xdif/8;
            }
    
        else if(x>destx){
            //we devide both x and y differences by the same number
            dx=xdif/8;
            }
    
        else if(x==destx){
            dx=0;
            }
        if(y<desty){
            dy=ydif/5;
            }
        else if(y>desty){
            dy=ydif/5;
            }
        else if(y==desty){
            dy=0;
            }
    
        x+=dx;
        y+=dy;
    

    你走了,在两点 item.x 和 touch x 之间的直线路径。

    【讨论】:

    • 第一个似乎效果不太好,我可能需要稍后再检查一下。第二部分我想避免使用。准确的方向很重要。
    • 你可以用你的数学来加强第二个,我只是把它简单了,这样你就可以看到基本的想法了。
    【解决方案2】:

    首先,数学 - 我认为问题在于,例如,tan(135deg) = tan (-45deg) = -1。因此,atan 的返回值范围在 -90 度和 90 度之间,作为模糊度的分辨率 (look at its graph here)。我认为 La5t5tarfighter 的解决方案——在某些情况下否定 x 运动——是在正确的轨道上,但在这些情况下你也需要否定 y 分量。你可以试试,但如果你使用 libGDX 的Vector2 类会简单得多。我就是这样做的:

    move.set(touchX, touchY);  // y should be through flipping or unproject() before this
    move.sub(objectPos);       // move now points from object to where you touched
    move.nor();                // now 1 unit long
    move.scl(SPEED*deltaTime); // multiplied by a constant and delta - framerate-independent
    objectPos.add(move);
    

    如果你愿意,你甚至可以把它串成一行:

    objectPos.add(move.set(x,y).sub(objectPos).nor().scl(SPEED*deltaTime));
    

    其次,您没有使用Camera。我不完全确定默认坐标系是什么,但我相信 y 轴指向上方,这与用于输入的坐标系不同 - Input.getY() 给出的 y 轴从左上角指向下方。如果你有Camera,你会这样做:

    cam.unproject(someVector.set(Gdx.input.getX(), Gdx.input.getY(), 0));
    

    缺少这个,你可能需要翻转 y 轴:

    event.y = Gdx.graphics.getHeight() - event.y;
    

    不过,这可能是错误的。尝试在触摸位置绘制对象 - 如果我在此位置正确,它看起来会垂直镜像。如果它在您触摸的位置正确绘制,请忽略此部分。

    【讨论】:

      猜你喜欢
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多