贪吃蛇 Java版(基于GUI)

Calandra ·
更新时间:2024-09-21
· 690 次阅读

  完全自己写的小程序,主要难点在控制蛇身的运动上,已经较好的解决,不完善的地方是没有进行画面双缓冲,但刷新频率较低,所以闪烁现象较不明显。

  界面如下:
import java.awt.*; import java.awt.event.*; import java.util.List; import java.util.ArrayList; public class SnakeClient extends Frame { /** * 贪吃蛇主客户端 * 蛇头可动,鸡蛋随机出现 * 0.4蛇身跟随着运动 */ 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 :忘记加入监听,导致方向不能控制 this.addKeyListener(new KeyMonitor()); new Thread(new MyThread()).start(); snakes.add(s); eggs.add(e); } class WinCloseMonitor extends WindowAdapter{ //      bug1 错把windowClosing 写成WindowClosing //      以后重写函数时注意复制或利用Eclipse的重写功能 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); } } } //  从蛇头到蛇尾编号id从0递增,根据id来移动蛇身,具体如下,记录下当前位置oldX,oldY //  当move()时,根据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; } //新版贪吃蛇,当到达边界时从另外一边出来 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; }

 



贪吃蛇 java版 gui JAVA

需要 登录 后方可回复, 如果你还没有账号请 注册新账号