自己写贪吃蛇的一下感悟

Posted ltdh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己写贪吃蛇的一下感悟相关的知识,希望对你有一定的参考价值。

贪吃蛇

思想

  1. 先建立一个大的JFrame框架

  2. 建立一个Jpanel中级容器 ,将JPanel放入框架中

  3. 建立一个Data类放置各种需要用的图片

具体实现

让Jpanel类继承JPanel

public class gameJpan extends JPanel

重写JPanel中的方法

protected void paintComponent(Graphics g)

开始在JPanel上添加贪吃蛇以外的东西

        super.paintComponent(g);
       this.setBackground(Color.BLACK);//设置背景色
       Data.header.paintIcon(this,g,200,11);//绘制顶部
       g.fillRect(25,75,850,600); //绘制游戏区域

添加完之后定义蛇

    int length;//蛇的长度
   int[]snakeX=new int[600];//蛇的容量
   int[]snakeY=new int[600];//蛇的容量

定义好后,让蛇显示在创建的游戏区域(因为我使用的蛇头是圆形 不分上下左右,所以用的是一个图)

if (fx.equals("R")){
           Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
      }
       else if (fx.equals("L")){
           Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
      }else if (fx.equals("U")){
           Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
      }else if (fx.equals("D")){
           Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
      }
       for (int i = 1; i <length ; i++) {
           Data.food.paintIcon(this,g,snakeX[i],snakeY[i]);
      }

初始化蛇,让蛇一开始都是在那个地方并且蛇的长度是一定的,并且把初始化放在构造函数中。fx定义的是方向

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";}

蛇画上去之后,设置用空格控制暂定和开始,需要用到按键监听,记住一定要用repaint(),使用监听需要在构造方法中加入this.addKeyListener(this);

boolean isStar=false;//定义是否开始
public void keyPressed(KeyEvent e) {
       int keyCode=e.getKeyCode();
       //按下空格之后的判别
       if (keyCode==KeyEvent.VK_SPACE){
               isStar=!isStar;
           repaint();//重新绘制JPanel
      }

然后开始让小蛇动起来,需要用到Timer类,这样就实现了小蛇可以一直往右边走

Timer timer=new Timer(100,this);//定义定时器
this.setFocusable(true);
timer.start();
?
public void actionPerformed(ActionEvent e) {
       //蛇身的移动
       if (isStar&&isFail==false){
           for (int i = length-1; i >0 ; i--) {
               snakeX[i]=snakeX[i-1];
               snakeY[i]=snakeY[i-1];
          }
   //蛇头的移动
           snakeX[0]=snakeX[0]+25;
           repaint();
       timer.start();

但是你会发现小蛇会走出屏幕,所以我们需要设置一下,具体参数可以自己设置

if (snakeX[0]>850){
           snakeX[0]=25;
      }

接下来我们要控制蛇可以上下左右移动,之前我们定义过方向fx,在键盘监听中设置按键链接的方向

if (keyCode == KeyEvent.VK_LEFT){
           fx="L";
      }else if (keyCode == KeyEvent.VK_RIGHT){
           fx="R";
      }else if (keyCode == KeyEvent.VK_UP){
           fx="U";
      }else if (keyCode == KeyEvent.VK_DOWN){
           fx="D";
      }

这只能是内层改变fx的值,如何让这个值影响蛇的移动

if (fx.equals("R")){
       snakeX[0]=snakeX[0]+25;
       if (snakeX[0]>850){
           snakeX[0]=25;
      }
  }
   else if (fx.equals("D")){
       snakeY[0]=snakeY[0]+25;
       if (snakeY[0]>650){
           snakeY[0]=75;
      }
  }
   else if (fx.equals("U")){
       snakeY[0]=snakeY[0]-25;
       if (snakeY[0]<75){
           snakeY[0]=650;
      }
          }
   else if (fx.equals("L")){
       snakeX[0]=snakeX[0]-25;
       if (snakeX[0]<25){
           snakeX[0]=850;
      }
          }

这样你就会有一个自由移动的蛇了

接下来我们就要设置食物了,同样需要初始化

         int foodX;
        int foodY;//定义食物横纵坐标
?
foodX= 25+25*random.nextInt(30);
       foodY= 75+75*random.nextInt(8);
?
       Data.food.paintIcon(this,g,foodX,foodY);
?

有了会动的蛇 还有随机出现的食物,我们就要让蛇碰到食物之后 长度增加,并且生成新的食物

if (snakeX[0]==foodX&&snakeY[0]==foodY) {
               length++;
foodX= 25+25*random.nextInt(30);
               foodY= 75+75*random.nextInt(8);}

设置完这些,工程已经进行一大半了,然后我们就要设置死亡机制

boolean isFail=false;//定义是否失败
if (isFail){
           g.setColor(Color.RED);
           g.setFont(new Font("微软雅黑",Font.BOLD,40));
           g.drawString("游戏失败,按下空格重新开始",200,300);
      }
if (isFail){ //在空格按键监听里边设置
               isFail=false;
               init();

for (int i = 1; i <length ; i++) {
               if (snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
                   isFail=true;
              }
          }

下边我们要设置障碍物,同样需要初始化。计算分数增加就不说了比较简单。

    int[]barrierX=new int[50];
   int[]barrierY=new int[50];
for (int i = 0; i <40 ; i++) {
           barrierY[i]=75+75*random.nextInt(8);
           barrierX[i]=25+25*random.nextInt(30);
      }
?
//控制障碍物
       if (score<50){
       for (int i = 0; i <5 ; i++) {
           Data.barrier.paintIcon(this,g,barrierX[i],barrierY[i]);
      }}
       else if (score<100&&score>=50) {
           for (int i = 0; i < 10; i++) {
               Data.barrier.paintIcon(this, g, barrierX[i], barrierY[i]);
          }
      }
       else if (score>=100&&score<170){
           for (int i = 0; i < 15; i++) {
               Data.barrier.paintIcon(this, g, barrierX[i], barrierY[i]);}
      }
       else {
           for (int i = 0; i < 20; i++) {
               Data.barrier.paintIcon(this, g, barrierX[i], barrierY[i]);}
      }
//设置障碍物可以动,吃一个食物动一下
if (score>=100&&score<170){
                   for (int i = 0; i <15 ; i++) {
                       barrierX[i]= 25+25*random.nextInt(30);
                       barrierY[i]= 75+75*random.nextInt(8);
                      }
                  }else if (score>=170)
                   for (int i = 0; i <20 ; i++) {
                       barrierX[i]= 25+25*random.nextInt(30);
                       barrierY[i]= 75+75*random.nextInt(8);
                      }
//设置碰触障碍物死亡
if (score<50) {
               for (int i = 0; i < 5; i++) {
                   if (snakeX[0] == barrierX[i] && snakeY[0] == barrierY[i]) {
                       isFail = true;
                  }
              }
          }else if (score<100&&score>=50){
               for (int i = 0; i <10 ; i++) {
                   if (snakeX[0] == barrierX[i] && snakeY[0] == barrierY[i]) {
                       isFail = true;
              }
          }}else if (score>=100&&score<170){
               for (int i = 0; i <15 ; i++) {
                   if (snakeX[0] == barrierX[i] && snakeY[0] == barrierY[i]) {
                       isFail = true;
                  }
              }}else
               for (int i = 0; i <20 ; i++) {
                   if (snakeX[0] == barrierX[i] && snakeY[0] == barrierY[i]) {
                       isFail = true;}}

这样一个简单的项目就算完成了。当然你还可以开发其他的 比如随着分数增加速度变快(为实现)

总结

  1. 动画动起来是用Timer计时器

  2. 控制方向的方法是设置变量,用键盘监听器监听改变变量,在Timer重写方法中说明变量控制的结果。

  3. 将同一资源整合到一个类里边方便阅读

以上是关于自己写贪吃蛇的一下感悟的主要内容,如果未能解决你的问题,请参考以下文章

贪吃蛇的java代码分析

求大神改一下贪吃蛇C++代码

关于C语言写贪吃蛇时,蛇的身体以及移动该怎么写

我也来写一个贪吃蛇

表弟打把王者的时间,我就用python写了个自动玩贪吃蛇的程序

重做贪吃蛇 万向移动型 蛇的移动和吃食部分C# wpf版