一条“蛇”的故事

129 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

我是11年上的大学。现在能成为一个码农,跟当年高考选志愿有很大的关系。

我老家是湖北下面的一个N线小农村。参加完高考,家里一群人就坐在一起讨论我上大学该学什么专业,我爷爷奶奶对这些不懂,只知道我要是能上大学,他们心里就是高兴,我爸和叔叔、伯伯就建议我去学一个有技术(手艺活)的专业,将来出了学校,能有一技之长,找工作也会好找一点。其实在这之前,我们(对,我早恋了,她家里给她推荐的就是计算机专业)心里已经有了心仪的学校。至于专业我没有太大的感觉。我一直没有跟家里人商量,因为在那个时候,那样一个农村,你说电脑,也有很多人没看见过。甚至很多人都以为,电脑就等同于玩游戏,就是不务正业。

后来,来到武汉上了大学。在刚接触代码的时候,就感觉特别新奇,了解跟多的有关计算机的人和事后,就更吸引我了。在大一下学期的时候,利用一个周末做出了我人生中第一个能玩的小游戏——贪吃蛇。当看着一个个代码运行起来,进入游戏的画面的时候,别提有多高兴。特别是发给女朋友和舍友看时,听着他们一声一声的赞美,极大的满足了我内心的虚荣心~。以至于现在想想,都能有点情不自禁的嘴角上扬。自此以后,就开始了无休止的“搬砖”。 附运行代码:

package com.Timor.java_0830;

import java.awt.Graphics;

public interface Dreawable  extends Config{

	void paint(Graphics g);

	void update();

}

package com.Timor.java_0830;

import java.awt.Color;
import java.awt.Graphics;

import org.omg.CORBA.INTERNAL;

public class Bacakground implements Dreawable{

	@Override
	public void paint(Graphics g) {
		g.setColor(Color.LIGHT_GRAY);
		for(int i=1;i<WIDTH_BLOCKS;i++){
			g.drawLine(i*BLOCK_BOX, 0, i*BLOCK_BOX, WINDOW_HEIGTH);
		}
		for(int i=1;i<HEIGHT_BLOCKS;i++){
			g.drawLine(0, i*BLOCK_BOX, WINDOW_WIDTH, i*BLOCK_BOX);
		}
		
	}

	@Override
	public void update() {
		
		
	}

}

package com.Timor.java_0830;

public interface Config {
	public static final int WINDOW_WIDTH=800;
	public static final int WINDOW_HEIGTH=600;
	public static final int BLOCK_BOX=20;
	public static final int WIDTH_BLOCKS = WINDOW_WIDTH / BLOCK_BOX;
	public static final int HEIGHT_BLOCKS = WINDOW_HEIGTH / BLOCK_BOX;
	public static final int REFRESH_INTERNAL = 300;
	

}

package com.Timor.java_0830;

public enum DIRECTION {
	LEFT ,RIGHT,UP,DOWN
}

package com.Timor.java_0830;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class Food implements Dreawable {
	public int x, y;
	private Color color = Color.RED;

	public Food() {
		Random random = new Random();
		 x = random.nextInt(WIDTH_BLOCKS);
		 y = random.nextInt(WIDTH_BLOCKS);

	}

	@Override
	public void paint(Graphics g) {
		g.setColor(color);
		g.fillRect(x * BLOCK_BOX, y * BLOCK_BOX, BLOCK_BOX, BLOCK_BOX);

	}

	@Override
	public void update() {
		color = (color == Color.RED ? Color.BLUE : Color.RED);

	}

} 

package com.Timor.java_0830;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;

import javax.swing.JPanel;

import com.Timor.java_0830.Snack.STATUS;

public class Screen extends JPanel implements Dreawable {
	private Bacakground bg;
	private Food food;
	private Snack snack;
	private boolean isRunning = true;
	private int accelerate = 0;

	public Screen() {
		bg = new Bacakground();
		food = new Food();
		snack = new Snack();
		new Refreash().start();
		KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		kfm.addKeyEventPostProcessor(keyEventPostProcessor);
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		bg.paint(g);
		food.paint(g);
		snack.paint(g);
		drawGameInfo(g);
	}


	

	public void drawGameInfo(Graphics g) {
		g.setColor(Color.PINK);
		g.setFont(new Font("微软雅黑", Font.BOLD, 25));
		g.drawString("蛇吃了" + snack.getAteFoodCount() + "个食物", 20, 20);
		if (snack.getStatus() == STATUS.DEAD) {
			g.setColor(Color.BLACK);
			g.setFont(new Font("微软雅黑", Font.BOLD, 50));
			g.drawString("游戏结束", 300, 400);
		}
	}

	private KeyEventPostProcessor keyEventPostProcessor = new KeyEventPostProcessor() {

		@Override
		public boolean postProcessKeyEvent(KeyEvent e) {
			switch (e.getKeyCode()) {
			case KeyEvent.VK_UP:
				snack.setDirection(DIRECTION.UP);
				break;
			case KeyEvent.VK_DOWN:
				snack.setDirection(DIRECTION.DOWN);
				break;
			case KeyEvent.VK_LEFT:
				snack.setDirection(DIRECTION.LEFT);
				break;
			case KeyEvent.VK_RIGHT:
				snack.setDirection(DIRECTION.RIGHT);
				break;

			default:
				break;
			}
			return true;
		}
	};

