我正在使用Xith3d在Java中启动3d游戏项目。它使用jagatoo进行输入,并且我已正确设置了所有内容。这是我的测试代码:

import org.jagatoo.input.InputSystem;
import org.jagatoo.input.devices.components.Key;
import org.jagatoo.input.devices.components.MouseButton;
import org.jagatoo.input.events.KeyReleasedEvent;
import org.jagatoo.input.events.MouseButtonPressedEvent;
import org.jagatoo.input.events.MouseButtonReleasedEvent;
import org.openmali.vecmath2.Colorf;
import org.openmali.vecmath2.Tuple3f;
import org.openmali.vecmath2.Vector3f;
import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loop.InputAdapterRenderLoop;
import org.xith3d.picking.NearestPickListener;
import org.xith3d.picking.PickResult;
import org.xith3d.picking.PickingLibrary;
import org.xith3d.render.Canvas3D;
import org.xith3d.render.Canvas3DFactory;
import org.xith3d.render.config.OpenGLLayer;
import org.xith3d.scenegraph.Appearance;
import org.xith3d.scenegraph.BranchGroup;
import org.xith3d.scenegraph.ColoringAttributes;
import org.xith3d.scenegraph.GroupNode;
import org.xith3d.scenegraph.OrderedGroup;
import org.xith3d.scenegraph.Transform;
import org.xith3d.scenegraph.TransparencyAttributes;
import org.xith3d.render.BaseRenderPassConfig;
import org.xith3d.scenegraph.View.ProjectionPolicy;
import org.xith3d.scenegraph.primitives.Cube;
import org.xith3d.schedops.movement.RotatableGroup;
import org.xith3d.schedops.movement.TransformationDirectives;

public class Test extends InputAdapterRenderLoop implements NearestPickListener
{

// Various variables defining the cube features:
private final TransparencyAttributes transAttribs = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.5f);
private final TransformationDirectives posXRotation = new TransformationDirectives(-0.25f, 0.0f, 0.0f);
private final TransformationDirectives negXRotation = new TransformationDirectives(0.25f, 0.0f, 0.0f);
private final TransformationDirectives posYRotation = new TransformationDirectives(0.0f, -0.25f, 0.0f);
private final TransformationDirectives negYRotation = new TransformationDirectives(0.0f, 0.25f, 0.0f);
private final float expandFactor = 3.0f;
private final float contractFactor = 0.0f;

// General variables:
private Canvas3D canvas;
private BranchGroup mainBranch;
private RotatableGroup cubeRotateGroup;
private RotatableGroup cubeRotatePlane;
private OrderedGroup cubeGroup;
private Cube[][][] cubes;
private GroupNode pickGroup;

// Translation variables:
private float currentTranslationFactor = 0.0f;

// Input variables:
private int initX;
private int initY;
private int finalX;
private int finalY;
private int latestClicked = -1;
    // Who's turn is it to pick a cube?
private int turnToPick;
    // Who's turn is it to rotate a plane?
private int turnToRotate;
private boolean isExpanded = false;
private boolean continueExpanding = false;

public Test() throws Exception
{

    // No FPS cap:
    super(120f);

    // Adjust the camera:
    Tuple3f eyePosition = new Vector3f(11.0f, 11.0f, 11.0f);
    Tuple3f viewFocus = new Vector3f(0.0f, 0.0f, 0.0f);
    Tuple3f vecUp = new Vector3f(1.0f, 0.0f, 0.0f);

    // Create environment:
    Xith3DEnvironment env = new Xith3DEnvironment(eyePosition, viewFocus, vecUp, this);

    // Create canvas:
    final OpenGLLayer oglLayer = OpenGLLayer.JOGL_AWT;
    this.canvas = Canvas3DFactory.createWindowed(oglLayer, 800, 800, false, "TCube");

    // Add canvas to environment:
    env.addCanvas(canvas);

    // Create main scene branch:
    mainBranch = new BranchGroup();
    env.addBranchGraph(mainBranch, new BaseRenderPassConfig(ProjectionPolicy.PERSPECTIVE_PROJECTION));

    // Register inputs:
    InputSystem.getInstance().registerNewKeyboardAndMouse(canvas.getPeer());
    this.pickGroup = env.addPerspectiveBranch(mainBranch).getBranchGroup();

    cubeGroup = createCubes();

    cubeRotateGroup = new RotatableGroup();
    cubeRotatePlane = new RotatableGroup();
    cubeRotateGroup.addChild(cubeGroup);

    mainBranch.addChild(cubeRotateGroup);
    mainBranch.addChild(cubeRotatePlane);

    this.getAnimator().addAnimatableObject(cubeRotateGroup);
    this.getAnimator().addAnimatableObject(cubeRotatePlane);

    //To-do: loading screen

    turnToPick = 0;
        // Must pick before rotating:
    turnToRotate = -1;

    this.begin();

}

