主类
package com.luffy.snake; import javax.swing.*; public class StartGame { public static void main(String[] args) { Jframe jframe = new Jframe(); //给窗口添加一个主面板 jframe.add(new GamePanel()); //设置窗口的基本属性 jframe.setBounds(10,10,930,740); jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jframe.setResizable(false); jframe.setVisible(true); } }
数据类
package com.luffy.snake; import javax.swing.*; import java.net.URL; public class Data { //相对路径 tx.jpg //绝对路径 / 相当于当前目录 //这里是相对路径,使用相对路径拿到资源设置为URL对象 public static URL headerURL = Data.class.getResource("statics/header.png");//计时板 public static URL upURL = Data.class.getResource("statics/up.png");//上 public static URL downURL = Data.class.getResource("statics/down.png");//下 public static URL leftURL = Data.class.getResource("statics/left.png");//左 public static URL rightURL = Data.class.getResource("statics/right.png");//右 public static URL bodyURL = Data.class.getResource("statics/body.png");//身体 public static URL foodURL = Data.class.getResource("statics/food.png");//食物 //将拿到的图片资源转换成图片标签 public static ImageIcon header = new ImageIcon(headerURL); public static ImageIcon up = new ImageIcon(upURL); public static ImageIcon down = new ImageIcon(downURL); public static ImageIcon left = new ImageIcon(leftURL); public static ImageIcon right = new ImageIcon(rightURL); public static ImageIcon body = new ImageIcon(bodyURL); public static ImageIcon food = new ImageIcon(foodURL); }
面板类
package com.luffy.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; public class GamePanel extends JPanel implements KeyListener, ActionListener { //定义蛇的数据结构 int length;//蛇的长度 int[] snakeX = new int[600];//蛇的x坐标 25 * 25 int[] snakeY = new int[500];//蛇的y坐标 25 * 25 boolean isStart = false;//游戏状态 String fx;//蛇的方向 Timer timer = new Timer(100,this);//定时器 Random random = new Random();//食物随机值 int foodX;//食物X坐标 int foodY;//食物Y坐标 boolean isFail;//失败状态 int score;//分数 //构造器 public GamePanel(){ init();//初始化数据 this.setFocusable(true);//获得焦点 this.addKeyListener(this);//启动键盘监听 timer.start();//启动定时器 } //初始化方法 public void init(){ length = 3;//长度 snakeX[0] = 100 ; snakeY[0] = 100;//蛇头 snakeX[1] = 75 ; snakeY[1] = 100;//第一个身体 snakeX[2] = 50 ; snakeY[2] = 100;//第二个身体 fx = "R";//方向 foodX = 25 + 25 * random.nextInt(34);//食物随机X值 foodY = 75 + 25 * random.nextInt(23);//食物随机Y值 isFail = false;//是否失败 score = 0;//积分 } //绘制面板,我们游戏中的所有东西,都是用这个画笔来画 @Override protected void paintComponent(Graphics g) { super.paintComponent(g);//调用一次清屏一次 setPanelProperty(g);//设置面板初始属性 setHeadDirection(g);//根据按下方向键设置蛇头部的方向 initSnakeBody(g);//初始加载蛇的两个身体 gameState(g);//游戏开始状态 refurbishData(g);//刷新数据 ifFail(g);//游戏失败提示文字 } //键盘监听事件 @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode();//获取键盘监听值 ifGameStateOperation(keyCode);//判断游戏失败状态 *** 作 setDirectionValue(keyCode);//根据按下的方向设置方向值 } //定时器监听事件 @Override public void actionPerformed(ActionEvent e) { //如果游戏状态不是暂停,并且游戏失败状态不为true if(isStart && isFail == false){ eatFood();//判断小蛇是否吃到食物,吃到就增长身体并且刷新食物位置 bodyMove();//身体移动 headMove();//头移动 collideBodyFail();//碰撞身体失败 } timer.start();//重启定时器刷新页面 } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } //设置面板初始属性 public void setPanelProperty(Graphics g){ this.setBackground(Color.WHITE);//设置面板为白色 Data.header.paintIcon(this,g,25,11);//将标题栏画入 g.fillRect(25,75,850,600);//画一个游戏场景的矩形 Data.food.paintIcon(this,g,foodX,foodY);//将食物第一次画在游戏上 } //根据按下方向键设置蛇头部的方向 public void setHeadDirection(Graphics g){ if(fx.equals("R")){//右 Data.right.paintIcon(this,g,snakeX[0],snakeY[0]); }else if(fx.equals("L")){//左 Data.left.paintIcon(this,g,snakeX[0],snakeY[0]); }else if(fx.equals("U")){//上 Data.up.paintIcon(this,g,snakeX[0],snakeY[0]); }else if(fx.equals("D")){//下 Data.down.paintIcon(this,g,snakeX[0],snakeY[0]); } } //初始加载蛇的两个身体 public void initSnakeBody(Graphics g){ for (int i = 1; i < length; i++) { Data.body.paintIcon(this,g,snakeX[i],snakeY[i]); } } //游戏开始状态 public void gameState(Graphics g){ if(isStart == false){ g.setColor(Color.white); g.setFont(new Font("微软雅黑",Font.BOLD,40)); g.drawString("按下空格开始游戏!",300,350); } } //刷新数据 public void refurbishData(Graphics g){ g.setColor(Color.white); g.setFont(new Font("微软雅黑",Font.BOLD,10)); g.drawString("长度:" + length,750,30); g.drawString("分数:" + score,750,50); } //游戏失败提示文字 public void ifFail(Graphics g){ if(isFail){//true为失败 g.setColor(Color.red); g.setFont(new Font("微软雅黑",Font.BOLD,40)); g.drawString("游戏失败,按下任意键重新开始!",175,350); } } //判断游戏失败状态操作 public void ifGameStateOperation(int keyCode){ if(isFail){ //失败按下空格键重新初始化开始界面 if(keyCode == KeyEvent.VK_SPACE){ init(); } }else{ //没有失败如果按的是空格则暂停游戏 if(keyCode == KeyEvent.VK_SPACE){ isStart = !isStart; repaint();//重绘画面 } } } //根据按下的方向设置方向值 public void setDirectionValue(int keyCode){ if(keyCode == KeyEvent.VK_UP){ if(fx == "D"){ fx = "D"; }else{ fx = "U"; } }else if(keyCode == KeyEvent.VK_DOWN){ if(fx == "U"){ fx = "U"; }else{ fx = "D"; } }else if(keyCode == KeyEvent.VK_LEFT){ if(fx == "R"){ fx = "R"; }else{ fx = "L"; } }else if(keyCode == KeyEvent.VK_RIGHT){ if(fx == "L"){ fx = "L"; }else{ fx = "R"; } } } //吃食物 public void eatFood(){ //判断小蛇是否吃到食物,吃到就增长身体并且刷新食物位置 if(snakeX[0] == foodX && snakeY[0] == foodY){ length++; score = score + 10; foodX = 25 + 25 * random.nextInt(34); foodY = 75 + 25 * random.nextInt(23); } } //身体移动 public void bodyMove(){ //身体随着长度而往头的方向依次前进移动 for(int i=length-1; i > 0; i--){ snakeX[i] = snakeX[i-1]; snakeY[i] = snakeY[i-1]; } } //头移动 public void headMove(){ //头根据按下后修改的方向键进行移动 if(fx.equals("U")){ snakeY[0] = snakeY[0] - 25;//小蛇的头往右25像素 if(snakeY[0] < 100){isFail = true;}//边界判断 repaint();//重绘画面 }else if(fx.equals("D")){ snakeY[0] = snakeY[0] + 25;//小蛇的头往右25像素 if(snakeY[0] > 625){isFail = true;}//边界判断 repaint();//重绘画面 }else if(fx.equals("L")){ snakeX[0] = snakeX[0] - 25;//小蛇的头往右25像素 if(snakeX[0] < 50){isFail = true;}//边界判断 repaint();//重绘画面 }else if(fx.equals("R")){ snakeX[0] = snakeX[0] + 25;//小蛇的头往右25像素 if(snakeX[0] > 845){isFail = true;}//边界判断 repaint();//重绘画面 } } //碰撞身体失败 public void collideBodyFail(){ //从身体开始判断 for(int i = 1; i < length; i++){ //循环全部身体,如果头撞到随意一个身体,将游戏失败状态改为true if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){ isFail = true; } } } }心得
跟着狂神视频学的,后面自己多写了一点代码,不让头部往身体的方向转,碰到边缘就死亡等
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)