qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

贪吃蛇 Java版(基于GUI)

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

posted on 2014-07-23 09:40 顺其自然EVO 阅读(327) 评论(0)  编辑  收藏 所属分类: 测试学习专栏


只有注册用户登录后才能发表评论。


网站导航:
 
<2014年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