貪吃蛇 Java版(基于GUI)
完全自己寫(xiě)的小程序,主要難點(diǎn)在控制蛇身的運(yùn)動(dòng)上,已經(jīng)較好的解決,不完善的地方是沒(méi)有進(jìn)行畫(huà)面雙緩沖,但刷新頻率較低,所以閃爍現(xiàn)象較不明顯。
界面如下:
import java.awt.*; import java.awt.event.*; import java.util.List; import java.util.ArrayList; public class SnakeClient extends Frame { /** * 貪吃蛇主客戶端 * 蛇頭可動(dòng),雞蛋隨機(jī)出現(xiàn) * 0.4蛇身跟隨著運(yùn)動(dòng) */ private static final long serialVersionUID = 1L; private static int WIDTH=406,HEIGHT=428; List<Snake> snakes=new ArrayList<Snake>(); List<Egg> eggs=new ArrayList<Egg>(); Snake s=new Snake(3,25,true,0,this); Snake body1=new Snake(3,45,false,1,this); Snake body2=new Snake(3,65,false,2,this); boolean eat=false; Egg e=new Egg(); public static void main(String []args){ SnakeClient sc=new SnakeClient(); sc.launchFrame(); } void launchFrame(){ this.setBounds(100, 100, WIDTH, HEIGHT); this.setVisible(true); this.setResizable(false); this.addWindowListener(new WinCloseMonitor()); // bug2 :忘記加入監(jiān)聽(tīng),導(dǎo)致方向不能控制 this.addKeyListener(new KeyMonitor()); new Thread(new MyThread()).start(); snakes.add(s); eggs.add(e); } class WinCloseMonitor extends WindowAdapter{ // bug1 錯(cuò)把windowClosing 寫(xiě)成WindowClosing // 以后重寫(xiě)函數(shù)時(shí)注意復(fù)制或利用Eclipse的重寫(xiě)功能 public void windowClosing(WindowEvent e){ System.exit(0); } } public void paint(Graphics g){ for(int i=0;i<snakes.size();i++){ Snake sn=snakes.get(i); if(s.hitSnake(sn)&&!sn.head){ snakes.removeAll(snakes); return; } sn.draw(g); if(sn.eatEgg(e)) eat=true; } if(eat){ snakes.add(new Snake(snakes.get(snakes.size()-1).oldX,snakes.get(snakes.size()-1).oldY, false,snakes.size(),this)); eat=false; eggs.remove(e); e=new Egg(); eggs.add(e); } e.draw(g); } class MyThread implements Runnable{ @Override public void run() { while(true){ repaint(); try { Thread.sleep(350); } catch (InterruptedException e) { e.printStackTrace(); } } } } class KeyMonitor extends KeyAdapter{ @Override public void keyPressed(KeyEvent e) { s.keyPressed(e); } } } |
import java.awt.*; import java.awt.event.KeyEvent; public class Snake { int x,y,oldX,oldY; int id; private static int WIDTH=20,HEIGHT=20,dx=20,dy=20; static Direction dir=Direction.STOP; boolean head;//判斷是否是是蛇頭 SnakeClient sc=null; private boolean live; public Snake(int x, int y, boolean head,int id,SnakeClient sc) { this.x = x; this.y = y; this.head = head; this.id=id; this.sc=sc; } void draw(Graphics g){ move(); Color c=g.getColor(); if(head){ g.setColor(Color.red); }else{ g.setColor(Color.green); } g.fillRect(x, y, WIDTH, HEIGHT); g.setColor(Color.black); g.drawRect(x, y, WIDTH, HEIGHT); g.setColor(c); } public void keyPressed(KeyEvent e) { if(!head) return; int key=e.getKeyCode(); switch(key){ case KeyEvent.VK_UP: if(Direction.D==dir) break; dir=Direction.U; break; case KeyEvent.VK_DOWN: if(Direction.U==dir) break; dir=Direction.D; break; case KeyEvent.VK_LEFT: if(Direction.R==dir) break; dir=Direction.L; break; case KeyEvent.VK_RIGHT: if(Direction.L==dir) break; dir=Direction.R; break; case KeyEvent.VK_F2: if(!live){ sc.snakes.add(sc.s); } } } // 從蛇頭到蛇尾編號(hào)id從0遞增,根據(jù)id來(lái)移動(dòng)蛇身,具體如下,記錄下當(dāng)前位置oldX,oldY // 當(dāng)move()時(shí),根據(jù)id-1的蛇身改變自己的位置; void move(){ oldX=x; oldY=y; if(!head){ if(dir==Direction.STOP) return; for(int i=0;i<sc.snakes.size();i++){ if(sc.snakes.get(i).id==id-1){ x=sc.snakes.get(i).oldX; y=sc.snakes.get(i).oldY; } } return; } switch(dir){ case U: y-=dy; break; case R: x+=dx; break; case D: y+=dy; break; case L: x-=dx; break; case STOP: break; } //新版貪吃蛇,當(dāng)?shù)竭_(dá)邊界時(shí)從另外一邊出來(lái) if(x<3) x=383; if(x>383) x=3; if(y<25) y=405; if(y>405) y=25; } public Rectangle getRect(){ return new Rectangle(x,y,WIDTH-1,HEIGHT-1); } boolean eatEgg(Egg e){ if(!head) { return false; } else{ return e.getRect().intersects(this.getRect()); } } boolean hitSnake(Snake s){ if(!head) return false; if(s.getRect().intersects(this.getRect())){ live = false; return true; }else{ return false; } } } [java] view plaincopy import java.awt.*; import java.util.*; public class Egg { private static int WIDTH=20,HEIGHT=20; private static Random r=new Random(); int x=3+20*r.nextInt(20); int y=25+20*r.nextInt(20); void draw(Graphics g){ Color c=g.getColor(); g.setColor(Color.pink); g.fillOval(x, y, WIDTH, HEIGHT); g.setColor(c); } public Rectangle getRect(){ return new Rectangle(x,y,WIDTH,HEIGHT); } } |
public enum Direction { U,R,D,L,STOP; } |
posted on 2014-07-23 09:40 順其自然EVO 閱讀(330) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 測(cè)試學(xué)習(xí)專(zhuān)欄