纯Java开发的游戏引擎V0.5

项目命名: JPhysicalEngine
项目目的: 自己爱好/毕业设计
项目人员:
运行机器: 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]  框架优化、简单的输入输出操作

赶紧弄了0.5版本。修改了碰撞底层的实现。
这个DEMO和上一个DEMO 的区别:

1、从updateWorld里面的碰撞检测看到,这个检测很方便。
2、底层判断已经使用了SAT判断。
3、修改了按键部分的BUG。
4、代码依然很少。
目前引用自制引擎做的DEMO2:

纯Java开发的游戏引擎V0.5

引入了引擎的DEMO代码:

/****************************************************************************    * org.ubird.demo.Demo2.java    *    * 该类属于JPhysicalEngine游戏引擎中的一部分。JPhysicalEngine游戏引擎    * 使用Java开发,是一款可以免费学习使用的2D游戏引擎。    *    ****************************************************************************    * Apache Licence 2.0    ****************************************************************************    *    * Copyright 2011 蔡俊鸿    *    * Licensed under the Apache License, Version 2.0 (the "License");    * you may not use this file except in compliance with the License.    * You may obtain a copy of the License at    *    *         *    * Unless required by applicable law or agreed to in writing, software    * distributed under the License is distributed on an "AS IS" BASIS,    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    * See the License for the specific language governing permissions and    * limitations under the License.    ****************************************************************************     *     * 创建于:2011-4-23    * @since JDK1.6    *    ****************************************************************************/   package org.ubird.demo;       import java.awt.Image;    import java.awt.event.KeyEvent;    import java.awt.event.KeyListener;    import java.io.IOException;    import javax.imageio.ImageIO;       import org.ubird.app.SimpleGame;    import org.ubird.collision.CollisionDetector;    import org.ubird.collision.CollisionResult;    import org.ubird.scene.node.ImageNode;    import org.ubird.scene.node.Node;    import org.ubird.scene.particle.ParticleNode;    import org.ubird.scene.particle.ParticleSystem;    import org.ubird.sound.SoundManager;    /**    * 测试类2    * @author junhong.c    * @version 1.0    * @version 1.1 [2011-05-05] 调整了碰撞检测部分的代码    * @version 1.1 [2011-05-05] 增加了按V可以显示物体的轴的功能    * @version 1.1 [2011-05-05] 增加了按B可以显示物体的边界的功能    * @date 2011-4-23    */   public class Demo2 extends SimpleGame{        private Node player;                private ParticleNode bombParticle = ParticleSystem.getParticles(500,15,15,10);        private ParticleNode hitParticle = ParticleSystem.getParticles(500,15,15,10);                private ImageNode[] bullets = new ImageNode[40];        private int currentBullet = 0;                private long delay;     //子弹延时        private boolean fire;        private boolean fire2;        private boolean fire3;        private boolean down;        private boolean up;        private boolean right;        private boolean left;        private Node[]  enemys = new ImageNode[7];        private Thread keyProcessThread;                public Demo2() {            super("Java2D游戏引擎 V0.5.0 -- By John.Cha");        }        public static void main(String[] args) throws IOException {            SimpleGame game = new Demo2();            game.setFPS(60);            game.setStageBackground("resources/bg.png");            game.setStageSize(1000,600);            game.start();        }           @Override       public void initWorld() {            initScene();            initNode();            initEvent();        }                /**        * 事件        */       private void initEvent() {            addKeyListener(new MyKeyListener());        }        /**        * 定义自己的事件监听        * @author junhong.c        * @version 1.0        * @date 2011-4-22        */       private class MyKeyListener implements KeyListener{            @Override           public void keyTyped(KeyEvent e) {                if(e.getKeyChar()=='v'){                    setDrawAxes(!isDrawAxes());                }                if(e.getKeyChar()=='b'){                    setDrawBounds(!isDrawBounds());                }            }            @Override           public void keyReleased(KeyEvent e) {                switch(e.getKeyCode()){                    case KeyEvent.VK_W :                        up=false;                        break;                    case KeyEvent.VK_S:                        down=false;                        break;                    case KeyEvent.VK_D:                        right=false;                        break;                    case KeyEvent.VK_A:                        left=false;                        break;                    case KeyEvent.VK_J:                        fire=false;                        break;                    case KeyEvent.VK_K:                        fire2=false;                        break;                    case KeyEvent.VK_L:                        fire3=false;                        break;                }            }            @Override           public void keyPressed(KeyEvent e) {                if(fire && e.getKeyCode()==KeyEvent.VK_A) return;                if(fire2 && e.getKeyCode()==KeyEvent.VK_S) return;                if(fire3 && e.getKeyCode()==KeyEvent.VK_D) return;                if(up && e.getKeyCode()==KeyEvent.VK_UP) return;                if(down && e.getKeyCode()==KeyEvent.VK_DOWN) return;                if(left && e.getKeyCode()==KeyEvent.VK_LEFT) return;                if(right && e.getKeyCode()==KeyEvent.VK_RIGHT) return;                                switch(e.getKeyCode()){                    case KeyEvent.VK_W :                        up=true;                        break;                    case KeyEvent.VK_S:                        down=true;                        break;                    case KeyEvent.VK_D:                        right=true;                        break;                    case KeyEvent.VK_A:                        left=true;                        break;                    case KeyEvent.VK_I:                        bombParticle.start(player.getLocation().getIntX()-player.getWidth()/2-3,player.getLocation().getIntY()-player.getHeight());                        break;                    case KeyEvent.VK_J:                        fire=true;                        break;                    case KeyEvent.VK_K:                        fire2=true;                        break;                    case KeyEvent.VK_L:                        fire3=true;                        break;                }                if(!getKeyProcessThread().isAlive())                    getKeyProcessThread().start();            }        }        /**        * 场景         */       private void initScene() {            add(bombParticle);            add(hitParticle);        }                /**        * 处理按键的线程        * @return        */       public Thread getKeyProcessThread(){            if(keyProcessThread==null){                keyProcessThread = new Thread(){                    public void run(){                        try {                            while(true){                                Thread.sleep(getSPF());                                float v = 0.2f;                                if(up)                                    player.getVelocity().setY(-v);                                else if(down)                                    player.getVelocity().setY(v);                                                                if(left)                                    player.getVelocity().setX(-v);                                else if(right)                                    player.getVelocity().setX(v);                                                                if(!(up||down))                                    player.getVelocity().setY(0);                                                                if(!(left||right))                                    player.getVelocity().setX(0);                                                                if( fire ){                                    if(delay <= System.currentTimeMillis()){                                        for(int i=0; i<2; i++){                                            bullets[currentBullet].getVelocity().setY(-v*2f);                                            bullets[currentBullet].getVelocity().setX(0);                                            int fix = i == 0 ? -15 : 15;                                            bullets[currentBullet].rotate(0);                                            float x = player.getLocation().getX()+(player.getWidth() - bullets[currentBullet].getWidth())*0.5f;                                            bullets[currentBullet].setLocation(fix+x, player.getLocation().getY()-bullets[currentBullet].getHeight());                                            bullets[currentBullet].rotate(0);                                                                                        currentBullet = ++currentBullet%bullets.length;                                            SoundManager.play("resources/sound/bullet.wav");                                                                                    }                                        delay = System.currentTimeMillis()+80;                                    }                                }                                                                if(fire2){                                    if(delay <= System.currentTimeMillis()){                                        for(int i=0; i<3; i++){                                            bullets[currentBullet].getVelocity().setY(-v*2f);                                            int fix = i == 0 ? -15 : i==2 ? 15 : 0;                                            float vx = i==0 ? -v/4 : i==1 ? 0 : v/4;                                            bullets[currentBullet].getVelocity().setX(vx);                                            bullets[currentBullet].rotate(0);                                                                                        float x = player.getLocation().getX()+(player.getWidth() - bullets[currentBullet].getWidth())*0.5f;                                            bullets[currentBullet].setLocation(fix+x, player.getLocation().getY()-bullets[currentBullet].getHeight());                                            bullets[currentBullet].rotate(0);                                                                                        currentBullet = ++currentBullet%bullets.length;                                            SoundManager.play("resources/sound/bullet.wav");                                        }                                        delay = System.currentTimeMillis()+100;                                    }                                }                                                                if(fire3){                                    for(int i=0; i<bullets.length; i++){                                        bullets[currentBullet].getVelocity().setY(-v*2f);                                                                                float shita = 6.28f*i/(bullets.length-1);                                        bullets[currentBullet].rotate(shita);                                                                                float vx = (float) (v*Math.cos(shita));                                        float vy = (float) (v*Math.sin(shita));                                                                                bullets[currentBullet].getVelocity().setX(vx);                                        bullets[currentBullet].getVelocity().setY(vy);                                                                                bullets[currentBullet].setLocation(                                                player.getLocation().getX()+(player.getWidth()-bullets[currentBullet].getWidth())/2,                                                player.getLocation().getY()+(player.getHeight()-bullets[currentBullet].getHeight())/2);                                                                                bullets[currentBullet].setDelay(currentBullet);                                                                                currentBullet = ++currentBullet%bullets.length;                                    }                                    SoundManager.play("resources/sound/bomb.wav");                                    fire3=false;                                }                            }                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                };            }            return keyProcessThread;        }        private void initNode() {                        try {                Image bulletImage = ImageIO.read(getClass().getClassLoader().getResource("resources/bullet.png"));                Image planeImage  = ImageIO.read(getClass().getClassLoader().getResource("resources/planes.png"));                                /*                * 初始化子弹                */               for(int i=0; i<bullets.length; i++){                    bullets[i] = new ImageNode(bulletImage,0,70,35,35);                    bullets[i].setSize(35,35);                    bullets[i].setLocation(-500,-500);                    bullets[i].setExtent(35/20);                    add(bullets[i]);                }                /*                * 初始化玩家                */               player = new ImageNode(planeImage,100,0,100,120);   //平抛--图像结点                player.setSize(60,72);                player.setLocation((getStageWidth()-player.getWidth())/2,getStageHeight()-player.getHeight());                player.setMass(10);                add(player);                                /*                * 初始化敌人                */               for(int i=0; i<enemys.length; i++){                    enemys[i] = new ImageNode(planeImage,0,0,100,120);                    enemys[i].setSize(60,72);                    enemys[i].rotate(6.28f*i/(enemys.length-1));                    enemys[i].setLocation(i*(enemys[i].getWidth()+70),100);                    add(enemys[i]);                }            } catch (IOException e1) {                e1.printStackTrace();            }        }           @Override       public void updateWorld(long time) {            player.update(time);                        bombParticle.update(time);            hitParticle.update(time);                        //更新子弹            for(int i=0; i<bullets.length; i++){                bullets[i].update(time);            }                        //更新敌机            for(int i=0; i<enemys.length; i++){                if(enemys[i]!=null){                    enemys[i].update(time);                }            }            //子弹和敌机碰撞检测            for(int i=0; i<bullets.length; i++){                if(bullets[i]!=null){                    for(int j=0; j<enemys.length; j++){                        if(enemys[j]!=null){                            CollisionResult cr = CollisionDetector.obb(bullets[i], enemys[j]);                            if(cr.isCollision()){                                int x = bullets[i].getLocation().getIntX(); //TODO 其实应该是碰撞的位置                                int y = bullets[i].getLocation().getIntY(); //TODO 其实应该是碰撞的位置                                bullets[i].getLocation().setY(-500);                                hitParticle.start(x, y);                            }                        }                    }                }            }        }    }  

linux

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxysg.html