m0_58996874 2021-06-23 19:17 采纳率: 0%
浏览 6

简要描述程序过程和思路

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 

//Main Class 

public class GreedSnake extends KeyAdapter{ 

JFrame mainFrame; 
Canvas paintCanvas; 
JLabel labelScore;//计分牌 
SnakeModel snakeModel=null;// 蛇 
public static final int DEFAULT_WIDTH=500; 
public static final int DEFAULT_HEIGHT=300; 
public static final int nodeWidth=10; 
public static final int nodeHeight=10; 

//GreedSnake():初始化游戏界面 

public GreedSnake(){ 

//设置界面元素 
mainFrame=new JFrame("贪吃蛇游戏"); 
Container cp=mainFrame.getContentPane(); 
labelScore=new JLabel("所得分数为:",JLabel.CENTER); 
cp.add(labelScore,BorderLayout.NORTH); 
paintCanvas=new Canvas(); 
paintCanvas.setSize(DEFAULT_WIDTH+1,DEFAULT_HEIGHT+1); 
paintCanvas.addKeyListener(this); 
cp.add(paintCanvas,BorderLayout.CENTER); 
JPanel panelButtom=new JPanel(); 
panelButtom.setLayout(new BorderLayout()); 
JLabel labelHelp;// 帮助信息 
labelHelp=new JLabel("按 PageUP 或 PageDown 键改变速度",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.NORTH); 
labelHelp=new JLabel("按 Enter 或 S 键重新开始游戏",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.CENTER); 
labelHelp=new JLabel("按 SPACE 键或 P 键暂停游戏",JLabel.CENTER); 
panelButtom.add(labelHelp,BorderLayout.SOUTH); 
cp.add(panelButtom,BorderLayout.SOUTH); 
mainFrame.addKeyListener(this); 
mainFrame.pack(); 
mainFrame.setResizable(false); 
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
mainFrame.setVisible(true); 
begin(); 
} 

//keyPressed():按键检测 

public void keyPressed(KeyEvent e){ 

int keyCode=e.getKeyCode(); 
if(snakeModel.running) 
switch(keyCode){ 
case KeyEvent.VK_UP: 
snakeModel.changeDirection(SnakeModel.UP); 
break; 
case KeyEvent.VK_DOWN: 
snakeModel.changeDirection(SnakeModel.DOWN); 
break; 
case KeyEvent.VK_LEFT: 
snakeModel.changeDirection(SnakeModel.LEFT); 
break; 
case KeyEvent.VK_RIGHT: 
snakeModel.changeDirection(SnakeModel.RIGHT); 
break; 
case KeyEvent.VK_ADD: 
case KeyEvent.VK_PAGE_UP: 
snakeModel.speedUp();// 加速 
break; 
case KeyEvent.VK_SUBTRACT: 
case KeyEvent.VK_PAGE_DOWN: 
snakeModel.speedDown();// 减速 
break; 
case KeyEvent.VK_SPACE: 
case KeyEvent.VK_P: 
snakeModel.changePauseState();// 暂停或继续 
break; 
default: 
} 
//重新开始 
if(keyCode==KeyEvent.VK_S || keyCode==KeyEvent.VK_ENTER){ 
snakeModel.running=false; 
begin(); 
} 
} 

//repaint():绘制游戏界面(包括蛇和食物) 

void repaint(){ 
Graphics g=paintCanvas.getGraphics(); 
//draw background 
g.setColor(Color.LIGHT_GRAY); 
g.fillRect(0,0,DEFAULT_WIDTH,DEFAULT_HEIGHT); 
//draw the snake 
g.setColor(Color.BLACK); 
LinkedList na=snakeModel.nodeArray; 
Iterator it=na.iterator(); 
while(it.hasNext()){ 

Node n=(Node)it.next(); 
drawNode(g,n); 
} 
// draw the food 
g.setColor(Color.RED); 
Node n=snakeModel.food; 
drawNode(g,n); 
updateScore(); 
} 

//drawNode():绘画某一结点(蛇身或食物) 

private void drawNode(Graphics g,Node n){ 
g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,nodeHeight-1); 
} 

//updateScore():改变计分牌 

public void updateScore(){ 
String s="所得分数为: "+snakeModel.score; 
labelScore.setText(s); 
} 

//begin():游戏开始,放置贪吃蛇 

void begin(){ 

if(snakeModel==null||!snakeModel.running){ 
snakeModel=new SnakeModel(this,DEFAULT_WIDTH/nodeWidth, 
DEFAULT_HEIGHT/nodeHeight); 
(new Thread(snakeModel)).start(); 
} 
} 

