贪吃蛇(定时器控制)

接上篇

SnakePanel类
package game.snake.first_try;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.nio.DoubleBuffer;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class SnakePanel extends JPanel implements KeyListener, ActionListener{
	//加载图片
	ImageIcon up = new ImageIcon("up.png");
	ImageIcon down = new ImageIcon("down.png");
	ImageIcon right = new ImageIcon("right.png");
	ImageIcon left = new ImageIcon("left.png");
	ImageIcon body = new ImageIcon("body.png");
	ImageIcon food = new ImageIcon("food.png");
	ImageIcon title = new ImageIcon("title.png");
	
	//数组来存放蛇身体节点的坐标
	int[] snakex = new int[850];
	int[] snakey = new int[850];
	
	int len = 3;  //初始长度
	int score = 0;//初始分数
	String direction = "R"; //初始方向
	
	Random random = new Random();
	//随机生成食物
	int foodx = random.nextInt(36) * 25 + 25; //25-925
	int foody = random.nextInt(24) * 25 + 75; //75-675
	
	boolean foodFitFlag = true;
	boolean isStarted = false;
	boolean isFaild = false;
	
	Timer timer = new Timer(150,this);
	
	public SnakePanel() {
		this.setFocusable(true); 
		initSnake();
		this.addKeyListener(this);
		timer.start();
	}
	
	//初始化
	public void initSnake() {
		isFaild = false;
		isStarted = false;
		len = 3;
		score = 0;
		direction = "R";
		snakex[0] = 100; 
		snakey[0] = 100; 
		snakex[1] = 75; 
		snakey[1] = 100; 
		snakex[2] = 50; 
		snakey[2] = 100;	
	}
	
	//判断食物生成位置是否在蛇身
	public boolean isFoodFit() {
		for (int i = 0; i < len; i++) {
			if(foodx == snakex[i] && foody == snakey[i]) {
				return false; //食物生成在蛇身
			}
		}
		return true;
	}
	
	/** 画板*/
	public void paint(Graphics g) {
		//画背景
		this.setBackground(Color.BLACK);
		g.fillRect(25, 75, 900, 625);
		//画标头
		title.paintIcon(this, g, 25, 10);
		//画蛇头
		if(direction.equals("R")) {
			right.paintIcon(this, g, snakex[0], snakey[0]);	
		}else if(direction.equals("L")) {
			left.paintIcon(this, g, snakex[0], snakey[0]);	
		}else if(direction.equals("U")) {
			up.paintIcon(this, g, snakex[0], snakey[0]);	
		}else if(direction.equals("D")) {
			down.paintIcon(this, g, snakex[0], snakey[0]);	
		}
		//画蛇身
		for(int i=1; i<len; i++) {
			body.paintIcon(this, g, snakex[i], snakey[i]);
		}
		//开始游戏提示字幕
		if(!isStarted) {
			g.setColor(Color.WHITE);
			g.setFont(new Font("arial",Font.BOLD,30));
			g.drawString("Press Space to Start or Pause", 230, 350);
		}
		//游戏结束提示
		if(isFaild) {
			g.setColor(Color.WHITE);
			g.setFont(new Font("arial",Font.BOLD,30));
			g.drawString("Game Over,Press Space to Start", 230, 350);
		}
		//画食物
		foodFitFlag = true;
		while(foodFitFlag) {
			if (isFoodFit()) {
				//食物位置合适
				food.paintIcon(this, g, foodx, foody);
				foodFitFlag = false;
			}else {
				//不合适重新生成
				foodx = random.nextInt(36) * 25 + 25;
				foody = random.nextInt(24) * 25 + 75;
			}
		}
		
		//分数显示
		g.setColor(Color.WHITE);
		g.setFont(new Font("arial",Font.PLAIN,15));
		g.drawString("Score: " + score, 800, 35);
		g.drawString("Length: " + len, 800, 55);
	}

	/** 键盘事件*/
	@Override
	public void keyPressed(KeyEvent arg0) {
		//开始暂停控制
		int keyCode = arg0.getKeyCode();
		if(keyCode == KeyEvent.VK_SPACE) {
			if(isFaild) {
				initSnake();
			}else{
				isStarted = !isStarted;
			}
		//设移动控制
		}else if(keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
			direction = "U";
		}else if(keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
			direction = "D";
		}else if(keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
			direction = "L";
		}else if(keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
			direction = "R";
		}
		
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO 自动生成的方法存根
		
	}

	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		timer.start();
		if(isStarted && !isFaild) {
			//蛇身移动----每个结点等于其前面结点的坐标
			for(int i=len; i>.0; i--) {
				snakex[i] = snakex[i-1];
				snakey[i] = snakey[i-1];
			}
			//蛇头移动
			if(direction.equals("R")) {
				snakex[0] = snakex[0] + 25;
				if(snakex[0] > 900) snakex[0] = 25;
			}else if(direction.equals("L")) {
				snakex[0] = snakex[0] - 25;	
				if(snakex[0] < 25) snakex[0] = 900;
			}else if(direction.equals("U")) {
				snakey[0] = snakey[0] - 25;
				if(snakey[0] < 75) snakey[0] = 675;
			}else if(direction.equals("D")) {
				snakey[0] = snakey[0] + 25;	
				if(snakey[0] > 675) snakey[0] = 75;
			}
			if(snakex[0] == foodx && snakey[0] == foody) {
				len++;
				score++;
				foodx = random.nextInt(36) * 25 + 25;
				foody = random.nextInt(22) * 25 + 75;
			}
			//失败判定
			for(int i = 1; i < len; i++) {
				if(snakex[0] == snakex[i] && snakey[0] == snakey[i]) {
					isFaild = true;
				}
			}
		}
		repaint();
	}

}

主类 Snack类
package game.snake.first_try;

import javax.swing.JFrame;

public class Snake {

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		
		frame.setBounds(550, 200, 950, 750);	//边界
		frame.setTitle("贪吃蛇1.0");		//标题
		frame.setResizable(false);		//能否改变大小
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	//退出方式
		
		frame.add(new SnakePanel());
				
		frame.setVisible(true);
	}

}

尾言

其实,定时器版和双缓冲版 对这个版本的贪吃蛇 作用并不大,或者说没有作用。主要还是因为,他的坐标是25的加的,即使他的加载很流畅,但是因为每次都是25的跨度,所以还是会有闪烁。不过这次经历确实给了我很多东西,还算不错。人生不止,代码不断。?加油!

你可能感兴趣的:(个人总结)