`
沙舟狼客
  • 浏览: 157680 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jogl入门之简单的贪吃蛇

阅读更多

1、代码:

 

package org.ligson.jogl.test;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.swing.JFrame;

import org.ligson.jogl.test.SnakeDemo.Dir;
/*
 * 事物只有一个
 */
public class SnakeDemo extends JFrame implements GLEventListener, Runnable,
		KeyListener {

	//产生食物随机坐标
	Random random = new Random();

	//枚举方向
	enum Dir {
		UP(1), DOWN(2), LEFT(3), RIGHT(4);
		final int d;

		private Dir(int d) {
			this.d = d;
		}

		public int getDir() {
			return this.d;
		}
	}

	//速度
	float speed = 10.0f;
	//长度
	int len = 5;

	// gl库的handler,相当于画笔
	GL gl;
	// 画布
	GLCanvas canvas;
	// 指定了一套OpenGL的功能:渲染内容必须支持,如色彩深度,以及立体是否已启用。
	GLCapabilities capabilities;

	Thread thread = new Thread(this);

	
	//蛇集合
	List<Snake> snakes = new ArrayList<Snake>();
	//食物集合
	List<Food> foods = new ArrayList<Food>();

	public SnakeDemo() {
		super("Demo4");
		this.setSize(500, 500);
		//屏幕中心
		this.setLocationRelativeTo(null);
		this.setResizable(false);

		capabilities = new GLCapabilities();
		canvas = new GLCanvas(capabilities);

		canvas.addGLEventListener(this);

		this.addKeyListener(this);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		this.add(canvas, BorderLayout.CENTER);

		thread.start();
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			canvas.display();
			//检查撞击
			checkHit();
		}
	}

	@Override
	public void display(GLAutoDrawable drawable) {
		gl.glClear(GL.GL_COLOR_BUFFER_BIT);
		gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glColor3f(1.0f, 0.0f, 0.0f);

		painSnakes();
		painFoods();

		gl.glFlush();
	}

	@Override
	public void displayChanged(GLAutoDrawable drawable, boolean arg1,
			boolean arg2) {

	}

	@Override
	public void init(GLAutoDrawable drawable) {
		gl = drawable.getGL();
		gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);

		gl.glShadeModel(GL.GL_FLAT);
		gl.glFrontFace(GL.GL_CW);

		//初始化蛇
		for (int i = 0; i < len; i++) {
			Snake snake = new Snake(10.0f, 10.0f, 0.0f, i * 10.0f, Dir.UP);
			snakes.add(snake);
		}
		//初始化食物
		Food food = new Food(10.0f, 10.0f, random.nextInt(250),
				random.nextInt(250));
		foods.add(food);
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
		if (h == 0) {
			h = 1;
		}

		int windowWidth;
		int windowHeight;

		gl.glViewport(0, 0, w, h);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();

		if (w <= h) {
			windowWidth = 250;
			windowHeight = 250 * h / w;
		} else {
			windowWidth = 250 * w / h;
			windowHeight = 250;
		}
		//重新定义世界坐标系,以窗口中心为(0,0,0)
		gl.glOrtho(0 - windowWidth, windowWidth, 0 - windowHeight,
				windowHeight, 250.0f, -250.0f);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();

	}

	public static void main(String[] args) {
		SnakeDemo demo = new SnakeDemo();
		demo.setVisible(true);
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		switch (key) {
		case KeyEvent.VK_UP:
			//防止向相反方向走
			if (snakes.get(0).getDir() != Dir.DOWN) {
				snakes.get(0).setDir(Dir.UP);
			}
			break;
		case KeyEvent.VK_DOWN:
			if (snakes.get(0).getDir() != Dir.UP) {
				snakes.get(0).setDir(Dir.DOWN);
			}
			break;
		case KeyEvent.VK_LEFT:
			if (snakes.get(0).getDir() != Dir.RIGHT) {
				snakes.get(0).setDir(Dir.LEFT);
			}
			break;

		case KeyEvent.VK_RIGHT:
			if (snakes.get(0).getDir() != Dir.LEFT) {
				snakes.get(0).setDir(Dir.RIGHT);
			}
			break;
		case KeyEvent.VK_EQUALS:
			len++;
			break;
		case KeyEvent.VK_MINUS:
			len--;
			if (len < 1) {
				len = 1;
			}
			break;
		default:
			break;
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {

	}

	private void painSnakes() {
		int abs = len - snakes.size();
		if (abs > 0) {
			for (int i = 0; i < abs; i++) {
				Snake lastSnake = snakes.get(snakes.size() - 1);
				Snake newSnake = new Snake(10.0f, 10.0f, lastSnake.getX() + 10,
						lastSnake.getY() + 10, lastSnake.getDir());
				snakes.add(newSnake);
			}
		} else if (abs < 0) {
			for (int i = 0; i < -abs; i++) {
				snakes.remove(snakes.size() - 1);
			}
		}

		for (int i = snakes.size() - 1; i >= 1; i--) {

			Snake tmpSnake = snakes.get(i);
			Snake prevSnake = snakes.get(i - 1);
			tmpSnake.setX(prevSnake.getX());
			tmpSnake.setY(prevSnake.getY());
			tmpSnake.setDir(prevSnake.getDir());

		}

		Snake snake = snakes.get(0);
		int h = getContentPane().getHeight();
		int w = getContentPane().getWidth();

		switch (snake.getDir().getDir()) {
		case 1:
			if ((snake.getY() + speed - 10.0f) > (h / 2.0)) {
				snake.setY(-250.0f);
			} else {
				snake.setY(snake.getY() + speed);
			}

			break;
		case 2:
			if ((snake.getY() + speed + snake.getHeight()) < -(h / 2.0)) {
				snake.setY(250.0f);
			} else {
				snake.setY(snake.getY() - speed);
			}

			break;
		case 3:
			if ((snake.getX() + speed + snake.getWidth()) < -(w / 2.0)) {
				snake.setX(250.0f);
			} else {
				snake.setX(snake.getX() - speed);
			}
			break;
		case 4:
			if ((snake.getX() + speed - 10.0f) > (w / 2.0)) {
				snake.setX(-250.0f);
			} else {
				snake.setX(snake.getX() + speed);
			}
			break;
		}
		snakes.set(0, snake);

		for (Snake snake2 : snakes) {
			snake2.pain(gl);
		}
	}

	private void painFoods() {
		if (foods.size() == 0) {
			Food food = new Food(10.0f, 10.0f, random.nextInt(250),
					random.nextInt(250));
			foods.add(food);
		}

		for (Food food : foods) {
			food.pain(gl);
		}
	}

	private void checkHit() {
		for (Snake snake : snakes) {
			for (Food food : foods) {
				if (Math.abs(snake.getX() - food.getX()) < 10.0f
						&& Math.abs(snake.getY() - food.getY()) < 10.0f) {
					len++;
					foods.remove(food);
					break;
				}
			}
		}
	}
}

class Food {
	private float width = 10.0f;
	private float height = 10.0f;
	private float x = 0.0f;
	private float y = 0.0f;

	public Food(float width, float height, float x, float y) {
		super();
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
	}

	public float getWidth() {
		return width;
	}

	public void setWidth(float width) {
		this.width = width;
	}

	public float getHeight() {
		return height;
	}

	public void setHeight(float height) {
		this.height = height;
	}

	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
	}

	public void pain(GL gl) {
		gl.glBegin(GL.GL_QUADS);
		gl.glVertex3f(this.x, this.y, 0.0f);
		gl.glVertex3f(this.x, this.y + height, 0.0f);
		gl.glVertex3f(this.x + width, this.y + height, 0.0f);
		gl.glVertex3f(this.x + width, this.y, 0.0f);
		gl.glEnd();
	}

}

class Snake {
	private float width = 10.0f;
	private float height = 10.0f;
	private float x = 0.0f;
	private float y = 0.0f;
	private Dir dir = Dir.UP;

	private Random random = new Random();

	public Snake(float width, float height, float x, float y, Dir dir) {
		super();
		this.width = width;
		this.height = height;
		this.x = x;
		this.y = y;
		this.dir = dir;
	}

	public float getWidth() {
		return width;
	}

	public void setWidth(float width) {
		this.width = width;
	}

	public float getHeight() {
		return height;
	}

	public void setHeight(float height) {
		this.height = height;
	}

	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
	}

	public Dir getDir() {
		return dir;
	}

	public void setDir(Dir dir) {
		this.dir = dir;
	}

	public float[] getPoints() {
		return null;
	}

	public void pain(GL gl) {
		gl.glColor3f(random.nextFloat(), random.nextFloat(), random.nextFloat());
		gl.glBegin(GL.GL_QUADS);
		gl.glVertex3f(this.x, this.y, 0.0f);
		gl.glVertex3f(this.x, this.y + height, 0.0f);
		gl.glVertex3f(this.x + width, this.y + height, 0.0f);
		gl.glVertex3f(this.x + width, this.y, 0.0f);
		gl.glEnd();
	}

	public String toString() {
		return "X:" + this.x + ";Y:" + this.y;

	}
}
 

2、jogl需要的库

http://ligson.iteye.com/blog/1331528

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics