我在java中使用Xith3d开始一个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目录下了。你不应该那样做
我已经按照这里所说的安装了项目,并运行了你的EmptyScene,没有例外。
[EDIT]也许你正在使用CLASSPATH var.链接jar ?如果是的话,看看这个
似乎需要将jagatoo.jar添加到类路径中。
右键单击项目,属性,选择java构建路径,单击libraries选项卡,并添加jar
确保在您的类路径中也有jagatoo.jar的依赖项。