Minecraft

From CS486wiki
Jump to navigationJump to search

Android Minecraft

Usage

First of all we have a map on an xls file (map.xls) and if we open it we can see the map of different levels, level 1 and level2.

By saving this map as a csv file in the directory src/mine/craft/levels/ (map.csv) we make it available to the android device and the relevant class on the same class path opens it and reads it. This way android device knows exactly how our map looks like.

Code description

Our class is Level in Level.java whose outline is this:


package mine.craft.levels;
/**
 * Level is the class that defines different levels (layers) 
 * for the game. The levels are stored in csv files in the
 * same directory.
 */
public class Level {
	public String[][][] maps = new String[0][20][20];
	public String[] names = new String[0];
	/**
	 * Load a new level file 
	 * @param fname The file to read from
	 * @return The newly created level
	 */
	public static Level load(String fname);
	public void print();
}

We don't yet use the variable "names" but we have it for future use.

The main activity is equally simple:


package mine.craft;
public class MinecraftActivity extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Level l = Level.load("map.csv");
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		FrameLayout fl = new FrameLayout(this);
		TextView tv = new TextView(this);
		tv.setText("...");
		fl.addView(new SquareGLSurfaceView(this, tv, l));
		fl.addView(tv);
		setContentView(fl);
	}
}


We can see that it basically initializes the Level variable l by loading the map.csv and then it follows closely Chapter 1 and 3 of the Pro OpenGL ES for Android (http://www.apress.com/9781430240020) in order to initialize and show a SquareGLSurfaceView that does all the rendering. A TextView is overlayed following these suggestions here: http://stackoverflow.com/questions/4680803/adding-text-view-to-surface-view in order to be able to output some debug data on top of the 3d Graphics. SquareGLSurfaceView is implemented in the mine.craft.primitives package (SquareGLSurfaceView.java) and has the following outline:


package mine.craft.primitives;
public class SquareGLSurfaceView extends GLSurfaceView { 
	public SquareGLSurfaceView(Context context, TextView tv, Level l){ 
	        mRenderer = new SquareRenderer(true, l);
	        setRenderer(mRenderer);
	}
	public boolean onTouchEvent(MotionEvent e) { …}
}


The code for onTouchEvent(MotionEvent e) comes almost entirely from this tutorial http://developer.android.com/resources/tutorials/opengl/opengl-es20.html which describes how to utilize the touch events to control the position and angle of the viewport for a 3D landscape. Our motion functions are the following:


float dx = x - mPreviousX;
float dy = y - mPreviousY;
mRenderer.mAngle += dx * 120f / 320;
mRenderer.mTransY += Math.cos(Math.PI * (mRenderer.mAngle/180)) * dy * TOUCH_SCALE_FACTOR;
mRenderer.mTransX += Math.sin(Math.PI * (mRenderer.mAngle/180)) * dy * TOUCH_SCALE_FACTOR;


We can see that the X-movement of the fingers defines the angle to which the player is heading and the y scrolling defines the movement of X,Y towards the angle he is heading to.

We can also notice that the 3D rendering for the whole surface is delegated to SquareRenderer. SquareRenderer is implemented in the same package and inside the SquareRenderer.java. The overview of the code is this one.


package mine.craft.primitives;
public class SquareRenderer implements GLSurfaceView.Renderer {
	 
    private double[] toWordCoordinates(double x, double y) ;
	void setLeval(int level) {
		this.level = level;
		//WE START WHERE S is IN THE MAP
		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 20; j++) {
				if ("S".equals(l.maps[level][i][j])) {
					mTransX = (2 * i);
					mTransY = (2 * j);
				}
				//Here is the end:
				else if ("E".equals(l.maps[level][i][j])) {
					double[] tar = toWordCoordinates(i, j);
					targetx=tar[0];
				    targety=tar[1];
				    break;
				}
			}
		}
	}

	public SquareRenderer(boolean useTranslucentBackground, Level l) {
		mTranslucentBackground = useTranslucentBackground;
		mFloor = new Floor();
		mCube = new Cube();
		redCube = new Cube(true);
		this.l = l;
		setLeval(0);
	}

	public void onDrawFrame(GL10 gl) {  
		1. calculate the distance from the goal
		2. if the distance < 2, then change level
		3. Initialize rendering engine
		4. Paint a flat surface (mFloor variable) as a floor.
		5. for i in 0..20 for j in 0..20 .. if Map[i][j]='W' paintCube if Map[i][j]='E' paintEndCube
		6. Increase a variable that makes the end cube rotate
	}

	public void onSurfaceChanged(GL10 gl, int width, int height);
	public void onSurfaceCreated(GL10 gl, EGLConfig config);
}


Most of the code from here comes from Chapter 3 - BouncyCube of Pro OpenGL ES for Android. There are two main classes that we use to do the rendering, the Floor and the Cube. The Floor is just gray - colored rectangle that we positioned in the bottom of our viewport to be able to have a feeling of ground on the game.


The Cube is coloured and comes directly from the Chapter 3 - BouncyCube but there is also a variation of it and that's why it has the constructor like this: public Cube(boolean fin) { init(fin); }


If fin is true, then the cube has the red colour scheme that demonstrates the end - target cube. Additionally that cube rotates automatically - in contrast to all the other cubes that represent walls and are stable (the rotation takes place on step 5 of the onDrawFrame method of SquareRenderer we saw before.



Things to be improved

Obviously this is a starting point for a full game, providing basic 3d rendering and navigation. What should be fixed first is the function private double[] toWordCoordinates(double x, double y) that converts from the x-y coordinates of the Map to the 3d position inside the 3D space. This way we will be able to disallow the player from crossing walls and we will be able to have an accurate measurement of the distance from the current point to the target point for each level.


Development Environment Requirements

Android Development Environment, Eclipse Helios Service Release 2 and the latest version of Java JDK is required.

Minimum configuration of development environment PC's:

  • Minimum processors requirement: 1 gigahertz (GHz) processor
  • Minimum memory requirement: 512 MB RAM
  • 2 GB of available hard disk space required
  • Windows 7