OpenGL版スライドパズルサンプルapk
ひとまずOpenGL版のスライドパズルサンプルの配布用apkを置きました。
Android端末のブラウザで以下にアクセスすると、ダウンロード・インストールできます。
http://www015.upp.so-net.ne.jp/chiaki_sugimoto/android/SlidePuzzle.apk
SlidePuzzle1としてインストールされます。アプリを起動すると、シャッフルされた画面が出るので、解答を求めて指でスライドしていきます。
またAndroid端末のmenuボタンを押すとGiveUPとShuffleのメニューが出るので、現在の画面状態からの解答プレビューを見たい時はGiveUPを、現在の画面状態からのシャッフルを行いたい時はShuffleを選択してください。
尚今回のように、AndroidMarket以外に配置した配布用署名付きapkをインストールするためには、Android端末側で以下の設定が必要です。
☆「設定」→「アプリケーション」→「提供元不明のアプリ」にチェックを入れる。(GDDPhoneはこの設定ですが、DevPhoneやその他製品により異なると思います)
AndroidMarketに出すわけではなく、あくまで自己メモを兼ねたサンプルなので、写真の自由選択やタイマーといったオプションはなく、至ってシンプルです。あと、GiveUp時の解答プレビューは最短経路ではありませんのであしからず。
SurfaceView版とView版も暇を見つけて、順次追加アップしたいと思います。
前回からの差分は、
・縦横の画面サイズをGDDPhone用専用(数値固定)から機種非依存(数値取得)に変更
・GiveUpモードとShuffleモードの追加
SlidePuzzle.javaにもメニューボタン等の変更が入りましたが、重要なポイントを含むSlidePuzzle_GLSurfaceView.javaの方だけ、メモとしてアップします。
package com.chiaki.example; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.ListIterator; import java.util.Random; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView; import android.opengl.GLU; import android.opengl.GLUtils; import android.view.KeyEvent; import android.view.MotionEvent; public class SlidePuzzle_GLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer { private Random rand=new Random(); private Bitmap image; private static int[] data=new int[25]; private FloatBuffer[] vertexBuff = new FloatBuffer[25]; private FloatBuffer textureBuff = null; private int[] textureId; private static int freeIdx; private static ArrayList<String> res; static ListIterator<String> ite; private static int pos; private static String reskey = null; private static boolean last_flg = false; private BitmapFactory.Options options; private Context context; public SlidePuzzle_GLSurfaceView(Context context) { super(context); initialize(context); for (int i=0;i<25;i++) data[i]=i; } private void initialize(Context context) { setFocusable(true); setFocusableInTouchMode(true); setFocusable(true); this.setRenderer( this ); ByteBuffer[] byteBuffer = new ByteBuffer[25]; for (int i = 0; i < 25; i++){ byteBuffer[i] = ByteBuffer.allocateDirect(4 * 3 * 4); byteBuffer[i].order(ByteOrder.nativeOrder()); vertexBuff[i] = byteBuffer[i].asFloatBuffer(); } ByteBuffer t_byteBuffer = ByteBuffer.allocateDirect(4 * 2 * 4); t_byteBuffer.order(ByteOrder.nativeOrder()); textureBuff = t_byteBuffer.asFloatBuffer(); textureBuff.put(new float[] { 0.0f, 1.0f, //左下 1.0f, 1.0f, //右下 0.0f, 0.0f, //左上 1.0f, 0.0f, //右上 }); textureBuff.position(0); Resources r=context.getResources(); int resID=R.drawable.picture; image = BitmapFactory.decodeResource(r,resID); res = new ArrayList<String>(); } private void loadTexture( GL10 gl ){ int width = image.getWidth(); int height = image.getHeight(); int[][] pixels = new int[25][(width/5) * (height/5)+1]; int img_pixels[] = new int[width * height]; for (int i = 0; i < 25; i++){ pixels[i] = new int[(width/5) * (height/5)]; } image.getPixels(img_pixels, 0, width, 0, 0, width, height); for (int y = 0; y < height/5; y++) { for (int x = 0; x < width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[0][x + y * (width/5)] = pixel; } for (int x = width/5; x < 2*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[1][(x - width/5) + y * (width/5)] = pixel; } for (int x = 2*width/5; x < 3*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[2][(x - 2*width/5) + y * (width/5)] = pixel; } for (int x = 3*width/5; x < 4*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[3][(x - 3*width/5) + y * (width/5)] = pixel; } for (int x = 4*width/5; x < width; x++) { int pixel = img_pixels[x + y * width]; pixels[4][(x - 4*width/5) + y * (width/5)] = pixel; } } for (int y = height/5; y < 2*height/5; y++) { for (int x = 0; x < width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[5][x + (y - height/5) * (width/5)] = pixel; } for (int x = width/5; x < 2*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[6][(x - width/5) + (y - height/5) * (width/5)] = pixel; } for (int x = 2*width/5; x < 3*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[7][(x - 2*width/5) + (y - height/5) * (width/5)] = pixel; } for (int x = 3*width/5; x < 4*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[8][(x - 3*width/5) + (y - height/5) * (width/5)] = pixel; } for (int x = 4*width/5; x < width; x++) { int pixel = img_pixels[x + y * width]; pixels[9][(x - 4*width/5) + (y - height/5) * (width/5)] = pixel; } } for (int y = 2*height/5; y < 3*height/5; y++) { for (int x = 0; x < width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[10][x + (y - 2*height/5) * (width/5)] = pixel; } for (int x = width/5; x < 2*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[11][(x - width/5) + (y - 2*height/5) * (width/5)] = pixel; } for (int x = 2*width/5; x < 3*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[12][(x - 2*width/5) + (y - 2*height/5) * (width/5)] = pixel; } for (int x = 3*width/5; x < 4*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[13][(x - 3*width/5) + (y - 2*height/5) * (width/5)] = pixel; } for (int x = 4*width/5; x < width; x++) { int pixel = img_pixels[x + y * width]; pixels[14][(x - 4*width/5) + (y - 2*height/5) * (width/5)] = pixel; } } for (int y = 3*height/5; y < 4*height/5; y++) { for (int x = 0; x < width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[15][x + (y - 3*height/5) * (width/5)] = pixel; } for (int x = width/5; x < 2*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[16][(x - width/5) + (y - 3*height/5) * (width/5)] = pixel; } for (int x = 2*width/5; x < 3*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[17][(x - 2*width/5) + (y - 3*height/5) * (width/5)] = pixel; } for (int x = 3*width/5; x < 4*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[18][(x - 3*width/5) + (y - 3*height/5) * (width/5)] = pixel; } for (int x = 4*width/5; x < width; x++) { int pixel = img_pixels[x + y * width]; pixels[19][(x - 4*width/5) + (y - 3*height/5) * (width/5)] = pixel; } } for (int y = 4*height/5; y < height; y++) { for (int x = 0; x < width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[20][x + (y - 4*height/5) * (width/5)] = pixel; } for (int x = width/5; x < 2*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[21][(x - width/5) + (y - 4*height/5) * (width/5)] = pixel; } for (int x = 2*width/5; x < 3*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[22][(x - 2*width/5) + (y - 4*height/5) * (width/5)] = pixel; } for (int x = 3*width/5; x < 4*width/5; x++) { int pixel = img_pixels[x + y * width]; pixels[23][(x - 3*width/5) + (y - 4*height/5) * (width/5)] = pixel; } for (int x = 4*width/5; x < width; x++) { int pixel = img_pixels[x + y * width]; pixels[24][(x - 4*width/5) + (y - 4*height/5) * (width/5)] = pixel; } } Bitmap[] bitmap = new Bitmap[25]; for (int i = 0; i < 25; i++){ bitmap[i] = Bitmap.createBitmap(width/5, height/5, Bitmap.Config.ARGB_8888); bitmap[i].setPixels(pixels[i], 0, width/5, 0, 0, width/5, height/5); bitmap[i] = Bitmap.createScaledBitmap(bitmap[i], 128, 128, true); } int[] textures = new int[25]; gl.glGenTextures(25, textures, 0); image.recycle(); textureId = new int[25]; for (int i = 0; i < 25; i++){ textureId[i] = textures[i]; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId[i]); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); GLUtils.texImage2D( GL10.GL_TEXTURE_2D, 0, bitmap[i], 0 ); bitmap[i].recycle(); } } @Override public void onResume(){ super.onResume(); this.onResume(); } @Override public void onPause(){ super.onPause(); this.onPause(); } private int displayWidth; private int displayHeight; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { displayWidth = getWidth(); displayHeight = getHeight(); gl.glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glShadeModel( GL10.GL_FLAT ); gl.glEnableClientState( GL10.GL_VERTEX_ARRAY ); gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY ); gl.glEnable( GL10.GL_TEXTURE_2D ); GLU.gluOrtho2D(gl, -1.0f, 1.0f, -1.0f, 1.0f); loadPicture(); this.loadTexture( gl ); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport( 0, 0, width, height ); } @Override public void onDrawFrame(GL10 gl) { boolean complete=true; for (int i=0;i<25;i++) { if (data[i]!=i) complete=false; } if (complete){ for (ite = res.listIterator(res.size()); ite.hasPrevious();){ ite.remove(); } } ByteBuffer[] byteBuffer = new ByteBuffer[25]; for (int i = 0; i < 25; i++){ byteBuffer[i] = ByteBuffer.allocateDirect(4 * 3 * 4); byteBuffer[i].order(ByteOrder.nativeOrder()); vertexBuff[i] = byteBuffer[i].asFloatBuffer(); } float tl_x = -1.0f; float tl_y = -1.0f; float tr_x = 1.0f; float tr_y = -1.0f; float ul_x = -1.0f; float ul_y = 1.0f; float ur_x = 1.0f; float ur_y = 1.0f; float ratiox = 2.0f/5; float ratioy = (2.0f/5)*((1.0f*displayWidth)/(1.0f*displayHeight)); tl_x = (ratiox * -0.5f); tl_y = (ratioy * -0.5f); tr_x = (ratiox * 0.5f); tr_y = (ratioy * -0.5f); ul_x = (ratiox * -0.5f); ul_y = (ratioy * 0.5f); ur_x = (ratiox * 0.5f); ur_y = (ratioy * 0.5f); float [] x = new float[25]; float [] y = new float[25]; for (int i = 0; i < 25; i++){ if (i%5 == 0){ x[i] = -1.0f; }else if(i%5 == 1){ x[i] = -1.0f/2.0f; }else if(i%5 == 2){ x[i] = 0; }else if(i%5 == 3){ x[i] = 1.0f/2.0f; }else if(i%5 == 4){ x[i] = 1.0f; } } for (int i = 0; i < 25; i++){ if (i/5 == 0){ y[i] = 1.0f; }else if(i/5 == 1){ y[i] = 1.0f/2.0f; }else if(i/5 == 2){ y[i] = 0; }else if(i/5 == 3){ y[i] = -1.0f/2.0f; }else if(i/5 == 4){ y[i] = -1.0f; } } for (int i = 0; i < 25; i++){ if (getmode() == KeyEvent.KEYCODE_DPAD_UP || getmode() == KeyEvent.KEYCODE_DPAD_DOWN){ if ((i <= (5*gettouchY() + gettouchX()) && i > (5*getfreeY() + getfreeX()) && (i == (5*getfreeY() + getfreeX())+5 || i == (5*getfreeY() + getfreeX())+10 || i == (5*getfreeY() + getfreeX())+15 || i == (5*getfreeY() + getfreeX())+20) && getslide_ysum() <= 60 && getslide_ysum() >= 0) ||(i >= (5*gettouchY() + gettouchX()) && i < (5*getfreeY() + getfreeX()) && (i == (5*getfreeY() + getfreeX())-5 || i == (5*getfreeY() + getfreeX())-10 || i == (5*getfreeY() + getfreeX())-15 || i == (5*getfreeY() + getfreeX())-20) && getslide_ysum() > -60 && getslide_ysum() < 0)){ vertexBuff[i].put(new float[] { tl_x+x[i]*(2.0f/2.5f), tl_y+y[i]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(getslide_ysum()*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, tr_x+x[i]*(2.0f/2.5f), tl_y+y[i]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(getslide_ysum()*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ul_x+x[i]*(2.0f/2.5f), ul_y+y[i]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(getslide_ysum()*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ur_x+x[i]*(2.0f/2.5f), ur_y+y[i]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(getslide_ysum()*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f}); vertexBuff[i].position(0); }else{ vertexBuff[i].put(new float[] { tl_x+x[i]*(2.0f/2.5f), tl_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[i]*(2.0f/2.5f), tr_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[i]*(2.0f/2.5f), ul_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[i]*(2.0f/2.5f), ur_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[i].position(0); } int[] textureId_tmp = new int[25]; if (getslide_ysum() >= 60 || getslide_ysum() <= -60){ if (getslide_ysum() >= 60){ for (int j=touchY;j>freeY;j--) { slidePiece(getmode(), 0); } }else if (getslide_ysum() <= -60){ for (int j=freeY;j>touchY;j--) { slidePiece(getmode(), 0); } } for (int j = 0; j < 25; j++){ textureId_tmp[j] = textureId[data[j]]; } for (int j = 0; j < 25; j++){ textureId[j] = textureId[j]; } s_touchX = 0; s_touchY = 0; e_touchX = 0; e_touchY = 0; slide_x = 0; slide_y = 0; slide_xsum = 0; slide_ysum = 0; reach_flg = true; } }else if (getmode() == KeyEvent.KEYCODE_DPAD_RIGHT || getmode() == KeyEvent.KEYCODE_DPAD_LEFT){ if ((i < (5*getfreeY() + getfreeX()) && i >= (5*gettouchY() + gettouchX()) && getslide_xsum() <= 60 && getslide_xsum() >= 0) || (i > (5*getfreeY() + getfreeX()) && i <= (5*gettouchY() + gettouchX()) && getslide_xsum() >= -60 && getslide_xsum() <= 0)){ vertexBuff[i].put(new float[] { tl_x+x[i]*(2.0f/2.5f)+(getslide_xsum()*(1.0f/(1.0f*displayWidth/2.0f))), tl_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[i]*(2.0f/2.5f)+(getslide_xsum()*(1.0f/(1.0f*displayWidth/2.0f))), tr_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[i]*(2.0f/2.5f)+(getslide_xsum()*(1.0f/(1.0f*displayWidth/2.0f))), ul_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[i]*(2.0f/2.5f)+(getslide_xsum()*(1.0f/(1.0f*displayWidth/2.0f))), ur_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[i].position(0); }else{ vertexBuff[i].put(new float[] { tl_x+x[i]*(2.0f/2.5f), tl_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[i]*(2.0f/2.5f), tr_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[i]*(2.0f/2.5f), ul_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[i]*(2.0f/2.5f), ur_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[i].position(0); } int[] textureId_tmp = new int[25]; if (getslide_xsum() >= 60 || getslide_xsum() <= -60){ if (getslide_xsum() >= 60){ for (int j=freeX;j>touchX;j--) { slidePiece(getmode(), 0); } }else if (getslide_xsum() <= -60){ for (int j=touchX;j>freeX;j--) { slidePiece(getmode(), 0); } } for (int j = 0; j < 25; j++){ textureId_tmp[j] = textureId[data[j]]; } for (int j = 0; j < 25; j++){ textureId[j] = textureId[j]; } s_touchX = 0; s_touchY = 0; e_touchX = 0; e_touchY = 0; slide_x = 0; slide_y = 0; slide_xsum = 0; slide_ysum = 0; reach_flg = true; } }else{ vertexBuff[i].put(new float[] { tl_x+x[i]*(2.0f/2.5f), tl_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[i]*(2.0f/2.5f), tr_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[i]*(2.0f/2.5f), ul_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[i]*(2.0f/2.5f), ur_y+y[i]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[i].position(0); } } if (getres_flg() && !complete){ if (ite.hasPrevious() || (!(ite.hasPrevious()) && last_flg)){ if ((pos == 0 || pos >= 60 || pos <= -60) && !last_flg){ reskey = (String) ite.previous(); ite.remove(); } if (reskey.equals("KeyEvent.KEYCODE_DPAD_UP")){ if (pos < 60){ for (int i = 0; i < 10; i++){ pos++; } freeIdx=0; for (; freeIdx<25; freeIdx++) { if (data[freeIdx]==24) break; } vertexBuff[freeIdx+5].put(new float[] { tl_x+x[freeIdx+5]*(2.0f/2.5f), tl_y+y[freeIdx+5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, tr_x+x[freeIdx+5]*(2.0f/2.5f), tl_y+y[freeIdx+5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ul_x+x[freeIdx+5]*(2.0f/2.5f), ul_y+y[freeIdx+5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ur_x+x[freeIdx+5]*(2.0f/2.5f), ur_y+y[freeIdx+5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f}); vertexBuff[freeIdx+5].position(0); } if (pos >= 60){ slidePiece(KeyEvent.KEYCODE_DPAD_UP, 1); pos = 0; } }else if (reskey.equals("KeyEvent.KEYCODE_DPAD_DOWN")){ if (pos > -60){ for (int i = 0; i < 10; i++){ pos--; } freeIdx=0; for (; freeIdx<25; freeIdx++) { if (data[freeIdx]==24) break; } vertexBuff[freeIdx-5].put(new float[] { tl_x+x[freeIdx-5]*(2.0f/2.5f), tl_y+y[freeIdx-5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, tr_x+x[freeIdx-5]*(2.0f/2.5f), tl_y+y[freeIdx-5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ul_x+x[freeIdx-5]*(2.0f/2.5f), ul_y+y[freeIdx-5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f, ur_x+x[freeIdx-5]*(2.0f/2.5f), ur_y+y[freeIdx-5]*(2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))+(pos*(1.0f/(1.0f*displayHeight/2.0f))), 0.0f}); vertexBuff[freeIdx-5].position(0); } if (pos <= -60){ slidePiece(KeyEvent.KEYCODE_DPAD_DOWN, 1); pos = 0; } }else if (reskey.equals("KeyEvent.KEYCODE_DPAD_LEFT")){ if (pos > -60){ for (int i = 0; i < 10; i++){ pos--; } freeIdx=0; for (; freeIdx<25; freeIdx++) { if (data[freeIdx]==24) break; } vertexBuff[freeIdx+1].put(new float[] { tl_x+x[freeIdx+1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), tl_y+y[freeIdx+1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[freeIdx+1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), tr_y+y[freeIdx+1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[freeIdx+1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), ul_y+y[freeIdx+1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[freeIdx+1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), ur_y+y[freeIdx+1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[freeIdx+1].position(0); } if (pos <= -60){ slidePiece(KeyEvent.KEYCODE_DPAD_LEFT, 1); pos = 0; } }else if(reskey.equals("KeyEvent.KEYCODE_DPAD_RIGHT")){ if (pos < 60){ for (int i = 0; i < 10; i++){ pos++; } freeIdx=0; for (; freeIdx<25; freeIdx++) { if (data[freeIdx]==24) break; } vertexBuff[freeIdx-1].put(new float[] { tl_x+x[freeIdx-1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), tl_y+y[freeIdx-1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, tr_x+x[freeIdx-1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), tr_y+y[freeIdx-1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ul_x+x[freeIdx-1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), ul_y+y[freeIdx-1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f, ur_x+x[freeIdx-1]*(2.0f/2.5f)+(pos*(1.0f/(1.0f*displayWidth/2.0f))), ur_y+y[freeIdx-1]*((2.0f/2.5f)*((1.0f*displayWidth)/(1.0f*displayHeight))), 0.0f}); vertexBuff[freeIdx-1].position(0); } if (pos >= 60){ slidePiece(KeyEvent.KEYCODE_DPAD_RIGHT, 1); pos = 0; } } if (!ite.hasPrevious()){ last_flg = true; } }else { reskey = null; last_flg = false; } boolean flg = false; for (int i=0;i<25;i++) { if (data[i]!=i){ flg = true; } } if (!flg){ complete=true; for (ite = res.listIterator(res.size()); ite.hasPrevious();){ ite.previous(); ite.remove(); } } }else{ res_flg = false; } gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT ); gl.glActiveTexture( GL10.GL_TEXTURE0 ); for (int i = 0; i < 25; i++){ if (data[i] == 24){ }else{ gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId[data[i]] ); gl.glPushMatrix(); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuff[i] ); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY ); gl.glEnable( GL10.GL_TEXTURE_2D ); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuff ); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4); gl.glPopMatrix(); } } if (complete) { } } public void loadPicture() { context = getContext(); Resources r=context.getResources(); int resID=R.drawable.picture; options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(r,resID, options); int scaleW = options.outWidth / displayHeight + 1; int scaleH = options.outHeight / displayWidth + 1; int scale = Math.max(scaleW, scaleH); options.inJustDecodeBounds = false; options.inSampleSize = scale; image = BitmapFactory.decodeResource(r,resID, options); image = Bitmap.createScaledBitmap(image, displayWidth, displayWidth, true); int[] DIR={ KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT }; int before = -1; int current = -1; for (int i=99;i>=0;i--) { current = (rand.nextInt()>>>1)%4; if (before == -1 || (before == 0 && current != 1) || (before == 1 && current != 0) || (before == 2 && current != 3) || (before == 3 && current != 2)){ slidePiece(DIR[current], 0); before = current; }else{ i++; } } } static void slidePiece(int key, int flg) { freeIdx=0; for (; freeIdx<25; freeIdx++) { if (data[freeIdx]==24) break; } if (flg == 0){ if (key==KeyEvent.KEYCODE_DPAD_UP && freeIdx/5<4) { res.add("KeyEvent.KEYCODE_DPAD_DOWN"); } else if (key==KeyEvent.KEYCODE_DPAD_DOWN && freeIdx/5>0) { res.add("KeyEvent.KEYCODE_DPAD_UP"); } else if (key==KeyEvent.KEYCODE_DPAD_LEFT && freeIdx%5<4) { res.add("KeyEvent.KEYCODE_DPAD_RIGHT"); } else if (key==KeyEvent.KEYCODE_DPAD_RIGHT && freeIdx%5>0) { res.add("KeyEvent.KEYCODE_DPAD_LEFT"); } } if (key==KeyEvent.KEYCODE_DPAD_UP && freeIdx/5<4) { data[freeIdx]=data[freeIdx+5]; data[freeIdx+5]=24; } else if (key==KeyEvent.KEYCODE_DPAD_DOWN && freeIdx/5>0) { data[freeIdx]=data[freeIdx-5]; data[freeIdx-5]=24; } else if (key==KeyEvent.KEYCODE_DPAD_LEFT && freeIdx%5<4) { data[freeIdx]=data[freeIdx+1]; data[freeIdx+1]=24; } else if (key==KeyEvent.KEYCODE_DPAD_RIGHT && freeIdx%5>0) { data[freeIdx]=data[freeIdx-1]; data[freeIdx-1]=24; } } static void Shuffle(){ int[] DIR={ KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT }; int before = -1; int current = -1; for (int i=99;i>=0;i--) { Random rand=new Random(); current = (rand.nextInt()>>>1)%4; if (before == -1 || (before == 0 && current != 1 && current != 0) || (before == 1 && current != 0 && current != 1) || (before == 2 && current != 3 && current != 2) || (before == 3 && current != 2 && current != 3)){ slidePiece(DIR[current], 0); before = current; }else { i++; } } } @Override public boolean onTouchEvent(MotionEvent event) { switch( event.getAction() ){ case MotionEvent.ACTION_DOWN : s_touchX = 0; s_touchY = 0; e_touchX = 0; e_touchY = 0; s_touchX = (int) event.getX(); s_touchY = (int) event.getY(); touchX=(int)(event.getX()-(getWidth()-displayWidth)/2)/60; touchY=(int)(event.getY()-(getHeight()-displayWidth)/2)/60; if (touchX<0 || 5<=touchX) return true; if (touchY<0 || 5<=touchY) return true; freeX=0; freeY=0; for (int i=0;i<25;i++) { if (data[i]==24) { freeX=i%5; freeY=i/5; break; } } if (touchX==freeX) { if (freeY<touchY) { mode = KeyEvent.KEYCODE_DPAD_UP; } else if (freeY>touchY) { mode = KeyEvent.KEYCODE_DPAD_DOWN; } } else if (touchY==freeY) { if (freeX<touchX) { mode = KeyEvent.KEYCODE_DPAD_LEFT; } else if (freeX>touchX) { mode = KeyEvent.KEYCODE_DPAD_RIGHT; } } break; case MotionEvent.ACTION_MOVE : e_touchX = (int) event.getX(); e_touchY = (int) event.getY(); slide_x = e_touchX - s_touchX; slide_y = s_touchY - e_touchY; if (getslide_x() > 60){ slide_x = 60; } if (getslide_x() < -60){ slide_x = -60; } if (getslide_y() > 60){ slide_y = 60; } if (getslide_y() < -60){ slide_y = -60; } if ((getslide_xsum() <= 60 && getslide_xsum() >=0) || (getslide_xsum() <= 0 && getslide_xsum() >= -60)){ slide_xsum =getslide_xsum() + getslide_x(); } if ((getslide_ysum() >= 0 && getslide_ysum() <= 60) || (getslide_ysum() <= 0 && getslide_ysum() >= -60)){ slide_ysum =getslide_ysum() + getslide_y(); } s_touchX = e_touchX; s_touchY = e_touchY; if (getreach_flg() == true){ s_touchX = 0; s_touchY = 0; e_touchX = 0; e_touchY = 0; slide_x = 0; slide_y = 0; slide_xsum = 0; slide_ysum = 0; mode = -1; reach_flg = false; } break; case MotionEvent.ACTION_UP : s_touchX = 0; s_touchY = 0; e_touchX = 0; e_touchY = 0; slide_x = 0; slide_y = 0; slide_xsum = 0; slide_ysum = 0; mode = -1; reach_flg = false; break; } return true; } public static void showResult(){ res_flg = true; last_flg = false; pos = 0; ite = res.listIterator(res.size()); } @Override public boolean onKeyDown(int keyCode,KeyEvent event) { slidePiece(keyCode, 0); return super.onKeyDown(keyCode,event); } public int getmode(){ return mode; } public int getslide_x(){ return slide_x; } public int getslide_y(){ return slide_y; } public int getslide_xsum(){ return slide_xsum; } public int getslide_ysum(){ return slide_ysum; } public int gettouchX(){ return touchX; } public int gettouchY(){ return touchY; } public int getfreeX(){ return freeX; } public int getfreeY(){ return freeY; } public boolean getreach_flg(){ return reach_flg; } public boolean getres_flg(){ return res_flg; } private int slide_x; private int slide_y; private int mode = -1; private int touchX; private int touchY; private int freeX; private int freeY; private int s_touchX = 0; private int s_touchY = 0; private int e_touchX = 0; private int e_touchY = 0; private int slide_xsum = 0; private int slide_ysum = 0; private boolean reach_flg = false; private static boolean res_flg = false; }