本人做的贪吃蛇游戏,大家可以交流一下。如有疑问可以问我!
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
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
Arrays.fill(matrix[i], false);
}
int initArrayLength=maxX>20?10:maxX/2;
nodeArray.clear();//清空蛇身
for(int i=0;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
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();
}
}
运行效果截图: