简单的贪吃蛇游戏
效果图:
游戏中图片
游戏失败
部分源码:
SnackView
// 屏幕的高度和宽度 private int screenHeight; private int screenWidth; // 每个小格子的高度和宽度 private int eachHeight; private int eachWidth; private Snack snack; private Food food; private Timer timer = new Timer(); Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { moveSnack(); invalidate(); } }; public SnackView(Context context) { super(context); this.context = context; // 获得屏幕的高和宽 DisplayMetrics metrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(metrics); screenHeight = metrics.heightPixels; screenWidth = metrics.widthPixels; eachHeight = screenHeight / 32; eachWidth = screenWidth / 20; // 初始化图片 headBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.head); bodyBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.body); foodBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.food); this.initSnack(); this.initFood(); gameRun(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint();// 定义画笔 paint.setColor(Color.GRAY);// 设置画笔颜色 paint.setAntiAlias(true);// 去除锯齿 paint.setStyle(Style.STROKE);// 设置空心实心 paint.setTextSize(40); drawLines(canvas, paint); if(isCollide()){ canvas.drawText("Game Over!", screenWidth/4, screenHeight/3, paint); timer.cancel(); }else{ this.drawSnack(canvas, paint); } boolean flag = IsRectCollision(snack.getHead().getPointX(), snack .getHead().getPointY(), eachWidth, eachHeight, food.getPointX(), food.getPointY(), eachWidth, eachHeight); if (flag) { food = null; snack.getBodyList().add(new Body()); this.initFood(); } else { this.drawFood(canvas, paint); } } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int x = (int) event.getX(); int y = (int) event.getY(); SnackDirection nowDir = snack.getSnackDirection(); int m = -800 * x + 800 * 480 - 480 * y; int n = 800 * x - 480 * y; if ((m > 0 && n > 0) && (nowDir != SnackDirection.DOWN)) { snack.setSnackDirection(SnackDirection.UP); } else if ((m > 0 && n < 0) && (nowDir != SnackDirection.RIGHT)) { snack.setSnackDirection(SnackDirection.LEFT); } else if ((m < 0 && n > 0) && (nowDir != SnackDirection.LEFT)) { snack.setSnackDirection(SnackDirection.RIGHT); } else if ((m < 0 && n < 0) && (nowDir != SnackDirection.UP)) { snack.setSnackDirection(SnackDirection.DOWN); } return super.onTouchEvent(event); } public void gameRun() { timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub handler.obtainMessage().sendToTarget(); } }, 100, 400); } /* * 画网格线 */ public void drawLines(Canvas canvas, Paint paint) { int startX = 0, startY = 0; for (int i = 0; i < 100; i++) { canvas.drawLine(0, startY, screenWidth, startY, paint); startY = startY + eachHeight; } for (int i = 0; i < 100; i++) { canvas.drawLine(startX, 0, startX, screenHeight, paint); startX = startX + eachWidth; } canvas.drawLine(0, 0, screenWidth, screenHeight, paint); canvas.drawLine(0, screenHeight, screenWidth, 0, paint); } // 初始化蛇 public void initSnack() { List<Body> bodies = new ArrayList<Body>(); Head head = new Head(eachWidth * 2, eachHeight * 2, headBitmap); Body body1 = new Body(eachWidth * 1, eachHeight * 2, bodyBitmap); Body body2 = new Body(eachWidth * 0, eachHeight * 2, bodyBitmap); bodies.add(body1); bodies.add(body2); snack = new Snack(head, bodies, SnackDirection.RIGHT); } // 画蛇 public void drawSnack(Canvas canvas, Paint paint) { canvas.drawBitmap(headBitmap, snack.getHead().getPointX(), snack .getHead().getPointY(), paint); for (int i = 0; i < snack.getBodyList().size(); i++) { canvas.drawBitmap(bodyBitmap, snack.getBodyList().get(i) .getPointX(), snack.getBodyList().get(i).getPointY(), paint); } } // 改变蛇身的位置 public void changSnackPosition(int pointX, int pointY) { for (int i = snack.getBodyList().size() - 1; i > 0; i--) { snack.getBodyList().get(i) .setPointX(snack.getBodyList().get(i - 1).getPointX()); snack.getBodyList().get(i) .setPointY(snack.getBodyList().get(i - 1).getPointY()); } snack.getBodyList().get(0).setPointX(snack.getHead().getPointX()); snack.getBodyList().get(0).setPointY(snack.getHead().getPointY()); } // 移动蛇 public void moveSnack() { int nowPointX = snack.getHead().getPointX(); int nowPointY = snack.getHead().getPointY(); if (snack.getSnackDirection() == SnackDirection.RIGHT) { changSnackPosition(nowPointX, nowPointY); if (nowPointX >= screenWidth - eachWidth) { snack.getHead().setPointX(0); } else { snack.getHead().setPointX(nowPointX + eachWidth); } } else if (snack.getSnackDirection() == SnackDirection.DOWN) { changSnackPosition(nowPointX, nowPointY); if (nowPointY >= screenHeight - eachHeight) { snack.getHead().setPointY(0); } else { snack.getHead().setPointY(nowPointY + eachHeight); } } else if (snack.getSnackDirection() == SnackDirection.LEFT) { changSnackPosition(nowPointX, nowPointY); if (nowPointX <= 0) { snack.getHead().setPointX(screenWidth - eachWidth); } else { snack.getHead().setPointX(nowPointX - eachWidth); } } else if (snack.getSnackDirection() == SnackDirection.UP) { changSnackPosition(nowPointX, nowPointY); if (nowPointY <= 0) { snack.getHead().setPointY(screenHeight - eachHeight); } else { snack.getHead().setPointY(nowPointY - eachHeight); } } } // 初始化food public void initFood() { int x = new Random().nextInt(20); int y = new Random().nextInt(30); food = new Food(eachWidth * x, eachHeight * y, foodBitmap); } // 在界面上画出Food public void drawFood(Canvas canvas, Paint paint) { if (food != null) { canvas.drawBitmap(foodBitmap, food.getPointX(), food.getPointY(), paint); } } /** * 矩形碰撞检测 参数为x,y,width,height * * @param x1 * 第一个矩形的x * @param y1 * 第一个矩形的y * @param w1 * 第一个矩形的w * @param h1 * 第一个矩形的h * @param x2 * 第二个矩形的x * @param y2 * 第二个矩形的y * @param w2 * 第二个矩形的w * @param h2 * 第二个矩形的h * @return 是否碰撞 */ public boolean IsRectCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { if (x2 > x1 && x2 >= x1 + w1) { return false; } else if (x2 < x1 && x2 <= x1 - w2) { return false; } else if (y2 > y1 && y2 >= y1 + h1) { return false; } else if (y2 < y1 && y2 <= y1 - h2) { return false; } else { return true; } } //检测蛇头是否与蛇身碰撞 public boolean isCollide() { boolean flag = false; for (int i = 0; i < snack.getBodyList().size(); i++) { flag = IsRectCollision(snack.getHead().getPointX(), snack.getHead() .getPointY(), eachWidth, eachHeight, snack.getBodyList() .get(i).getPointX(), snack.getBodyList().get(i).getPointY(), eachWidth, eachHeight); if(flag){ break; } } return flag; } }
源码下载:android_snack.rar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构