贪吃蛇 Java版(基于GUI)

来源:互联网 发布:打印机wsd端口是什么 编辑:程序博客网 时间:2024/06/04 18:45

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

界面如下:




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{@Overridepublic void run() {while(true){repaint();try {Thread.sleep(350);} catch (InterruptedException e) {e.printStackTrace();}}}}class KeyMonitor extends KeyAdapter{@Overridepublic 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;}}}

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















0 0
原创粉丝点击