0

经过大量的试验和错误,我能够为立方体绘制一个立方体和一个瓷砖贴图。我添加了输入,这样当您移动手指时,相机就会移动。但现在我想在我的游戏进程中添加下一步。我希望它让我的立方体移动到我在 3d 空间中按下手指的位置。听起来有点困难。我想做的是让你用一根手指在地图上滑动相机,另一根手指双击并移动。到目前为止,我的立方体在原地抖动和摆动,但没有移动到我想要它去的地方。当然,我的代码都不是完美的,我对 gluunproject 的关注可能远非正确。到目前为止,这是我的代码

多维数据集创建者和更新代码//它的简短

public shapemaker(int x, int y, int z,int width)
{
    centerx =x;
    centery =y;
    centerz =z;



        mysquare1= new square(centerx,centery,centerz-5,1,.0f,.0f,1f,"vert");
        mysquare2= new square(centerx-1,centery,centerz-6f,1,.0f,1.0f,.0f,"side");
        mysquare3= new square(centerx,centery,centerz-7,1,1.0f,.0f,.0f,"vert");
        mysquare4= new square(centerx+1,centery,centerz-6f,1,.0f,.5f,.5f,"side");
        mysquare5= new square(centerx,centery-1,centerz-6f,1,.5f,.5f,.0f,"horiz");
        mysquare6= new square(centerx,centery+1,centerz-6f,1,.5f,.0f,.5f,"horiz");
}

public void updatecube(float x, float y, float z)
{


        centerx =x;
        centery =y;
        centerz =z;

        mysquare1= new square(centerx,centery,centerz-5,1,.0f,.0f,1f,"vert");
        mysquare2= new square(centerx-1,centery,centerz-6f,1,.0f,1.0f,.0f,"side");
        mysquare3= new square(centerx,centery,centerz-7,1,1.0f,.0f,.0f,"vert");
        mysquare4= new square(centerx+1,centery,centerz-6f,1,.0f,.5f,.5f,"side");
        mysquare5= new square(centerx,centery-1,centerz-6f,1,.5f,.5f,.0f,"horiz");
        mysquare6= new square(centerx,centery+1,centerz-6f,1,.5f,.0f,.5f,"horiz");
}

public void drawcube(GL10 gl)
{
    mysquare1.draw(gl);        
    mysquare2.draw(gl);        
    mysquare3.draw(gl);        
    mysquare4.draw(gl);        
    mysquare5.draw(gl);        
    mysquare6.draw(gl);

}
public float getcenterx()
{
    return centerx;
}
public float getcentery()
{
    return centery;
}
public float getcenterz()
{
    return centerz;
}

这是实际的实现代码,它基于谷歌对 opengl 的介绍

class ClearGLSurfaceView extends GLSurfaceView {
    private static final String BufferUtils = null;
    float x =0;
    float y =0;
    float z =0f;
    float prevx=0;
    float prevy=0;
    GL10 mygl;
   // GL gl;
    float mywidth;
    float myheight;








public ClearGLSurfaceView(Context context,float width, float height) {
    super(context);
    mRenderer = new ClearRenderer();
    setRenderer(mRenderer);
    mywidth = width;
    myheight = height;





}
@Override
public boolean onTouchEvent(final MotionEvent event)
{

    queueEvent(new Runnable() {
        // Find the index of the active pointer and fetch its position
        public void run()
        {
            float curx = event.getX();
            float cury = event.getY();
            final int action = event.getAction();
            if(action == MotionEvent.ACTION_MOVE)
            {


            if(curx>prevx)
            {
                  x-=.1f;
            }
            if(curx<prevx)
            {
                  x+=.1f;
            }
            if(cury>prevy)
            {
                  y+=.1f;
            }
            if(cury<prevy)
            {
                  y-=.1f;
            }



            }
            if(action == MotionEvent.ACTION_DOWN)
            {
                // GLU.gluUnProject(winX, winY, winZ, model,
                //       modelOffset, project, projectOffset, view, viewOffset, obj, objOffset)
                vector2d moveto = new vector2d(0,0);
                moveto = mRenderer.getworkcoords(curx,cury);
                Log.i("move to ", "x "+moveto.x+" y "+ moveto.y+" z " + moveto.z);
                mRenderer.updatemoveto(moveto.x, moveto.y);



            }
            prevx= curx;
            prevy = cury;

            mRenderer.updatecamera(x, y, z);
}
 });
    return true;
} 

    ClearRenderer mRenderer;

}

