Java3D JApplet随着旋转和翻译而闪烁

时间:2014-05-30 05:04:46

标签: java swing applet flicker java-3d

我正在使用java3D制作游戏。它涉及使用“wasd”键进行翻译并使用鼠标旋转的视图。但是,当我同时旋转和平移时,屏幕上的3D形状会来回闪烁。

我尝试研究这个问题,大多数人说我需要双缓冲,但Java3D会自动加倍缓冲。

如何使我的程序平稳无闪烁地运行?

这是我的一部分代码,包括一些设置以及旋转和翻译方法:

import java.applet.Applet;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class PlayerMechanics extends Applet implements KeyListener, MouseListener,
MouseMotionListener
{

    Runner runner;

    SimpleUniverse universe;

    Canvas3D c;

    BranchGroup mainGroup = new BranchGroup();

    TransformGroup charViewGroup = new TransformGroup();
    ViewingPlatform CharVP;

    TransformGroup groundGroup;

    final static int SCREENWIDTH = 900;
    final static int SCREENHEIGHT = 540;

    final float CHARACTERHEIGHT = 2.0f;

    float MouseX = 0.0f;
    float MouseY = 0.0f;

    float Speed = 0.0f;
    float Iteration = 0.0f;
    float xinterval = 0.0f;
    float zinterval = 0.0f;

    float xloc = 0.0f;
    float yloc = 0.0f;
    float zloc = 0.0f;

    float CVrotX = 0.0f;
    float CVrotY = 0.0f;
    float CVrotZ = 0.0f;

    Vector3f loc = new Vector3f(xloc, yloc, zloc);

    boolean moveForward = false;
    boolean moveLeft = false;
    boolean moveBackward = false;
    boolean moveRight = false;

    boolean rotUp = false;
    boolean rotLeft = false;
    boolean rotDown = false;
    boolean rotRight = false;

    public PlayerMechanics()
    {   
        setLayout(new BorderLayout());

        GraphicsConfiguration config = 
                SimpleUniverse.getPreferredConfiguration();
        c = new Canvas3D(config);
        add("Center", c);

        c.addKeyListener(this);
        c.addMouseListener(this);
        c.addMouseMotionListener(this);

        universe = new SimpleUniverse(c);

        //Position Cursor in Center of Screen
        repositionCursor();

        //Create Cubes
        for(float a = 0.0f; a < 0.4; a = a + 0.1f)
        {
            float CubeSize = 0.5f;

            float x = 0.0f;
            float y = 0.0f;
            float z = -5.0f;

            if(a == 0.1f)
            {
                x = -5.0f;
                y = 0.0f;
                z = 0.0f;
            }
            else if(a == 0.2f)
            {
                x = 0.0f;
                y = 0.0f;
                z = 5.0f;
            }
            else if(a == 0.3f)
            {
                x = 5.0f;
                y = 0.0f;
                z = 0.0f;
            }

            TransformGroup tg = new TransformGroup();
            Transform3D transform = new Transform3D();
            ColorCube cube = new ColorCube(CubeSize);
            Vector3f vector = new Vector3f(x, y, z);
            transform.setTranslation(vector);
            tg.setTransform(transform);
            tg.addChild(cube);
            mainGroup.addChild(tg);
        }

        //Set viewpoint
        charViewGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        CharVP = universe.getViewingPlatform();
        charViewGroup = CharVP.getMultiTransformGroup().getTransformGroup(0);

        resetViewingPlatform();

        universe.addBranchGraph(mainGroup);

        runner = new Runner();
        runner.start();
    }

    public class Runner extends Thread
    {
        public void run()
        {
            while(true)
            {
                try
                {       
                    characterMovement();

                    Thread.sleep(50);
                }
                catch(Exception e)
                {
                    System.out.println("Error Encountered!  " + 
                                e.getMessage() + "!");
                }
            }
        }
    }

    @Override
    public void mouseDragged(MouseEvent e){}

    @Override
    public void mouseMoved(MouseEvent e)
    {   
            float XZero = (float)(SCREENWIDTH/2);
        float YZero = (float)(SCREENHEIGHT/2);

        MouseX = (float)(e.getX());
        MouseY = (float)(e.getY());

        float NewX = XZero - MouseX;
        float NewY = YZero - MouseY;

        changeRotationView(NewX, NewY);
        repositionCursor();
    }

    @Override
    public void keyPressed(KeyEvent e)
    {       
        int keyCode = e.getKeyCode();

        switch(keyCode)
        {
            case KeyEvent.VK_W:
                moveForward = true;
                break;
            case KeyEvent.VK_A:
                moveLeft = true;
                break;
            case KeyEvent.VK_S:
                moveBackward = true;
                break;
            case KeyEvent.VK_D:
                moveRight = true;
                break;

            //Press Esc to close program    
            case KeyEvent.VK_ESCAPE:
                System.exit(0);
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e)
    {   
        int keyCode = e.getKeyCode();

        switch(keyCode)
        {
            case KeyEvent.VK_W:
                moveForward = false;
                break;
            case KeyEvent.VK_A:
                moveLeft = false;
                break;
            case KeyEvent.VK_S:
                moveBackward = false;
                break;
            case KeyEvent.VK_D:
                moveRight = false;
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e){}

    @Override
    public void mouseClicked(MouseEvent e){}

    @Override
    public void mouseEntered(MouseEvent e){}

    @Override
    public void mouseExited(MouseEvent e){}

    @Override
    public void mousePressed(MouseEvent e){}

    @Override
    public void mouseReleased(MouseEvent e){}

    public void resetViewingPlatform()
    {   
        Transform3D charViewTrans = new Transform3D();
        charViewGroup.getTransform(charViewTrans);

        //Set Rotation
        Transform3D charViewRotY = new Transform3D();
        Transform3D charViewRotX = new Transform3D();
        charViewRotY.rotY(CVrotY);
        charViewRotX.rotX(CVrotX);
        charViewTrans.mul(charViewRotY, charViewRotX);

        Transform3D charViewTHPRotY = new Transform3D();
        Transform3D charViewTHPRotX = new Transform3D();
        charViewTHPRotY.rotY(CVrotY);
        charViewTHPRotX.rotX(-0.1f);

        //Set Translation
        loc = new Vector3f(xloc, yloc, zloc);

        charViewTrans.setTranslation(loc);

        charViewGroup.setTransform(charViewTrans);
    }

    public void characterMovement()
    {       
        float angle = CVrotY;

        float walkSpeed = 0.3f;

        byte xSign = 1;
        byte zSign = 1;

        boolean flipflop = false;

        //Quadrant I
        if(CVrotY < (float)(-Math.PI/2) && CVrotY > (float)(-Math.PI))
        {
            angle = (float)(-Math.PI) - CVrotY;

            xSign = 1;
            zSign = 1;
        }
        //Quadrant II
        if(CVrotY < 0 && CVrotY > (float)(-Math.PI/2))
        {
            xSign = 1;
            zSign = -1;
            flipflop = true;
        }
        //Quadrant III
        if(CVrotY > 0 && CVrotY < (float)(Math.PI/2))
        {
            xSign = -1;
            zSign = -1;
        }
        //Quadrant IV
        if(CVrotY > (float)(Math.PI/2) && CVrotY < (float)(Math.PI))
        {
            angle = (float)(Math.PI) - CVrotY;

            xSign = -1;
            zSign = 1;
            flipflop = true;
        }

        xinterval = walkSpeed*(float)(Math.sin(angle));
        zinterval = walkSpeed*(float)(Math.cos(angle));

        if(moveForward)
        {
            xloc = xloc + (Math.abs(xinterval)*xSign);
            zloc = zloc + (Math.abs(zinterval)*zSign);
        }
        if(moveLeft)
        {
            if(!flipflop)
            {
                xloc = xloc + (Math.abs(zinterval)*xSign);
                zloc = zloc - (Math.abs(xinterval)*zSign);
            }
            else
            {
                xloc = xloc + (Math.abs(zinterval)*-xSign);
                zloc = zloc - (Math.abs(xinterval)*-zSign);
            }
        }   
        if(moveBackward)
        {
            xloc = xloc - (Math.abs(xinterval)*xSign);
            zloc = zloc - (Math.abs(zinterval)*zSign);
        }
        if(moveRight)
        {
            if(!flipflop)
            {
                xloc = xloc - (Math.abs(zinterval)*xSign);
                zloc = zloc + (Math.abs(xinterval)*zSign);
            }
            else
            {
                xloc = xloc - (Math.abs(zinterval)*-xSign);
                zloc = zloc + (Math.abs(xinterval)*-zSign);
            }
        }

        resetViewingPlatform();
    }

    public void changeRotationView(float x, float y)
    {
        //Rotate Y-axis
        CVrotY = CVrotY + (x/100)/2;
        if(CVrotY >= (float)(Math.PI))
        {
            CVrotY = CVrotY - (float)(2*Math.PI);
        }
        else if(CVrotY <= (float)(-Math.PI))
        {
            CVrotY = CVrotY + (float)(2*Math.PI);
        }

        //Rotate X-axis
        if(CVrotX <= (float)(Math.PI/2) && CVrotX >= (float)(-Math.PI/2))
        {
            CVrotX = CVrotX + (y/100)/2;
        }
        else
        {
            if(CVrotX <= (float)(-Math.PI/2))
            {
                    CVrotX = (float)((-Math.PI/2)+0.001);
            }
            if(CVrotX >= (float)(Math.PI/2))
            {
                CVrotX = (float)((Math.PI/2)-0.001);
            }

        }

        resetViewingPlatform();
    }

    public void repositionCursor()
    {
        try 
        {
            Point windowLoc = c.getLocationOnScreen();

            int xCoord = (windowLoc.x + (SCREENWIDTH/2));
            int yCoord = (windowLoc.y + (SCREENHEIGHT/2));

            Robot robot = new Robot();
            robot.mouseMove(xCoord, yCoord);
        }
        catch(AWTException e){}
    }

    public static void main(String[] args)
    {
        PlayerMechanics playerMechanics = new PlayerMechanics();

        new MainFrame(playerMechanics, SCREENWIDTH, SCREENHEIGHT);
    }
}

任何帮助将不胜感激。谢谢!

0 个答案:

没有答案