This example shows how you can create Rubik’s cube in android.
Algorithm:
1.) Create a new project by File-> New -> Android Project name it RubikCubeAnimationExample.
2.) Create and write following into src/M4.java:
package com.example.RubikCubeAnimationExample;
public class M4 {
public float[][] m = new float[4][4];
public M4() {
}
public M4(M4 other) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
m[i][j] = other.m[i][j];
}
}
}
public float[][] m = new float[4][4];
public M4() {
}
public M4(M4 other) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
m[i][j] = other.m[i][j];
}
}
}
public void multiply(GLVertex src, GLVertex dest) {
dest.x = src.x * m[0][0] + src.y * m[1][0] + src.z * m[2][0] +m[3][0];
dest.y = src.x * m[0][1] + src.y * m[1][1] + src.z * m[2][1] +m[3][1];
dest.z = src.x * m[0][2] + src.y * m[1][2] + src.z * m[2][2] +m[3][2];
}
public M4 multiply(M4 other) {
M4 result = new M4();
float[][] m1 = m;
float[][] m2 = other.m;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
result.m[i][j] = m1[i][0]*m2[0][j] +m1[i][1]*m2[1][j] + m1[i][2]*m2[2][j] + m1[i][3]*m2[3][j];
}
}
return result;
}
public void setIdentity() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
m[i][j] = (i == j ? 1f : 0f);
}
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[ ");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
builder.append(m[i][j]);
builder.append(" ");
}
if (i < 2)
builder.append("\n ");
}
builder.append(" ]");
return builder.toString();
}
}
dest.x = src.x * m[0][0] + src.y * m[1][0] + src.z * m[2][0] +m[3][0];
dest.y = src.x * m[0][1] + src.y * m[1][1] + src.z * m[2][1] +m[3][1];
dest.z = src.x * m[0][2] + src.y * m[1][2] + src.z * m[2][2] +m[3][2];
}
public M4 multiply(M4 other) {
M4 result = new M4();
float[][] m1 = m;
float[][] m2 = other.m;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
result.m[i][j] = m1[i][0]*m2[0][j] +m1[i][1]*m2[1][j] + m1[i][2]*m2[2][j] + m1[i][3]*m2[3][j];
}
}
return result;
}
public void setIdentity() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
m[i][j] = (i == j ? 1f : 0f);
}
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[ ");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
builder.append(m[i][j]);
builder.append(" ");
}
if (i < 2)
builder.append("\n ");
}
builder.append(" ]");
return builder.toString();
}
}
3.) Create and write following into src/Layer.java:
package com.example.RubikCubeAnimationExample;
public class Layer {
public Layer(int axis) {
mAxis = axis;
mTransform.setIdentity();
}
public void startAnimation() {
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.startAnimation();
}
}
}
public Layer(int axis) {
mAxis = axis;
mTransform.setIdentity();
}
public void startAnimation() {
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.startAnimation();
}
}
}
public void endAnimation() {
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.endAnimation();
}
}
}
public void setAngle(float angle) {
// normalize the angle
float twopi = (float)Math.PI *2f;
while (angle >= twopi) angle -= twopi;
while (angle < 0f) angle += twopi;
// mAngle = angle;
float sin = (float)Math.sin(angle);
float cos = (float)Math.cos(angle);
float[][] m = mTransform.m;
switch (mAxis) {
case kAxisX:
m[1][1] = cos;
m[1][2] = sin;
m[2][1] = -sin;
m[2][2] = cos;
m[0][0] = 1f;
m[0][1] = m[0][2] = m[1][0] = m[2][0] = 0f;
break;
case kAxisY:
m[0][0] = cos;
m[0][2] = sin;
m[2][0] = -sin;
m[2][2] = cos;
m[1][1] = 1f;
m[0][1] = m[1][0] = m[1][2] = m[2][1] = 0f;
break;
case kAxisZ:
m[0][0] = cos;
m[0][1] = sin;
m[1][0] = -sin;
m[1][1] = cos;
m[2][2] = 1f;
m[2][0] = m[2][1] = m[0][2] = m[1][2] = 0f;
break;
}
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.animateTransform(mTransform);
}
}
}
GLShape[] mShapes = new GLShape[9];
M4 mTransform = new M4();
int mAxis;
static public final int kAxisX = 0;
static public final int kAxisY = 1;
static public final int kAxisZ = 2;
}
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.endAnimation();
}
}
}
public void setAngle(float angle) {
// normalize the angle
float twopi = (float)Math.PI *2f;
while (angle >= twopi) angle -= twopi;
while (angle < 0f) angle += twopi;
// mAngle = angle;
float sin = (float)Math.sin(angle);
float cos = (float)Math.cos(angle);
float[][] m = mTransform.m;
switch (mAxis) {
case kAxisX:
m[1][1] = cos;
m[1][2] = sin;
m[2][1] = -sin;
m[2][2] = cos;
m[0][0] = 1f;
m[0][1] = m[0][2] = m[1][0] = m[2][0] = 0f;
break;
case kAxisY:
m[0][0] = cos;
m[0][2] = sin;
m[2][0] = -sin;
m[2][2] = cos;
m[1][1] = 1f;
m[0][1] = m[1][0] = m[1][2] = m[2][1] = 0f;
break;
case kAxisZ:
m[0][0] = cos;
m[0][1] = sin;
m[1][0] = -sin;
m[1][1] = cos;
m[2][2] = 1f;
m[2][0] = m[2][1] = m[0][2] = m[1][2] = 0f;
break;
}
for (int i = 0; i < mShapes.length; i++) {
GLShape shape = mShapes[i];
if (shape != null) {
shape.animateTransform(mTransform);
}
}
}
GLShape[] mShapes = new GLShape[9];
M4 mTransform = new M4();
int mAxis;
static public final int kAxisX = 0;
static public final int kAxisY = 1;
static public final int kAxisZ = 2;
}
4.) Create and write following into src/KubeRenderer.java:
package com.example.RubikCubeAnimationExample;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
class KubeRenderer implements GLSurfaceView.Renderer {
public interface AnimationCallback {
void animate();
}
public interface AnimationCallback {
void animate();
}
public KubeRenderer(GLWorld world, AnimationCallback callback) {
mWorld = world;
mCallback = callback;
}
mWorld = world;
mCallback = callback;
}
public void onDrawFrame(GL10 gl) {
if (mCallback != null) {
mCallback.animate();
}
gl.glClearColor(0.5f,0.5f,0.5f,1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
if (mCallback != null) {
mCallback.animate();
}
gl.glClearColor(0.5f,0.5f,0.5f,1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
mWorld.draw(gl);
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float)width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
gl.glDisable(GL10.GL_DITHER);
gl.glActiveTexture(GL10.GL_TEXTURE0);
}
gl.glViewport(0, 0, width, height);
float ratio = (float)width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
gl.glDisable(GL10.GL_DITHER);
gl.glActiveTexture(GL10.GL_TEXTURE0);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}
public void setAngle(float angle) {
mAngle = angle;
}
mAngle = angle;
}
public float getAngle() {
return mAngle;
}
return mAngle;
}
private GLWorld mWorld;
private AnimationCallback mCallback;
private float mAngle;
}
private AnimationCallback mCallback;
private float mAngle;
}
5.) Create and write following into src/GLWorld.java:
package com.example.RubikCubeAnimationExample;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.Iterator;
import java.util.ArrayList;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.Iterator;
import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;
public class GLWorld {
public void addShape(GLShape shape) {
mShapeList.add(shape);
mIndexCount += shape.getIndexCount();
}
public void generate() {
ByteBuffer bb = ByteBuffer.allocateDirect(mVertexList.size()*4*4);
bb.order(ByteOrder.nativeOrder());
mColorBuffer = bb.asIntBuffer();
mShapeList.add(shape);
mIndexCount += shape.getIndexCount();
}
public void generate() {
ByteBuffer bb = ByteBuffer.allocateDirect(mVertexList.size()*4*4);
bb.order(ByteOrder.nativeOrder());
mColorBuffer = bb.asIntBuffer();
bb = ByteBuffer.allocateDirect(mVertexList.size()*4*3);
bb.order(ByteOrder.nativeOrder());
mVertexBuffer = bb.asIntBuffer();
bb.order(ByteOrder.nativeOrder());
mVertexBuffer = bb.asIntBuffer();
bb = ByteBuffer.allocateDirect(mIndexCount*2);
bb.order(ByteOrder.nativeOrder());
mIndexBuffer = bb.asShortBuffer();
bb.order(ByteOrder.nativeOrder());
mIndexBuffer = bb.asShortBuffer();
Iterator<GLVertex> iter2 = mVertexList.iterator();
while (iter2.hasNext()) {
GLVertex vertex = iter2.next();
vertex.put(mVertexBuffer, mColorBuffer);
}
while (iter2.hasNext()) {
GLVertex vertex = iter2.next();
vertex.put(mVertexBuffer, mColorBuffer);
}
Iterator<GLShape> iter3 = mShapeList.iterator();
while (iter3.hasNext()) {
GLShape shape = iter3.next();
shape.putIndices(mIndexBuffer);
}
}
public GLVertex addVertex(float x, float y, float z) {
GLVertex vertex = new GLVertex(x, y, z, mVertexList.size());
mVertexList.add(vertex);
return vertex;
}
public void transformVertex(GLVertex vertex, M4 transform) {
vertex.update(mVertexBuffer, transform);
}
while (iter3.hasNext()) {
GLShape shape = iter3.next();
shape.putIndices(mIndexBuffer);
}
}
public GLVertex addVertex(float x, float y, float z) {
GLVertex vertex = new GLVertex(x, y, z, mVertexList.size());
mVertexList.add(vertex);
return vertex;
}
public void transformVertex(GLVertex vertex, M4 transform) {
vertex.update(mVertexBuffer, transform);
}
int count = 0;
public void draw(GL10 gl)
{
mColorBuffer.position(0);
mVertexBuffer.position(0);
mIndexBuffer.position(0);
public void draw(GL10 gl)
{
mColorBuffer.position(0);
mVertexBuffer.position(0);
mIndexBuffer.position(0);
gl.glFrontFace(GL10.GL_CW);
gl.glShadeModel(GL10.GL_FLAT);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
count++;
}
static public float toFloat(int x) {
return x/65536.0f;
}
gl.glShadeModel(GL10.GL_FLAT);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
count++;
}
static public float toFloat(int x) {
return x/65536.0f;
}
private ArrayList<GLShape> mShapeList = new ArrayList<GLShape>();
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
private int mIndexCount = 0;
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
private int mIndexCount = 0;
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ShortBuffer mIndexBuffer;
}
private IntBuffer mColorBuffer;
private ShortBuffer mIndexBuffer;
}
6.) Create and write following into src/GLVertex.java:
package com.example.RubikCubeAnimationExample;
import java.nio.IntBuffer;
public class GLVertex {
public float x;
public float y;
public float z;
final short index; // index in vertex table
GLColor color;
public float y;
public float z;
final short index; // index in vertex table
GLColor color;
GLVertex() {
this.x = 0;
this.y = 0;
this.z = 0;
this.index = -1;
}
this.x = 0;
this.y = 0;
this.z = 0;
this.index = -1;
}
GLVertex(float x, float y, float z, int index) {
this.x = x;
this.y = y;
this.z = z;
this.index = (short)index;
}
this.x = x;
this.y = y;
this.z = z;
this.index = (short)index;
}
@Override
public boolean equals(Object other) {
if (other instanceof GLVertex) {
GLVertex v = (GLVertex)other;
return (x == v.x && y == v.y && z == v.z);
}
return false;
}
public boolean equals(Object other) {
if (other instanceof GLVertex) {
GLVertex v = (GLVertex)other;
return (x == v.x && y == v.y && z == v.z);
}
return false;
}
static public int toFixed(float x) {
return (int)(x * 65536.0f);
}
return (int)(x * 65536.0f);
}
public void put(IntBuffer vertexBuffer, IntBuffer colorBuffer) {
vertexBuffer.put(toFixed(x));
vertexBuffer.put(toFixed(y));
vertexBuffer.put(toFixed(z));
if (color == null) {
colorBuffer.put(0);
colorBuffer.put(0);
colorBuffer.put(0);
colorBuffer.put(0);
} else {
colorBuffer.put(color.red);
colorBuffer.put(color.green);
colorBuffer.put(color.blue);
colorBuffer.put(color.alpha);
}
}
vertexBuffer.put(toFixed(x));
vertexBuffer.put(toFixed(y));
vertexBuffer.put(toFixed(z));
if (color == null) {
colorBuffer.put(0);
colorBuffer.put(0);
colorBuffer.put(0);
colorBuffer.put(0);
} else {
colorBuffer.put(color.red);
colorBuffer.put(color.green);
colorBuffer.put(color.blue);
colorBuffer.put(color.alpha);
}
}
public void update(IntBuffer vertexBuffer, M4 transform) {
// skip to location of vertex in mVertex buffer
vertexBuffer.position(index * 3);
// skip to location of vertex in mVertex buffer
vertexBuffer.position(index * 3);
if (transform == null) {
vertexBuffer.put(toFixed(x));
vertexBuffer.put(toFixed(y));
vertexBuffer.put(toFixed(z));
} else {
GLVertex temp = new GLVertex();
transform.multiply(this, temp);
vertexBuffer.put(toFixed(temp.x));
vertexBuffer.put(toFixed(temp.y));
vertexBuffer.put(toFixed(temp.z));
}
}
}
vertexBuffer.put(toFixed(x));
vertexBuffer.put(toFixed(y));
vertexBuffer.put(toFixed(z));
} else {
GLVertex temp = new GLVertex();
transform.multiply(this, temp);
vertexBuffer.put(toFixed(temp.x));
vertexBuffer.put(toFixed(temp.y));
vertexBuffer.put(toFixed(temp.z));
}
}
}
7.) Create and write following into src/GLShape.java:
package com.example.RubikCubeAnimationExample;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Iterator;
public class GLShape {
public GLShape(GLWorld world) {
mWorld = world;
}
public void addFace(GLFace face) {
mFaceList.add(face);
}
public void setFaceColor(int face, GLColor color) {
mFaceList.get(face).setColor(color);
}
public void putIndices(ShortBuffer buffer) {
Iterator<GLFace> iter = mFaceList.iterator();
while (iter.hasNext()) {
GLFace face = iter.next();
face.putIndices(buffer);
}
}
public int getIndexCount() {
int count = 0;
Iterator<GLFace> iter = mFaceList.iterator();
while (iter.hasNext()) {
GLFace face = iter.next();
count += face.getIndexCount();
}
return count;
}
mWorld = world;
}
public void addFace(GLFace face) {
mFaceList.add(face);
}
public void setFaceColor(int face, GLColor color) {
mFaceList.get(face).setColor(color);
}
public void putIndices(ShortBuffer buffer) {
Iterator<GLFace> iter = mFaceList.iterator();
while (iter.hasNext()) {
GLFace face = iter.next();
face.putIndices(buffer);
}
}
public int getIndexCount() {
int count = 0;
Iterator<GLFace> iter = mFaceList.iterator();
while (iter.hasNext()) {
GLFace face = iter.next();
count += face.getIndexCount();
}
return count;
}
public GLVertex addVertex(float x, float y, float z) {
// look for an existing GLVertex first
Iterator<GLVertex> iter = mVertexList.iterator();
while (iter.hasNext()) {
GLVertex vertex = iter.next();
if (vertex.x == x && vertex.y == y && vertex.z == z) {
return vertex;
}
}
// doesn’t exist, so create new vertex
GLVertex vertex = mWorld.addVertex(x, y, z);
mVertexList.add(vertex);
return vertex;
}
// look for an existing GLVertex first
Iterator<GLVertex> iter = mVertexList.iterator();
while (iter.hasNext()) {
GLVertex vertex = iter.next();
if (vertex.x == x && vertex.y == y && vertex.z == z) {
return vertex;
}
}
// doesn’t exist, so create new vertex
GLVertex vertex = mWorld.addVertex(x, y, z);
mVertexList.add(vertex);
return vertex;
}
public void animateTransform(M4 transform) {
mAnimateTransform = transform;
if (mTransform != null)
transform = mTransform.multiply(transform);
mAnimateTransform = transform;
if (mTransform != null)
transform = mTransform.multiply(transform);
Iterator<GLVertex> iter = mVertexList.iterator();
while (iter.hasNext()) {
GLVertex vertex = iter.next();
mWorld.transformVertex(vertex, transform);
}
}
public void startAnimation() {
}
while (iter.hasNext()) {
GLVertex vertex = iter.next();
mWorld.transformVertex(vertex, transform);
}
}
public void startAnimation() {
}
public void endAnimation() {
if (mTransform == null) {
mTransform = new M4(mAnimateTransform);
} else {
mTransform = mTransform.multiply(mAnimateTransform);
}
}
if (mTransform == null) {
mTransform = new M4(mAnimateTransform);
} else {
mTransform = mTransform.multiply(mAnimateTransform);
}
}
public M4 mTransform;
public M4 mAnimateTransform;
protected ArrayList<GLFace> mFaceList = newArrayList<GLFace>();
protected ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
protected ArrayList<Integer> mIndexList = new ArrayList<Integer>(); // make more efficient?
protected GLWorld mWorld;
}
public M4 mAnimateTransform;
protected ArrayList<GLFace> mFaceList = newArrayList<GLFace>();
protected ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
protected ArrayList<Integer> mIndexList = new ArrayList<Integer>(); // make more efficient?
protected GLWorld mWorld;
}
8.) Create and write following into src/GLFace.java:
package com.example.RubikCubeAnimationExample;
import android.util.Log;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.ArrayList;
public class GLFace {
public GLFace() {
}
// for triangles
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3) {
addVertex(v1);
addVertex(v2);
addVertex(v3);
}
// for quadrilaterals
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3, GLVertex v4) {
addVertex(v1);
addVertex(v2);
addVertex(v3);
addVertex(v4);
}
public void addVertex(GLVertex v) {
mVertexList.add(v);
}
// must be called after all vertices are added
public void setColor(GLColor c) {
int last = mVertexList.size() - 1;
if (last < 2) {
Log.e("GLFace", "not enough vertices in setColor()");
} else {
GLVertex vertex = mVertexList.get(last);
// only need to do this if the color has never been set
if (mColor == null) {
while (vertex.color != null) {
mVertexList.add(0, vertex);
mVertexList.remove(last + 1);
vertex = mVertexList.get(last);
}
}
vertex.color = c;
}
}
// for triangles
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3) {
addVertex(v1);
addVertex(v2);
addVertex(v3);
}
// for quadrilaterals
public GLFace(GLVertex v1, GLVertex v2, GLVertex v3, GLVertex v4) {
addVertex(v1);
addVertex(v2);
addVertex(v3);
addVertex(v4);
}
public void addVertex(GLVertex v) {
mVertexList.add(v);
}
// must be called after all vertices are added
public void setColor(GLColor c) {
int last = mVertexList.size() - 1;
if (last < 2) {
Log.e("GLFace", "not enough vertices in setColor()");
} else {
GLVertex vertex = mVertexList.get(last);
// only need to do this if the color has never been set
if (mColor == null) {
while (vertex.color != null) {
mVertexList.add(0, vertex);
mVertexList.remove(last + 1);
vertex = mVertexList.get(last);
}
}
vertex.color = c;
}
mColor = c;
}
public int getIndexCount() {
return (mVertexList.size() - 2) * 3;
}
public void putIndices(ShortBuffer buffer) {
int last = mVertexList.size() - 1;
}
public int getIndexCount() {
return (mVertexList.size() - 2) * 3;
}
public void putIndices(ShortBuffer buffer) {
int last = mVertexList.size() - 1;
GLVertex v0 = mVertexList.get(0);
GLVertex vn = mVertexList.get(last);
// push triangles into the buffer
for (int i = 1; i < last; i++) {
GLVertex v1 = mVertexList.get(i);
buffer.put(v0.index);
buffer.put(v1.index);
buffer.put(vn.index);
v0 = v1;
}
}
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
private GLColor mColor;
}
GLVertex vn = mVertexList.get(last);
// push triangles into the buffer
for (int i = 1; i < last; i++) {
GLVertex v1 = mVertexList.get(i);
buffer.put(v0.index);
buffer.put(v1.index);
buffer.put(vn.index);
v0 = v1;
}
}
private ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
private GLColor mColor;
}
9.) Create and write following into src/GLColor.java:
package com.example.RubikCubeAnimationExample;
public class GLColor {
public final int red;
public final int green;
public final int blue;
public final int alpha;
public final int green;
public final int blue;
public final int alpha;
public GLColor(int red, int green, int blue, int alpha) {
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
}
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
}
public GLColor(int red, int green, int blue) {
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = 0×10000;
}
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = 0×10000;
}
@Override
public boolean equals(Object other) {
if (other instanceof GLColor) {
GLColor color = (GLColor)other;
return (red == color.red &&
green == color.green &&
blue == color.blue &&
alpha == color.alpha);
}
return false;
}
}
public boolean equals(Object other) {
if (other instanceof GLColor) {
GLColor color = (GLColor)other;
return (red == color.red &&
green == color.green &&
blue == color.blue &&
alpha == color.alpha);
}
return false;
}
}
10.) Create and write following into src/Cube.java:
package com.example.RubikCubeAnimationExample;
}
public class Cube extends GLShape {
public Cube(GLWorld world, float left, float bottom, float back, floatright, float top, float front) {
super(world);
GLVertex leftBottomBack = addVertex(left, bottom, back);
GLVertex rightBottomBack = addVertex(right, bottom, back);
GLVertex leftTopBack = addVertex(left, top, back);
GLVertex rightTopBack = addVertex(right, top, back);
GLVertex leftBottomFront = addVertex(left, bottom, front);
GLVertex rightBottomFront = addVertex(right, bottom, front);
GLVertex leftTopFront = addVertex(left, top, front);
GLVertex rightTopFront = addVertex(right, top, front);
addFace(new GLFace(leftBottomBack, leftBottomFront, rightBottomFront, rightBottomBack));
addFace(new GLFace(leftBottomFront, leftTopFront, rightTopFront, rightBottomFront));
addFace(new GLFace(leftBottomBack, leftTopBack, leftTopFront, leftBottomFront));
addFace(new GLFace(rightBottomBack, rightBottomFront, rightTopFront, rightTopBack));
addFace(new GLFace(leftBottomBack, rightBottomBack, rightTopBack, leftTopBack));
addFace(new GLFace(leftTopBack, rightTopBack, rightTopFront, leftTopFront));
}
public static final int kBottom = 0;
public static final int kFront = 1;
public static final int kLeft = 2;
public static final int kRight = 3;
public static final int kBack = 4;
public static final int kTop = 5;
super(world);
GLVertex leftBottomBack = addVertex(left, bottom, back);
GLVertex rightBottomBack = addVertex(right, bottom, back);
GLVertex leftTopBack = addVertex(left, top, back);
GLVertex rightTopBack = addVertex(right, top, back);
GLVertex leftBottomFront = addVertex(left, bottom, front);
GLVertex rightBottomFront = addVertex(right, bottom, front);
GLVertex leftTopFront = addVertex(left, top, front);
GLVertex rightTopFront = addVertex(right, top, front);
addFace(new GLFace(leftBottomBack, leftBottomFront, rightBottomFront, rightBottomBack));
addFace(new GLFace(leftBottomFront, leftTopFront, rightTopFront, rightBottomFront));
addFace(new GLFace(leftBottomBack, leftTopBack, leftTopFront, leftBottomFront));
addFace(new GLFace(rightBottomBack, rightBottomFront, rightTopFront, rightTopBack));
addFace(new GLFace(leftBottomBack, rightBottomBack, rightTopBack, leftTopBack));
addFace(new GLFace(leftTopBack, rightTopBack, rightTopFront, leftTopFront));
}
public static final int kBottom = 0;
public static final int kFront = 1;
public static final int kLeft = 2;
public static final int kRight = 3;
public static final int kBack = 4;
public static final int kTop = 5;
}
11.) Run for output.
Steps:
1.) Create a project named RubikCubeAnimationExample and set the information as stated in the image.
Build Target: Android 4.0
Application Name: RubikCubeAnimationExample
Package Name: com. example. RubikCubeAnimationExample
Activity Name: RubikCubeAnimationExampleActivity
Min SDK Version: 14
Application Name: RubikCubeAnimationExample
Package Name: com. example. RubikCubeAnimationExample
Activity Name: RubikCubeAnimationExampleActivity
Min SDK Version: 14
2.) Open RubikCubeAnimationExampleActivity.java file and write following code there:
package com.example.RubikCubeAnimationExample;
import java.util.Random;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
public class RubikCubeAnimationExampleActivity extends Activity implementsKubeRenderer.AnimationCallback {
private GLWorld makeGLWorld()
{
GLWorld world = new GLWorld();
{
GLWorld world = new GLWorld();
int one = 0×10000;
int half = 0×08000;
GLColor red = new GLColor(one, 0, 0);
GLColor green = new GLColor(0, one, 0);
GLColor blue = new GLColor(0, 0, one);
GLColor yellow = new GLColor(one, one, 0);
GLColor orange = new GLColor(one, half, 0);
GLColor white = new GLColor(one, one, one);
GLColor black = new GLColor(0, 0, 0);
int half = 0×08000;
GLColor red = new GLColor(one, 0, 0);
GLColor green = new GLColor(0, one, 0);
GLColor blue = new GLColor(0, 0, one);
GLColor yellow = new GLColor(one, one, 0);
GLColor orange = new GLColor(one, half, 0);
GLColor white = new GLColor(one, one, one);
GLColor black = new GLColor(0, 0, 0);
float c0 = -1.0f;
float c1 = -0.38f;
float c2 = -0.32f;
float c3 = 0.32f;
float c4 = 0.38f;
float c5 = 1.0f;
float c1 = -0.38f;
float c2 = -0.32f;
float c3 = 0.32f;
float c4 = 0.38f;
float c5 = 1.0f;
// top back, left to right
mCubes[0] = new Cube(world, c0, c4, c0, c1, c5, c1);
mCubes[1] = new Cube(world, c2, c4, c0, c3, c5, c1);
mCubes[2] = new Cube(world, c4, c4, c0, c5, c5, c1);
// top middle, left to right
mCubes[3] = new Cube(world, c0, c4, c2, c1, c5, c3);
mCubes[4] = new Cube(world, c2, c4, c2, c3, c5, c3);
mCubes[5] = new Cube(world, c4, c4, c2, c5, c5, c3);
// top front, left to right
mCubes[6] = new Cube(world, c0, c4, c4, c1, c5, c5);
mCubes[7] = new Cube(world, c2, c4, c4, c3, c5, c5);
mCubes[8] = new Cube(world, c4, c4, c4, c5, c5, c5);
// middle back, left to right
mCubes[9] = new Cube(world, c0, c2, c0, c1, c3, c1);
mCubes[10] = new Cube(world, c2, c2, c0, c3, c3, c1);
mCubes[11] = new Cube(world, c4, c2, c0, c5, c3, c1);
// middle middle, left to right
mCubes[12] = new Cube(world, c0, c2, c2, c1, c3, c3);
mCubes[13] = null;
mCubes[14] = new Cube(world, c4, c2, c2, c5, c3, c3);
// middle front, left to right
mCubes[15] = new Cube(world, c0, c2, c4, c1, c3, c5);
mCubes[16] = new Cube(world, c2, c2, c4, c3, c3, c5);
mCubes[17] = new Cube(world, c4, c2, c4, c5, c3, c5);
// bottom back, left to right
mCubes[18] = new Cube(world, c0, c0, c0, c1, c1, c1);
mCubes[19] = new Cube(world, c2, c0, c0, c3, c1, c1);
mCubes[20] = new Cube(world, c4, c0, c0, c5, c1, c1);
// bottom middle, left to right
mCubes[21] = new Cube(world, c0, c0, c2, c1, c1, c3);
mCubes[22] = new Cube(world, c2, c0, c2, c3, c1, c3);
mCubes[23] = new Cube(world, c4, c0, c2, c5, c1, c3);
// bottom front, left to right
mCubes[24] = new Cube(world, c0, c0, c4, c1, c1, c5);
mCubes[25] = new Cube(world, c2, c0, c4, c3, c1, c5);
mCubes[26] = new Cube(world, c4, c0, c4, c5, c1, c5);
mCubes[0] = new Cube(world, c0, c4, c0, c1, c5, c1);
mCubes[1] = new Cube(world, c2, c4, c0, c3, c5, c1);
mCubes[2] = new Cube(world, c4, c4, c0, c5, c5, c1);
// top middle, left to right
mCubes[3] = new Cube(world, c0, c4, c2, c1, c5, c3);
mCubes[4] = new Cube(world, c2, c4, c2, c3, c5, c3);
mCubes[5] = new Cube(world, c4, c4, c2, c5, c5, c3);
// top front, left to right
mCubes[6] = new Cube(world, c0, c4, c4, c1, c5, c5);
mCubes[7] = new Cube(world, c2, c4, c4, c3, c5, c5);
mCubes[8] = new Cube(world, c4, c4, c4, c5, c5, c5);
// middle back, left to right
mCubes[9] = new Cube(world, c0, c2, c0, c1, c3, c1);
mCubes[10] = new Cube(world, c2, c2, c0, c3, c3, c1);
mCubes[11] = new Cube(world, c4, c2, c0, c5, c3, c1);
// middle middle, left to right
mCubes[12] = new Cube(world, c0, c2, c2, c1, c3, c3);
mCubes[13] = null;
mCubes[14] = new Cube(world, c4, c2, c2, c5, c3, c3);
// middle front, left to right
mCubes[15] = new Cube(world, c0, c2, c4, c1, c3, c5);
mCubes[16] = new Cube(world, c2, c2, c4, c3, c3, c5);
mCubes[17] = new Cube(world, c4, c2, c4, c5, c3, c5);
// bottom back, left to right
mCubes[18] = new Cube(world, c0, c0, c0, c1, c1, c1);
mCubes[19] = new Cube(world, c2, c0, c0, c3, c1, c1);
mCubes[20] = new Cube(world, c4, c0, c0, c5, c1, c1);
// bottom middle, left to right
mCubes[21] = new Cube(world, c0, c0, c2, c1, c1, c3);
mCubes[22] = new Cube(world, c2, c0, c2, c3, c1, c3);
mCubes[23] = new Cube(world, c4, c0, c2, c5, c1, c3);
// bottom front, left to right
mCubes[24] = new Cube(world, c0, c0, c4, c1, c1, c5);
mCubes[25] = new Cube(world, c2, c0, c4, c3, c1, c5);
mCubes[26] = new Cube(world, c4, c0, c4, c5, c1, c5);
// paint the sides
int i, j;
// set all faces black by default
for (i = 0; i < 27; i++) {
Cube cube = mCubes[i];
if (cube != null) {
for (j = 0; j < 6; j++)
cube.setFaceColor(j, black);
}
}
int i, j;
// set all faces black by default
for (i = 0; i < 27; i++) {
Cube cube = mCubes[i];
if (cube != null) {
for (j = 0; j < 6; j++)
cube.setFaceColor(j, black);
}
}
// paint top
for (i = 0; i < 9; i++)
mCubes[i].setFaceColor(Cube.kTop, orange);
// paint bottom
for (i = 18; i < 27; i++)
mCubes[i].setFaceColor(Cube.kBottom, red);
// paint left
for (i = 0; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kLeft, yellow);
// paint right
for (i = 2; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kRight, white);
// paint back
for (i = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kBack, blue);
// paint front
for (i = 6; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kFront, green);
for (i = 0; i < 9; i++)
mCubes[i].setFaceColor(Cube.kTop, orange);
// paint bottom
for (i = 18; i < 27; i++)
mCubes[i].setFaceColor(Cube.kBottom, red);
// paint left
for (i = 0; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kLeft, yellow);
// paint right
for (i = 2; i < 27; i += 3)
mCubes[i].setFaceColor(Cube.kRight, white);
// paint back
for (i = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kBack, blue);
// paint front
for (i = 6; i < 27; i += 9)
for (j = 0; j < 3; j++)
mCubes[i + j].setFaceColor(Cube.kFront, green);
for (i = 0; i < 27; i++)
if (mCubes[i] != null)
world.addShape(mCubes[i]);
if (mCubes[i] != null)
world.addShape(mCubes[i]);
// initialize our permutation to solved position
mPermutation = new int[27];
for (i = 0; i < mPermutation.length; i++)
mPermutation[i] = i;
mPermutation = new int[27];
for (i = 0; i < mPermutation.length; i++)
mPermutation[i] = i;
createLayers();
updateLayers();
updateLayers();
world.generate();
return world;
}
}
private void createLayers() {
mLayers[kUp] = new Layer(Layer.kAxisY);
mLayers[kDown] = new Layer(Layer.kAxisY);
mLayers[kLeft] = new Layer(Layer.kAxisX);
mLayers[kRight] = new Layer(Layer.kAxisX);
mLayers[kFront] = new Layer(Layer.kAxisZ);
mLayers[kBack] = new Layer(Layer.kAxisZ);
mLayers[kMiddle] = new Layer(Layer.kAxisX);
mLayers[kEquator] = new Layer(Layer.kAxisY);
mLayers[kSide] = new Layer(Layer.kAxisZ);
}
mLayers[kUp] = new Layer(Layer.kAxisY);
mLayers[kDown] = new Layer(Layer.kAxisY);
mLayers[kLeft] = new Layer(Layer.kAxisX);
mLayers[kRight] = new Layer(Layer.kAxisX);
mLayers[kFront] = new Layer(Layer.kAxisZ);
mLayers[kBack] = new Layer(Layer.kAxisZ);
mLayers[kMiddle] = new Layer(Layer.kAxisX);
mLayers[kEquator] = new Layer(Layer.kAxisY);
mLayers[kSide] = new Layer(Layer.kAxisZ);
}
private void updateLayers() {
Layer layer;
GLShape[] shapes;
int i, j, k;
Layer layer;
GLShape[] shapes;
int i, j, k;
// up layer
layer = mLayers[kUp];
shapes = layer.mShapes;
for (i = 0; i < 9; i++)
shapes[i] = mCubes[mPermutation[i]];
layer = mLayers[kUp];
shapes = layer.mShapes;
for (i = 0; i < 9; i++)
shapes[i] = mCubes[mPermutation[i]];
// down layer
layer = mLayers[kDown];
shapes = layer.mShapes;
for (i = 18, k = 0; i < 27; i++)
shapes[k++] = mCubes[mPermutation[i]];
layer = mLayers[kDown];
shapes = layer.mShapes;
for (i = 18, k = 0; i < 27; i++)
shapes[k++] = mCubes[mPermutation[i]];
// left layer
layer = mLayers[kLeft];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
layer = mLayers[kLeft];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// right layer
layer = mLayers[kRight];
shapes = layer.mShapes;
for (i = 2, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
layer = mLayers[kRight];
shapes = layer.mShapes;
for (i = 2, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// front layer
layer = mLayers[kFront];
shapes = layer.mShapes;
for (i = 6, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
layer = mLayers[kFront];
shapes = layer.mShapes;
for (i = 6, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
// back layer
layer = mLayers[kBack];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
layer = mLayers[kBack];
shapes = layer.mShapes;
for (i = 0, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
// middle layer
layer = mLayers[kMiddle];
shapes = layer.mShapes;
for (i = 1, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
layer = mLayers[kMiddle];
shapes = layer.mShapes;
for (i = 1, k = 0; i < 27; i += 9)
for (j = 0; j < 9; j += 3)
shapes[k++] = mCubes[mPermutation[i + j]];
// equator layer
layer = mLayers[kEquator];
shapes = layer.mShapes;
for (i = 9, k = 0; i < 18; i++)
shapes[k++] = mCubes[mPermutation[i]];
layer = mLayers[kEquator];
shapes = layer.mShapes;
for (i = 9, k = 0; i < 18; i++)
shapes[k++] = mCubes[mPermutation[i]];
// side layer
layer = mLayers[kSide];
shapes = layer.mShapes;
for (i = 3, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
}
layer = mLayers[kSide];
shapes = layer.mShapes;
for (i = 3, k = 0; i < 27; i += 9)
for (j = 0; j < 3; j++)
shapes[k++] = mCubes[mPermutation[i + j]];
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mView = new GLSurfaceView(getApplication());
mRenderer = new KubeRenderer(makeGLWorld(), this);
mView.setRenderer(mRenderer);
setContentView(mView);
}
mRenderer = new KubeRenderer(makeGLWorld(), this);
mView.setRenderer(mRenderer);
setContentView(mView);
}
@Override
protected void onResume()
{
super.onResume();
mView.onResume();
}
protected void onResume()
{
super.onResume();
mView.onResume();
}
@Override
protected void onPause()
{
super.onPause();
mView.onPause();
}
protected void onPause()
{
super.onPause();
mView.onPause();
}
public void animate() {
// change our angle of view
mRenderer.setAngle(mRenderer.getAngle() + 1.2f);
// change our angle of view
mRenderer.setAngle(mRenderer.getAngle() + 1.2f);
if (mCurrentLayer == null) {
int layerID = mRandom.nextInt(9);
mCurrentLayer = mLayers[layerID];
mCurrentLayerPermutation = mLayerPermutations[layerID];
mCurrentLayer.startAnimation();
boolean direction = mRandom.nextBoolean();
int count = mRandom.nextInt(3) + 1;
int layerID = mRandom.nextInt(9);
mCurrentLayer = mLayers[layerID];
mCurrentLayerPermutation = mLayerPermutations[layerID];
mCurrentLayer.startAnimation();
boolean direction = mRandom.nextBoolean();
int count = mRandom.nextInt(3) + 1;
count = 1;
direction = false;
mCurrentAngle = 0;
if (direction) {
mAngleIncrement = (float)Math.PI / 50;
mEndAngle = mCurrentAngle + ((float)Math.PI * count) / 2f;
} else {
mAngleIncrement = -(float)Math.PI / 50;
mEndAngle = mCurrentAngle - ((float)Math.PI * count) / 2f;
}
}
direction = false;
mCurrentAngle = 0;
if (direction) {
mAngleIncrement = (float)Math.PI / 50;
mEndAngle = mCurrentAngle + ((float)Math.PI * count) / 2f;
} else {
mAngleIncrement = -(float)Math.PI / 50;
mEndAngle = mCurrentAngle - ((float)Math.PI * count) / 2f;
}
}
mCurrentAngle += mAngleIncrement;
if ((mAngleIncrement > 0f && mCurrentAngle >= mEndAngle) ||
(mAngleIncrement < 0f && mCurrentAngle <= mEndAngle)) {
mCurrentLayer.setAngle(mEndAngle);
mCurrentLayer.endAnimation();
mCurrentLayer = null;
(mAngleIncrement < 0f && mCurrentAngle <= mEndAngle)) {
mCurrentLayer.setAngle(mEndAngle);
mCurrentLayer.endAnimation();
mCurrentLayer = null;
// adjust mPermutation based on the completed layer rotation
int[] newPermutation = new int[27];
for (int i = 0; i < 27; i++) {
newPermutation[i] = mPermutation[mCurrentLayerPermutation[i]];
}
mPermutation = newPermutation;
updateLayers();
int[] newPermutation = new int[27];
for (int i = 0; i < 27; i++) {
newPermutation[i] = mPermutation[mCurrentLayerPermutation[i]];
}
mPermutation = newPermutation;
updateLayers();
} else {
mCurrentLayer.setAngle(mCurrentAngle);
}
}
mCurrentLayer.setAngle(mCurrentAngle);
}
}
GLSurfaceView mView;
KubeRenderer mRenderer;
Cube[] mCubes = new Cube[27];
// a Layer for each possible move
Layer[] mLayers = new Layer[9];
// permutations corresponding to a pi/2 rotation of each layer about its axis
static int[][] mLayerPermutations = {
// permutation for UP layer
{ 2, 5, 8, 1, 4, 7, 0, 3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for DOWN layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20,23, 26, 19, 22, 25, 18, 21, 24 },
// permutation for LEFT layer
{ 6, 1, 2, 15, 4, 5, 24, 7, 8, 3, 10, 11, 12, 13, 14, 21, 16, 17, 0,19, 20, 9, 22, 23, 18, 25, 26 },
// permutation for RIGHT layer
{ 0, 1, 8, 3, 4, 17, 6, 7, 26, 9, 10, 5, 12, 13, 14, 15, 16, 23, 18,19, 2, 21, 22, 11, 24, 25, 20 },
// permutation for FRONT layer
{ 0, 1, 2, 3, 4, 5, 24, 15, 6, 9, 10, 11, 12, 13, 14, 25, 16, 7, 18,19, 20, 21, 22, 23, 26, 17, 8 },
// permutation for BACK layer
{ 18, 9, 0, 3, 4, 5, 6, 7, 8, 19, 10, 1, 12, 13, 14, 15, 16, 17, 20,11, 2, 21, 22, 23, 24, 25, 26 },
// permutation for MIDDLE layer
{ 0, 7, 2, 3, 16, 5, 6, 25, 8, 9, 4, 11, 12, 13, 14, 15, 22, 17, 18,1, 20, 21, 10, 23, 24, 19, 26 },
// permutation for EQUATOR layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 17, 10, 13, 16, 9, 12, 15, 18,19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for SIDE layer
{ 0, 1, 2, 21, 12, 3, 6, 7, 8, 9, 10, 11, 22, 13, 4, 15, 16, 17, 18, 19, 20, 23, 14, 5, 24, 25, 26 }
};
KubeRenderer mRenderer;
Cube[] mCubes = new Cube[27];
// a Layer for each possible move
Layer[] mLayers = new Layer[9];
// permutations corresponding to a pi/2 rotation of each layer about its axis
static int[][] mLayerPermutations = {
// permutation for UP layer
{ 2, 5, 8, 1, 4, 7, 0, 3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for DOWN layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20,23, 26, 19, 22, 25, 18, 21, 24 },
// permutation for LEFT layer
{ 6, 1, 2, 15, 4, 5, 24, 7, 8, 3, 10, 11, 12, 13, 14, 21, 16, 17, 0,19, 20, 9, 22, 23, 18, 25, 26 },
// permutation for RIGHT layer
{ 0, 1, 8, 3, 4, 17, 6, 7, 26, 9, 10, 5, 12, 13, 14, 15, 16, 23, 18,19, 2, 21, 22, 11, 24, 25, 20 },
// permutation for FRONT layer
{ 0, 1, 2, 3, 4, 5, 24, 15, 6, 9, 10, 11, 12, 13, 14, 25, 16, 7, 18,19, 20, 21, 22, 23, 26, 17, 8 },
// permutation for BACK layer
{ 18, 9, 0, 3, 4, 5, 6, 7, 8, 19, 10, 1, 12, 13, 14, 15, 16, 17, 20,11, 2, 21, 22, 23, 24, 25, 26 },
// permutation for MIDDLE layer
{ 0, 7, 2, 3, 16, 5, 6, 25, 8, 9, 4, 11, 12, 13, 14, 15, 22, 17, 18,1, 20, 21, 10, 23, 24, 19, 26 },
// permutation for EQUATOR layer
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 17, 10, 13, 16, 9, 12, 15, 18,19, 20, 21, 22, 23, 24, 25, 26 },
// permutation for SIDE layer
{ 0, 1, 2, 21, 12, 3, 6, 7, 8, 9, 10, 11, 22, 13, 4, 15, 16, 17, 18, 19, 20, 23, 14, 5, 24, 25, 26 }
};
// current permutation of starting position
int[] mPermutation;
int[] mPermutation;
// for random cube movements
Random mRandom = new Random(System.currentTimeMillis());
// currently turning layer
Layer mCurrentLayer = null;
// current and final angle for current Layer animation
float mCurrentAngle, mEndAngle;
// amount to increment angle
float mAngleIncrement;
int[] mCurrentLayerPermutation;
Random mRandom = new Random(System.currentTimeMillis());
// currently turning layer
Layer mCurrentLayer = null;
// current and final angle for current Layer animation
float mCurrentAngle, mEndAngle;
// amount to increment angle
float mAngleIncrement;
int[] mCurrentLayerPermutation;
// names for our 9 layers (based on notation from http://www.cubefreak.net/notation.html)
static final int kUp = 0;
static final int kDown = 1;
static final int kLeft = 2;
static final int kRight = 3;
static final int kFront = 4;
static final int kBack = 5;
static final int kMiddle = 6;
static final int kEquator = 7;
static final int kSide = 8;
static final int kUp = 0;
static final int kDown = 1;
static final int kLeft = 2;
static final int kRight = 3;
static final int kFront = 4;
static final int kBack = 5;
static final int kMiddle = 6;
static final int kEquator = 7;
static final int kSide = 8;
}
3.) Compile and build the project.
Output
No comments:
Post a Comment