要求:
①实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子,上下左右控 制“蛇”的移动,吃到“豆子”以后“蛇”的身体加长一点。
②“蛇”碰到边界或蛇头与蛇身相撞,蛇死亡,游戏结束。
③为游戏设计友好的交互界面;例如欢迎界面,游戏界面, 游戏结束界面。要有开始键、暂停键和停止退出的选项。
④对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。
了解完具体要求后有了大致的流程
实现:
1.首先我是先去建立游戏界面,设置GUI界面,蛇和食物,代码如下:
//主函数
package Snake;
import javax.swing.*;
//设置窗口并加载
import javax.swing.JFrame;
public class SnakeWin {
public static void main(String[] args) {
new StartView();
}
}
//游戏界面
package Snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.Timer;
public class SnakePanel extends JPanel implements KeyListener, ActionListener {
//加载所有图片
ImageIcon up = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\up.png");
ImageIcon down = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\down.png");
ImageIcon left = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\left.png");
ImageIcon right = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\right.png");
ImageIcon body = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\body.png");
ImageIcon food = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\food.png");
ImageIcon title = new ImageIcon("F:\\软件实习\\贪吃蛇\\图片\\title.png");
//蛇的数据结构设计
int[] snakex = new int[750];
int[] snakey = new int[750];
int len = 3;
int score;
String direction = "R";//R
//食物生成
Random r = new Random();
int foodx = r.nextInt(34) * 25 + 25;
int foody = r.nextInt(24) * 25 + 75;
//游戏是否开始
boolean isStarted = false;
//游戏是否失败
boolean isFaild = false;
//初始化蛇
public void initSnake() {
isStarted = false;
isFaild = false;
len = 3;
direction = "R";
snakex[0] = 100;
snakey[0] = 100;
snakex[1] = 75;
snakey[1] = 100;
snakex[2] = 50;
snakey[2] = 100;
score = 0;
}
public SnakePanel() {
this.setFocusable(true);
initSnake();//放置静态蛇
this.addKeyListener(this);//添加键盘监听接口
timer.start();
}
//设置蛇移动速度
Timer timer = new Timer(225, this);
public void paint(Graphics g) {
//设置背景黑色
this.setBackground(Color.white);
//设置标题
title.paintIcon(this, g, 25, 0);
g.fillRect(25, 75, 850, 600);
g.setColor(Color.black);
g.setFont(new Font("微软雅黑", Font.BOLD, 20));
g.drawString("长度:" + len, 750, 35);
g.drawString("分数:" + score, 750, 65);
//画蛇头
if (direction.equals("R")) {
right.paintIcon(this, g, snakex[0], snakey[0]);
} else if (direction.equals("L")) {
left.paintIcon(this, g, snakex[0], snakey[0]);
} else if (direction.equals("U")) {
up.paintIcon(this, g, snakex[0], snakey[0]);
} else if (direction.equals("D")) {
down.paintIcon(this, g, snakex[0], snakey[0]);
}
//画蛇身
for (int i = 1; i < len; i++) {
body.paintIcon(this, g, snakex[i], snakey[i]);
}
//画开始提示语
if (!isStarted) {
g.setColor(Color.white);
g.setFont(new Font("微软雅黑", Font.BOLD, 30));
g.drawString("按空格开始或暂停", 330, 350);
}
//画失败提示语
if (isFaild) {
g.setColor(Color.white);
g.setFont(new Font("微软雅黑", Font.BOLD, 30));
g.drawString("游戏结束,请按空格键开始", 250, 350);
}
//画食物
// if(foodx<)
food.paintIcon(this, g, foodx, foody);
}
@Override
public void keyTyped(KeyEvent e) {
}
//监听按键
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
//实现空格暂停继续
if (keyCode == KeyEvent.VK_SPACE) {
if (isFaild) {
initSnake();
} else {
isStarted = !isStarted;
}
repaint();
}
//实现转向
else if (keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
direction = "D";
} else if (keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
direction = "U";
} else if (keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
direction = "L";
} else if (keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
direction = "R";
}
}
@Override
public void keyReleased(KeyEvent e) {
}
/*
* 1.定个闹钟
* 2.蛇移动
* 3.重画一次蛇
*/
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
if (isStarted && !isFaild) {
//移动身体
for (int i = len; i > 0; i--) {
snakex[i] = snakex[i - 1];
snakey[i] = snakey[i - 1];
}
//头移动
if (direction.equals("R")) {
//横坐标+25
snakex[0] = snakex[0] + 25;
if (snakex[0] > 850) isFaild = true;
;
} else if (direction.equals("L")) {
//横坐标-25
snakex[0] = snakex[0] - 25;
if (snakex[0] < 25) isFaild = true;
;
} else if (direction.equals("U")) {
//纵坐标-25
snakey[0] = snakey[0] - 25;
if (snakey[0] < 75) isFaild = true;
;
} else if (direction.equals("D")) {
//纵坐标+25
snakey[0] = snakey[0] + 25;
if (snakey[0] > 650) isFaild = true;
;
}
//吃食物
if (snakex[0] == foodx && snakey[0] == foody) {
len++;
score += 10;
foodx = r.nextInt(34) * 25 + 25;
foody = r.nextInt(24) * 25 + 75;
}
//判断游戏失败
for (int i = 1; i < len; i++) {
if (snakex[0] == snakex[i] && snakey[0] == snakey[i]) {
isFaild = true;
}
}
}
repaint();
}
}
出现的效果如下: 2.下一步进行完善游戏,设置游戏开始界面并且给游戏界面进行美化
①游戏开始界面。代码如下·:
package Snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class StartView implements ActionListener {
//创建开始游戏欢迎界面
private Frame jf = new Frame("贪吃蛇");
//提示性标签
private JLabel jl;
//设置进入游戏按钮
private JButton jb;
//实现按钮的方法
private void setButton() {
jf.setLayout(null);
jb = new JButton("开始游戏");//按钮提示内容
jb.setBounds(300, 500, 400, 70);
jb.setFont(new Font("微软雅黑", Font.BOLD, 50));//按钮字体大小
jb.setBackground(new Color(177, 120, 205, 205));
jf.add(jb);//加入窗口
jb.addActionListener((ActionListener) this);//为按钮实现监听
}
//实现标签的方法
private void setLabel() {
jf.setLayout(null);
jl = new JLabel("欢迎来到贪吃蛇游戏");
jl.setFont(new Font("微软雅黑", Font.BOLD, 30));
jl.setBackground(new Color(196, 34, 169));//字体颜色
jl.setBounds(340, 100, 400, 80);//相对位置
jf.add(jl);///加到窗口
}
StartView() {
//设置窗口背景颜色
jf.setBackground(new Color(190, 44, 79));
//设置按钮信息
setButton();
//设置标签并加入窗口
setLabel();
//设置点击右上角的关闭窗口结束程序
jf.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//设置窗口绝对位置
jf.setLocation(500, 200);
//设置窗口大小
jf.setSize(920, 720);
//窗口大小不能改变
jf.setResizable(false);
//窗口可见
jf.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jb) {
//设置游戏界面的窗口
JFrame frame = new JFrame();
frame.setBounds(500, 200, 920, 720);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SnakePanel panel = new SnakePanel();
frame.add(panel);
frame.setVisible(true);
//new SnakePanel();
jf.dispose();
new SnakePanel();
}
}
public static void main(String[] args) {
new StartView();
}
}
心得体会
通过这次课程设计,我对这学期所学的JAVA语言程序设计有一个更深刻的了解,将所学的知识应用于实践,由于所学知识有限,为了使游戏能够实现自己预先的构想,我通过上网和去图书馆找程序,比较好的流程图及功能模块,不断阅读修改代码使程序达到预期所要实现的目标,完成课程设计后,可以感觉到自己对Java程序的又有了新的认识。总之,通过本次的课程设计,使我平时学到的理论知识得到了很好地升华,理论与实际得到一次很好的结合,为我今后参加工作打下了坚实的基础,使我受益匪浅。