Android用SurfaceView写一个简单有趣的游戏--《数字组合》之一

最近突然有了一个想法--做一款android的简单游戏练练手,既要实现起来简单(毕竟只有一个人,框架什么的暂且就不用考虑了),又要能够达到对android知识框架的复习和游戏要有可玩性,终于用了几个星期写完了。和大家分享分享体会吧。

本来打算写一个专栏的。看以后的时间吧。

首先介绍一下游戏的主要思想和SurfaceView也就是游戏主界面的代码分享,后续部分再更新吧。

在点击 开始游戏 后,进行组合数字的选择,根据难易程度系统默认选择2和8,选择界面中间显示选择的组合数字,第一个数字表示第一个组合数字,

即在游戏过程中能被整除的那个数字,第二个数字表示第二个组合数字,即在游戏过程中不能被整除的那个数字。选择结束后开始游戏。

在游戏准备完成后开始游戏,随机下落一定范围内的数字,判断该数字是否被第一个组合数字整除而不能被第二个数字整除,若是,点击该数字,分数加上对应值,否则分数减去对应值。

下落数字的范围会随着等级的提升变大。下落速度和数字的产生速度也为随之加快。当分数小于0或错过的正确值大于5时游戏结束!

1.游戏主界面activity

package com.gymyang.number.views;

import android.graphics.BitmapFactory;
import android.view.KeyEvent;
import android.view.View;

import com.gymyang.number.BaseActivity;
import com.gymyang.number.R;
import com.gymyang.number.utils.DeviceTools;
import com.gymyang.number.utils.GlobalFields;

/**
 *  Class Name: NumberGameActivity.java
 *  Function:
 *  		主逻辑activity
 *     Modifications:
 *
 *  @author Administrator
 *  @DateTime 2014-11-11 下午8:09:55
 *  @version 1.0
 */
public class NumberGameActivity extends BaseActivity
{

	private GameView gameView;
//	private TextView noticeTx;

	@Override
	protected void initView()
	{
		loadResource();

//		setContentView(R.layout.game_view);
//		gameView = (GameView) findViewById(R.id.game_view_main);
//		noticeTx = (TextView) findViewById(R.id.game_view_notice);

		gameView = new GameView(this,this);
		setContentView(gameView);
	}