public OrderedGroup createCubes()
{
    OrderedGroup og = new OrderedGroup();

    cubes = new Cube[3][3][3];

    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            for (int k = 0; k < 3; k++)
            {

                // Compute the coordinates for the given cube:
                float x = 3.0f * (i - 1);
                float y = 3.0f * (j - 1);
                float z = 3.0f * (k - 1);

                cubes[i][j][k] = new Cube(2.0f, initialAppearance());
                cubes[i][j][k].setName("" + ((i * 9) + (j * 3) + k));
                og.addChild(new Transform().setTranslation(x, y, z).add(cubes[i][j][k]));

            }

    return og;

}

public Appearance initialAppearance()
{

    Appearance app = new Appearance();

    app.setColoringAttributes(new ColoringAttributes(Colorf.LIGHT_GRAY , ColoringAttributes.SHADE_GOURAUD));
    app.setTransparencyAttributes(transAttribs);

    return app;

}

public Appearance changeAppearance(int i)
{

    Appearance app = new Appearance();
    Colorf colour = new Colorf();

    colour = (i == 0) ? Colorf.ORANGE : (i == 1) ? Colorf.GREEN : null;
    app.setColoringAttributes(new ColoringAttributes(colour, ColoringAttributes.SHADE_GOURAUD));

    app.setTransparencyAttributes(transAttribs);

    return app;

}

protected void prepareNextFrame( long gameTime, long frameTime, TimingMode tm )
{

    super.prepareNextFrame( gameTime, frameTime, tm );

    if (isExpanded && currentTranslationFactor < expandFactor)
        continueExpanding = true;
    else if (!isExpanded && currentTranslationFactor > contractFactor)
        continueExpanding = true;
    else
    {
        continueExpanding = false;
        System.gc(); // possibly not needed!
    }

    if (continueExpanding)
    {

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                for (int k = 0; k < 3; k++)
                {

                    // Compute the coordinates for the given cube:
                    float x = currentTranslationFactor * (i - 1);
                    float y = currentTranslationFactor * (j - 1);
                    float z = currentTranslationFactor * (k - 1);

                    cubes[i][j][k].getParent().detach();
                    cubeRotateGroup.addChild(new Transform().setTranslation(x, y, z).add(cubes[i][j][k].getParent()));

                }

        currentTranslationFactor = isExpanded ? (currentTranslationFactor + 0.1f) : (currentTranslationFactor - 0.1f);

        // Hack job! Removes jumping from expansion to contraction and vice-versa:
        if (currentTranslationFactor >= expandFactor)
            currentTranslationFactor = 3;
        else if (currentTranslationFactor <= contractFactor)
            currentTranslationFactor = 0;

    }

}

@Override
public void onKeyReleased(KeyReleasedEvent e, Key key)
{

    switch (key.getKeyID()) {

    case ESCAPE:
        this.end();
        break;

    case _0:
        turnToPick = 0;
        break;

    case _1:
        turnToPick = 1;
        break;

    case LEFT:
        cubeRotateGroup.setTransformationDirectives(posXRotation);
        break;

    case RIGHT:
        cubeRotateGroup.setTransformationDirectives(negXRotation);
        break;

    case UP:
        cubeRotateGroup.setTransformationDirectives(negYRotation);
        break;

    case DOWN:
        cubeRotateGroup.setTransformationDirectives(posYRotation);
        break;

    case SPACE:

        if (continueExpanding)
            System.out.println("Current translation not finished!");
        else if (!isExpanded)
            isExpanded = true;
        else
            isExpanded = false;

        break;

    }
}

@Override
public void onObjectPicked(PickResult nearest, Object userObject, long pickTime) {

    latestClicked = Integer.parseInt(nearest.getNode().getName());
    System.out.println("Picked cube " + latestClicked);

    Colorf colour = new Colorf();
    // Transparency not working!
    colour = (turnToPick == 0) ? Colorf.ORANGE :  (turnToPick == 1) ? Colorf.GREEN : null;

    try { nearest.getGeometry().setColor(0, colour); }
    catch (NullPointerException e) { System.out.println("It must be someone's turn!"); }

    turnToPick = -1;

}

public void onMouseButtonPressed(MouseButtonPressedEvent e, MouseButton button) {

    initX = e.getX();
    initY = e.getY();

    PickingLibrary.pickNearest(pickGroup, canvas, button, initX, initY, this);

}

