原本以爲做一個貪喫蛇的雛形很簡單,因爲它的行爲很簡單,但是到具體開發的時候發現有很多細節需要注意:
- 鍵盤監聽
- 如何讓蛇移動起來
- 如何控制蛇的速度
- 如何讓蛇邊長
- 蛇碰到身子要死亡
- 碰到牆也要死亡
- 如何控制蛇的速度
- 蛇不能後退走
- 如何控制蛋的隨機出現
- 如何控制蛋的顏色變化
- 還要有計分功能
以下是代碼的具體實現,一共有四個類,其中一個是測試類
MyYard.java
package eggs;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
import yard.MyYard;
public class MyEgg {
int row,col;
private Color color;
private static Random r =new Random();
public MyEgg(){
this(r.nextInt(MyYard.ROWS-2)+2,r.nextInt(MyYard.COLS));
}
public MyEgg(int row,int col){
this.row=row;
this.col=col;
}
public void draw (Graphics g){
if(color == Color.PINK){
color = Color.GREEN;
}else{
color = Color.PINK;
}
g.setColor(color);
g.fillOval(MyYard.BLOCK_SIZE * col, MyYard.BLOCK_SIZE * row, MyYard.BLOCK_SIZE, MyYard.BLOCK_SIZE);
}
public void reAppear(){
this.row=r.nextInt(MyYard.ROWS-2)+2;
this.col=r.nextInt(MyYard.COLS);
}
public Rectangle getRect(){
return new Rectangle(MyYard.BLOCK_SIZE*col,MyYard.BLOCK_SIZE*row,MyYard.BLOCK_SIZE,MyYard.BLOCK_SIZE);
}
}
MySnake.java
package snake;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import eggs.MyEgg;
import yard.MyYard;
public class MySnake {
private Node head =null;
private Node tail =null;
private int SCORE =0;
public MySnake(){
tail=head=new Node(15,15,1);
}
public Node getHead(){
return this.head;
}
public int getScore(){
return this.SCORE;
}
public void addToHead(){
Node node = null;
switch (head.dir){
case 1:
node = new Node(head.row-1,head.col,1);
break;
case 2:
node = new Node(head.row,head.col+1,2);
break;
case 3:
node = new Node(head.row+1,head.col,3);
break;
case 4:
node = new Node(head.row,head.col-1,4);
break;
}
node.next=head;
head.privious=node;
head=node;
}
private void deleteFromTail() {
tail=tail.privious;
tail.next=null;
}
public void draw(Graphics g){
addToHead();
deleteFromTail();
for(Node n=head;n!=null;n=n.next){
n.draw(g);
}
}
public class Node{
public int row;
public int col;
int dir;
public Node next;
Node privious;
Node(int row,int col,int dir){
this.row=row;
this.col=col;
this.dir=dir;
}
public Rectangle getRect(){
return new Rectangle(MyYard.BLOCK_SIZE*col,MyYard.BLOCK_SIZE*row,MyYard.BLOCK_SIZE,MyYard.BLOCK_SIZE);
}
void draw (Graphics g){
g.setColor(Color.RED);
g.fillRect(MyYard.BLOCK_SIZE * col, MyYard.BLOCK_SIZE * row, MyYard.BLOCK_SIZE, MyYard.BLOCK_SIZE);
}
}
public void eat(MyEgg e){
if(head.getRect().intersects(e.getRect())){
e.reAppear();
this.addToHead();
SCORE +=5;
}
}
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
switch(key){
case KeyEvent.VK_UP:
if(head.dir!=3)
head.dir = 1;
break;
case KeyEvent.VK_RIGHT:
if(head.dir!=4)
head.dir = 2;
break;
case KeyEvent.VK_DOWN:
if(head.dir!=1)
head.dir = 3;
break;
case KeyEvent.VK_LEFT:
if(head.dir!=2)
head.dir = 4;
break;
}
}
}
MyEgg.java
package eggs;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
import yard.MyYard;
public class MyEgg {
int row,col;
private Color color;
private static Random r =new Random();
public MyEgg(){
this(r.nextInt(MyYard.ROWS-2)+2,r.nextInt(MyYard.COLS));
}
public MyEgg(int row,int col){
this.row=row;
this.col=col;
}
public void draw (Graphics g){
if(color == Color.PINK){
color = Color.GREEN;
}else{
color = Color.PINK;
}
g.setColor(color);
g.fillOval(MyYard.BLOCK_SIZE * col, MyYard.BLOCK_SIZE * row, MyYard.BLOCK_SIZE, MyYard.BLOCK_SIZE);
}
public void reAppear(){
this.row=r.nextInt(MyYard.ROWS-2)+2;
this.col=r.nextInt(MyYard.COLS);
}
public Rectangle getRect(){
return new Rectangle(MyYard.BLOCK_SIZE*col,MyYard.BLOCK_SIZE*row,MyYard.BLOCK_SIZE,MyYard.BLOCK_SIZE);
}
}
TestDemo.java
package test;
import org.junit.Test;
import yard.MyYard;
public class TestDemo {
@Test
public void testSnakeAndEggs(){
new MyYard().launch();
}
}
總結:這個貪喫蛇雛形雖然只有兩百多行,但是在編寫的過程中我學到了很多東西。也意識到很重要的一點:很多在我們潛意識裏認爲理所應當的邏輯在實際開發中都需要我們考慮;