手把手带你完成期末作业——贪吃蛇Java版

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

  界面如下:

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 snakes=new ArrayList();

List eggs=new ArrayList();

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

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

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交流群664389243,不管你是小白还是大牛欢迎入驻,大家一起交流成长。

你可能感兴趣的:(手把手带你完成期末作业——贪吃蛇Java版)