项目实例--大炮小兵游戏源码解析

游戏说明:大炮2个棋子,小兵18个棋子,大炮隔格可以吃掉小兵,小兵只好一步一步围死大炮
 
  package com.wenbo.game.cbp;
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.os.Bundle;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.Window;
  import android.view.WindowManager;
  public class cannonBombpawn extends Activity {
  ChessView cv;
  final int MENU_START=Menu.FIRST;
  final int MENU_BIN=Menu.FIRST+1;
  final int MENU_PAO=Menu.FIRST+2;
  final int MENU_HELP=Menu.FIRST+3;
  final int MENU_QUIT=Menu.FIRST+4;
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  //设置全屏
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  setContentView(R.layout.main);
  cv = (ChessView) findViewById(R.id.myview);
  }
  public boolean onCreateOptionsMenu(Menu menu) {
  menu.add(0,MENU_START, 0, "开始游戏");
  menu.add(0,MENU_BIN, 0, "选择小兵");
  menu.add(0,MENU_PAO, 0, "选择大炮");
  menu.add(0,MENU_HELP, 0, "游戏帮助");
  menu.add(0,MENU_QUIT, 0, "退出");
  return true;
  }
  /* (non-Javadoc)
  * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
  */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
  super.onOptionsItemSelected(item);
  switch(item.getItemId()){
  case MENU_START:
  cv.init();
  break;
  case MENU_HELP:
  Intent in = new Intent();
  in.setClass(cannonBombpawn.this, AboutActivy.class);
  startActivity(in);
  break;
  case MENU_QUIT:
  openDialog();
  break;
  case MENU_BIN:
  cv.choiceBin();
  break;
  case MENU_PAO:
  cv.choicePao();
  break;
  }
  return true;
  }
  /**
  * 用户点击退出对话框
  *@author chenbo
  *@date 2010-12-17
  */
  private void openDialog(
  AlertDialog.Builder bl = new AlertDialog.Builder(this);
  bl.setTitle("退出游戏");
  bl.setMessage("确定要退出游戏?");
  bl.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  public void onClick(DialogInterface dialog, int which) {
  finish();
  }
  });
  bl.setNegativeButton("取消", new DialogInterface.OnClickListener() {
  @Override
  public void onClick(DialogInterface dialog, int which) {
  }
  });
  bl.show();
  }
  }
 
  /**
  *@author chenbo
  */
  package com.wenbo.game.cbp;
  import java.util.ArrayList;
  import java.util.Random;
  import java.util.Timer;
  import android.app.AlertDialog;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.res.Resources;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Paint;
  import android.graphics.Paint.Style;
  import android.util.AttributeSet;
  import android.view.MotionEvent;
  import android.view.View;
  import android.widget.TextView;
  import android.widget.Toast;
  /**
  * @author Administrator
  *
  */
  public class ChessView extends View {
  private int sum=18;
  private static int qipansize = 6;//棋盘的大小6*6
  private static int gewidth=50;//每格的宽度
  //private static int chesssize =30;//棋子的大小
  protected static int sx=30;// 棋盘定位的左上角X
  protected static int sy=100;// 棋盘定位的左上角Y
  private Pwan bin;//兵或者炮对象
  private boolean isFirstChoice=true;
  private boolean isPawn=true;
  private boolean successMove=false;
  public static ChessView c;
  private int red =Color.RED;
  Context mycontext;
  private Resources res;
  private boolean isSelected;
  Bitmap[] chessImage;//棋子图片数组
  private boolean trun =true;// 默认用户选择是小兵 大炮先走
  private boolean isComputer=false;
  private static int[][] qipan = new int[qipansize][qipansize];;//[i][j]=1代表坐标上有棋子,0代表没有棋子
  private Paint p = new Paint();//画笔
  private Paint pchoice = new Paint();
  private int myCR=-1;//当前棋子所在的行
  private int myCC=-1;//所在的列
  int bx=0;//用于记录选择棋子的x坐标
  int by=0;//
  private int binsum=0;
  private int paosum=0;
  int gamestate = GAMESTATE_READY;//游戏现在的状态,0为没有开始,1正在游戏,2gameover
  static final int GAMESTATE_READY = 0;
  static final int GAMESTATE_RUN = 1;
  static final int GAMESTATE_OVER = 2;
  public TextView gametv; // 根据游戏状态设置显示的文字
  ArrayList<Pwan> blist = new ArrayList<Pwan>();
  /**
  * @param context
  * @param attrs
  */
  public ChessView(Context context, AttributeSet attrs) {
  super(context, attrs);
  System.out.println("super chessview");
  this.setFocusable(true);//获得触摸时焦点
  this.setFocusableInTouchMode(true);
  c=this;
  mycontext=context;
  res= context.getResources();
  chessImage=new Bitmap[2];//棋子图片数组
  chessImage[0]=BitmapFactory.decodeResource(res, R.drawable.pao);
  chessImage[1]=BitmapFactory.decodeResource(res, R.drawable.bin);
  }
  public void init(){
  gamestate=GAMESTATE_RUN;//初始化的时候游戏运行
  }
  public void choiceBin() {
  trun=true;
  gamestate=GAMESTATE_RUN;//初始化的时候游戏运行
  }
  public void choicePao(){
  trun=false;
  gamestate=GAMESTATE_RUN;//初始化的时候游戏运行
  }
  /**
  * @param context
  */
  public ChessView(Context context) {
  super(context);
  }
  /**
  * 画棋盘
  */
  protected void onDraw(Canvas canvas) {
  /*int c = Color.rgb(10,240,240);//设置画笔的颜色
  p.setColor(c);
  p.setStrokeWidth(2);
  p.setStyle(Style.STROKE);
  for(int i=0;i<5;i++){
  for(int j=0;j<5;j++){
  int mLeft = i * gewidth + sx;
  int mTop = j * gewidth + sy;
  int mRright = mLeft + gewidth;
  int mBottom = mTop + gewidth;
  canvas.drawRect(mLeft, mTop, mRright, mBottom, p);
  }
  }
  //画棋盘的边框
  p.setStrokeWidth(4);
  canvas.drawRect(sx, sy, sx + gewidth*5, sy + gewidth*5, p);*/
  drawChess(canvas);
  }
  /**
  * 画棋子
  *@author chenbo
  *@date 2010-12-2
  * @param canvas
  */
  public void drawChess(Canvas canvas){
  //画棋子,通过图片来画
  if(myCC!=-1){
  for(int i=0;i<blist.size();i++){
  Pwan b = blist.get(i);
  Bitmap bitmap =b.getBin();
  int binx =b.getBx();
  int biny = b.getBy();
  int mLeft = binx* gewidth + sx-10;
  int mTop = biny * gewidth + sy-10;
  if(b.getBx()==bx&&b.getBy()==by){
  pchoice.setColor(red);
  pchoice.setStrokeWidth(1);
  pchoice.setStyle(Style.STROKE);
  if(bitmap.equals(chessImage[1])){
  canvas.drawBitmap(chessImage[1], mLeft, mTop,null);
  isPawn=true;
  }else{
  canvas.drawBitmap(chessImage[0], mLeft, mTop,null);
  isPawn=false;
  }
  canvas.drawCircle(mLeft+10, mTop+10, 15,pchoice);//选中棋子的画圈
  isSelected=true;
  }else{
  if(b.getBin().equals(chessImage[1])){//是兵画兵
  canvas.drawBitmap(chessImage[1], mLeft, mTop,null);
  }else{//是炮画炮
  canvas.drawBitmap(chessImage[0], mLeft, mTop,null);
  }
  }
  }
  }
  else{//初始化的游戏界面,第一次把棋子的坐标添加到list中
  for(int i=0;i<=5;i++){
  for(int j=0;j<=5;j++){
  int mLeft = i * gewidth + sx-10;
  int mTop = j * gewidth + sy-10;
  if((i==2&&j==0)||(i==3&&j==0)){//画大炮
  paosum++;
  canvas.drawBitmap(chessImage[0], mLeft, mTop, null);
  blist.add(new Pwan(chessImage[0], i, 0,paosum));//添加到列表,此时的坐标是整数值
  qipan[i][j]=1;
  }
  if(j==3||j==4||j==5){//画小兵
  binsum++;
  canvas.drawBitmap(chessImage[1], mLeft, mTop, null);
  blist.add(new Pwan(chessImage[1], i, j,binsum));
  qipan[i][j]=1;
  }
  }
  }
  }
  }
  private boolean choiceChess(int x,int y){
  for(int i=0;i<blist.size();i++){
  bin= blist.get(i);
  int binx = bin.getBx();
  int biny = bin.getBy();
  if(binx==x && biny==y){//确定选择的对象在图片的显示范围内
  if(trun){
  if(bin.getBin().equals(chessImage[1])){//用户选择是小兵
  invalidate();//重画突出选中的棋子
  isFirstChoice=false;
  return true;
  }else{
  System.out.println("please choice youselfchess bin ok?");
  }
  }
  if(!trun) {
  if(bin.getBin().equals(chessImage[0])){//用户选择是大炮
  invalidate();//重画突出选中的棋子
  isFirstChoice=false;
  return true;
  }else{
  System.out.println("please choice youselef chess pao ok?");
  }
  }
  }
  }
  return false;
  }
  //游戏开始
  private void gamebegin(int x,int y) {
  if(!isComputer){
  if(!isFirstChoice){
  //第二步选择要走的坐标
  if(isSelected==true&&isPawn==true&&qipan[x][y]==0){
  if(binRule(bx,by,x,y)){
  isComputer=true;
  try {
  Thread.sleep(500);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  cumputerMove();
  }
  System.out.println("The 2 step");
  }
  if(isSelected==true&&isPawn==false){
  if(paoRule(bx,by,x,y)){
  isComputer=true;
  try {
  Thread.sleep(500);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  cumputerMove();
  }
  System.out.println("The 2 step");
  }
  }
  }
  if(choiceChess(x, y)){
  bx=x;//记住选择的棋子
  by=y;
  myCC=by;
  myCR= bx;
  isFirstChoice=false;//已经选择
  //System.out.println("The 1 step");
  }
  }
  /**
  * 该电脑走了
  *@author chenbo
  * @throws InterruptedException
  *@date
  */
  public void cumputerMove() {
  if(isComputer){
  successMove=false;
  Random r = new Random();
  Pwan b ;
  if(trun){//此时电脑是大炮
  while(true){
  b = blist.get(r.nextInt(blist.size()));
  int i=r.nextInt(5);
  int j = r.nextInt(5);
  if(b.getBin().equals(chessImage[0])){
  int m = b.getBx();
  int n = b.getBy();
  if(paoRule(m, n, i,j)){//成功走了一步
  isComputer=false;
  break;
  }
  }
  }
  }
  if(!trun){//此时电脑是小兵
  while(true){
  b = blist.get(r.nextInt(blist.size()));
  int i=r.nextInt(5);
  int j = r.nextInt(5);
  if(b.getBin().equals(chessImage[1])){
  int m = b.getBx();
  int n = b.getBy();
  if(binRule(m, n, i,j)){//成功走了一步
  System.out.println(m+","+n);
  System.out.println(i+","+j);
  isComputer=false;
  break;
  }
  }
  }
  }
  }
  }
  private void checkWin(int m,int n){
  //此时想吃掉兵的时候,必须隔格,相邻一个单位上没有棋子
  int up1=n-2;
  int up2=n-1;
  int down1=n+2;
  int down2=n+1;
  int left1=m-2;
  int left2=m-1;
  int right1=m+2;
  int right2=m+1;
  if(up1>=0&&up1<=5&&up2>=0&&up2<=5){
  if ((qipan[m][n-2]==1)&&(qipan[m][n-1]==0)) {//上
  eatPwan(m, n, m, n-2);
  }
  }
  if((qipan[m][n+2]==1)&&(qipan[m][n+1]==0)){
  if ((qipan[m][n+2]==1)&&(qipan[m][n+1]==0)) {//下
  eatPwan(m, n, m, n+2);
  }
  }
  if ((qipan[m-2][n]==1)&&(qipan[m-1][n]==0)) {//左
  eatPwan(m, n, m-2, n);
  }
  if ((qipan[m+2][n]==1)&&(qipan[m+1][n]==0)) {//右
  eatPwan(m, n, m+2, n);
  }
  }
  /*
  * 处理触摸屏事件
  */
  @Override
  public boolean onTouchEvent(MotionEvent event) {
  switch(event.getAction()){
  case MotionEvent.ACTION_DOWN:{//只有按下去才生效
  int x,y;
  float x0=gewidth-(event.getX()-sx)%gewidth;//只有在棋盘范围内的才有效
  float y0 =gewidth-(event.getY()-sy)%gewidth;
  if(x0<gewidth/2){//范围上最接近那个坐标点x
  x= (int) ((event.getX()-sx)/gewidth)+1;
  }else{
  x= (int) ((event.getX()-sx)/gewidth);
  }
  if(y0<gewidth/2){//范围上最接近那个坐标点y
  y= (int) ((event.getY()-sy)/gewidth)+1;
  }else{
  y= (int) ((event.getY()-sy)/gewidth);
  }
  if(gamestate==1){
  gamebegin(x, y);//
  }
  //坐标必须在棋盘上
  /*if ((x >= 0 && x < qipansize - 1)&& (y >= 0 && y < qipansize - 1)) {
  // System.out.println("move to:("+x+","+y+")");
  }*/
  }
  }
  return true;
  }
  /**
  * 游戏过程中信息提示
  *@author chenbo
  *@date
  * @param message
  */
  private void showMessage(String message){
  Toast.makeText(mycontext, message, Toast.LENGTH_SHORT).show();
  }
  /**
  * 显示弹出确认框
  *@author chenbo
  *@date
  * @param message
  */
  private void showDialog(String message){
  AlertDialog.Builder bl = new AlertDialog.Builder(mycontext);
  bl.setTitle("游戏结束");
  bl.setMessage(message+"取得胜利!");
  bl.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  public void onClick(DialogInterface dialog, int which) {
  new cannonBombpawn();
  }
  });
  bl.show();
  }
  /**
  * 兵的走法,只能向前或者横向移动
  *@author chenbo
  *@date
  * @param m棋子当前x坐标
  * @param n 棋子当前的y坐标
  * @param sx选择的x坐标
  * @param sy选择的y坐标
  */
  private boolean binRule(int m,int n,int sx,int sy){
  if(sy<=n||1==1){//只能向前或者横向移动
  if ((sy - n == -1) &&(sx - m == 0)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, false);
  }
  if ((sy - n == 1) &&(sx - m == 0)&&(qipan[sx][sy]==0)) {//可以向后移动
  return changeTwoChessNum(m, n, sx, sy, false);
  }
  if ((sy - n == 0) &&(sx - m == 1)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, false);
  }
  if ((sy - n == 0)&& (sx - m == -1)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, false);
  }
  }
  return false;
  }
  /**
  * 炮的走法:一次可以向前后左右移动一个单位,隔格的时候可以吃掉小兵
  *@author chenbo
  *@date 2010-12-6
  * @param m棋子当前x坐标
  * @param n 棋子当前的y坐标
  * @param sx选择的x坐标
  * @param sy选择的y坐标
  */
  private boolean paoRule(int m,int n,int sx,int sy){
  //此时想吃掉兵的时候,必须隔格,相邻一个单位上没有棋子
  if ((sy - n ==-2)&& (sx - m == 0)&&(qipan[sx][sy]==1)&&(qipan[sx][sy+1]==0)) {
  return eatPwan(m, n, sx, sy);
  }
  if ((sy - n ==2)&& (sx - m == 0)&&(qipan[sx][sy]==1)&&(qipan[sx][sy-1]==0)) {
  return eatPwan(m, n, sx, sy);
  }
  if ((sy - n == 0)&&(sx - m == 2)&&(qipan[sx][sy]==1)&&(qipan[sx-1][sy]==0)) {
  return eatPwan(m, n, sx, sy);
  }
  if ((sy - n == 0)&&(sx - m == -2)&&(qipan[sx][sy]==1)&&(qipan[sx+1][sy]==0)) {
  return eatPwan(m, n, sx, sy);
  }
  //正常的移动一个
  if ((sy - n ==-1)&& (sx - m == 0)&&(qipan[sx][sy]==0)) {//正常步骤走一格
  return changeTwoChessNum(m, n, sx, sy, true);
  }
  if ((sy - n ==1)&& (sx - m == 0)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, true);
  }
  if ((sy - n == 0)&&(sx - m == 1)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, true);
  }
  if ((sy - n == 0)&&(sx - m == -1)&&(qipan[sx][sy]==0)) {
  return changeTwoChessNum(m, n, sx, sy, true);
  }
  return false;
  }
  /**改变两个坐标的值,实现棋子move
  *@author chenbo
  *@date
  * @param m棋子当前x坐标
  * @param n 棋子当前的y坐标
  * @param sx选择的x坐标
  * @param sy选择的y坐标
  * @param b 如果是兵false,没有吃的权利,如果是炮true,有吃掉的权利
  */
  protected boolean changeTwoChessNum(int m, int n, int sx, int sy, boolean b) {
  for(int i=0;i<blist.size();i++){
  Pwan bin = blist.get(i);
  if(bin.getBx()==m&&bin.getBy()==n){
  bin.setBx(sx);//交换位置
  bin.setBy(sy);
  qipan[m][n]=0;
  qipan[sx][sy]=1;
  System.out.println("hava exchange 1");
  invalidate();
  isSelected=false;
  isFirstChoice=true;
  successMove=true;
  return true;
  }
  }
  return false;
  }
  protected boolean eatPwan(int m, int n, int sx, int sy){
  for(int i=0;i<blist.size();i++){
  Pwan bin = blist.get(i);
  if(bin.getBx()==sx&&bin.getBy()==sy){//被吃到的时候,当然只能吃bin,不能是自己的
  if(bin.getBin().equals(chessImage[1])){
  blist.remove(i);
  qipan[sx][sy]=0;
  sum--;
  showMessage("吃掉一个小兵!");
  if(sum==1){
  showDialog("大炮");
  }
  }else{
  //System.out.println("can not eat
  showDialog("不能吃自己");
  break;
  }
  }
  }
  for(int i=0;i<blist.size();i++){
  if(bin.getBx()==m&&bin.getBy()==n&&(qipan[sx][sy]==0)){
  bin.setBx(sx);//交换位置
  bin.setBy(sy);
  qipan[m][n]=0;
  qipan[sx][sy]=1;
  invalidate();
  System.out.println("hava exchange 2");
  isSelected=false;
  isFirstChoice=true;
  successMove=true;
  return true;
  }
  }
  return false;
  }
  }


下载: 大炮小兵源码解析代码

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值