学习了线程,向量泛型编程,可以通过一个实例来应用所学知识,本课实现了经典游戏贪食蛇,自认为结构还算合理于2009年8月12日,16:05分
实现贪食蛇的思路
1。首先定义窗口200X400 ,实现控制1个矩形方块20X20
2。通过按键控制方块移动
3。实现线程控制方块移动每次一格(20X20),通过按键改变方向
4.实现在窗口中随机出现可以吃的小块 作为要是20的倍数
5.实现方块和可以吃的小块碰撞
6.将蛇的身体每一块定义为Vector,有每块对应一个对象
Node{
int x;
int y;
int nextDir;
}
7。实现死亡判定和分数判定
第一个类:
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class SnakeFrame extends JFrame implements KeyListener{
public JPanel gamePanel;//游戏面板
public Vector<Node>allNode=new Vector<Node>(); // 所有结点
class Node{
int x;
int y;
int nextDir;
public Node(int x,int y,int d)
{
this.x=x;
this.y=y;
this.nextDir=d;
}
};
public static final int S_UP=1;
public static final int S_DOWN=2;
public static final int S_LEFT=3;
public static final int S_RIGHT=4;
public static final int S_STOP=-1;
//头节点
public Node head=new Node(80,80,SnakeFrame.S_LEFT);
public Node eatNode;
public Random rand=new Random();
public SnakeFrame()
{
this.setBounds(0, 0, 200, 400);
this.setTitle("贪食蛇");
this.setClosed();
gamePanel=new JPanel();
gamePanel.setSize(200, 400);
gamePanel.setVisible(true);
this.getContentPane().add(gamePanel);
this.addKeyListener(this);
}
//实现关闭的处理
public void setClosed()
{
WindowAdapter wa=new WindowAdapter()
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
this.addWindowListener(wa);
}
public void paintGame()
{ Graphics g=this.gamePanel.getGraphics();
g.setColor(new Color(255,255,255));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
//绘制头
g.setColor(new Color(255,0,0));
g.fillRect(head.x, head.y, 20, 20);
//绘制身体
g.setColor(new Color(220,220,220));
Iterator<Node> it=this.allNode.iterator();
while(it.hasNext())//如果还有下一个
{Node nownode=it.next();//获取下一个节点
g.fillRect(nownode.x, nownode.y, 20, 20);
}
//绘制可以吃的小块
g.setColor(new Color(0,0,255));
g.fillRect(eatNode.x, eatNode.y, 20, 20);
//
g.drawString("fenshu:30", 30, 30);
}
public void startGame()
{ int x=rand.nextInt(10);
int y=rand.nextInt(20);
this.eatNode=new Node(x*20,y*20,SnakeFrame.S_STOP);
Thread t=new Thread()
{
public void run()
{
while(true)
{ paintGame();//绘制游戏
move(head);//移动头
//移动所有身体块
moveAllNode();
///
if(checkEat(head)){
Node endNode;
if(allNode.size()==0)
{endNode=head;}
else{
endNode=allNode.lastElement();
}
switch(endNode.nextDir)
{case SnakeFrame.S_DOWN:
allNode.add(new Node(endNode.x,endNode.y-20,SnakeFrame.S_DOWN));
break;
case SnakeFrame.S_UP:
allNode.add(new Node(endNode.x,endNode.y+20,SnakeFrame.S_UP));
break;
case SnakeFrame.S_LEFT:
allNode.add(new Node(endNode.x+20,endNode.y,SnakeFrame.S_LEFT));
break;
case SnakeFrame.S_RIGHT:
allNode.add(new Node(endNode.x-20,endNode.y,SnakeFrame.S_RIGHT));
break;
}
}
try{Thread.sleep(300);}catch(Exception e){}
}
}
};
t.start();
}
public void moveAllNode()
{
Iterator<Node> node=allNode.iterator();
int dir=head.nextDir;
int tmp;
while(node.hasNext())
{Node nownode=node.next();
switch(nownode.nextDir)
{case SnakeFrame.S_DOWN:nownode.y+=20;break;
case SnakeFrame.S_UP:nownode.y-=20;break;
case SnakeFrame.S_LEFT:nownode.x-=20;break;
case SnakeFrame.S_RIGHT:nownode.x+=20;break;
}
tmp=nownode.nextDir;
nownode.nextDir=dir;
dir=tmp;
}
}
public void move(Node node)//移动某一个块
{
switch(node.nextDir)
{case SnakeFrame.S_DOWN:
node.y+=20;
break;
case SnakeFrame.S_UP:
node.y-=20;
break;
case SnakeFrame.S_LEFT:
node.x-=20;
break;
case SnakeFrame.S_RIGHT:
node.x+=20;
break;
}
}
public boolean checkEat(Node node)
{
if((node.x==eatNode.x)&&(node.y==eatNode.y))
{
System.out.println("okeat");
int x=rand.nextInt(10);
int y=rand.nextInt(20);
this.eatNode=new Node(x*20,y*20,SnakeFrame.S_STOP);//这里其实可以不用new
return true;
}
return false;
}
public void keyPressed(KeyEvent e) {
System.out.println(e.getKeyCode());
if(e.getKeyCode()==37&&head.nextDir!=SnakeFrame.S_LEFT){
head.nextDir=SnakeFrame.S_LEFT;
}
if(e.getKeyCode()==38&&head.nextDir!=SnakeFrame.S_UP){
head.nextDir=SnakeFrame.S_UP;}
if(e.getKeyCode()==39&&head.nextDir!=SnakeFrame.S_RIGHT){
head.nextDir=SnakeFrame.S_RIGHT;}
if(e.getKeyCode()==40&&head.nextDir!=SnakeFrame.S_DOWN){
head.nextDir=SnakeFrame.S_DOWN;}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
第2个类
public class Snake {
public static void main(String dd[])
{
SnakeFrame sf=new SnakeFrame();
sf.setVisible(true);
sf.startGame();
}
}