开源项目之Android小游戏 Android Shapes

Android Shapes是一个简单的图形匹配的游戏!~~适合儿童!

该项目只有六个目标文件,效果如图:


游戏关键实现类:

public class GameView extends View
{

	// Logging for this activity
	private String TAG;

	// Game modes
	private int mMode;
	private static final int STATE_LOADING = 0; // loading for first time
	private static final int STATE_RUNNING = 1;
	private static final int STATE_PAUSED = 2;
	// private static final int STATE_WIN = 3;
	// private static final int STATE_LOSE = 4;

	private int mLevel;

	// Whether the main shape is getting moved by the user
	private boolean movingObject;

	// private Context mContext;

	private int mBoardWidth = 1;
	private int mBoardHeight = 1;

	// Each shape's width will be the screen width divided by this number
	private final int WIDTH_RATIO = 7;

	// Coordinates of each shape
	private Rect squareRect;
	private Rect circleRect;
	private Rect triangleRect;
	private Rect centreRect; // centre of game board - used as default position
								// for the moveable shape
	private Rect currentShapeRect; // moveable shape
	private Rect pauseButtonRect;

	private Paint squarePaint;
	private Paint circlePaint;
	private Paint trianglePaint;
	private Paint pausePaint;

	private Path trianglePath;

	// Which shape is the moveable shape
	private int mCurrentShape;
	private static final int SQUARE = 0;
	private static final int CIRCLE = 1;
	private static final int TRIANGLE = 2;
	private static final int PAUSE = 3;

	private Handler mHandler;

	private Vibrator mVibrator;
	private int VIBRATE_DURATION = 100;
	private boolean willVibrate;

	public GameView(Context context, String loggingString, Handler handler,
			Vibrator vibrator, boolean returning)
	{
		super(context);
		TAG = loggingString;
		mHandler = handler;
		mVibrator = vibrator;

		if (returning)
		{
			mMode = STATE_RUNNING;
		} else
		{
			mMode = STATE_LOADING; // we're still loading the game up (not yet
									// running)
		}

		squarePaint = new Paint();
		squarePaint.setStyle(Paint.Style.FILL);
		squarePaint.setColor(Color.RED);

		circlePaint = new Paint();
		circlePaint.setStyle(Paint.Style.FILL);
		circlePaint.setColor(Color.BLUE);

		trianglePaint = new Paint();
		trianglePaint.setStyle(Paint.Style.FILL);
		trianglePaint.setColor(Color.YELLOW);

		pausePaint = new Paint();
		pausePaint.setColor(Color.WHITE);
		pausePaint.setStrokeWidth((float) 5);

		trianglePath = new Path();

	}

	public void startGame()
	{
		mLevel = 0;
		nextLevel();
		mMode = STATE_RUNNING;
		showBeginningAnimation();
	}

	// Displays a simple animation before the beginning of the game
	private void showBeginningAnimation()
	{
		// TODO add in some animation showing multiple shapes (can block UI)
		invalidate();
	}

	// Move on to the next level
	private void nextLevel()
	{
		mLevel++;
		mCurrentShape = Math.round((float) Math.random() * 2);
		movingObject = false;
		currentShapeRect = new Rect(centreRect);
		sendLevel(mLevel);
	}

	private void sendLevel(int level)
	{
		Message msg = mHandler.obtainMessage();
		Bundle b = new Bundle();
		b.putInt("level", level);
		msg.setData(b);
		mHandler.sendMessage(msg);
	}

	// User has let go of the moveable shape on something other than any other
	// shape
	// so just move it back to the beginning location
	private void wrongShape()
	{
		movingObject = false;
		currentShapeRect.set(centreRect);
		// TODO: add in some animation moving shape back to centre
	}

	protected void onDraw(Canvas canvas)
	{
		drawShape(canvas, SQUARE, squareRect);
		drawShape(canvas, CIRCLE, circleRect);
		drawShape(canvas, TRIANGLE, triangleRect);
		drawShape(canvas, PAUSE, pauseButtonRect);

		if (mMode == STATE_RUNNING)
		{
			Log.d(TAG, "current shape = " + mCurrentShape);
			drawShape(canvas, mCurrentShape, currentShapeRect);
		}
	}