	private class Refreash extends Thread {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (isRunning) {
				try {
					Thread.sleep(REFRESH_INTERNAL-accelerate);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				update();
			}
		}
	}

	public void update() {
		snack.update();
		food.update();
		snack.eatFood(food);
		snack.crash();
		if (snack.getStatus() == STATUS.DEAD) {
			// snake.reset();
			accelerate = 0;
			isRunning = false;
		} else if (snack.getStatus() == STATUS.GROWING) {
			food = new Food();
			accelerate += 50;
			if (accelerate > 250)
				accelerate = 250;
		}
		repaint();
	}

}

package com.Timor.java_0830;

import java.awt.Color;
import java.awt.Graphics;
import java.util.LinkedList;

public class Snack implements Dreawable {
	private STATUS status = STATUS.ALIVE;
	private DIRECTION direction = DIRECTION.RIGHT;
	LinkedList<Snackbody> bodyList = new LinkedList<>();
	private int ateFoodCount = 0;

	public enum STATUS {
		ALIVE, DEAD, GROWING
	}

	public Snack() {
		reset();
	}

	public void reset() {
		status=STATUS.ALIVE;
		bodyList.clear();
		bodyList.add(new Snackbody(10, 6));
		bodyList.add(new Snackbody(9, 6));
		bodyList.add(new Snackbody(8, 6));
		bodyList.add(new Snackbody(7, 6));
	}

	public void crash() {
		Snackbody head = bodyList.getFirst();
		if(head.x < 0 || head.x > WIDTH_BLOCKS || head.y < 0 || head.y > HEIGHT_BLOCKS){
			status = STATUS.DEAD;
		}
		for (int i = 1; i < bodyList.size(); i++) {
			Snackbody snakeNode = bodyList.get(i);
			if (head.x == snakeNode.x && head.y == snakeNode.y) {
				status = STATUS.DEAD;
				snakeNode.setColor(Color.CYAN);
			}
		}
	}
	public void eatFood(Food food){
		Snackbody head = bodyList.getFirst();
		boolean isAteFood = (head.x == food.x && head.y == food.y);
		if(isAteFood) {
			status = STATUS.GROWING;
			ateFoodCount++;
		}
	}
	public int getAteFoodCount() {
		return ateFoodCount;
	}

	@Override
	public void paint(Graphics g) {
		for (Snackbody body : bodyList) {
			body.paint(g);
		}

	}
	public STATUS getStatus() {
		return status;
	}

	@Override
	public void update() {
		// TODO Auto-generated method stub
		Snackbody oldHead = bodyList.getFirst();
		Snackbody newHead = null;
		if (direction == DIRECTION.UP) {
			newHead = new Snackbody(oldHead.x, oldHead.y - 1);
		} else if (direction == DIRECTION.DOWN) {
			newHead = new Snackbody(oldHead.x, oldHead.y + 1);
		} else if (direction == DIRECTION.LEFT) {
			newHead = new Snackbody(oldHead.x - 1, oldHead.y);
		} else if (direction == DIRECTION.RIGHT) {
			newHead = new Snackbody(oldHead.x + 1, oldHead.y);
		}
		bodyList.addFirst(newHead);
		if(status != STATUS.GROWING) bodyList.removeLast(); else status = STATUS.ALIVE;
	}
	public void setDirection(DIRECTION direction) {
		if(this.direction == DIRECTION.UP && direction == DIRECTION.DOWN) return;
		if(this.direction == DIRECTION.DOWN && direction == DIRECTION.UP) return;
		if(this.direction == DIRECTION.LEFT && direction == DIRECTION.RIGHT) return;
		if(this.direction == DIRECTION.RIGHT && direction == DIRECTION.LEFT) return;
		this.direction = direction;
	}

	public class Snackbody implements Dreawable {
		private int x, y;
		private Color color = Color.BLACK;

		public void setColor(Color color) {
			this.color = color;
		}

		public Snackbody(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		@Override
		public void paint(Graphics g) {
			g.setColor(color);
			g.fillRect(x * BLOCK_BOX, y * BLOCK_BOX, BLOCK_BOX, BLOCK_BOX);
		}

		@Override
		public void update() {
			// TODO Auto-generated method stub

		}

	}

}

package com.Timor.java_0830;

import java.awt.Dimension;

import javax.swing.JFrame;

public class SnackTest extends JFrame implements Config {
	private static Screen screen;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SnackTest st = new SnackTest();
		Dimension ds = st.getToolkit().getScreenSize();
		int x = (ds.width - WINDOW_WIDTH) / 2;
		int y = (ds.height - WINDOW_HEIGTH) / 2;
		st.setBounds(x, y, WINDOW_WIDTH, WINDOW_HEIGTH);
		st.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		screen=new Screen();
		st.add(screen);
		st.setVisible(true);

	}

}

——————代码很青涩,仅供把玩。