项目准备

需求分析

实现贪吃蛇的基本功能并加以拓展

编程语言及开发工具

JAVA,IDEA

项目软件概述

界面

功能

1.能正常实现贪吃蛇的基本功能

2.蛇初始的颜色为白色,食物的颜色是随机的,蛇在吃到食物后会变成与食物一样的颜色

3.空格键控制开始、暂停和重新开始

代码

Main类

import javax.swing.*;
import java.awt.*;
import java.util.Random;public class Main extends JFrame {Win Win;static final int Width = 530 , Height = 590;static Random random = new Random();static int r = random.nextInt(128,256);static int g = random.nextInt(128,256);static int b = random.nextInt(128,256);static Color snakeColor =Color.white;static Color foodColor =new Color(Main.r, Main.g, Main.b);Main() {super("贪吃蛇");Win = new Win();//在JFrame窗口容器里添加其他组件add(Win);//设置组件的大小this.setSize(Width, Height);//设置组件的可见性this.setVisible(true);//设置组件的位置this.setLocationRelativeTo(null);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);}public static void main(String[] args) {new Main();}
}

Win类

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;public class Win extends JPanel implements ActionListener, KeyListener {//     用数字代表方向static final int Up = 0 , Down = 1 , Left = 2 , Right = 3;//    GameWidth/GameHeight :游戏区域的宽、高//    GameLocX / GameLocY:游戏区域的左上角位置的坐标static final int GameLocX = 10, GameLocY = 50 , GameWidth = 500 , GameHeight = 500 , Size = 20;//Size:每次移动的位置大小以及增加的长度//    rx,ry:食物的坐标static int rx , ry , score = 0 , speed = 5;static boolean startFlag = false;static JButton startButton , stopButton;Snake snake;public Win() {snake = new Snake();//  随机初始化食物的位置rx = (int)(Math.random() * (GameWidth - 20) + GameLocX);ry = (int)(Math.random() * (GameHeight - 20) + GameLocY);rx-=rx%10;if(rx%20==0){rx-=10;}ry-=ry%10;if(ry%20==0){ry-=10;}startButton = new JButton("开始");stopButton = new JButton("暂停");setLayout(new FlowLayout(FlowLayout.LEFT));// 添加两个按键:开始、暂停this.add(startButton);this.add(stopButton);// 添加两个按键的监听事件startButton.addActionListener(this);stopButton.addActionListener(this);this.addKeyListener(this);new Thread(new snackThread()).start();}public void paint(Graphics g) {super.paint(g);
//        设置画笔颜色g.setColor(Color.black);g.fillRect(GameLocX, GameLocY, GameWidth, GameHeight);g.setColor(Color.GRAY);g.drawRect(GameLocX, GameLocY, GameWidth, GameHeight);//网格线for(int i=1;i<=24;i++){//画横线g.drawLine(GameLocX,GameLocY+i*20,GameLocX+GameWidth,GameLocY+i*20);//画竖线g.drawLine(GameLocX+i*20,GameLocY,GameLocX+i*20,GameLocY+GameHeight);}
//        绘制字符串g.drawString("按下空格开始/暂停/重新开始         "+"分数: " + score + "    速度: " + speed, 150, 25);g.setColor(Main.foodColor);g.fillRect(rx, ry, 20, 20);
//        画蛇snake.draw(g);}public void actionPerformed(ActionEvent e) {
//      当开始按钮被点击时,开始按钮将不能再被点击if(e.getSource() == startButton) {startFlag = true;startButton.setEnabled(false);stopButton.setEnabled(true);}if(e.getSource() == stopButton) {startFlag = false;startButton.setEnabled(true);stopButton.setEnabled(false);}this.requestFocus();}public void keyPressed(KeyEvent e) {if(e.getKeyCode()==KeyEvent.VK_SPACE){if(Snake.Dead()){Main.snakeColor =Color.white;Snake.curDir = 3;Snake.lt.clear();Snake.lt.add(new Node(350 , 250));}else {if (startFlag) {startFlag = false;startButton.setEnabled(true);stopButton.setEnabled(false);} else {startFlag = true;startButton.setEnabled(false);stopButton.setEnabled(true);}}}
//     当还没按下开始按钮时,按键不可用if(!startFlag)return ;switch (e.getKeyCode()) {
//         如果蛇的长度为1,则表示刚开始,什么方向都可以;
//         若蛇的长度不为1,则表示它在运动,此时不能操作它向反方向运动case KeyEvent.VK_UP -> {if (snake.length() != 1 && snake.getDir() == Down) {break;}snake.changeDir(Up);}case KeyEvent.VK_DOWN -> {if (snake.length() != 1 && snake.getDir() == Up) {break;}snake.changeDir(Down);}case KeyEvent.VK_LEFT -> {if (snake.length() != 1 && snake.getDir() == Right) {break;}snake.changeDir(Left);}case KeyEvent.VK_RIGHT -> {if (snake.length() != 1 && snake.getDir() == Left) {break;}snake.changeDir(Right);}}}public void keyReleased(KeyEvent e) {}public void keyTyped(KeyEvent e) {}class snackThread implements Runnable {public void run() {while(true) {try {
//                  通过线程休眠时间控制蛇的速度Thread.sleep(Math.max(130 - speed, 50));repaint(); // 调用paint(),重绘组件(刷新界面)if(startFlag) {snake.move();}}catch(InterruptedException e) {e.printStackTrace();}}}}
}

Snake类

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;class Node {private int x , y;public Node() {}public Node(int a , int b){x = a;y = b;}public Node(Node tmp) {x = tmp.getX();y = tmp.getY();}int getX() {return x;}int getY() {return y;}
}
public class Snake {static final int[][] DIR = {{0 , -1} , {0 , 1} , {-1 , 0} , {1 , 0}};static final List<Node> lt = new ArrayList<Node>();static int curDir; //当前运动方向public Snake() {curDir = 3;lt.add(new Node(350 , 250));}int length() {return lt.size();}int getDir() {return curDir;}void draw(Graphics g){for (Node node : lt) {g.setColor(Main.snakeColor);g.fillRect(node.getX(), node.getY(), 20, 20);}}public static boolean Dead() {for(int i = 1; i < lt.size(); i++) {if(lt.get(0).getX() == lt.get(i).getX() && lt.get(0).getY() == lt.get(i).getY())return true;}int tx = lt.get(0).getX() + Win.Size * DIR[curDir][0];int ty = lt.get(0).getY() + Win.Size * DIR[curDir][1];if(tx > Win.GameLocX + Win.GameWidth - Win.Size+20)return true;if(tx < Win.GameLocX-20)return true;if(ty > Win.GameLocY + Win.GameHeight - Win.Size+20)return true;if(ty < Win.GameLocY-20)return true;return false;}Node headMove(){
//      当向上或向下时,curDir为0/1,此时X轴不变(即 snackWin.Size * DIR[curDir][0]的值为0),Y轴变化
//      当向左或向右时,curDir为2/3,此时Y轴不变(即 snackWin.Size * DIR[curDir][1]的值为0),X轴变化int tx = lt.get(0).getX() + Win.Size * DIR[curDir][0];int ty = lt.get(0).getY() + Win.Size * DIR[curDir][1];return new Node(tx, ty);}public void move(){
//      头部的位置Node head = headMove();
//    新添加的节点Node newNode = new Node();boolean eat = false;//     abs()返回参数的绝对值
//     通过判断头部的X/Y坐标位置和食物的X/Y坐标位置,由于头部大小是20,故距离小于20就代表吃到了if(Math.abs(head.getX() - Win.rx) < 20 && Math.abs(head.getY() - Win.ry) < 20) {eat = true;newNode = new Node(lt.get(lt.size() - 1));Win.rx = (int)(Math.random() * (Win.GameWidth - 20) + Win.GameLocX);Win.ry = (int)(Math.random() * (Win.GameHeight - 20) + Win.GameLocY);Win.rx-= Win.rx%10;if(Win.rx%20==0){Win.rx-=10;}Win.ry-= Win.ry%10;if(Win.ry%20==0){Win.ry-=10;}for(int i = 1; i < lt.size(); i++) {if(Win.rx == lt.get(i).getX() && Win.ry == lt.get(i).getY()){Win.rx = (int)(Math.random() * (Win.GameWidth - 20) + Win.GameLocX);Win.ry = (int)(Math.random() * (Win.GameHeight - 20) + Win.GameLocY);Win.rx-= Win.rx%10;if(Win.rx%20==0){Win.rx-=10;}Win.ry-= Win.ry%10;if(Win.ry%20==0){Win.ry-=10;}}}}//      把前一个点的位置给后一点(即移动)for(int i = lt.size() - 1; i > 0; i--){lt.set(i, lt.get(i - 1));}lt.set(0, head);if(Dead()) {Win.score = 0 ; Win.speed = 5;Main.snakeColor=new Color(255,255,255);Win.startFlag = false;Win.startButton.setEnabled(true);Win.stopButton.setEnabled(false);}
//        如果吃到了食物,则eat为true。此时添加节点、分数加一,速度加一,将蛇的颜色变为食物的颜色,然后再随机生成一个食物颜色if(eat) {lt.add(newNode);Win.score++;Win.speed++;Main.snakeColor = Main.foodColor;Main.foodColor =new Color(Main.r, Main.g, Main.b);Random random = new Random();Main.r = random.nextInt(50,256);Main.g = random.nextInt(50,256);Main.b = random.nextInt(50,256);}}void changeDir(int dir) {curDir = dir;}}

软件技术实习项目二 会变色的贪吃蛇相关推荐

  1. 计算机软件技术实习项目二(一) 贪吃蛇项目准备

    计算机软件技术实习项目二(一) 贪吃蛇项目准备 文章目录 计算机软件技术实习项目二(一) 贪吃蛇项目准备 一.贪吃蛇介绍 二.开发工具 三.实现原理 1.消息与消息队列 2.消息映射 3.设备环境 4 ...

  2. 软件技术实习项目:实验二、贪吃蛇游戏

    目录 1.系统简介 1.1设计背景 1.2开发工具及环境 2.系统分析与设计 2.1设计目的 2.2功能需求 2.3系统功能代码设计 2.3.1包和类的说明 2.3.2简单计算器的源代码清单 3.系统 ...

  3. 软件技术实习项目:实验三、迷宫游戏设计

    目录 1.系统简介 1.1设计背景 1.2开发工具及环境 2.系统分析与设计 2.1设计目的 2.2功能需求 2.3系统功能代码设计 2.3.1算法说明 3.系统调试 3.1编写源程序界面 4.设计总 ...

  4. 项目二 Visual studio 实现贪吃蛇C++

    一 实现过程中遇到的问题及相关代码: 1.error C2665: "outtextxy": 2 个重载中没有一个可以转换所有参数类型 错误原因 VC6 默认使用的 MBCS 编码 ...

  5. 软件技术实习项目三 迷宫

    1.实习内容 1) 迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫: 2) 要求查找并理解迷宫生成的算法,并尝试用两种不同的算法来生成随机的迷宫. 3) 要求迷宫游戏支持玩家走迷宫 ...

  6. 【使用java swing制作简易贪吃蛇游戏】软件实习项目二

    一.项目准备 需求分析: 实现贪吃蛇游戏基本功能,屏幕上随机出现一个"食物",称为豆子,上下左右控制"蛇"的移动,吃到"豆子"以后" ...

  7. 软件技术实习_当您还在学校时,如何获得一流的技术实习机会和技术工作

    软件技术实习 by Michael Deng 邓小平 当您还在学校时,如何获得一流的技术实习机会和技术工作 (How to land a top-notch tech internship - and ...

  8. 华为无线通用软件开发 实习一面二面

    2022年秋招/春招/提前批/大厂面经整理(持续更新中~) 华为无线通用软件开发 实习一面二面 一面 50min 1.自我介绍(自己介绍了一下专业.院校.成绩.做过的项目.参加的竞赛) 2.面试官:你 ...

  9. 计算机软件技术实习 项目一 简单计算器的实现(实验准备)1-(1)

    目录 一.需求分析 二.重难点 三.编程语言 四.开发工具/平台 一.需求分析 1. 能通过设计的按钮控件输入并实现算术表达式,表达式在文本框中显示,运算结果输出显示: 2.保存和浏览历史运算记录: ...

最新文章

  1. Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮
  2. (转)ubuntu 文件系统
  3. 树梅派kali界面_使用树莓派和kali Linux打造便携式渗透套件
  4. Eclipse下的项目管理插件介绍
  5. Project查看资源分配情况
  6. eclipse java source_Eclipse中查看JAVA源代码显示SOURCE NOT FOUND解决办法
  7. 读书笔记——Accelerated C++ Chapter 12 使类对象获得数值功能
  8. 【Spark】Spark的Kryo序列化
  9. AGC 019F.Yes or No(思路 组合)
  10. 【python】字符串的操作与方法、元组的定义与操作
  11. linux 软连接【转】
  12. dlink虚拟服务器端口转发,D-Link路由器端口转发怎么设置【图文教程】
  13. 使用foobar2000将cue文件分割wav、ape、flac无损音乐
  14. mac环境下Android 反编译
  15. JVM HotSpot 可达性分析算法实现细节
  16. Spire.Office for .NET 7.9.2 去掉license.dll注册功能
  17. 【VUE3】Hash模式与HTML5模式使用区别
  18. Python-pip 安装与使用
  19. android studio卸载找不到uninstall
  20. AppOps 命令大全

热门文章

  1. java建立http_java-创建一个HttpEntity
  2. Spring与Serverless 相关服务了解
  3. 1951年-2019年重庆天气分析
  4. 数据科学统计学:什么是偏度?
  5. Linux下使用crontab定时重启java服务
  6. python savefig_解决Python plt.savefig 保存图片时一片空白的问题
  7. 【云周刊】第189期:在云栖大会上服务了12万人的“刷脸”技术,将如何赋能零售行业?...
  8. 前端ssr跟ssg的区别
  9. HTML5期末大作业:电竞游戏网站设计——电竞游戏介绍响应式网页(7页) HTML+CSS+JavaScript
  10. 互联网早报:微信红包封面升级:支持个人定制...