类 ClearRenderer 实现 GLSurfaceView.Renderer {

       GL10 mygl;
       GL11 mygl11;

       int viewport[] = new int[4];
        float modelview[] = new float[16];
        float projection[] = new float[16];
        float wcoord[] = new float[4];

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);  // OpenGL docs.
    gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.
    gl.glClearDepthf(1.0f);// OpenGL docs.
    gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.
    gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
                      GL10.GL_NICEST);

    mygl = gl;
    mygl11 = (GL11) gl;
    int index;
    int counter = 0;
    float zcoord = -7.0f;

  mygl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview, 0);
  mygl11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, projection, 0);
  mygl11.glGetIntegerv(GL11.GL_VIEWPORT, viewport, 0);

    for(int x=0;x<11;x++)
    {
        for(int y =0;y<10;y++)
        {
            index = tilemap1[y][x];
            if(index==0)
            {
                tiles[counter]=new square(x,y,zcoord,0.5f,1.0f,0.0f,0f,"vert");

            }
            if(index==1)
            {
                tiles[counter]=new square(x,y,zcoord,0.5f,0f,1.0f,0f,"vert");

            }
            if(index==2)
            {
                tiles[counter]=new square(x,y,zcoord,0.5f,0.0f,0.0f,1f,"vert");

            }
            counter++;
        }
    }


}

public vector2d getworkcoords(float width,float height)
{
     float[] depth = new float[1];
     float winx = width;
     float winy =viewport[3]-height;
    //vector2d position = new vector2d(0,0);
    int test = GLU.gluUnProject(winx, winy,0.0f, modelview, 0, projection,
            0, viewport, 0, wcoord, 0);

    vector2d v = new vector2d(0,0);
    v.x = wcoord[0];
    v.y = wcoord[1];
    v.z = wcoord[2];
    return v ;
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
    gl.glViewport(0, 0, w, h);

    gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.

    gl.glLoadIdentity();// OpenGL docs.

    GLU.gluPerspective(gl, 45.0f,
                               (float) w / (float) h,
                               0.1f, 100.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.

    gl.glLoadIdentity();// OpenGL docs.
}

public float movetox;
public float movetoy;
float currentposx;
float currentposy;

public void updatemoveto(float x , float y) { movetox = x; 移动玩具 = y; } 公共无效 onDrawFrame(GL10 gl) {

    gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    currentposx = mycube.getcenterx();
    currentposy = mycube.getcentery();

    float x = movetox -currentposx;
    float y = movetoy - currentposy;
    double angle = Math.atan2(y, x);
    double mx =.5f*  Math.cos(angle);
    double my = .5f* Math.sin(angle);



    double mmx = mx+ currentposx;
    double mmy = my+ currentposy;

    mycube.updatecube((float)(mmx), (float)(mmy),0);  


    mycube.drawcube(gl);

    for(int i = 0;i<110;i++)
    {

            tiles[i].draw(gl);

    }


}

public void setColor(float r, float g, float b) {
    mRed = r;
    mGreen = g;
    mBlue = b;
}
public void updatecamera(float myx, float myy, float myz)
{

    mygl.glLoadIdentity();// OpenGL docs.
    GLU.gluLookAt(mygl, myx, myy, myz, myx, myy, myz-10, 0, 1, 0);

}


private float mRed;
private float mGreen;
private float mBlue;


int tilemap1[][] = {
        {0,0,0,0,0,0,0,0,0,0,0},
        {0,1,2,1,1,1,1,1,1,1,0},
        {0,1,2,1,1,1,1,1,1,1,0},
        {0,1,2,1,1,1,1,1,1,1,0},
        {0,1,2,2,2,1,1,1,1,1,0},
        {0,1,1,1,2,1,1,1,1,1,0},
        {0,1,1,1,2,1,1,1,1,1,0},
        {0,1,1,1,2,1,1,1,1,1,0},
        {0,1,1,1,2,2,1,1,1,1,0},
        {0,0,0,0,0,0,0,0,0,0,0},
};
square[] tiles = new square[110];

shapemaker mycube = new shapemaker(0,0,0,1);

}

我没有包括 on create 方法和 on pause 方法。我还想要关于设计代码结构的建议,因为我的实现远非完美。

所以简而言之。我想帮助弄清楚如何修改我制作的代码以使立方体移动到我按下的位置。以及如何改进代码

谢谢

4

1 回答 1

0

首先,

您不需要在每次移动时重新创建顶点。这是一项非常复杂的任务,它会降低帧率 (FPS)。在您的代码中,您有模型矩阵。通常它负责模型的平移、缩放旋转(在您的示例中为网格、立方体)。在通常情况下,您必须转换模型矩阵,然后转换多个模型、投影和视图矩阵,您将获得设备屏幕的矩阵。然后通过顶点位置和这个矩阵的乘法,你会得到顶点的正确位置。

你可以看看这个问题/答案

于 2011-04-18T02:29:42.763 回答