用Java写一个贪吃蛇游戏

目录

创建窗体

创建游戏棋盘

创建蛇的节点

创建蛇身

让蛇移动

添加键盘监听

添加边界处理

把食物绘制到棋盘上

吃食物


创建窗体

创建一个MainFrame类继承JFrame,表示主窗体。

public class MainFrame extends JFrame {//创建窗体对象时,初始化船体参数public MainFrame(){initFrame();}
}

MainFrame类中写一个initFrame方法,初始化窗体参数

//1.初始化窗体参数
private void initFrame() {//设置窗体标题setTitle("黑马贪吃蛇");//设置窗体大小setSize(610, 640);//设置窗体位置setLocation(400, 400);//设置窗体大小不能改变setResizable(false);//设置窗体关闭按钮的作用,是正常退出setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

在MainFrame中添加一个main方法,创建窗体并运行,就可以看到窗体了

//主方法
public static void main(String[] args) {//创建窗体,并显示在屏幕上new MainFrame().setVisible(true);
}

创建游戏棋盘

在JFrame类中写一个initGamePanel方法,初始化游戏棋盘

//初始化游戏面板
private void initGamePanel() {JPanel jPanel = new JPanel() {//paint是用来绘制面板中的内容@Overridepublic void paint(Graphics g) {//设置画笔颜色g.setColor(Color.black); //设置画笔颜色是黑色//绘制40条横线(起点横坐标,起点纵坐标,终点横坐标,终点纵坐标)for(int i=1;i<=40;i++){g.drawLine(0,15*i,600,15*i);}//绘制40条竖线for (int i=1;i<=40;i++){g.drawLine(15*i,0,15*i,600);}}};add(jPanel);
}

创建蛇的节点

创建一个Node类表示节点,一条蛇有若干个节点组成,每一个节点其实就是一个小方格,我们用行和列来定义节点在棋盘中的位置。

public class Node {private int x; //横坐标private int y; //纵坐标public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}
}

创建蛇身

创建Snake类表示蛇,一条蛇有多个节点使用LinkedList集合存储Node节点,蛇出生的时候 有3个节点。

public class Snake {//bodyprivate LinkedList<Node> body;//创建蛇对象时,初始化蛇身public Snake() {initSnake();}//初始化蛇身 3个节点public void initSnake(){//创建蛇的躯体body=new LinkedList<>();//给蛇添加3个节点,在棋盘的中心位置横向排列body.add(new Node(20,20));body.add(new Node(21,20));body.add(new Node(22,20));}//获取蛇蛇身public LinkedList<Node> getBody(){return body;}
}

把蛇绘制到棋盘上

在MainFrame中添加一个创建Snake的成员变量,表示窗体中有一条蛇

public class MainFrame extends JFrame {//定义成员变量private Snake snake=new Snake();....
}

在绘制棋盘的paint方法中,添加下面的代码绘制把蛇绘制到棋盘上

//绘制横线
...
//绘制竖线
...//绘制蛇,根据每一个节点的坐标在棋盘上绘制矩形
for (Node node : snake.getBody()) {//每一个节点的宽度和高度是15g.fillRect(node.getX()*15,node.getY()*15,15,15);
} 

 再次运行,就可以看到有一条蛇静静的躺在棋盘中间了

让蛇移动

定义一个枚举类型,表示运动的4个方向

public enum  Direction {UP,DOWN,LEFT,RIGHT
}

在Snake类中定义一个移动方向的变量成员变量,和move方法。

public class Snake{//蛇头运动的方向private Direction direction;//移动的方法: 每次移动在蛇头运动方向添加一个节点,再删除最后一个节点public void move(){//获取蛇头的节点Node head = body.getFirst();//新的蛇头节点Node newHead=null;//检查移动的方向switch (direction){//如果向左移动case LEFT://创建一个新的蛇头节点newHead=new Node(head.getX()-1,head.getY());//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);//删除蛇尾body.removeLast();break;case RIGHT://创建一个新的蛇头节点newHead=new Node(head.getX()-1,head.getY());//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);//删除蛇尾body.removeLast();break;case UP://创建一个新的蛇头节点newHead=new Node(head.getX(),head.getY()-1);//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);//删除蛇尾body.removeLast();break;case DOWN://创建一个新的蛇头节点newHead=new Node(head.getX(),head.getY()+1);//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);//删除蛇尾body.removeLast();break;}}
}

 在MainFrame类中,创建一个定时器每100毫秒,重绘游戏棋盘

public class MainFrame extends JFrame {...//游戏棋盘面板JPanel jPanel=null;//定义定时器private Timer timer;public MainFrame() throws HeadlessException {//初始化窗体参数initFrame();//初始化窗体中的游戏面板initGamePanel();//初始化定时器initTimer();}//2.初始化游戏棋盘private void initGamePanel() {jPanel = new JPanel() {//paint是用来绘制面板中的内容@Overridepublic void paint(Graphics g) {//每次重绘时清空面板中的内容g.clearRect(0,0,getWidth(),getHeight());....}};add(jPanel);}//3.初始化定时器private void initTimer() {TimerTask task=new TimerTask() {@Overridepublic void run() {//调用蛇移动的方法snake.move();//每次移动重绘游戏棋盘,会自动调用jPanel的paint方法jPanel.repaint();}};timer=new Timer();timer.scheduleAtFixedRate(task,0,100);}
}

添加键盘监听

在MainFrame类中,添加一个setKeyListener的方法,监听上下左右四个键

public class MainFrame extends JFrame {...public MainFrame() throws HeadlessException {...//添加键盘监听setkeyListener();}//添加键盘监听private void setkeyListener() {//对上下左右键进行监听addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {switch (e.getKeyCode()){//按下上键case KeyEvent.VK_UP://蛇头方向改为上snake.setDirection(Direction.UP);break;//按下下键case KeyEvent.VK_DOWN://蛇头方向改为下snake.setDirection(Direction.DOWN);break;//按下左键case KeyEvent.VK_LEFT://蛇头方向改为左snake.setDirection(Direction.LEFT);break;//按下右键case KeyEvent.VK_RIGHT://蛇头方向改为右snake.setDirection(Direction.RIGHT);break;}}});}
}

到此蛇就可以跟随键盘移动了

添加边界处理

当蛇移动到边界处就游戏结束,把标记改为false

public class Snake{...//定义一个标记true表示蛇是活的,可以运动private boolean isLive=true;//检查蛇是否碰壁private void checkOver() {//获取蛇头Node head = body.getFirst();int x=head.getX();int y=head.getY();if(x<0||y<0||x>=40||y>=40){isLive=false;}}
}

在定时器中调用checkOver()方法

//3.初始化定时器
private void initTimer() {TimerTask task=new TimerTask() {@Overridepublic void run() {//移动snake.move();//检查是否碰壁snake.checkOver();}};timer=new Timer();timer.scheduleAtFixedRate(task,0,100);
}

把食物绘制到棋盘上

创建一个Food类表示食物,其实食物也是一个节点,所以让Food继承Node

public class Food extends Node {//创建食物的时候,随机产生一个位置public Food() {reset();}//随产生位置public void reset(){//随机生成食物的坐标Random r=new Random();setX(r.nextInt(40));setY(r.nextInt(40));}
}

在MainFrame中定义一个成员Food表示食物,并把食物绘制到棋盘上

public class MainFrame extends JFrame {//定义食物private Node food=new Node();public MainFrame() throws HeadlessException {//初始化窗体参数initFrame();//初始化窗体中的游戏面板initGamePanel();//初始化定时器initTimer();//添加键盘监听setkeyListener();}//2.初始化游戏棋盘private void initGamePanel() {jPanel = new JPanel() {//paint是用来绘制面板中的内容@Overridepublic void paint(Graphics g) {//清空棋盘g.clearRect(0,0,600,600);//绘制横线、绘制竖线、绘制蛇//绘制食物g.fillRect(food.getX()*15,food.getY()*15,15,15);}};add(jPanel);}
}

吃食物

在Snake类中添加一个eatFood方法

//吃食物
public void eatFood() {//获取蛇头Node head = body.getFirst();//如果蛇头和食物的位置重合,就在蛇头添加一个元素if(head.getX()==MainFrame.food.getX()&&head.getY()==MainFrame.food.getY()){//沿着蛇头运动方向创建一个节点//新的蛇头节点Node newHead=null;//检查移动的方向switch (direction){//如果向左移动case LEFT://创建一个新的蛇头节点newHead=new Node(head.getX()-1,head.getY());//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);break;case RIGHT://创建一个新的蛇头节点newHead=new Node(head.getX()+1,head.getY());//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);break;case UP://创建一个新的蛇头节点newHead=new Node(head.getX(),head.getY()-1);//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);break;case DOWN://创建一个新的蛇头节点newHead=new Node(head.getX(),head.getY()+1);//把心得蛇头节点添加到body的第一个元素body.addFirst(newHead);break;}//每次吃完食物,让食物重置MainFrame.food.reset();}
}

在定时器中调用吃食物的方法

//2.初始化游戏棋盘
private void initGamePanel() {jPanel = new JPanel() {//paint是用来绘制面板中的内容@Overridepublic void paint(Graphics g) {//清空棋盘g.clearRect(0,0,600,600);//绘制横线、绘制竖线、绘制蛇//绘制食物g.fillRect(food.getX()*15,food.getY()*15,15,15);}};add(jPanel);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/147874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 字母异位词分组 哈表 集合

&#x1f468;‍&#x1f3eb; 力扣 字母异位词分组 ⭐ 思路 由于互为字母异位词的两个字符串包含的字母相同&#xff0c;因此对两个字符串分别进行排序之后得到的字符串一定是相同的&#xff0c;故可以将排序之后的字符串作为哈希表的键。 &#x1f351; AC code class Solut…

解析Spring Boot中的CommandLineRunner和ApplicationRunner:用法、区别和适用场景详解

在Spring Boot应用程序中&#xff0c;CommandLineRunner和ApplicationRunner是两个重要的接口&#xff0c;它们允许我们在应用程序启动后执行一些初始化任务。本文将介绍CommandLineRunner和ApplicationRunner的区别&#xff0c;并提供代码示例和使用场景&#xff0c;让我们更好…

阿里云配置ssl(Apache)

阿里云申请证书&#xff0c;有个专门的免费的申请方式与普通证书是平级的功能&#xff1b; 访问服务器&#xff0c;判断apache是不是开启ssl功能&#xff0c;如果没有安装就安装它 [rootcentos ~]# rpm -qa | grep mod_ssl //什么没显示说明没装 yum install mod_ssl openssl …

公共字段自动填充-@TableField的fill实现(2)

TheadLocal 客户端发送的每次http请求&#xff0c;在服务端都会分配新的线程。因此登录检查过滤器、controller、元数据对象处理器属于一个线程。 TheadLocal是线程的局部变量&#xff1a; TheadLocal常用方法&#xff1a; 如何在元数据对象处理器中获取当前登录用户的id&…

大数据专业有哪些基础的理论和技术

大数据专业有哪些基础的理论和技术 大数据专业涉及的基础理论和技术很广泛&#xff0c;主要包括以下几个方面&#xff1a; 数据管理与处理理论&#xff1a;大数据处理涉及到海量数据的管理、存储和处理&#xff0c;因此数据库理论、数据结构与算法、数据压缩与索引等知识是非常…

Spring Boot 项目部署方案!打包 + Shell 脚本部署详解

文章目录 概要一 、profiles指定不同环境的配置二、maven-assembly-plugin打发布压缩包三、 分享shenniu_publish.sh程序启动工具四、linux上使用shenniu_publish.sh启动程序 概要 本篇和大家分享的是springboot打包并结合shell脚本命令部署&#xff0c;重点在分享一个shell程…

【MATLAB源码-第83期】基于matlab的MIMO中V-BALST结构ZF和MMSE检测算法性能误码率对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在多输入多输出&#xff08;MIMO&#xff09;通信系统中&#xff0c;V-BLAST&#xff08;垂直波束形成层间空间时间编码技术&#xff09;是一种流行的技术&#xff0c;用于提高无线通信的数据传输速率和容量。它通过在不同的…

如何将 Docsify 项目部署到 CentOS 系统的 Nginx 中

文章目录 第一步&#xff1a;准备 CentOS 服务器第二步&#xff1a;安装 Node.js 和 Docsify第三步&#xff1a;初始化 Docsify 项目第四步&#xff1a;本地预览 Docsify 项目第五步&#xff1a;配置 Nginx 服务器第六步&#xff1a;重启 Nginx 服务器拓展&#xff1a;使用 HTT…

k8s-部署Redis-cluster(TLS)

helm pull bitnami/redis-cluster v8.3.8拉取源码生成证书 git clone https://github.com/redis/redis.git #文档 https://redis.io/docs/management/security/encryption/#getting-started生成你的TLS证书用官网的工具生成 1 Run ./utils/gen-test-certs.sh 生成根CA和服务…

Python 如何实现备忘录设计模式?什么是备忘录设计模式?Python 备忘录设计模式示例代码

什么是备忘录&#xff08;Memento&#xff09;设计模式&#xff1f; 备忘录&#xff08;Memento&#xff09;设计模式是一种行为型设计模式&#xff0c;用于捕获一个对象的内部状态&#xff0c;并在对象之外保存这个状态&#xff0c;以便在需要时恢复对象到先前的状态。这种模…

JAVA for 循环训练 Pattern

import java.util.Scanner;public class Pattern {public static void main(String[] args) {int[] arr {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};Scanner in new Scanner(System.in);System.out.print("请输入n:");int n in.nextInt();in.close();for …

【小沐学GIS】电子海图OpenCPN源代码编译和运行(VS2017 + Win10)

1、简介 免费的开源海图仪和船用GPS导航软件 https://opencpn.org/ 1.1 OpenCPN概述 OpenCPN是一款自由软件&#xff08;GPLv2&#xff09;&#xff0c;用于创建简洁的海图绘图仪和导航软件&#xff0c;可以在航行过程中使用或者作为计划工具。OpenCPN提供大量免费海图下载&a…

「项目阅读系列」go-gin-example star 6.5k!(1)

文章目录 准备工作适宜人群项目信息 项目结构代码阅读主要模块代码主函数模块router 路由模块auth 授权模块数据库 修改文章请求分析其他依赖 总结 准备工作 适宜人群 初学 go 语法&#xff0c;希望了解 go 项目的构建过程和方式。 项目信息 go-gin-example 项目是使用 gin…

037、目标检测-SSD实现

之——简单实现 目录 之——简单实现 杂谈 正文 1.类别预测层 2.边界框预测 3.多尺度输出联结做预测&#xff08;提高预测效率&#xff09; 4.多尺度实现 5.基本网络块 6.完整模型 杂谈 原理查看&#xff1a;037、目标检测-算法速览-CSDN博客 正文 1.类别预测层 类别…

Python学习(一)基础语法

文章目录 1. 入门1.1 解释器的作用1.2 下载1.3 基础语法输入输出语法与引号注释&#xff1a;变量&#xff1a; 数据类型与四则运算数据类型四则运算数据类型的查看type()数据类型的转换int()、int()、float() 流程控制格式化输出循环与遍历逻辑运算符list遍历字典dict遍历 跳出…

类模板成员函数类外实现

#include<iostream> #include<string> using namespace std;//类模板成员函数类外实现 template<class T1,class T2> class Person { public:Person(T1 name,T2 age); // { // this->m_namename; // this->m_ageage; // }void showPerson(); // { /…

HarmonyOS开发Java与ArkTS如何抉择

在“鸿蒙系统实战短视频App 从0到1掌握HarmonyOS”视频课程中&#xff0c;很多学员来问我&#xff0c;在HarmonyOS开发过程中&#xff0c;面对Java与ArkTS&#xff0c;应该选哪样&#xff1f; 本文详细分析Java与ArkTS在HarmonyOS开发过程的区别&#xff0c;力求解答学员的一些…

Navicat 基于 GaussDB 主备版的快速入门

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

12-1- GAN -简单网络-线性网络

功能 随机噪声→生成器→MINIST图像。 训练方法 0 损失函数:gan的优化目标是一个对抗损失,是二分类问题,用BCELoss 1 判别器的训练,首先固定生成器参数不变,其次判别器应当将真实图像判别为1,生成图像判别为0 loss=loss(real_out, 1)+loss(fake_out, 0) 2 生成器的…

【Linux】-进程间通信-匿名管道通信(以及模拟一个进程池)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …