13/100发布文章 博文管理我的博客退出 Trash Temp Java – 贪吃蛇日志 欢迎使用CSDN-markdown编辑器 添加摘要 记录我写贪吃蛇的历程## 标题。
从接到任务到现在已经过了一个多星期了,贪吃蛇游戏我已经实现了:蛇头的移动以及游戏界面的构建。
思路:先做一个最简单的版本,实现基本的功能。在这个版本里,游戏界面由JFrame窗口嵌套两个JPanel来实现,JFrame的布局目前是采用null,等游戏的基本功能实现后会修改为合适的布局。
第一个JPanel用于构建游戏区域,采用GridLayout布局,目前已设计成2020的网格(在该JPanel中嵌套一个长度为400的JPanel数组,即小面板,小面板背景设为绿色,其长和宽为20个像素,两两之间的间距为1个像素,使用setSize()方法对大、小面板的尺寸进行设计+GridLayout布局 便能实现2020的网格)。同时此面板还要继承KeyListener实现对自身的监听。在通过对键盘的监听实现蛇头的移动时,我遇到了一个问题:当主窗口只嵌套一个面板时,蛇头的移动可以顺利实现,但是一旦主窗口嵌套了两个面板,就监听不了游戏界面的面板。看了看一些博客后我找到了原因:若我的监听器用于监听主面板,一旦主面板嵌套了一个以上的组件,我所要监听的组件便无法聚焦(第一个JPanel,即我要监听的面板,没有设置获取焦点的方法“this.setFocusable(true);”)。改良之后,我让继承了KeyListener的JPanel监听自己本身,并且设置了获取焦点的方法,这样一来即使在主面板中嵌套了多个容器,蛇头任然可以受键盘的控制而移动。以下链接是在解决焦点问题时找到的博客:解决焦点问题
以下为游戏界面的面板,其中蛇头有自己的类,记录坐标。
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;public class SnakePanel1 extends JPanel implements KeyListener{
JPanel jps[]; //定义面板数组,充当背景。
SnakeHead head; //定义蛇头
public SnakePanel1() { //构造方法
this.head = new SnakeHead();
this.setSize(419,419); //设置大面板尺寸
this.setLayout(new GridLayout(20,20,1,1)); //设置大面板布局方式:分成20*20的区域,间距为1个像素
jps = new JPanel[400]; //创建一个容量为400的JPanels数组,存放小面板
for(int i=0; i<jps.length; i++) {
jps[i] = new JPanel();
jps[i].setBackground(Color.green); //设置小面板的颜色为绿色
this.add(jps[i]); //在大面板中添加小面板
}
this.setFocusable(true); //获取焦点
addKeyListener(this); //监听自己
}
public void setColor(Color c) {
for(int i=0; i<jps.length; i++) {
jps[i].setBackground(c); //设置小面板的颜色为绿色
}
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED);
g.fillRect(this.head.getX(), this.head.getY(), 20, 20);
} @Override
public void keyPressed(KeyEvent e) { // TODO 自动生成的方法存根
int n = e.getKeyCode();
if(n == KeyEvent.VK_UP) {
head.setY(head.getY()-21);
}
else if(n == KeyEvent.VK_DOWN) {
head.setY(head.getY()+21);
}
else if(n == KeyEvent.VK_LEFT) {
head.setX(head.getX()-21);
}
else if(n == KeyEvent.VK_RIGHT) {
head.setX(head.getX()+21);
}
repaint();
} @Override
public void keyReleased(KeyEvent arg0) {
// TODO 自动生成的方法存根
} @Override
public void keyTyped(KeyEvent arg0) {
// TODO 自动生成的方法存根
}
}
总面板的效果图如下:
当然,这个界面是最初版本,相对简陋,之后会改良。
主面板嵌套的第二个面板为 按钮&信息区域,鼠标点击设置按钮会弹出一个窗口,在这个窗口中用户可以选择游戏模式,以及自定义游戏按键(这功两个能尚未实现)。
接下来我完成的任务有:
- 实现食物类的最简单版本:每个食物都有一定的分数,蛇吃掉一个食物,身体变长、得分。当蛇吃掉一个食物后,才在随机位置生成另一个食物。
- 蛇身体的增长:通过数组来实现,目前没有思路。
- 游戏结束:当且仅当蛇撞墙、或用户点击结束键时,游戏结束。
- 计算游戏时间。
- 实现 按钮&信息区域 面板。
- AI贪吃蛇。
- 保存用户的最高分以及自定义的按键设置。
- 上传最高分。