和TTS 有所不同的贪吃蛇 能穿墙而不是撞墙 [纯代码]
[来源] 达内 [编辑] 达内 [时间]2013-08-13
参赛人:陈彬豪
获得奖项:三等奖
内容:
第一步
,就是先把单个格子的属性创建出来
public class Cell {
int row;
int col;
int color;
static int indexRow = 10000;//这个参数是上下穿墙用的,为了保证不用完,要尽可能的大
static int indexCol = 10000;//这个参数是左右穿墙用的,为了保证不用完,要尽可能的大
public Cell(){//对于父类,无参数构造器不一定用到,应该习惯的写上
}
public Cell(int x, int y, int color) {
super();
this.row = x;
this.col = y;
this.color = color;
}
//各属性的get set方法
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getRow() {
return row;
}
public void setRow(int x) {
this.row = x;
}
public int getCol() {
return col;
}
public void setCol(int y) {
this.col = y;
}
/**向X轴负正向走*/
public void left(){
row = (indexRow+(--row))%40;/
*这就是穿墙的关键,40是贪吃蛇墙的长,%40就能使蛇走不出墙,
注意
!!(--row)不能写成(row--) */
}
/**向X轴负方向走*/
public void right(){
row= (indexRow+(++row))%40;
}
/**向Y轴负方向走*/
public void up(){
col = (indexCol+(--col))%40;
}
/**向Y轴正方向走*/
public void down(){
col = (indexCol+(++col))%40;
}
public String toString(){
return row+","+col;
}
}
第二步,对蛇身的构造,以及蛇运动的方法
import java.util.Arrays;
public class Body extends Cell{
/**蛇身的颜色*/
public static final int BADY_COLOR = 0x66ccff;
/** 身体 */
public Cell[] bodys;
/**头*/
protected Cell head;
public Body(){
bodys = new Cell[5];
head = new Cell(4,10,BADY_COLOR);
bodys[0] = head;
bodys[1] = new Cell(3,10,BADY_COLOR);
bodys[2] = new Cell(2,10,BADY_COLOR);
bodys[3] = new Cell(1,10,BADY_COLOR);
bodys[4] = new Cell(0,10,BADY_COLOR);
}
/**绝对左移*/
public Cell[] moveLeft() {
int i;
worm Worm = new worm();
//当前蛇身的长度
int length = Worm.getBodyCellsLength();
//对蛇身数组的扩容
bodys = Arrays.copyOf(bodys, length);
for(i = length-1;i>0;i--){
if(bodys[i]==null){//如果吃了食物就会扩容,扩容的新元素为null
bodys[i]=new Cell();
}
bodys[i].col=bodys[i-1].col;
bodys[i].row=bodys[i-1].row;
}
head.left();
return bodys;
}
/**绝对左移*/
public Cell[] moveRight() {
int i;
worm Worm = new worm();
int length = Worm.getBodyCellsLength();
bodys = Arrays.copyOf(bodys, length);
for(i = length-1;i>0;i--){
if(bodys[i]==null){
bodys[i]=new Cell();
}
bodys[i].setCol(bodys[i-1].col);
bodys[i].setRow(bodys[i-1].row);
}
head.right();
return bodys;
}
/**绝对上移*/
public Cell[] goUp() {
int i;
worm Worm = new worm();
int length = Worm.getBodyCellsLength();
bodys = Arrays.copyOf(bodys, length);
for(i = length-1;i>0;i--){
if(bodys[i]==null){
bodys[i]=new Cell();
}
bodys[i].col=bodys[i-1].col;
bodys[i].row=bodys[i-1].row;
}
head.up();
return bodys;
}
/**绝对下移*/
public Cell[] goDown() {
int i;
worm Worm = new worm();
int length = Worm.getBodyCellsLength();
bodys = Arrays.copyOf(bodys, length);
for(i = length-1;i>0;i--){
if(bodys[i]==null){
bodys[i]=new Cell();
}
bodys[i].col=bodys[i-1].col;
bodys[i].row=bodys[i-1].row;
}
head.down();
return bodys;
}
public Cell[] getBody(){
return bodys;
}
public String toString(){
return Arrays.toString(bodys);
}
}
第三步 绘制动作方法和绘图
import java.awt.Color;
import java.awt.Font;
import ;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.ImageObserver;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class worm extends JPanel {
public static final int ROWS = 40;
public static final int COLS = 40;
private Cell[][] wall = new Cell[ROWS][COLS];
/** 每一格的大小规格 */
public static final int CELL_SIZE = 10;
/** 与边框的距离 */
public static final int ADD = 20;
public static final int BG_COLOR = 0xc3d5ea;
/** 背景色 */
public static final int FONT_COLOR = 0xffffff;
/** 边框线条颜色 */
public static final int BORDER_COLOR = 0x667799;
/** 食物的颜色 */
public static final int FOOD_COLOR = 0xff0000;
/** 蛇身的颜色 */
public static final int BADY_COLOR = 0x66ccff;
/** 是否吃到的判定 */
public static boolean eat = false;
/** 正在向绝对上走 */
public static boolean goingUp = false;
/** 正在向绝对下走 */
public static boolean goingDwon = false;
/** 正在向绝对右走 */
public static boolean moveingRight = false;
/** 正在向绝对左走 */
public static boolean moveingLeft = false;
/**游戏结束*/
public static boolean gameOver = false;
/**暂停判定*/
public static boolean pause = false;
/**速度*/
public static int speed;
/**分数*/
public static int score;
/** 食物 */
public static Cell food;
/** 吃到食物前一格时的最后一格 */
public Cell tempBody;
public Timer timer;
public static Body body;
/** 蛇身 */
public static Cell[] bodyCells;
public static JFrame frame = new JFrame("贪吃蛇");
public static worm panel = new worm(null);
// ------------------------------------开始---------------------------------
public worm(LayoutManager layout){
super(layout);
}
public worm(){
}
public static void main(String[] args) {
Random ra = new Random();
/** 食物 */
food = new Cell(ra.nextInt(ROWS), ra.nextInt(COLS), FOOD_COLOR);
frame.setSize((COLS +7) * CELL_SIZE-20, (ROWS+8) * CELL_SIZE + 90);
frame.setResizable(false);//禁止窗口缩放
frame.setLocationRelativeTo(null);// 窗口居中//null是窗口的相对位置,没有就是居中
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置关闭窗口就关闭软件
frame.add(panel);// 窗口中添加面板
frame.setVisible(true);// 显示窗口
panel.action();
}
/** 动作流程 */
private void action() {
startAction();
this.requestFocus();// 为当前面板请求获得输入焦点,this对象就获得了输入焦点,以后任何的键盘输入目标就是这个面板
this.addKeyListener(new KeyListener() {// 添加键盘监听,
public void keyPressed(KeyEvent e) {// 按键按下去
System.out.println("type:" + e.getKeyCode());
int key = e.getKeyCode();
if(gameOver!= true){
switch (key) {
case 'A':
if(goingUp||goingDwon){
moveLeftAction();
pause=false;
}
break;
case 'D':
if(goingUp || goingDwon){
moveRightAction();
pause=false;
}
break;
case 'W':
if(moveingRight || moveingLeft){
goUpAction();
pause=false;
}
break;
case 'S':
if(moveingLeft || moveingRight){
goDwonAction();
pause=false;
}
break;
case KeyEvent.VK_SPACE:
if(pause==false){
pauseAction();
pause=true;
}
}
repaint();
}
if(key==KeyEvent.VK_Q){
gameOver=true;
pause=false;
timer.cancel();
repaint();
}
if(gameOver){
if(key==KeyEvent.VK_ENTER){
startAction();
}
}
/**ESC 退出系统*/
if(key==KeyEvent.VK_ESCAPE){
(0);
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
}// 按键松开
public void keyTyped(KeyEvent e) {
int key = e.getKeyCode();
if(key=='T'){
(0);
}
}// 按键按一下
});
}
/**开始流程*/
public void startAction(){
gameOver = false;
pause = false;
score = 0;
level();
body = new Body();
bodyCells = body.bodys;
newFood();
moveingRight = true;
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
TempBody(bodyCells);
bodyCells = body.moveRight();
level();
gameOverAction();
bodyCells = grow(bodyCells, food, tempBody);
repaint();
}
}, 500, speed);
repaint();
}
/**结束流程*/
public void gameOverAction() {
if (gameOver()) {
System.out.println("gameOver");
timer.cancel();
}
}
private void pauseAction() {
timer.cancel();
pause = true;
}
/** 向上走流程 */
private void goUpAction() {
timer.cancel();
goingUp = true;
goingDwon = false;
moveingRight = false;
moveingLeft = false;
level();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
TempBody(bodyCells);
bodyCells = body.goUp();
gameOverAction();
bodyCells = grow(bodyCells, food, tempBody);
repaint();
}
}, 0, speed);
}
/** 向下走流程 */
private void goDwonAction() {
timer.cancel();
goingUp = false;
goingDwon = true;
moveingRight = false;
moveingLeft = false;
level();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
TempBody(bodyCells);
bodyCells = body.goDown();
gameOverAction();
bodyCells = grow(bodyCells, food, tempBody);
repaint();
}
}, 0, speed);
}
/** 向左走流程 */
private void moveLeftAction() {
timer.cancel();
goingUp = false;
goingDwon = false;
moveingRight = false;
moveingLeft = true;
level();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
TempBody(bodyCells);
bodyCells = body.moveLeft();
gameOverAction();
bodyCells = grow(bodyCells, food, tempBody);
repaint();
}
}, 0, speed);
}
/** 想右走流程 */
private void moveRightAction() {
timer.cancel();
goingUp = false;
goingDwon = false;
moveingRight = true;
moveingLeft = false;
level();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
TempBody(bodyCells);
bodyCells = body.moveRight();
gameOverAction();
bodyCells = grow(bodyCells, food, tempBody);
repaint();
}
}, 0, speed);
}
/** 吃到食物前一格时的最后一格 */
public void TempBody(Cell[] bodyCells) {
tempBody = new Cell(bodyCells[bodyCells.length - 1].row,
bodyCells[bodyCells.length - 1].col,
bodyCells[bodyCells.length - 1].color);
}
/** 增加1格 tempBody:吃到食物前一格时的最后一格 */
public Cell[] grow(Cell[] bodyCells, Cell food, Cell tempBody) {
if (eatFood(bodyCells[0], food)) {
bodyCells = Arrays.copyOf(bodyCells, bodyCells.length + 1);
bodyCells[bodyCells.length - 1] = tempBody;
score = (bodyCells.length-5)*10;
newFood();
return bodyCells;
}
return bodyCells;
}
/** 判断是否吃到食物 */
public static boolean eatFood(Cell head, Cell food) {
eat = food.row == head.row && food.col == head.col;
return eat;
}
/** 刷新食物 */
public void newFood() {
if (eat) {
Random ra = new Random();
/** 食物 */
food = new Cell(ra.nextInt(20), ra.nextInt(20), FOOD_COLOR);
for(Cell cell: bodyCells){
if(food.row==cell.row && food.col== cell.col){
newFood();
}
}
eat = false;
}
}
private void level(){
int index = 100;
int scoreIndex = score;
speed=200;
if(scoreIndex>=index){
speed-=50;
scoreIndex-=index;
}
if(scoreIndex>=index){
speed-=50;
scoreIndex-=index;
index=50;
}
if(scoreIndex>=index){
speed-=50;
scoreIndex-=index;
index=100;
}
if(scoreIndex>=index){
speed-=10;
scoreIndex-=index;
}
}
/** 游戏结束判定 */
private boolean gameOver() {
for (int i = 1; i < bodyCells.length; i++) {
gameOver = bodyCells[0].row == bodyCells[i].row
&& bodyCells[0].col == bodyCells[i].col;
if (gameOver == true) {
return gameOver;
}
}
return gameOver;
}
public int getBodyCellsLength() {
return bodyCells.length;
}
public worm getworm(){
worm we = new worm();
return we;
}
// -------------------------------------------------------------------------------------------
/** JPanel 类利用paint(图画)方法绘制界面,子类重写paint方法可以修改绘图逻辑 */
public void paint(Graphics g) {
paintBackBorder(g);
//paintWall(g);//绘制墙的格子,方便蛇的运动,但玩的时候最好注释掉,这要更美观
paintBody(g);
paintFood(g);
paintScore(g);
paintTetrisBorder(g);
}
/** 填充背景 */
private void paintBackBorder(Graphics g) {
g.setColor(new Color(0x000000));
g.fillRect(ADD, ADD+CELL_SIZE * 10, CELL_SIZE * ROWS, CELL_SIZE * COLS);
g.setColor(new Color(0xc3d5ea));
g.fillRect(ADD, ADD, CELL_SIZE *ROWS, CELL_SIZE * 10);
}
/** 绘制墙 */
private void paintWall(Graphics g) {
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
Cell cell = wall[row][col];
// 墙的格子
// g.setColor(new Color(BORDER_COLOR));
// g.drawRect(ADD +col * CELL_SIZE, ADD+10*CELL_SIZE+row * CELL_SIZE,
// CELL_SIZE, CELL_SIZE);
}
}
}
/** 绘制食物 */
private void paintFood(Graphics g) {
int row = food.getRow();
int col = food.getCol();
g.setColor(new Color(food.getColor()));
g.fill3DRect(ADD + row * CELL_SIZE, ADD + col * CELL_SIZE+CELL_SIZE * 10, CELL_SIZE,
CELL_SIZE, true);
g.setColor(new Color(0xffffff));
g.draw3DRect(ADD + row * CELL_SIZE, ADD + col * CELL_SIZE+CELL_SIZE * 10, CELL_SIZE,
CELL_SIZE, true);
}
/** 绘制蛇身 */
private void paintBody(Graphics g) {
for (Cell cell : bodyCells) {
int row = cell.getRow();
int col = cell.getCol();
g.setColor(new Color(0x66ccff));
g.fill3DRect(ADD + row * CELL_SIZE, ADD + col * CELL_SIZE+CELL_SIZE * 10,
CELL_SIZE, CELL_SIZE, true);
g.setColor(new Color(0xffffff));
g.draw3DRect(ADD + row * CELL_SIZE, ADD + col * CELL_SIZE+CELL_SIZE * 10,
CELL_SIZE, CELL_SIZE, true);
}
}
/** 绘制文字 */
private void paintScore(Graphics g) {
Font font = new Font(getFont().getName(), Font.BOLD, 35);
String str = "SCORE : " + score;
g.setColor(new Color(FONT_COLOR));
g.setFont(font);
g.drawString(str, 13 * CELL_SIZE, 7 * CELL_SIZE);
str = "[SPACE]PAUSE";
font = new Font(getFont().getName(), Font.BOLD, 20);
g.setFont(font);
g.drawString(str, 4 * CELL_SIZE, 11 * CELL_SIZE);
str = "[Q]QUIT";
g.drawString(str, 25 * CELL_SIZE, 11 * CELL_SIZE);
if(pause){
font = new Font(getFont().getName(), Font.BOLD, 100);
g.setFont(font);
str = "PAUSE";
g.drawString(str, 6 * CELL_SIZE, 35 * CELL_SIZE);
}
if(gameOver){
font = new Font(getFont().getName(), Font.BOLD, 60);
g.setFont(font);
str = "GAME OVER ";
g.drawString(str, 4 * CELL_SIZE, 25 * CELL_SIZE);
font = new Font(getFont().getName(), Font.BOLD, 20);
g.setFont(font);
str = "YOUR SCORE ";
g.drawString(str, 16 * CELL_SIZE, 30 * CELL_SIZE);
font = new Font(getFont().getName(), Font.BOLD, 100);
g.setFont(font);
str = scoreString(score);
g.drawString(str, 6 * CELL_SIZE, 40 * CELL_SIZE);
str = "[ENTER] START ";
font = new Font(getFont().getName(), Font.BOLD, 40);
g.setFont(font);
g.drawString(str, 7 * CELL_SIZE, 45* CELL_SIZE);
}
}
/** 绘制边框 */
private void paintTetrisBorder(Graphics g) {
g.setColor(new Color(BORDER_COLOR));// 绘制边线
g.drawRect(ADD, ADD+CELL_SIZE * 10, CELL_SIZE * COLS, CELL_SIZE * ROWS);
g.drawRect(ADD, ADD, CELL_SIZE*COLS, CELL_SIZE* 10);
}
private String scoreString(int score){
String str= ""+score;
for(int i=0;i<3-(str.length())/2;i++){
if(str.length()%2==0){
str+=" ";
}
if(str.length()%2!=0){
str=" "+str;
}
}
return str;
}
}
以上就是完整的代码,亲测能用,复制粘贴就用运行,基本上都有注释,看注释就能明白了,写程序加注释是很好的习惯,不然不只是用的人不知道说什么,写到后面很可能连自己都不知哪个方法是干什么的!!!
写这篇东西纯属学习上的交流,给多少分就随意把,本人觉得征文的这个系统太坑爹了,进来了居然不打分不给走(x.x)
网友评论 已有 0 条评论,查看更多评论»