//main():主函数 

public static void main(String[] args){ 

GreedSnake gs=new GreedSnake(); 
} 
} 

//Node:结点类 

class Node{ 
int x; 
int y; 
Node(int x,int y){ 
this.x=x; 
this.y=y; 
} 
} 

//SnakeModel:贪吃蛇模型 

class SnakeModel implements Runnable{ 

GreedSnake gs; 
boolean[][] matrix;// 界面数据保存在数组里 
LinkedList nodeArray=new LinkedList(); 
Node food; 
int maxX;//最大宽度 
int maxY;//最大长度 
int direction=2;//方向 
boolean running=false; 
int timeInterval=200;// 间隔时间(速度) 
double speedChangeRate=0.75;// 速度改变程度 
boolean paused=false;// 游戏状态 
int score=0; 
int countMove=0; 
// UP和DOWN是偶数,RIGHT和LEFT是奇数 
public static final int UP=2; 
public static final int DOWN=4; 
public static final int LEFT=1; 
public static final int RIGHT=3; 

//GreedModel():初始化界面 

public SnakeModel(GreedSnake gs,int maxX,int maxY){ 

this.gs=gs; 
this.maxX=maxX; 
this.maxY=maxY; 
matrix=new boolean[maxX][]; 
for(int i=0;i<maxX;++i){ 
matrix[i]=new boolean[maxY]; 
Arrays.fill(matrix[i],false);// 没有蛇和食物的地区置false 
} 
//初始化贪吃蛇 
int initArrayLength=maxX>20 ? 10 : maxX/2; 
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 
} 

//changeDirection():改变运动方向 

public void changeDirection(int newDirection){ 

if(direction%2!=newDirection%2){// 避免冲突 
direction=newDirection; 
} 
} 

//moveOn():贪吃蛇运动函数 

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]){// 吃到食物或者撞到身体 

if(x==food.x&&y==food.y){// 吃到食物 

nodeArray.addFirst(food);// 在头部加上一结点 
//计分规则与移动长度和速度有关 
int scoreGet=(10000-200*countMove)/timeInterval; 
score+=scoreGet>0 ? scoreGet : 10; 
countMove=0; 
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;//越界(撞到墙壁) 
} 

//run():贪吃蛇运动线程 

public void run(){ 
running=true; 
while(running){ 
try{ 
Thread.sleep(timeInterval); 
} 
catch(Exception e){ 
break; 
} 
if(!paused){ 

if(moveOn()){// 未结束 
gs.repaint(); 
} 
else{//游戏结束 
JOptionPane.showMessageDialog(null,"GAME OVER", 
"Game Over",JOptionPane.INFORMATION_MESSAGE); 
break; 
} 
} 
} 
running=false; 
} 

//createFood():生成食物及放置地点 

private Node createFood(){ 

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

//speedUp():加快蛇运动速度 

public void speedUp(){ 
timeInterval*=speedChangeRate; 
} 

//speedDown():放慢蛇运动速度 

public void speedDown(){ 

timeInterval/=speedChangeRate; 
} 

//changePauseState(): 改变游戏状态(暂停或继续) 

public void changePauseState(){ 

paused=!paused; 
} 
}
  • 写回答

1条回答 默认 最新

  • CSDN专家-sinJack 2021-06-23 19:37
    关注

    一个贪吃蛇的窗体游戏,里面主要的内容也加了注释。你从main方法一步步看代码。如有不懂的,可以问。

    评论

报告相同问题?

悬赏问题

  • ¥15 鼠标右键,撤销删除 复制 移动,要怎样删除
  • ¥15 使用MATLAB进行余弦相似度计算加速
  • ¥15 服务器安装php5.6版本
  • ¥15 我想用51单片机和数码管做一个从0开始的计数表 我写了一串代码 但是放到单片机里面数码管只闪烁一下然后熄灭
  • ¥20 系统工程中,状态空间模型中状态方程的应用。请猛男来完整讲一下下面所有问题
  • ¥15 我想在WPF的Model Code中获取ViewModel Code中的一个参数
  • ¥15 arcgis处理土地利用道路 建筑 林地分类
  • ¥20 使用visual studio 工具用C++语音,调用openslsx库读取excel文件的sheet问题
  • ¥100 寻会做云闪付tn转h5支付链接的技术
  • ¥15 DockerSwarm跨节点无法访问问题