您的位置:首页 > 编程语言 > Java开发

纯Java开发的游戏引擎V0.4--DEMO -- 物理引擎

2011-04-22 10:39 489 查看
项目命名:
JPhysicalEngine

项目目的:
自己爱好/毕业设计

项目人员: http://blog.csdn.net/kakashi8841
运行机器:
Intel P8600 2.4GHz、2G内存、Intel GMA X4500 HD

开发环境:
Linux UBuntu 10.10

开发语言:
Java

开发工具:
Eclipse

项目描述:
使用Java开发的2D游戏物理引擎,可以使得以后开发类似愤怒的小鸟、雷电等物理、碰撞、动作类游戏可以更快速、更方便。

项目进度:

【已实现】


版本 完成日期 实现功能

V0.1 [2011-04-07] 大致框架

V0.2 [2011-04-11] 基本动画

V0.3 [2011-04-15] 恒力和AABB碰撞检测

V0.4 [2011-04-22] 框架优化、简单粒子系统

【待实现】


版本 计划完成日期 实现功能

V0.5 [2011-05-05] 更精确的OBB碰撞检测

V0.6 [2011-05-10] 变力

V0.7 [2011-05-12] 更完善的粒子系统

V0.8 [2011-05-17] 弹力、引力

V0.9 [2011-05-20] 框架优化、简单的输入输出操作



目前引用***引擎做的DEMO:




















这个DEMO主要是这样的:

1、移动鼠标,左下角的箭头方向会指向你的鼠标

2、按住左键,会蓄力(看到左上角那个蓄力条吗)。蓄力越多,松开左键发出的子弹(那些红色和蓝色的方块)越多,速度越快。最多10个^_^

3、每按一次鼠标右键,可以发射一颗子弹。

4、小球碰到子弹会有简单粒子效果(那些绿色矩形)产生,而且速度会叠加(同向加速/反向减速),子弹水平速度为0。



引入***引擎后的DEMO代码:



/*
 * org.ubird.demo.Demo.java
 * CREATED ON 2011-4-3 上午10:53:37
 * COPYRIGHT 2011 CNDW.COM. ALL RIGHTS RESERVED.
 * USE IS SUBJECT TO LICENSE TERMS.
 */
package org.ubird.demo;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import org.ubird.app.SimpleGame;
import org.ubird.collision.CollisionDetector;
import org.ubird.force.GravityForce;
import org.ubird.force.StaticForce;
import org.ubird.scene.ImageNode;
import org.ubird.scene.Node;
import org.ubird.scene.NumberNode;
import org.ubird.scene.RectangleNode;
import org.ubird.scene.Vector;
import org.ubird.scene.particle.ParticleNode;
import org.ubird.scene.particle.ParticleSystem;
/**
 * 测试类1
 * @author junhong.c
 * @version 1.0
 * @date 2011-4-3
 */
public class DemoGame extends SimpleGame{
	private Node sprite1;
	private Node sprite2;
	private Node arrow;
	
	private Node floor;
	private Node rightWall;
	
	private ParticleNode p = ParticleSystem.getParticles(200,20,20,5);
	private ParticleNode p2 = ParticleSystem.getParticles(200,15,15,10);
	
	private Node[] bullet = new ImageNode[20];
	private int current = 0;
	private Node leftWall;
	
	private boolean isPress = false;
	private int power = 0;
	private NumberNode powerNode;
	
	public DemoGame() {
		super("Java2D游戏引擎 V0.4.0 -- By John.Cha");
	}
	public static void main(String[] args) throws IOException {
		SimpleGame game = new DemoGame();
		game.setFPS(60);
		game.setStageBackground("resources/bg.png");
		game.setStageSize(1000,600);
		game.start();
	}
	@Override
	public void initWorld() {
		initScene();
		initNode();
		initEvent();
	}
	
	/**
	 * 事件
	 */
	private void initEvent() {
		addMouseAdapter(new MyMouseListener());
	}
	/**
	 * 定义自己的事件监听
	 * @author junhong.c
	 * @version 1.0
	 * @date 2011-4-21
	 */
	class MyMouseListener extends MouseAdapter{
		
		/**
		 * 旋转箭头
		 */
		@Override
		public void mouseMoved(MouseEvent e) {
			float shita = getRotate(e);
			arrow.rotate(shita);
		}
		
		/**
		 * 蓄力
		 */
		@Override
		public void mousePressed(MouseEvent e){
			isPress = true;
		}
		
		/**
		 * 发射子弹
		 */
		@Override
		public void mouseReleased(MouseEvent e) {
			isPress = false;
			if(e.getButton()==3){
				float shita = getRotate(e);
				float v = 0.5f;
				float x = arrow.getLocation().getX()+arrow.getWidth();
				
				bullet[current].setLocation((float) (x*Math.cos(shita)), arrow.getLocation().getY()+arrow.getHeight()/2-(float) (x*Math.sin(shita)));
				bullet[current].setVelocity(new Vector((float) (v*Math.cos(shita)),-(float) (v*Math.sin(shita))));
				current = ++current%bullet.length;
			}else{
				int num = (power+1)%100/10;
				
				for(int i=0; i<num; i++){
					float shita = getRotate(e);
					float v = power/160f;
					float x = arrow.getLocation().getX()+arrow.getWidth();
					
					bullet[current].setLocation((float) (x*Math.cos(shita)), arrow.getLocation().getY()+arrow.getHeight()/2-(float) (x*Math.sin(shita)));
					bullet[current].setVelocity(new Vector((float) (v*Math.cos(shita)),-(float) (v*Math.sin(shita))));
					bullet[current].setDelay(i*7);
					current = ++current%bullet.length;
				}
			}
			
		}
		
