java script模式下的贪吃蛇游戏

本人做的贪吃蛇游戏,大家可以交流一下。如有疑问可以问我!




import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.media.AudioClip;
import javafx.scene.media.AudioClipBuilder;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class GreedSnake extends Application{

AudioClip bgSound = AudioClipBuilder.create()       //播放音乐
.source(getClass().getResource("/music/yourname.mp3").toExternalForm())
.cycleCount(Integer.MAX_VALUE).build();

BorderPane pane=new BorderPane();//界面
static TextField text3=new TextField();

public static void main(String[] args){
Application.launch(args);
}


  public void start(Stage primaryStage) throws Exception{
 bgSound.play();//开始播放音乐
 ImageView bgView = new ImageView("photo/bj.jpg");//添加背景图片
      pane.getChildren().add(bgView);//添加进入背景图片
 
 final SnakeModel model = new SnakeModel(30,30);
 SnakeView view=new SnakeView(model);
 
 //添加一个观察者,让view成为model的观察者
 model.addObserver(view);
 (new Thread(model)).start();
 pane.setCenter(view);
 
 VBox vvv=new VBox();
 Text text=new Text("规则:"+"\n"+"方向键控制蛇的方向"+"\n"+"page_up手动加速"+"\n"+"page_down手动减速"+"\n"
 +"P键暂停"+"\n"+"Enter重新开始游戏"+"\n"+"蛇吃到食物后会自动加速"+"\n"+"自带音乐");
 text.setFont(new Font("Times Roman",20));
 
 Text text2=new Text("\n\n"+"分数");
 text2.setFont(new Font("Times Roman",20));
 text3.setMaxSize(100,60);
 text3.setEditable(false);//键盘不能修改  text3里的内容
 
 Runnable runnable = new Runnable() {       //定时器,用来写分数
public void run() {
if (model.running==true) {
text3.setText(String.valueOf(model.score));
}
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);
runnable.run();
 


 vvv.getChildren().addAll(text,text2,text3);
 pane.setRight(vvv);
 
 Scene scene=new Scene(pane,640,450);
 primaryStage.setTitle("GreedSnake");
 primaryStage.setScene(scene);
 primaryStage.show();
 
 view.requestFocus();
  }
}



import java.util.*;




import javafx.event.EventHandler;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
 class SnakeModel extends Observable implements
      Runnable,EventHandler<KeyEvent>{
      boolean[][] matrix;
      LinkedList nodeArray=new LinkedList();//记录蛇身长度   坐标  方向
      Node food;//食物
      
      int maxX;//蛇能运动的总界面
      int maxY;
      int direction=SnakeModel.UP;//指示,蛇运动方向
      boolean running=false;//定时器指示开或关

      int  timeInterval=500;//蛇移动的速度  ,500微妙
      double speedChangeRate=0.75;//变速
      boolean paused=false;//暂停指示符
      
      int score=0;//分数
      int countMove=0;//吃到食物前移动的次数
      
      public static final int UP=2;//蛇运动方向的定义
      public static final int DOWN=4;
      public static final int LEFT=1;
      public static final int RIGHT=3;
      
      public SnakeModel(int maxX,int maxY){
     this.maxX=maxX;
     this.maxY=maxY;
     
     reset();
      }
      
      public void reset(){//初始化参数
     direction=SnakeModel.UP;
     timeInterval=500;
     score=0;
     countMove=0;
     running=true;//开启定时器
     
     matrix=new boolean[maxX][];//参数指示的全部格子设为FALSE
     for(int i=0;i<maxX;++i){
     matrix[i]=new boolean[maxY];
     Arrays.fill(matrix[i], false);
     }
     
     int initArrayLength=maxX>20?10:maxX/2;
     nodeArray.clear();//清空蛇身
     
     for(int i=0;i<initArrayLength;i++){//定义初始蛇的长度  以及其各个蛇身点的坐标
     int x=maxX/2+i;
     int y=maxY/2;
     nodeArray.addLast(new Node(x,y));
     matrix[x][y]=true;//标记为这里有东西   true
     }
     food=createFood();//创建食物
     matrix[food.x][food.y]=true;//标记为这里有东西   true
      }
      public void changeDirection(int newDirection){//蛇   改变方向函数
     if(direction%2!=newDirection%2){//保证了蛇不会反向运动
     direction=newDirection;
     }
      }
      public boolean moveOn(){//移动函数
     Node n=(Node)nodeArray.getFirst();//获得蛇头的参数
     int x=n.x;
     int y=n.y;
     switch (direction){
     case UP:
     y--;
     break;
     
     case DOWN:
     y++;
     break;
     case LEFT:
     x--;
     break;
     case RIGHT:
     x++;
     break;
      }
     if((0<=x&&x<maxX)&&(0<=y&&y<maxY)){//如果蛇能运动到下一个点
     if(matrix[x][y]){//如果那个点  是true分两类情况   ,一是食物 则能过去  ,2是蛇自己的身体则不能过去
     if(x==food.x&&y==food.y){
     nodeArray.addFirst(food);
     int scoreGet=(10000-200*countMove)/timeInterval;//分数加成
     score+=scoreGet>0?scoreGet:10;
     countMove=0;//吃到食物前移动的次数
     speedUp();//蛇加速
     food=createFood();//在创建食物


     matrix[food.x][food.y]=true;
     return true;
     }
     else{//遇到蛇身
     return false;
     }
    }
    else{//正常通过  ,没遇到墙,食物,蛇自己
    nodeArray.addFirst(new Node(x,y));
    matrix[x][y]=true;
    n=(Node)nodeArray.removeLast();
    matrix[n.x][n.y]=false;
    countMove++;
    return true;
    }
    }
     return false;
    }
      
      public void run(){//定时器//
     running=true;
     while(running){
     try{
     Thread.sleep(timeInterval);      
     }catch(Exception e){
     break;
     }
     if(!paused){
     if(moveOn()){
     setChanged();
     notifyObservers();
     }else{
     GreedSnake.text3.setText("you failed");//
     break;
     }
    }
     }
    running=false; 
      }
      private Node createFood(){  //在matrix上false 的点随机创建食物
     int x=0;
     int y=0;
     do{
     Random r=new Random();
     x=r.nextInt(maxX);
     y=r.nextInt(maxY);
     }while(matrix[x][y]);
     return new Node(x,y);
      }
      public void speedUp(){//    加速 
     timeInterval*=speedChangeRate;
      }
      public void speedDown(){//  减速
     timeInterval/=speedChangeRate;
      }
      public void changePauseState(){//暂停按钮
     paused=!paused;
      }


      public void handle(KeyEvent e){//键盘操作键
     KeyCode keyCode=e.getCode();
     if(this.running){
     switch(keyCode){
     case UP:
        this.changeDirection(SnakeModel.UP);
         break;
         case DOWN:
         this.changeDirection(SnakeModel.DOWN);
         break;
         case LEFT:
         this.changeDirection(SnakeModel.LEFT);
         break;
         case RIGHT:
         this.changeDirection(SnakeModel.RIGHT);
         break;
         case PAGE_UP:
         this.speedUp();
         break;
         case PAGE_DOWN:
         this.speedDown();
         break;
         case P:
         this.changePauseState();
         break;
         //default:
     }
     }
     if(keyCode==KeyCode.ENTER){
     this.reset();
     }
      }
}
 class Node{
int x;
int y;
Node(int x,int y){
this.x=x;
this.y=y;
}
 }







import java.util.*;




import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;


public class SnakeView extends Canvas implements Observer{
SnakeModel model=null;
public static final int canvasWidth =300;
public static final int canvasHright =300;
public static final int nodeWidth =10;
public static final int nodeHeight =10;
public SnakeView(SnakeModel model){
this.model=model;
this.setWidth(canvasWidth+1);
this.setHeight(canvasHright+1);
this.setOnKeyPressed(model);
repaint();
}
void repaint(){
GraphicsContext g=this.getGraphicsContext2D();
//draw background
g.setFill(Color.YELLOW);//画背景,白色方块
g.fillRect(0,0, canvasWidth,canvasHright);

g.setFill(Color.BLACK);//化蛇
LinkedList na=model.nodeArray;
Iterator it=na.iterator();
while(it.hasNext()){ //化每一节蛇
Node n=(Node)it.next();
drawNode(g,n);//函数
}
//draw the food
g.setFill(Color.RED);//画食物   红色方块
Node n=model.food;
drawNode(g,n);
}
private void drawNode(GraphicsContext g,Node n){//  画方块     及填充蛇和食物
g.fillRect(n.x*nodeWidth,n.y*nodeHeight ,nodeWidth-1 , nodeHeight -1);
}
public void update(Observable o,Object arg){//更新界面,每一次移动和迟到食物后,都会影响蛇在界面上的分布,每一次移动重画一次
repaint();
}
}


运行效果截图:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值