Java贪吃蛇小游戏,我家小AD从小水蛇成长为水中巨蟒!
Posted 编程界明世隐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java贪吃蛇小游戏,我家小AD从小水蛇成长为水中巨蟒!相关的知识,希望对你有一定的参考价值。
老程序员花二天时间做的Java贪吃蛇
引言:
每一个人童年时都有一个乃至数个伟大的梦想,我小时候的梦想:
1.孙悟空,因为我想成为一个降妖除魔、72变,最重要的是我想去哪就去哪,一个跟斗就起飞!
2.葫芦娃,因为分开时个个独挡一面、身怀绝技;合体时,完美无敌,想大就大、想小就小!
3.军事家,我从小比较喜欢看抗日电视剧,感觉我们国家从苦难中走出来很不容易,我那时希望自己成为军事家,能够保卫好我们的国家!
4.科学家,老师跟我们说科学家是国家栋梁!我也希望能够成为杰出的科学家,提升我们国家的科技。
5.工程师,成为一名优秀的工程师,能建设好我们的国家!
带着这些梦想,我通过十几年的努力学习,我从农村来到了城市,从学校走出来到了社会,成为了一名 IT工程师。
这样也不错,好歹也算是完成了童年的梦想,虽然算不上很优秀,但是也很努力,IT工程师也是工程师!
你们呢?小伙伴们,可以留言说说你们曾经的梦想,让大家呱唧呱唧!
我现在想做的:
1.在自己岗位上做好自己的事情,就是为国家做贡献!
2.带小AD上分,让小AD变成200斤,那种很Carry、漫天飞羽可以坐死敌人的那种!
这不小AD叫我带着上分,因为体重才90斤不到,怎么打的过?于是我决定给AD增肥,让AD从小水蛇变成巨蟒!
小AD:_明哥带我上分!快点,头输麻了
明世隐:你玩什么英雄?
小AD:我新练的英雄,很厉害,你猜猜看!
明世隐:元芳?贼厉害,我赌你的枪里没有子弹!
小AD:不,攻速很快。
明世隐:狄仁杰?现在是逮捕时间!
小AD:人家大炮。
明世隐:黄忠?大炮一架,彪悍的人生不需要解释!
小AD:no,很萌。
明世隐:兔耳朵大小姐,来一发吗,满足你。
小AD:是小鲁班。
明世隐:就这。有人需要技术支持吗; 智商二百五。我懂了,难怪你上不了分,让哥给你推荐一个新英雄。
小AD:什么英雄?
明世隐:狂蟒之灾—哥斯拉。
小AD:没听过,什么东西?好像很熟悉,名字听起来有点猛(du)
明世隐:走,哥带你练级先!
小AD:好嘞
效果图
先上最终的效果图,这里界面做的感觉不是很好看,但我觉得问题不大,功能到位就好!
实现思路
两块画布:
画布1: 用来绘制静态东西,比如游戏区边框、网格、得分区域框、时间框、按钮等,无需刷新的部分。
画布2: 用来绘制游戏动态的部分,比如 蛇、蛇的移动、食物,蛇吃食物生长、积分显示、时间更新 等。
代码实现
创建窗口
首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(window的对象),每个游戏都有一个窗口,设置好窗口标题、尺寸、布局等就可以。
/*
* 游戏窗体类
*/
public class GameFrame extends JFrame {
public GameFrame() {
setTitle("贪吃蛇");//设置标题
setSize(788, 476);//设定尺寸
getContentPane().setBackground(new Color(169,169,169));//添加背景
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮是关闭程序
setLocationRelativeTo(null); //设置居中
setResizable(false); //不允许修改界面大小
}
}
小AD:明哥你在干嘛?不是带我练英雄吗?
明世隐:是啊,我正在热身,你等等!
小AD:哦。
画布1
创建面板容器BackPanel继承至JPanel
/*
* 背景画布类
*/
public class BackPanel extends JPanel{
BackPanel panel=this;
private JFrame mainFrame=null;
//构造里面初始化相关参数
public BackPanel(JFrame frame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame = frame;
mainFrame.setVisible(true);
}
}
再创建一个Main类,来启动这个窗口。
public class Main {
//主类
public static void main(String[] args) {
GameFrame frame = new GameFrame();
BackPanel panel = new BackPanel(frame);
frame.add(panel);
frame.setVisible(true);//设定显示
}
}
右键执行这个Main类,窗口建出来了
小AD:哥你在做游戏?
明世隐:不,我在带你打野升级!
小AD:你真的在做游戏?
明世隐:哦不,我在带你打野升级!
小AD:哥,你真的可以这样吗?
明世隐:哥要把你培养成200斤的ADC.
小AD:我去你的吧,到时候嫁不出去就找你。
明世隐:好呀,我很多粉丝,你到时候挑一个带回家。我给你们发红包!你们给喜糖!
小AD:明哥真(sha)好(bi)!
创建菜单及菜单选项
创建菜单
private void initMenu(){
// 创建菜单及菜单选项
jmb = new JMenuBar();
JMenu jm1 = new JMenu("游戏");
jm1.setFont(new Font("仿宋", Font.BOLD, 15));// 设置菜单显示的字体
JMenu jm2 = new JMenu("帮助");
jm2.setFont(new Font("仿宋", Font.BOLD, 15));// 设置菜单显示的字体
JMenuItem jmi1 = new JMenuItem("开始新游戏");
JMenuItem jmi2 = new JMenuItem("退出");
jmi1.setFont(new Font("仿宋", Font.BOLD, 15));
jmi2.setFont(new Font("仿宋", Font.BOLD, 15));
JMenuItem jmi3 = new JMenuItem("操作说明");
jmi3.setFont(new Font("仿宋", Font.BOLD, 15));
JMenuItem jmi4 = new JMenuItem("失败判定");
jmi4.setFont(new Font("仿宋", Font.BOLD, 15));
jm1.add(jmi1);
jm1.add(jmi2);
jm2.add(jmi3);
jm2.add(jmi4);
jmb.add(jm1);
jmb.add(jm2);
mainFrame.setJMenuBar(jmb);// 菜单Bar放到JFrame上
jmi1.addActionListener(this);
jmi1.setActionCommand("Restart");
jmi2.addActionListener(this);
jmi2.setActionCommand("Exit");
jmi3.addActionListener(this);
jmi3.setActionCommand("help");
jmi4.addActionListener(this);
jmi4.setActionCommand("lost");
}
实现ActionListener并重写方法actionPerformed
actionPerformed方法的实现
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
System.out.println(command);
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("宋体", Font.ITALIC, 18)));
if ("Exit".equals(command)) {
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.exit(0);
}
}else if("Restart".equals(command)){
if(!"end".equals(gamePanel.gameFlag)){
JOptionPane.showMessageDialog(null, "正在游戏中无法重新开始!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}else{
if(gamePanel!=null) {
gamePanel.restart();
btnStart.setText("暂停");
}
}
}else if("help".equals(command)){
JOptionPane.showMessageDialog(null, "[下][S]、[左][A]、[右][D]、[上][W]控制方向",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}else if("lost".equals(command)){
JOptionPane.showMessageDialog(null, "蛇咬到自己则失败!",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}else if("start".equals(command)){
mainFrame.requestFocus();
if("start".equals(gamePanel.gameFlag)){//进入暂停
gamePanel.pause();
btnStart.setText("继续");
}else if("pause".equals(gamePanel.gameFlag)){//进入继续
gamePanel.goOn();
btnStart.setText("暂停");
}else if("end".equals(gamePanel.gameFlag)){//进入重开
gamePanel.restart();
btnStart.setText("暂停");
}
}
}
绘制游戏区域
绘制游戏区域边框
//绘制边框
private void drawBorder(Graphics g) {
BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(128,128,128));
g_2d.setStroke(bs_2);
RoundRectangle2D.Double rect = new RoundRectangle2D.Double(6, 6, 613, 413, 2, 2);
g_2d.draw(rect);
}
绘制右边辅助区域
//绘制右边区域边框
private void drawBorderRight(Graphics g) {
BasicStroke bs_2=new BasicStroke(12L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(128,128,128));
g_2d.setStroke(bs_2);
RoundRectangle2D.Double rect = new RoundRectangle2D.Double(636, 6, 140, 413, 2, 2);
g_2d.draw(rect);
}
在BackPanel 中重写paint 方法,并调用刚才两个区域绘制方法。
绘制积分区域
//绘制积分区域
private void drawCount(Graphics g) {
BasicStroke bs_2=new BasicStroke(3L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(70,70,70));
g_2d.setStroke(bs_2);
g_2d.drawRect(650, 17, 110, 80);
//得分
g.setFont(new Font("宋体", Font.BOLD, 20));
g.drawString("得分:",680, 40);
}
绘制时间区域
//绘制时间区域
private void drawTime(Graphics g) {
BasicStroke bs_2=new BasicStroke(3L,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(70,70,70));
g_2d.setStroke(bs_2);
g_2d.drawRect(650, 120, 110, 120);
//时间
g.setFont(new Font("宋体", Font.BOLD, 20));
g.drawString("时间:",680, 140);
}
绘制网格(30列 20行)
//绘制网格
private void drawGrid(Graphics g) {
Graphics2D g_2d=(Graphics2D)g;
g_2d.setColor(new Color(255,255,255,150));
int x1=12;
int y1=20;
int x2=612;
int y2=20;
for (int i = 0; i <= ROWS; i++) {
y1 = 12 + 20*i;
y2 = 12 + 20*i;
g_2d.drawLine(x1, y1, x2, y2);
}
y1=12;
y2=412;
for (int i = 0; i <= COLS; i++) {
x1 = 12 + 20*i;
x2 = 12 + 20*i;
g_2d.drawLine(x1, y1, x2, y2);
}
}
在paint方法中调用
创建游戏右边区域的一个暂停按钮
//初始化
private void init() {
// 开始/停止按钮
btnStart = new JButton();
btnStart.setFont(new Font("黑体", Font.PLAIN, 18));
btnStart.setFocusPainted(false);
btnStart.setText("暂停");
btnStart.setBounds(660, 300, 80, 43);
btnStart.setBorder(BorderFactory.createRaisedBevelBorder());
this.add(btnStart);
btnStart.addActionListener(this);
btnStart.setActionCommand("start");
}
此时基本布局已经完成了。
小AD:明哥这是什么游戏!
明世隐:AD起飞小游戏。
小AD:这。。。,看起来我是不得不学咯。
明世隐:那不能这么说,我是这种强迫人家学习的人吗。
小AD:明哥真是(bu)好(yao)人(lian)!
明世隐:谢谢夸奖,我们继续。
画布2
GamePanel 继承至 JPanel 并重写 paint 方法
修改Main类,将画布2也放到窗口中
public class Main {
//主类
public static void main(String[] args) {
GameFrame frame = new GameFrame();
BackPanel panel = new BackPanelJava贪吃蛇小游戏