写一个贪吃蛇
键盘监听
定时器Timer
时间监听
画笔
1、数据中心类
定义图片URL
定义图标
头部上下左右、身体、实物、横幅的图标
2、游戏启动类
main方法启动游戏
定义主窗口
设置主窗口大小值,可见,大小,关闭事件
添加画板
3、游戏画板类
-
定义数据
- 蛇的长度
- 蛇的坐标
- 头部方向
- 食物的坐标
- random随机食物坐标
- 积分
- 游戏的启动状态
- 游戏的失败状态
- 定时器Timer(int多少毫秒执行一次,对象)
-
构造器:
- 调用初始化方法,
- 获得焦点
- 获得键盘事件
- 启动定时器
-
初始化方法
- 初始化蛇的长度
- 初始化蛇的头部位置,身体位置
- 初始化头部的朝向
- 随机食物的坐标
- 积分初始化0
-
绘制画板
- 清屏
- 设置画板背景颜色
- 设置画板界面大小及位置 fillRect
- 把横幅画上去,数据中心获取(data)
- 积分画上去
- 设置积分字体。setFont(Font)
- 设置标语,drawString(字体,x,y)
- 画食物
- 画小蛇头
- 判断四个方向使用不同的ImageIcon
- 画小蛇身体
- 坐标就是蛇头的后一个坐标
- 判断游戏是否开始
- 设置标语,drawString(字,x,y)
- 判断游戏是否失败
- 设置标语,drawString(字,x,y)
-
键盘监听事件
- 可以实现KeyListener接口,重写keyPresssed按下方法
- 监听空格
- 监听上下左右键
-
事件监听,需要通过固定事件来刷新
- 判断游戏开始、失败状态
- 判断是否吃到食物
- 让小蛇头部移动(for)
- 判断方向及边界
- 让小蛇身体移动(for)小蛇身体坐标就是前一节的坐标
- 判断是否失败(for)
- 重画
- 定时器开启
1, 数据类
- 定义各部分的图片数据
package com.ccc.testsnake;
import javax.swing.*;
import java.net.URL;
public class Data {
private static URL urlHeader = Data.class.getResource("z-image/header.png");
private static URL urlUp = Data.class.getResource("z-image/up.png");
private static URL urlDown = Data.class.getResource("z-image/down.png");
private static URL urlLeft = Data.class.getResource("z-image/left.png");
private static URL urlRight = Data.class.getResource("z-image/right.png");
private static URL urlBody = Data.class.getResource("z-image/body.png");
private static URL urlfood = Data.class.getResource("z-image/food.png");
private static URL urlfood2 = Data.class.getResource("z-image/up.png");
public static ImageIcon headerImageIcon = new ImageIcon(urlHeader);
public static ImageIcon UpImageIcon = new ImageIcon(urlUp);
public static ImageIcon downImageIcon = new ImageIcon(urlDown);
public static ImageIcon leftImageIcon = new ImageIcon(urlLeft);
public static ImageIcon rightImageIcon = new ImageIcon(urlRight);
public static ImageIcon bodyImageIcon = new ImageIcon(urlBody);
public static ImageIcon foodImageIcon = new ImageIcon(urlfood);
public static ImageIcon food2ImageIcon = new ImageIcon(urlfood2);
}
2, 启动类
- 启动游戏, 设置主窗体参数
package com.ccc.testsnake;
import javax.swing.*;
import java.awt.*;
public class StartSnakeGame {
public static void main(String[] args) {
JFrame jFrame = new JFrame("空格开始游戏");
//添加panel 画板
jFrame.add(new GamePanel());
jFrame.setVisible(true);
jFrame.setResizable(false);
jFrame.setBackground(Color.WHITE);
jFrame.setBounds(700,300,870,725);
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
3, 画板类
- 画蛇,
- 监听
package com.ccc.testsnake;
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;
public class GamePanel extends JPanel implements KeyListener, ActionListener {
private int length;//蛇的长度
private String direction;//蛇头的方向
private int count ;//分数
private boolean isStart = false;//开始状态
private boolean isFailed = false;//失败状态
private int[] snakeX;private int[] snakeY;
private int foodX;private int foodY;
private int food2X;private int food2Y;
Random random;//随机数
Timer timer = new Timer(120,this);//定时器
public GamePanel() {
init();
this.addKeyListener(this);
this.setFocusable(true);
timer.start();
}
//初始化方法
private void init(){
length = 3;
snakeX = new int[825];
snakeY = new int[625];
direction = "R";
random = new Random();
foodX = 300;foodY = 300;
food2X = 600;food2Y = 600;
//初始化蛇默认坐标
for (int i = 0; i <length; i++) {
snakeX[i] = 100-(25*i);snakeY[i] = 100;//边界 x 25,y 75
}
// snakeX[0] = 100;snakeY[0] = 100;
// snakeX[1] = 75;snakeY[1] = 100;
// snakeX[2] = 50;snakeY[2] = 100;
}
//画板
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
//画横幅
Data.headerImageIcon.paintIcon(this,g,0,11);
g.fillRect(25,75,800,600);
g.setColor(Color.PINK);
g.setFont(new Font("微软雅黑",Font.BOLD,20));
g.drawString("积 分:"+count+"分",440,30);
g.drawString("你有多长:"+length+"cm",440,50);
//画食物
Data.foodImageIcon.paintIcon(this,g,foodX,foodY);
if (((length+foodX)%3)==0){
Data.food2ImageIcon.paintIcon(this,g,food2X,food2Y);
}
//画蛇头
if (direction .equals("U")){
Data.UpImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(direction.equals("D")){
Data.downImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(direction.equals("L")){
Data.leftImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
}else if(direction.equals("R")){
Data.rightImageIcon.paintIcon(this,g,snakeX[0],snakeY[0]);
}
//画身体
for (int i = 1; i < length; i++) {
Data.bodyImageIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
}
if (isFailed==true){
g.setColor(Color.YELLOW);
g.setFont(new Font("微软雅黑",Font.BOLD,28));
if (count<500){
g.drawString("才吃这么点! 按空格重新开始! 得分:"+count,200,400);
}else if (count<1000){
g.drawString("吃饱了吧! 按空格重新开始! 得分:"+count,200,400);
}else{
g.drawString("无敌!!! 按空格重新开始! 得分:"+count,200,400);
}
}
if (isStart==false){
g.setColor(Color.RED);
g.setFont(new Font("微软雅黑",Font.BOLD,28));
g.drawString("就这? 按空格开始!",300,400);
}
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode==KeyEvent.VK_SPACE){
if (isFailed){
isFailed = false;count =0;
}else{
isStart = !isStart;
}
repaint();
}
if(isStart==true && isFailed == false){
if ((keyCode==KeyEvent.VK_UP || keyCode == KeyEvent.VK_W)&& direction!="D"){
direction = "U";
}else if ((keyCode==KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) && direction!="U"){
direction = "D";
}else if ((keyCode==KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) && direction!="R"){
direction = "L";
}else if ((keyCode==KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) && direction!="L"){
direction = "R";
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (isStart==true && isFailed==false){
for (int i = 1; i < length; i++) {
//食物不能和身体重叠
if (foodX == snakeX[i] && foodY == snakeY[i] ){
foodX = 25+25* random.nextInt(32);
foodY = 75+25* random.nextInt(24);
}
if (food2Y == snakeY[i] &&food2X == snakeX[i] ){
food2Y = 75+25* random.nextInt(23);
food2X = 25+25* random.nextInt(31);
}
//头部不能和身体重叠
if (snakeX[0]==snakeX[i] && snakeY[0] ==snakeY[i]){
isFailed = true;
init();
}
}
//如果头部坐标相同,代表吃到了食物,长度加1,分数加20
if (snakeX[0]==foodX && snakeY[0] == foodY){
length++;
count+=20;
foodX = 25+25* random.nextInt(32);
foodY = 75+25* random.nextInt(24);
}else if (snakeX[0]==food2X && snakeY[0] == food2Y){
length+=5;count+=100;
food2X = 25+25* random.nextInt(32);
food2Y = 75+25* random.nextInt(24);
for (int i = 0; i < 5; i++) {
snakeX[length-1-i] = snakeX[length-6];
snakeY[length-1-i] = snakeY[length-6];
}
}
//小蛇动起来
for (int i = length-1; i >0 ; i--) {
snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
//蛇头怎么移动
if (direction.equals("U")){
snakeY[0] -=25;
}else if (direction.equals("D")){
snakeY[0] +=25;
}else if (direction.equals("L")){
snakeX[0] -=25;
}else if (direction.equals("R")){
snakeX[0] +=25;
}
//撞到墙失败
if (snakeX[0]==825 || snakeX[0]==0 || snakeY[0]==50 || snakeY[0]==675 ){
isFailed = true;
init();
}
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
下载地址
https://download.csdn.net/download/xbd_zc/52913026
下载