	// Draws "shape" on the canvas, in position rect
	private void drawShape(Canvas canvas, int shape, Rect rect)
	{
		switch (shape)
		{
		case SQUARE:
			canvas.drawRect(rect.left, rect.top, rect.right, rect.bottom,
					squarePaint);
			break;
		case CIRCLE:
			canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2,
					circlePaint);
			break;
		case TRIANGLE:
			trianglePath.reset();
			trianglePath.moveTo(rect.left, rect.bottom);
			trianglePath.lineTo(rect.right, rect.bottom);
			trianglePath.lineTo(rect.centerX(), rect.top);
			trianglePath.lineTo(rect.left, rect.bottom);
			trianglePath.close();
			canvas.drawPath(trianglePath, trianglePaint);
			break;
		case PAUSE:
			int heightCoefficient = (rect.bottom - rect.top) / 5;
			int widthCoefficient = (rect.right - rect.left) / 3;
			canvas.drawLine(rect.left + widthCoefficient, rect.top
					+ heightCoefficient, rect.left + widthCoefficient,
					rect.bottom - heightCoefficient, pausePaint);
			canvas.drawLine(rect.right - widthCoefficient, rect.top
					+ heightCoefficient, rect.right - widthCoefficient,
					rect.bottom - heightCoefficient, pausePaint);
			break;
		default:
			Log.d(TAG, "Shape not found (shape = " + mCurrentShape);
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
		super.onSizeChanged(w, h, oldw, oldh);

		mBoardWidth = w;
		mBoardHeight = h;

		//
		// Create all the shapes here so that onDraw is as slim as possible
		//
		int shapeWidth, shapeHeight;

		if (mBoardHeight >= mBoardWidth)
		{
			shapeWidth = mBoardWidth / WIDTH_RATIO;
			shapeHeight = mBoardWidth / WIDTH_RATIO;
		} else
		{
			shapeWidth = mBoardHeight / WIDTH_RATIO;
			shapeHeight = mBoardHeight / WIDTH_RATIO;
		}

		// Position of the main shapes, each represented as a rectangle
		squareRect = new Rect(0, 0, shapeWidth, shapeHeight);
		circleRect = new Rect(0, mBoardHeight - shapeHeight, shapeWidth,
				mBoardHeight);
		triangleRect = new Rect(mBoardWidth - shapeWidth, mBoardHeight
				- shapeHeight, mBoardWidth, mBoardHeight);

		// Position of the shape which is moveable
		centreRect = new Rect(mBoardWidth / 2 - shapeWidth / 2, mBoardHeight
				/ 2 - shapeHeight / 2, mBoardWidth / 2 + shapeWidth / 2,
				mBoardHeight / 2 + shapeHeight / 2);
		currentShapeRect = new Rect(centreRect);

		// Position of pause "button"
		pauseButtonRect = new Rect(mBoardWidth - shapeWidth, 0, mBoardWidth,
				shapeHeight);

		if (mMode == STATE_LOADING)
		{
			startGame(); // loading up for first time so start game
							// automatically
		} else
		{
			invalidate(); // re-draw screen with changed dimensions
		}
	}

	// User has pressed down on the screen
	private void touchDown(int x, int y)
	{
		if (currentShapeRect.contains(x, y))
		{
			movingObject = true;
			touchMove(x, y);
		}
	}

	// User is dragging finger against screen
	private void touchMove(int x, int y)
	{
		if (movingObject)
		{
			currentShapeRect.offsetTo(x - currentShapeRect.width() / 2, y
					- currentShapeRect.height() / 2);
		}
	}

	// User has removed finger from screen
	private void touchUp(int x, int y)
	{
		// if landed on pause button or clicked pause button
		if (mMode == STATE_RUNNING)
		{
			if (pauseButtonRect.contains(x, y))
			{
				pause();
			}
		} else if (mMode == STATE_PAUSED)
		{
			unPause();
		}

		// if we are moving the shape then check if we have landed on another
		// shape
		if (movingObject)
		{
			if (mCurrentShape == SQUARE)
			{
				if (Rect.intersects(currentShapeRect, squareRect))
				{
					nextLevel();
					vibratePhone(VIBRATE_DURATION);
					return;
				}
			} else if (mCurrentShape == CIRCLE)
			{
				if (Rect.intersects(currentShapeRect, circleRect))
				{
					nextLevel();
					vibratePhone(VIBRATE_DURATION);
					return;
				}
			} else if (mCurrentShape == TRIANGLE)
			{
				if (Rect.intersects(currentShapeRect, triangleRect))
				{
					nextLevel();
					vibratePhone(VIBRATE_DURATION);
					return;
				}
			}
			wrongShape();
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		int x = (int) event.getX();
		int y = (int) event.getY();

		switch (event.getAction())
		{
		case MotionEvent.ACTION_DOWN:
			touchDown(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			touchMove(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			touchUp(x, y);
			invalidate();
			break;
		}
		return true;
	}

	public void setWillVibrate(boolean willVibrate)
	{
		this.willVibrate = willVibrate;
	}

	private void vibratePhone(int duration)
	{
		if (willVibrate)
		{
			mVibrator.vibrate(duration);
		}
	}

	public void pause()
	{
		if (mMode == STATE_RUNNING)
		{
			mMode = STATE_PAUSED;
			movingObject = false;
			currentShapeRect = new Rect(centreRect);

			Message msg = mHandler.obtainMessage();
			Bundle b = new Bundle();
			b.putString("mode", "pause");
			msg.setData(b);
			mHandler.sendMessage(msg);
		}
	}

	public void unPause()
	{
		mMode = STATE_RUNNING;
		invalidate();
	}

	@Override
	public void onWindowFocusChanged(boolean hasWindowFocus)
	{
		// if (!hasWindowFocus) pause();
	}

	public Bundle saveState(Bundle map)
	{
		if (map != null)
		{
			map.putInt("mLevel", Integer.valueOf(mLevel));
			map.putInt("mCurrentShape", Integer.valueOf(mCurrentShape));
		}
		return map;
	}

	public void restoreState(Bundle savedState)
	{
		mLevel = savedState.getInt("mLevel");
		mCurrentShape = savedState.getInt("mCurrentShape");
		movingObject = false;
		mMode = STATE_RUNNING;
		sendLevel(mLevel);
		invalidate();
	}

}

代码简单易懂!~~

学习的目标是成熟!~~~


你可能感兴趣的:(android,移动平台)