	/**
	 *  Function:
	 * 		加载资源
	 *  @author Administrator
	 *  @DateTime 2014-11-12 上午9:22:40
	 */
	private void loadResource()
	{
		GlobalFields.DEVICE_WIDTH = DeviceTools.getDeviceInfo(this)[0];
		GlobalFields.DEVICE_HEIGHT = DeviceTools.getDeviceInfo(this)[1];

		GlobalFields.BG_GRAY = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_gray);
		GlobalFields.BG_GREEN = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_green);
		GlobalFields.BG_WHITE = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_white);
		GlobalFields.BG_RED = BitmapFactory.decodeResource(getResources(), R.drawable.number_bg_red);
		GlobalFields.NUMBER_1 = BitmapFactory.decodeResource(getResources(), R.drawable.num1);
		GlobalFields.NUMBER_2 = BitmapFactory.decodeResource(getResources(), R.drawable.num2);
		GlobalFields.NUMBER_3 = BitmapFactory.decodeResource(getResources(), R.drawable.num3);
		GlobalFields.PAUSE_BG = BitmapFactory.decodeResource(getResources(), R.drawable.pause_bg);
		GlobalFields.PAUSE_BTNBG = BitmapFactory.decodeResource(getResources(), R.drawable.pause_button_bg);

		GlobalFields.scaleWidth = GlobalFields.DEVICE_WIDTH / (float)GlobalFields.BG_GRAY.getWidth();
		GlobalFields.scaleHeight = GlobalFields.DEVICE_HEIGHT / (float)GlobalFields.BG_GRAY.getHeight();
		GlobalFields.BG_GRAY = DeviceTools.resizeBitmap(GlobalFields.BG_GRAY);

		GlobalFields.PAUSE_BG = DeviceTools.resizeBitmap(GlobalFields.PAUSE_BG,
				GlobalFields.DEVICE_WIDTH / 5 *4, GlobalFields.DEVICE_HEIGHT / 4);
		GlobalFields.PAUSE_BTNBG = DeviceTools.resizeBitmap(GlobalFields.PAUSE_BTNBG,
				GlobalFields.DEVICE_WIDTH / 5 *2 - 10,GlobalFields.PAUSE_BG.getHeight() / 4);

	}

	@Override
	protected void setListener()
	{

	}

	@Override
	protected void logicWork()
	{

	}

	@Override
	public void onClick(View v)
	{

	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		if(keyCode == KeyEvent.KEYCODE_BACK){
			if(gameView.CURRENT_STATE == gameView.PREPARE_FINISH){
				gameView.CURRENT_STATE = gameView.GAME_PAUSE;
			}

			//MyWindowManager.showErrorDialog(getBaseContext(), "游戏暂停!");

			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}

2.游戏主界面SurfaceView具体实现

package com.gymyang.number.views;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.gymyang.number.sprite.BaseSprite;
import com.gymyang.number.sprite.LevelText;
import com.gymyang.number.sprite.NumberBlock;
import com.gymyang.number.sprite.NumberBlockManager;
import com.gymyang.number.sprite.ScoreText;
import com.gymyang.number.sprite.StateBar;
import com.gymyang.number.sprite.TouchAble;
import com.gymyang.number.utils.DeviceTools;
import com.gymyang.number.utils.GlobalFields;
import com.gymyang.number.utils.LevelManager;

/**
 *  Class Name: GameView.java
 *  Function:
 *  		大管家
 *     Modifications:
 *
 *  @author Administrator
 *  @DateTime 2014-11-11 下午10:36:53
 *  @version 1.0
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable
{
	/** GameView单例存在 */
	private static GameView gameView;
	public static GameView getInstance(){
		return gameView;
	}

	private NumberGameActivity activity;
	private SurfaceHolder surfaceHolder;
	private Paint paint;
	// 游戏进行状态
	private boolean flag = true;
	private Canvas canvas;

	/** 格子宽度 */
	public int BLOCK_WIDTH;
	/** 格子高度  */
	public int BLOCK_HEIGHT;

	/** 准备开始 */
	private final int PREPARE_START = 200;
	/** 准备完成*/
	public final int PREPARE_FINISH = 201;
	/** 游戏结束 */
	private final int GAME_OVER = 202;
	/** 暂停 */
	public final int GAME_PAUSE = 203;

	/** 当前进度状态 */
	public int CURRENT_STATE = PREPARE_START;

	/**
	 * 格子对象集合
	 */
	private LinkedList<BaseSprite> blockSprites;
	/** 死掉了的精灵 */
	private List<BaseSprite> deadSprites;
	/** 数字格子管理 */
	private NumberBlockManager numberBlockManager;

	private StateBar stateBar;

	private float dp = 1;

	public GameView(Context context,NumberGameActivity activity)
	{
		super(context);
		this.activity = activity;
		paint = new Paint();
		getHolder().addCallback(this);
		surfaceHolder = getHolder();
		gameView = this;
		GlobalFields.dp = DeviceTools.getScreenDensity(context);
		dp = GlobalFields.dp;
	}

	public GameView(Context context)
	{
		super(context);
		paint = new Paint();
		getHolder().addCallback(this);
		surfaceHolder = getHolder();
		gameView = this;
		GlobalFields.dp = DeviceTools.getScreenDensity(context);
		dp = GlobalFields.dp;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		paint.setColor(Color.WHITE);
		paint.setTextSize(30*dp);

		GlobalFields.SCORE = 0;

		LevelManager.initChildren();

		BLOCK_WIDTH = GlobalFields.DEVICE_WIDTH / GlobalFields.CURRENT_COLUMNS;
		BLOCK_HEIGHT = GlobalFields.DEVICE_HEIGHT / GlobalFields.CURRENT_LINES;

		blockSprites = new LinkedList<BaseSprite>();
		deadSprites = new ArrayList<BaseSprite>();
		numberBlockManager = new NumberBlockManager();

		stateBar = new StateBar();

		resetBitmap();
		new Thread(this){}.start();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height)
	{}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{}

	/**
	 *  Function:
	 * 		拉伸格子背景资源
	 *  @author Administrator
	 *  @DateTime 2014-11-12 下午2:57:30
	 */
	private void resetBitmap()
	{
		GlobalFields.BG_GREEN = DeviceTools.resizeBitmap(GlobalFields.BG_GREEN,BLOCK_WIDTH,BLOCK_HEIGHT);
		GlobalFields.BG_RED = DeviceTools.resizeBitmap(GlobalFields.BG_RED,BLOCK_WIDTH,BLOCK_HEIGHT);
		GlobalFields.BG_WHITE = DeviceTools.resizeBitmap(GlobalFields.BG_WHITE,BLOCK_WIDTH,BLOCK_HEIGHT);
	}

	@Override
	public void run()
	{
		while (flag) {
			synchronized (surfaceHolder) {
				try {
					canvas = surfaceHolder.lockCanvas();
					canvas.drawBitmap(GlobalFields.BG_GRAY, 0, 0, paint);

					updateState();
					ondraw(canvas);
				} catch (Exception e) {
					// TODO: handle exception
				} finally {
					if(canvas != null){
						surfaceHolder.unlockCanvasAndPost(canvas);
					}
				}
			}

			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 *  Function:
	 * 		更新状态
	 *  @author Administrator
	 *  @DateTime 2014-11-12 下午3:37:47
	 */
	private void updateState()
	{
		deadSprites.clear();

		for(BaseSprite sprite : blockSprites){
			if(!sprite.isAlive()){
				deadSprites.add(sprite);
			}
		}

		blockSprites.removeAll(deadSprites);
	}

	/**
	 *  Function:
	 *
	 *  @author Administrator
	 *  @DateTime 2014-11-11 下午11:31:45
	 *  @param canvas2
	 */
	private void ondraw(Canvas canvas)
	{
		if(CURRENT_STATE == PREPARE_START){
			drawDevideLines(canvas);
		}else if(CURRENT_STATE == PREPARE_FINISH){
			drawDevideLines(canvas);
			// 绘制数字格子
			numberBlockManager.drawSelf(canvas, paint);
			for(BaseSprite sprite : blockSprites){
				sprite.drawSelf(canvas, paint);
			}

			// 绘制状态栏
			drawStateBar(canvas);

			if(GlobalFields.MISSED < 0 || GlobalFields.SCORE < 0){
				CURRENT_STATE = GAME_OVER;
			}
		}else if(CURRENT_STATE == GAME_PAUSE){
			// TODO 游戏暂停
			drawPause(canvas);
			//canvas.drawText("游戏暂停", GlobalFields.DEVICE_WIDTH / 2 -20, GlobalFields.DEVICE_HEIGHT / 2 -20, paint);
		}else if(CURRENT_STATE == GAME_OVER){
			// TODO 游戏结束
			drawGameOver(canvas);
		}
	}

	private int overHeight = 0;
	/**
	 *  Function:
	 * 		游戏结束
	 *  @author Administrator
	 *  @DateTime 2014-11-16 下午2:36:52
	 */
	private void drawGameOver(Canvas canvas){
		int preColor = paint.getColor();
		float textSize = paint.getTextSize();
		Align preTextStyle = paint.getTextAlign();

		paint.setColor(Color.RED);
		paint.setTextSize(32*dp);
		paint.setTextAlign(Paint.Align.CENTER);
		canvas.drawText("Game Over !",GlobalFields.DEVICE_WIDTH / 2,
				overHeight, paint);

		paint.setColor(preColor);
		paint.setTextSize(textSize);
		paint.setTextAlign(preTextStyle);

		if(overHeight < GlobalFields.DEVICE_HEIGHT / 2){
			overHeight += 50;
		}else if(overHeight >= GlobalFields.DEVICE_HEIGHT / 2 &&
				overHeight < GlobalFields.DEVICE_HEIGHT / 2 + 20){
			overHeight += 5;
		}else if(overHeight >= GlobalFields.DEVICE_HEIGHT / 2 + 20 &&
				overHeight < GlobalFields.DEVICE_HEIGHT){
			overHeight += 50;
		}else if(overHeight >= GlobalFields.DEVICE_HEIGHT){
			// TODO 回到主界面
			flag = false;
			activity.finish();
		}
	}

	private int pauseHeight = 0;
	private int pauseWidth = (GlobalFields.DEVICE_WIDTH - GlobalFields.PAUSE_BG.getWidth()) / 2;
	private int pauseTextHeight = pauseHeight + (GlobalFields.PAUSE_BG.getHeight() -
			GlobalFields.PAUSE_BTNBG.getHeight());
	/** 退出游戏 触摸区域 */
	private Rect exitTouchArea;
	/** 继续游戏 触摸区域 */
	private Rect goonTouchArea;
	/**
	 *  Function:
	 * 		绘制暂停状态
	 *  @author Administrator
	 *  @DateTime 2014-11-16 下午1:33:12
	 */
	private void drawPause(Canvas canvas){
		if(exitTouchArea != null){
			exitTouchArea = null;
		}
		if(goonTouchArea != null){
			goonTouchArea = null;
		}
		exitTouchArea = new Rect(pauseWidth + 5, (pauseHeight +pauseTextHeight - 5),
				(pauseWidth + 5) + GlobalFields.PAUSE_BTNBG.getWidth(),
				(pauseHeight +pauseTextHeight - 5) + GlobalFields.PAUSE_BTNBG.getHeight());
		goonTouchArea = new Rect((pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5),
				(pauseHeight +pauseTextHeight - 5),
				(pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5) + GlobalFields.PAUSE_BTNBG.getWidth(),
				(pauseHeight +pauseTextHeight - 5) + GlobalFields.PAUSE_BTNBG.getHeight());

		int preColor = paint.getColor();
		float textSize = paint.getTextSize();
		Align preTextStyle = paint.getTextAlign();

		canvas.drawBitmap(GlobalFields.PAUSE_BG, pauseWidth, pauseHeight, paint);
		canvas.drawBitmap(GlobalFields.PAUSE_BTNBG, pauseWidth + 5,
				pauseHeight +pauseTextHeight - 5, paint);
		canvas.drawBitmap(GlobalFields.PAUSE_BTNBG, pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2 + 5,
				pauseHeight +pauseTextHeight - 5, paint);

		paint.setColor(Color.BLUE);
		paint.setTextSize(28*dp);
		paint.setTextAlign(Paint.Align.CENTER);
		canvas.drawText("游戏暂停",pauseWidth + GlobalFields.PAUSE_BG.getWidth() / 2,
				pauseHeight + GlobalFields.PAUSE_BG.getHeight() / 2, paint);

		paint.setTextSize(18*dp);
		canvas.drawText("返回菜单", pauseWidth + 5 + GlobalFields.PAUSE_BTNBG.getWidth() / 2,
				pauseHeight +pauseTextHeight + GlobalFields.PAUSE_BTNBG.getHeight() / 2,
				paint);
		canvas.drawText("继续游戏",
				pauseWidth + GlobalFields.PAUSE_BTNBG.getWidth()/2*3 + 5,
				pauseHeight +pauseTextHeight + GlobalFields.PAUSE_BTNBG.getHeight() / 2, paint);

		paint.setColor(preColor);
		paint.setTextSize(textSize);
		paint.setTextAlign(preTextStyle);

		if(pauseHeight < GlobalFields.DEVICE_HEIGHT / 2 - GlobalFields.PAUSE_BG.getHeight() / 2){
			pauseHeight += 60;
		}
	}

	/**
	 *  Function:
	 * 		绘制状态栏
	 *  @author Administrator
	 *  @DateTime 2014-11-12 下午7:50:30
	 */
	private void drawStateBar(Canvas canvas)
	{
		stateBar.drawSelf(canvas, paint);
	}

	private boolean isAddNumber = false;
	/**
	 *  Function:
	 *		请求加入格子
	 *  @author Administrator
	 *  @DateTime 2014-11-12 下午3:22:09
	 */
	public void apply2AddNumber(){
		synchronized (surfaceHolder) {
			int raceWay = 0, number = 0;
			raceWay = (int) (Math.random() * GlobalFields.CURRENT_COLUMNS);
			number = (int) (Math.random() * GlobalFields.MAX_NUMBER + 1);

			isAddNumber = false;
			// TODO 添加数字格子
			if(blockSprites.size() > 0){
//				BaseSprite sprite = blockSprites.getLast();

				for(int i=blockSprites.size()-1 ; i>0 ;i--){
					BaseSprite sprite = blockSprites.get(i);
					if(sprite.locationX == raceWay){
						if(sprite.locationY > BLOCK_HEIGHT){
							blockSprites.add(new NumberBlock(raceWay, number));
						}
						isAddNumber = true;
						break;
					}
				}

				if(!isAddNumber){
					blockSprites.add(new NumberBlock(raceWay, number));
					isAddNumber = true;
				}
			}else{
				blockSprites.add(new NumberBlock(raceWay, number));
				isAddNumber = true;
			}

		}
	}

	/**
	 *  Function:
	 *		请求加入加分显示
	 *  @author Administrator
	 *  @DateTime 2014-11-12 下午3:22:09
	 */
	public void apply2AddScoreText(int x,int y,String msg,int flag){
		synchronized (surfaceHolder) {
			// TODO 请求加入加分显示
			blockSprites.add(new ScoreText(x, y, msg, flag));
		}
	}

	/**
	 *  Function:
	 * 		等级上升
	 *  @author Administrator
	 *  @DateTime 2014-11-13 下午12:07:36
	 */
	public void requestAddLevel()
	{
		synchronized (surfaceHolder) {
			// TODO 请求加入加分显示
			blockSprites.add(new LevelText());
		}
	}

	/**
	 *  Function:
	 * 		请求重新绘制格子
	 *  @author Administrator
	 *  @DateTime 2014-11-13 下午12:07:36
	 */
	public void requestReDraw()
	{
		BLOCK_WIDTH = GlobalFields.DEVICE_WIDTH / GlobalFields.CURRENT_COLUMNS;
		BLOCK_HEIGHT = GlobalFields.DEVICE_HEIGHT / GlobalFields.CURRENT_LINES;
		DRAW_DEVIDE_LINE = 1;
		DRAW_DEVIDE_COLUMN = 1;
		DRAW_TIME = 1;
		i=1;j=1;k=1;SPACE=6;

		GlobalFields.BG_WHITE = DeviceTools.resizeBitmap(GlobalFields.BG_WHITE, BLOCK_WIDTH, BLOCK_HEIGHT);
		GlobalFields.BG_GREEN = DeviceTools.resizeBitmap(GlobalFields.BG_GREEN, BLOCK_WIDTH, BLOCK_HEIGHT);
		GlobalFields.BG_RED = DeviceTools.resizeBitmap(GlobalFields.BG_RED, BLOCK_WIDTH, BLOCK_HEIGHT);

		CURRENT_STATE = PREPARE_START;
	}

	/********************************** 传递触摸事件 **************************************/
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		if(CURRENT_STATE == GAME_PAUSE){
			int x = (int) event.getX();
			int y = (int) event.getY();

			if (exitTouchArea.contains(x, y)) {
				CURRENT_STATE = GAME_OVER;
				pauseHeight = 0;
				return true;
			}

			if(goonTouchArea.contains(x, y)){
				CURRENT_STATE = PREPARE_FINISH;
				pauseHeight = 0;
				return true;
			}
		}else{
			for (BaseSprite sprite : blockSprites) {
				if (sprite instanceof TouchAble) {
					if (((TouchAble) sprite).onTouch(event)) {
						return true;
					}
				}
			}
		}

		return false;
	}

	/******************************** 绘制分割线 ****************************************/
	// 列分割线游标
	private int DRAW_DEVIDE_LINE = 1;
	// 行分割线游标
	private int DRAW_DEVIDE_COLUMN = 1;
	// 倒计时游标
	private int DRAW_TIME = 1;
	// 行列遍历 最大值
	int i=1,j=1,k=1,SPACE=6;
	/**
	 *  Function:
	 * 		绘制分割线
	 *  @author Administrator
	 *  @DateTime 2014-11-12 上午9:31:11
	 */
	private void drawDevideLines(Canvas canvas)
	{
		drawNotice();

		paint.setStyle(Paint.Style.STROKE);
		paint.setColor(Color.LTGRAY);

		// 绘制列分割线
		for(int x=1;x<=i;x++){
			canvas.drawLine(BLOCK_WIDTH * x, 0, BLOCK_WIDTH * x, GlobalFields.DEVICE_HEIGHT, paint);
		}
		if(DRAW_DEVIDE_LINE % SPACE == 0){
			i++;
		}
		if(i >= GlobalFields.CURRENT_COLUMNS){
			// 回归i,j 避免溢出
			i = GlobalFields.CURRENT_COLUMNS - 1;
		}else{
			DRAW_DEVIDE_LINE++;
		}

		// 绘制行分割线
		if(DRAW_DEVIDE_LINE >= (GlobalFields.CURRENT_COLUMNS - 1)*SPACE){
			for(int y=1;y<=j;y++){
				canvas.drawLine(0, BLOCK_HEIGHT * y, GlobalFields.DEVICE_WIDTH, BLOCK_HEIGHT * y, paint);
			}
			if(DRAW_DEVIDE_COLUMN % SPACE == 0){
				j++;
			}
			if(j >= GlobalFields.CURRENT_LINES){
				// 回归i,j 避免溢出
				j = GlobalFields.CURRENT_LINES - 1;
			}else{
				DRAW_DEVIDE_COLUMN++;
			}
		}

		// 准备倒计时
		if(DRAW_DEVIDE_COLUMN >= (GlobalFields.CURRENT_LINES - 1)*SPACE){
			int left = GlobalFields.DEVICE_WIDTH / 2 - GlobalFields.NUMBER_1.getWidth() / 2;
			int top = GlobalFields.DEVICE_HEIGHT / 2 - GlobalFields.NUMBER_1.getHeight() / 2;
			if(k == 1){
				canvas.drawBitmap(GlobalFields.NUMBER_3, left, top, paint);
			}else if(k == 2){
				canvas.drawBitmap(GlobalFields.NUMBER_2, left, top, paint);
			}else if(k == 3){
				canvas.drawBitmap(GlobalFields.NUMBER_1, left, top, paint);

				CURRENT_STATE = PREPARE_FINISH;
			}

			if(DRAW_TIME % SPACE == 0){
				k++;
			}
			if(k < 3){
				DRAW_TIME++;
			}
		}
	}

	private int noticeHeight = GlobalFields.DEVICE_HEIGHT/4*3;
	private void drawNotice(){
		int preColor = paint.getColor();
		float textSize = paint.getTextSize();
		Align preTextStyle = paint.getTextAlign();

		paint.setTextAlign(Paint.Align.CENTER);
		paint.setTextSize(16*dp);
		paint.setColor(Color.rgb(8, 103, 23));
		canvas.drawText("点击能被组合数字一:【"+GlobalFields.SENSETIVE_NUMBER+"】",
				GlobalFields.DEVICE_WIDTH / 2,
				noticeHeight, paint);
		canvas.drawText("但不能被组合数字二: 【"+GlobalFields.SENSETIVE_NUMBER2+"】 的数",
				GlobalFields.DEVICE_WIDTH / 2, noticeHeight+30, paint);
		canvas.drawText("等级越高!速度越快!数字越大!",
				GlobalFields.DEVICE_WIDTH / 2, noticeHeight+60, paint);
		canvas.drawText("你准备好了吗?",
				GlobalFields.DEVICE_WIDTH / 2, noticeHeight+90, paint);
		noticeHeight -= 20;

		paint.setColor(preColor);
		paint.setTextSize(textSize);
		paint.setTextAlign(preTextStyle);
	}

}
时间: 2024-11-05 12:34:06

Android用SurfaceView写一个简单有趣的游戏--《数字组合》之一的相关文章

一个简单有趣的SQL存储过程——个人财务管理

刚开始学习存储过程的小白,网上看完语法后一般都会想实践一下,但往往又不知道该写个什么样的存储过程来练手,以下就提供一个简单有趣.用来查询每月个人财务状况的存储过程. 一.建表 首先需要建一张事实表,用来记录每月重要的支出,包括支出的类型.费用.付款方式.每月付款时间.首次分期还贷时间.最后分期还贷时间(还完的时间).用途.支出大类...不一定会都用到,也可以根据实际情况做相应的增减,以下仅提供一个例子. CREATE TABLE [dbo].[Fact_CostType] ( [CostType

linux设备驱动第三篇:写一个简单的字符设备驱动

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [plain] vie

(2)自己写一个简单的servle容器

自己写一个简单的servlet,能够跑一个简单的servlet,说明一下逻辑. 首先是写一个简单的servlet,这就关联到javax.servlet和javax.servlet.http这两个包的类,其中一个比较重要的接口就是:javax.servlet.Servlet,所有的servlet必须实现实现或者继承实现该接口的类. Servlet接口有五个方法: public void init(ServletConfig config) throws ServletException publi

分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业不是百度来的,我只是百度了一些示例代码的意思,怎么用!算了,越解释万一越黑呢!哈哈O(∩_∩)O哈哈~) ----------------------------------------------------------------分界线------------------------------

Java写一个简单学生管理系统

其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来做一个有界面的学生管理系统.其实都并不会太难. 今天我就先写一个简单的用List来实现学生管理系统: 首先,管理系统是针对学生对象的,所以我们先把学生对象就写出来: package bean; public class Student { String name; String studentId;

DuiVision开发教程(2)-如何写一个简单的界面程序

基于DuiVision界面库开发的界面程序主要包括如下几部分内容: 1.资源定义,包括图片资源.各个窗口界面的xml定义文件 2.事件处理类代码,用于处理界面响应消息 3.其他业务逻辑代码 下面举例说明如何写一个简单的界面程序. 第一步:使用VC向导创建一个有两个tab页面的DuiVision工程 向导生成的解决方案文件如下: 默认有两个工程,分别是DuiVision库和应用程序工程.自动生成的代码目录中bin目录下的内容那个如下,bkimg目录存放窗口背景图片,skins目录存放图片资源,xm

linux设备驱动第三篇:如何写一个简单的字符设备驱动?

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [email prot

利用servlet和html写一个简单的登录

写一个简单的html登录页面,然后利用servlet来进行验证账号密码. html代码: <!DOCTYPE html> <html> <title>登陆页面</title> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action = &

如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个iPhone/iPad开发者,能够自己写一个简单的web服务器将是很有用的. 例如,你可能希望在软件启动时显示一些来自服务器的更新,或者在服务器端保存一些用户数据.除了你的想象力,没有什么能限制你了. 在第一篇中,我们将会一步一步的建立一个web服务器,基于promo code system(促销码系