我正在使用 openGL es 2.0 为 android 开发一个简单的游戏。游戏将是 2D 的,类似于旧的超级马里奥,玩家可以左右/上下移动,但没有深度。
级别将大于屏幕,因此图形必须滚动。这就是问题所在。我不知道在哪里/何时停止滚动。
例子。假设背景是 100x100 大小的带有纹理的正方形。假设在屏幕上,任何时候都只有 1/4 的背景可见。然后当我将屏幕向右移动时,我希望它在背景的右边缘到达屏幕边缘时停止滚动。
我现在能做的最好的事情就是在“视图”的中心位于背景边缘时停止滚动。但这并不好,因为屏幕的 3/4 都是空白的。
如何计算从视图中心到屏幕边缘的“偏移量”?
注意:我不想使用正交投影。
这是渲染器的代码。
package com.huntedseas;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.util.Log;
public class GameRenderer implements Renderer {
protected LevelGenerator generator;
protected SquareGL squareGL;
protected static float angleX;
protected static float angleY;
protected static float angleZ;
protected static float viewX = 0;
protected static float viewY = 0;
//private float viewZ = 0;
private float[] mProjectionMatrix = new float[16]; //Projekcijska matrika
private float[] mVMatrix = new float[16];
private float[] mMVPMatrix = new float[16];
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig conunused) {
GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
GLES20.glDisable(GLES20.GL_CULL_FACE); //No culling of back faces \\ To nevem al je treba da je uklopljeno al ne
GLES20.glDisable(GLES20.GL_DEPTH_TEST); //No depth testing \\ --||--
GLES20.glEnable(GLES20.GL_BLEND); //Blending
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA); //Interpolated blending
generator = new LevelGenerator();
}
@Override
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
moveView();
Matrix.setLookAtM(mVMatrix, 0, viewY, viewX, -10, viewY, viewX, 0, 0.0f, 1.0f, 0.0f); //set view
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mVMatrix, 0); //calculate view transformation
generator.draw(mMVPMatrix);
}
@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width/height;
float left =-ratio;
float right = ratio;
float bottom = -1.0f;
float top = 1.0f;
float near = 1.0f;
float far = 20.0f;
Log.d("ratio","ratio: "+left+" r: "+right+" w: "+width+" h: "+height);
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}
long lastTime = System.currentTimeMillis();
public void moveView(){
if((System.currentTimeMillis()-lastTime) >= 33){
lastTime = System.currentTimeMillis();
Log.d("viewX","viewX: "+viewX + "viewY:"+viewY);
if( (viewX - angleX/10) < Level1.viewXP && (viewX - angleX/10) > Level1.viewXM) viewX -= angleX/10;
if( (viewY - angleY/10) < Level1.viewYP && (viewY - angleY/10) > Level1.viewYM) viewY -= angleY/10;
//if(Math.abs(viewX - angleX/10) < 10) viewX-=angleX/10;
//if(Math.abs(viewY - angleY/10) < 10) viewY-=angleY/10;
//if(Math.abs(viewZ - (angleZ-5)/10) < 10) viewZ+=(angleZ-5)/10;
}
}
}