		private float getRotate(MouseEvent e){
			int y = getStageHeight();
			float shita = e.getX()==0 ? 0 : 
				(float) Math.atan( ((double)y-e.getY()) / e.getX() );
			return shita;
		}
	}
	
	/**
	 * 场景 
	 */
	private void initScene() {
		floor = new RectangleNode();
		floor.setSize(getStageWidth(),20);
		floor.setLocation(0,getStageHeight()-20);
		floor.setFill(true);
		add(floor);
		
		rightWall = new RectangleNode();
		rightWall.setSize(20,getStageHeight());
		rightWall.setLocation(getStageWidth()-rightWall.getWidth(),0);
		rightWall.setFill(true);
		add(rightWall);
		
		leftWall = new RectangleNode();
		leftWall.setSize(20,getStageHeight());
		leftWall.setLocation(0,0);
		leftWall.setFill(true);
		add(leftWall);
		
		powerNode = new NumberNode();
		powerNode.setMaxNumber(100);
		powerNode.setSize(300,15);
		powerNode.setLocation(40,20);
		add(powerNode);
		
		add(p);
		add(p2);
	}
	/**
	 * 
	 */
	private void initNode() {
		
		/**
		 * 初始化子弹
		 */
		try {
			for(int i=0; i<bullet.length; i++){
				bullet[i] = new ImageNode("resources/bullet.png",i%2*35,0,35,35);
				bullet[i].addStaticForce(new GravityForce(3f));
				bullet[i].setSize(35,35);
				bullet[i].setLocation(-500,-500);
				add(bullet[i]);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			sprite1 = new ImageNode("resources/bullet.png",70,0,35,35);	//平抛
			sprite1.setSize(35,35);
			sprite1.setLocation(250,100);
			sprite1.setVelocity(new Vector(-0.2f,0));
			sprite1.setFill(true);
			sprite1.setBackgroundColor(Color.GREEN);
			sprite1.addStaticForce(new GravityForce(10.8f));
			sprite1.setMass(10);
			add(sprite1);
		} catch (IOException e1) {
			e1.printStackTrace();
		};
		
		
		try {
			sprite2 = new ImageNode("resources/chrome.png");	//平抛--图像结点
			sprite2.setSize(25,25);
			sprite2.setLocation(100,10);
			sprite2.setVelocity(new Vector(0.2f,0));
			sprite2.addStaticForce(new GravityForce(10.8f));
			sprite2.setMass(10);
			add(sprite2);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			arrow = new ImageNode("resources/arrow.png");	//平抛--图像结点
			arrow.setSize(60,30);
			arrow.setCenter(0,arrow.getHeight()/2);
			arrow.setLocation(20,floor.getLocation().getY()-arrow.getHeight()/2);
			arrow.setMass(10);
			add(arrow);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void updateWorld(long time) {
		sprite1.update(time);
		sprite2.update(time);
		arrow.update(time);
		
		p.update(time);
		p2.update(time);
		
		for(int i=0; i<bullet.length; i++){
			if(bullet[i]!=null){
				bullet[i].update(time);
			}
		}
		
		if(isPress){
			power = power%100+1; 
		}else{
			if(power>0)
				power--;
		}
		powerNode.setNumber(power);
		powerNode.update(time);	//显示数字的结点
		
		if(CollisionDetector.aabb(sprite2, floor)){
			sprite2.getVelocity().setY(-sprite2.getVelocity().getY());
			p.start(sprite2.getLocation().getIntX()+sprite2.getWidth()/2, sprite2.getLocation().getIntY()+sprite2.getHeight()/2);
			//TODO 碰撞后的解决应该更精确
		}
		if(CollisionDetector.aabb(sprite2, leftWall) || CollisionDetector.aabb(sprite2, rightWall)){
			sprite2.getVelocity().setX(-sprite2.getVelocity().getX());
			//TODO 碰撞后的解决应该更精确
		}
		
		if(sprite1.getLocation().getY() >= getStageHeight()-20-sprite1.getHeight()){	//检测和地板的碰撞
			sprite1.getLocation().setY(getStageHeight()-20-sprite1.getHeight());
			sprite1.getVelocity().setY(sprite1.getVelocity().getY()*-1);	//速度Y反向
		}
		if(sprite1.getLocation().getX() >= getStageWidth()-sprite1.getWidth()){
			sprite1.getLocation().setX(getStageWidth()-sprite1.getWidth());
			sprite1.getVelocity().setX(sprite1.getVelocity().getX()*-1);	//速度X反向
		}
		if(sprite1.getLocation().getX() <= 0 ){
			sprite1.getLocation().setX(0);
			sprite1.getVelocity().setX(sprite1.getVelocity().getX()*-1);	//速度X反向
		}
		
		for(int i=0; i<bullet.length; i++){
			if(bullet[i]!=null){
				if(CollisionDetector.aabb(bullet[i], sprite1)){	
					sprite1.getVelocity().add(new Vector(bullet[i].getVelocity().getX(),0));
					p2.start(sprite1.getLocation().getIntX()+sprite1.getWidth()/2, sprite1.getLocation().getIntY()+sprite1.getHeight()/2);
					bullet[i].getVelocity().setX(0);
				}
				if(CollisionDetector.aabb(bullet[i], sprite2)){	//和精灵2碰撞,爆炸
					bullet[i].getVelocity().setX(0);
					p.start(sprite2.getLocation().getIntX()+sprite2.getWidth()/2, sprite2.getLocation().getIntY()+sprite2.getHeight()/2);
					sprite2.setLocation(-500, -500);
					sprite2.setVelocity(new Vector(0,0));
					sprite2.removeAllForce();
				}
			}
		}
		
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: