package com.example.administrator.eatingjj;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by Administrator on 2017/7/22.
*/
public class Eating extends View {
private static final int UP = 2; //蛇頭移動四個方向
private static final int DOWN = 3;
private static final int LEFT = 1;
private static final int RIGHT = 0;
private int x1 = 0, y1 = 0, x2 = 0, y2 = 0; //在touch事件中用來記錄按下點和擡起點的座標
private int MoveLength = 100; //當移動的的距離超過100時,滑屏轉彎纔有效
private int time = 300; //handle事件的週期,也可理解爲蛇移動的速度
private int panWidth; //遊戲區域寬
private int panHidth; //遊戲區域高
private float panLineHeight; //格子高
private float panLineWidth; //格子寬
private float rare=(3*1.0f/4); //Bitmap的size與格子的size的比例
private int MAX_LINE =14; //橫向格子個數
private int MAXLONG_LINE=25; //縱向格子個數
private List<Point> mSnakeArray = new ArrayList<>(); //蛇身的鏈表
private Bitmap SnakeHead;
private Bitmap SnakeBody;
private Bitmap SnakeBody_rirht; //蛇身的四個朝向
private Bitmap SnakeBody_left;
private Bitmap SnakeBody_up;
private Bitmap SnakeBody_down;
private Bitmap Snakefood; //食物的圖像
private int Director=DOWN; //蛇頭前進的方向
private Point food; //食物的座標
private boolean mIsGameover; //判斷遊戲是否結束
private Paint paint = new Paint(); //畫筆
private Handler handler = new Handler() {
public void handleMessage(Message message) {
Moving();
}
};
//具體實現蛇的移動,更新蛇的鏈表,喫豆子,判斷遊戲是否結束,重繪
public void SnakeMove() {
Point snakehead = mSnakeArray.get(mSnakeArray.size() - 1);
Point next = null;
int x = snakehead.x;
int y = snakehead.y;
switch (Director) {
case UP: {
next = new Point(x, (y - 1 + MAXLONG_LINE) % MAXLONG_LINE);
break;
}
case DOWN: {
next = new Point(x, (y + 1) % MAXLONG_LINE);
break;
}
case RIGHT: {
next = new Point((x + 1) % MAX_LINE, y);
break;
}
case LEFT: {
next = new Point((x - 1 + MAX_LINE) % MAX_LINE, y);
break;
}
}
if (mSnakeArray.contains(next)) {
mIsGameover=true;
}
mSnakeArray.add(next);
mSnakeArray.remove(0);
if (mSnakeArray.contains(food)) {
mSnakeArray.add(0,food);
creatfood();
if(time>50) time-=5; //每喫一個豆子,速度提升
}
invalidate();
}
//handle週期調用的函數,用來實現蛇的自動移動,以及檢測遊戲是否結束
private void Moving() {
SnakeMove();
if(mIsGameover)
{
GameOver();
}
else
{
handler.sendEmptyMessageDelayed(1, time);
}
}
//遊戲結束時產生的對話框,退出遊戲或再來一局
private void GameOver()
{
AlertDialog.Builder builder=new AlertDialog.Builder(this.getContext());
builder.setTitle("GAME OVER");
builder.setMessage("你的長度爲 "+mSnakeArray.size()+" ! 是否重新開局?");
builder.setNegativeButton("是的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
GameAgain();
}
});
builder.setPositiveButton("退出遊戲", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
});
AlertDialog modalDialog=builder.create();
modalDialog.show();
}
//初始化畫筆
public Eating(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(0x22000000);
init();
handler.sendEmptyMessageDelayed(1, time);
}
//自定義畫筆,初始化蛇的位置
private void init() {
paint.setColor(0x40000000); //灰
paint.setAntiAlias(true); //抗鋸齒
paint.setDither(true); //防抖動
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
mSnakeArray.clear();
mSnakeArray.add(new Point(MAX_LINE-2, 1));
mSnakeArray.add(new Point(MAX_LINE-2, 2));
mSnakeArray.add(new Point(MAX_LINE-2, 3));
SnakeBody_rirht = BitmapFactory.decodeResource(getResources(), R.drawable.shi1);
SnakeBody_down = BitmapFactory.decodeResource(getResources(), R.drawable.shi2);
SnakeBody_up = BitmapFactory.decodeResource(getResources(), R.drawable.shi3);
SnakeBody_left = BitmapFactory.decodeResource(getResources(), R.drawable.shi4);
SnakeBody = SnakeBody_down;
SnakeHead = SnakeBody_down;
Snakefood = BitmapFactory.decodeResource(getResources(), R.drawable.food);
}
//設置自定義控件的高度和寬度,這裏設置爲全屏
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(widthSize,heightSize);
}
//設置棋盤的寬度和格子寬度,以及Bitmap的size
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
panWidth = w;
panHidth = h;
panLineWidth = (panWidth * 1.0f) / MAX_LINE;
panLineHeight=(panHidth*1.0f)/MAXLONG_LINE;
creatfood(); //遊戲開始時,出現第一個食物
SnakeBody = Bitmap.createScaledBitmap(SnakeBody, (int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f), false);
SnakeBody_left = Bitmap.createScaledBitmap(SnakeBody_left, (int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f),false);
SnakeBody_rirht = Bitmap.createScaledBitmap(SnakeBody_rirht,(int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f),false);
SnakeBody_up = Bitmap.createScaledBitmap(SnakeBody_up,(int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f),false);
SnakeBody_down = Bitmap.createScaledBitmap(SnakeBody_down,(int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f),false);
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
Snakefood = Bitmap.createScaledBitmap(Snakefood,(int)(panLineWidth*rare*1.0f), (int)(panLineHeight*rare*1.0f),false);
}
//touch事件,通過滑動實現上下左右轉彎
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mIsGameover) return false;
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
x1 = (int) event.getX();
y1 = (int) event.getY();
} else if (action == MotionEvent.ACTION_UP) {
x2 = (int) event.getX();
y2 = (int) event.getY();
if (Director == RIGHT || Director == LEFT) {
if (y2 - y1 >= MoveLength) {
Director = DOWN;
SnakeHead = SnakeBody_down;
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
SnakeMove();
} else if (y1 - y2 >= MoveLength) {
Director = UP;
SnakeHead = SnakeBody_up;
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
SnakeMove();
}
} else if (Director == UP || Director == DOWN) {
if (x2 - x1 >= MoveLength) {
Director = RIGHT;
SnakeHead = SnakeBody_rirht;
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
SnakeMove();
} else if (x1 - x2 >= MoveLength) {
Director = LEFT;
SnakeHead = SnakeBody_left;
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
SnakeMove();
}
}
invalidate();
}
return true;
}
//繪圖
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//drawBoard(canvas);
drawSnake(canvas);
}
//重新開局
public void GameAgain()
{
mIsGameover=false;
mSnakeArray.clear();
mSnakeArray.add(new Point(MAX_LINE-2, 1));
mSnakeArray.add(new Point(MAX_LINE-2, 2));
mSnakeArray.add(new Point(MAX_LINE-2, 3));
Director=DOWN;
time=300;
SnakeHead=SnakeBody_down;
SnakeHead = Bitmap.createScaledBitmap(SnakeHead,(int)(panLineWidth), (int)(panLineHeight),false);
handler.sendEmptyMessageDelayed(1, time);
invalidate();
Toast.makeText(getContext(),"重新開局",Toast.LENGTH_SHORT).show();
}
//設計遊戲初期時用到
private void drawBoard(Canvas canvas)
{
int w=panWidth;
int h=panHidth;
float lineheight=panLineHeight;
float linewidth=panLineWidth;
for(int i=0;i<MAXLONG_LINE;i++)
{
int startx = 0;
int endx=w;
int y=(int)(i*lineheight);
canvas.drawLine(startx,y,endx,y,paint);
}
for(int i=0;i<MAXLONG_LINE;i++)
{
int starty = 0;
int endy=h;
int y=(int)(i*linewidth);
canvas.drawLine(y,starty,y,endy,paint);
}
}
//畫食物,畫蛇身,畫蛇頭
private void drawSnake(Canvas canvas)
{
canvas.drawBitmap(Snakefood,food.x*panLineWidth+(1-rare)/2*panLineWidth,food.y*panLineHeight+(1-rare)/2*panLineWidth,null);
for(int i=0,n=mSnakeArray.size();i<n-1;i++)
{
Point snakepoint=mSnakeArray.get(i);
Point next=mSnakeArray.get(i+1);
if(snakepoint.x==next.x)
{
if((snakepoint.y+1)%MAXLONG_LINE==next.y) SnakeBody=SnakeBody_down;
else SnakeBody=SnakeBody_up;
}
else if(snakepoint.y==next.y)
{
if((snakepoint.x+1)%MAX_LINE==next.x) SnakeBody=SnakeBody_rirht;
else SnakeBody=SnakeBody_left;
}
canvas.drawBitmap(SnakeBody,snakepoint.x*panLineWidth+(1-rare)/2*panLineWidth,snakepoint.y*panLineHeight+(1-rare)/2*panLineHeight,null);
}
Point snakepoint=mSnakeArray.get(mSnakeArray.size()-1);
canvas.drawBitmap(SnakeHead,snakepoint.x*panLineWidth,snakepoint.y*panLineHeight,null);
}
//隨機產生一個食物,且食物不能出現在蛇的身上
private void creatfood()
{
food=new Point(new Random().nextInt(MAX_LINE),new Random().nextInt(MAXLONG_LINE));
while (mSnakeArray.contains(food))
{
food=new Point(new Random().nextInt(MAX_LINE),new Random().nextInt(MAXLONG_LINE));
}
}
}
Android-貪喫蛇(二)-自定義的view
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.