public void onMouseButtonReleased(MouseButtonReleasedEvent e, MouseButton button)
{

    if (turnToPick == -1)
    {

        finalX = e.getX();
        finalY = e.getY();

        int diffX = finalX - initX;
        int diffY = finalY - initY;

        if (Math.abs(diffX) > Math.abs(diffY) && latestClicked != -1)
        {

            System.out.println(diffX);
            System.out.println(diffY);

            int xPlaneToRotate = latestClicked / 9;

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                {

                    cubes[xPlaneToRotate][i][j].getParent().detach();
                    cubeRotatePlane.addChild(cubes[xPlaneToRotate][i][j].getParent());

                }

            TransformationDirectives xRotate = (diffX > 0) ? negXRotation : posXRotation;

            cubeRotatePlane.setTransformationDirectives(xRotate);

        }
        else if (Math.abs(diffX) < Math.abs(diffY) && latestClicked != -1)
        {

            int yPlaneToRotate = -1;

            // Hack job! Must be changed:
                switch (latestClicked)
                {
                case 0:
                case 1:
                case 2:
                case 9:
                case 10:
                case 11:
                case 18:
                case 19:
                case 20:

                    yPlaneToRotate = 0;
                    break;

                case 3:
                case 4:
                case 5:
                case 12:
                case 13:
                case 14:
                case 21:
                case 22:
                case 23:

                    yPlaneToRotate = 1;
                    break;

                case 6:
                case 7:
                case 8:
                case 15:
                case 16:
                case 17:
                case 24:
                case 25:
                case 26:

                    yPlaneToRotate = 2;
                    break;

                }

                for (int i = 0; i < 3; i++)
                    for (int j = 0; j < 3; j++)
                    {

                        cubes[i][yPlaneToRotate][j].getParent().detach();
                        cubeRotatePlane.addChild(cubes[i][yPlaneToRotate][j].getParent());

                    }

                TransformationDirectives yRotate = (diffY < 0) ? negYRotation : posYRotation;

                cubeRotatePlane.setTransformationDirectives(yRotate);

        }
        else
        {

            System.out.println("Try harder!");

        }

    }

}

@Override
public void onPickingMissed(Object userObject, long pickTime) {

    System.out.println("Pick a cube!");

}

@Override
public boolean testIntersectionsInWorldSpaceForPicking() {
    // TODO Auto-generated method stub
    return false;
}

public static void main(String[] args) throws Exception
{

    new Test();

}

}


但是,当我运行它时,Eclipse以亮红色文本抛出此错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/jagatoo/input/listeners/InputListener
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:314)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Caused by: java.lang.ClassNotFoundException: org.jagatoo.input.listeners.InputListener
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    ... 23 more
Could not find the main class: Test. Program will exit.


我不确定此错误来自何处,我需要帮助。任何意见,将不胜感激。我已正确链接了库,甚至尝试添加
导入org.jagatoo.input.listeners.InputListener;
在顶部,它仍然给我相同的输出。

[编辑]
我尝试运行一项更简单的测试,以确保一切正常,并使用相同的配置对以下代码进行了测试:

import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loop.RenderLoop;
import org.xith3d.render.Canvas3D;
import org.xith3d.render.Canvas3DFactory;


public class EmptyScene
{
public EmptyScene()
{
    Xith3DEnvironment env = new Xith3DEnvironment();

    Canvas3D canvas = Canvas3DFactory.createWindowed( 800, 600,
                                                      "My empty scene" );
    env.addCanvas( canvas );
    RenderLoop rl = new RenderLoop();
    rl.setMaxFPS( 120f );
    rl.setXith3DEnvironment( env );
    // never forget to start the RenderLoop!
    rl.begin();
}
public static void main( String[] args ) throws Exception
{
    new EmptyScene();
}
}


现在,Eclipse给了我这个错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/jagatoo/datatypes/Enableable
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    at EmptyScene.<init>(EmptyScene.java:11)
    at EmptyScene.main(EmptyScene.java:24)
Caused by: java.lang.ClassNotFoundException: org.jagatoo.datatypes.Enableable
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
    ... 12 more


我什至没有使用Jagatoo,而Xith给了我错误。这里有些麻烦,但我看不到问题所在。预先感谢任何可以解决此问题的人。

最佳答案

我猜您将xith3d jar复制到了jre / lib / ext目录中。你不应该那样做

我已经按照here的说明安装了项目,并且无例外地运行了EmptyScene。

[编辑]也许您正在使用CLASSPATH变量。链接罐子?如果是这样,请查看this

10-07 15:33