Java3D JApplet随着旋转和平移而闪烁
我正在用java3D制作一个游戏。它包括使用“wasd”键转换视图和使用鼠标旋转视图。然而,当我同时旋转和平移时,屏幕上的3D形状来回闪烁 我试图研究这个问题,大多数人说我需要双缓冲区,但Java3D会自动双缓冲区 我如何使我的程序运行平稳,无闪烁 以下是我的部分代码,包括一些设置以及旋转和平移方法:Java3D JApplet随着旋转和平移而闪烁,java,swing,applet,flicker,java-3d,Java,Swing,Applet,Flicker,Java 3d,我正在用java3D制作一个游戏。它包括使用“wasd”键转换视图和使用鼠标旋转视图。然而,当我同时旋转和平移时,屏幕上的3D形状来回闪烁 我试图研究这个问题,大多数人说我需要双缓冲区,但Java3D会自动双缓冲区 我如何使我的程序运行平稳,无闪烁 以下是我的部分代码,包括一些设置以及旋转和平移方法: import java.applet.Applet; import java.awt.AWTException; import java.awt.BorderLayout; import java
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);
}
}
import java.applet.applet;
导入java.awt.AWTException;
导入java.awt.BorderLayout;
导入java.awt.GraphicsConfiguration;
导入java.awt.Point;
导入java.awt.Robot;
导入java.awt.event.*;
导入javax.media.j3d.*;
导入javax.vecmath.*;
导入com.sun.j3d.utils.geometry.ColorCube;
导入com.sun.j3d.utils.universe.SimpleUniverse;
导入com.sun.j3d.utils.universe.ViewingPlatform;
公共类PlayerMechanics扩展小程序实现KeyListener、MouseListener、,
鼠标移动
{
跑步者;
简单宇宙;
拉票;
BranchGroup mainGroup=新建BranchGroup();
TransformGroup charViewGroup=新建TransformGroup();
查看平台字符;
变革型组;
最终静态int屏幕宽度=900;
最终静态int屏幕高度=540;
最终浮点字符高度=2.0f;
浮动鼠标=0.0f;
浮动鼠标=0.0f;
浮动速度=0.0f;
浮点迭代=0.0f;
浮动xinterval=0.0f;
浮动zinterval=0.0f;
浮动xloc=0.0f;
浮动yloc=0.0f;
浮动zloc=0.0f;
浮动CVrotX=0.0f;
浮动CVrotY=0.0f;
浮动CVrotZ=0.0f;
向量3f loc=新向量3f(xloc、yloc、zloc);
布尔向前移动=假;
布尔左=假;
布尔向后移动=假;
布尔moveRight=false;
布尔rotUp=false;
布尔左=假;
布尔rottown=false;
布尔右=假;
公共游戏机()
{
setLayout(新的BorderLayout());
图形配置配置=
SimpleUniverse.getPreferredConfiguration();
c=新画布3D(配置);
添加(“中心”,c);
c、 addKeyListener(此);
c、 addMouseListener(这个);
c、 addMouseMotionListener(此);
宇宙=新的简单宇宙(c);
//将光标定位在屏幕中央
重新定位光标();
//创建立方体
对于(浮动a=0.0f;a<0.4;a=a+0.1f)
{
浮体立方尺寸=0.5f;
浮动x=0.0f;
浮动y=0.0f;
浮动z=-5.0f;
如果(a==0.1f)
{
x=-5.0f;
y=0.0f;
z=0.0f;
}
否则如果(a==0.2f)
{
x=0.0f;
y=0.0f;
z=5.0f;
}
否则如果(a==0.3f)
{
x=5.0f;
y=0.0f;
z=0.0f;
}
TransformGroup tg=新TransformGroup();
Transform3D transform=新建Transform3D();
ColorCube立方体=新的ColorCube(立方体尺寸);
向量3f向量=新向量3f(x,y,z);
transform.setTranslation(向量);
tg.setTransform(transform);
tg.addChild(立方体);
主组:addChild(tg);
}
//设定视点
charViewGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
CharVP=universe.getViewingPlatform();
charViewGroup=CharVP.getMultiTransferMgroup().getTransferMgroup(0);
重置ViewingPlatform();
universe.addBranchGraph(主组);
runner=新runner();
runner.start();
}
公共类运行程序扩展线程
{
公开募捐
{
while(true)
{
尝试
{
characterMovement();
睡眠(50);
}
捕获(例外e)
{
System.out.println(“遇到错误!”+
e、 getMessage()+“!”;
}
}
}
}
@凌驾
公共无效mouseDragged(MouseEvent e){}
@凌驾
public void mouseMoved(MouseEvent e)
{
浮动XZero=(浮动)(屏幕宽度/2);
浮动YZero=(浮动)(屏幕高度/2);
MouseX=(float)(e.getX());
MouseY=(float)(e.getY());
float NewX=XZero-MouseX;
float NewY=YZero-MouseY;
changeRotationView(NewX,NewY);
重新定位光标();
}
@凌驾
按下公共无效键(按键事件e)
{
int keyCode=e.getKeyCode();
开关(钥匙代码)
{
case KeyEvent.VK_W:
向前移动=真;
打破
case KeyEvent.VK_A:
moveLeft=true;
打破
case KeyEvent.VK_S:
向后移动=真;
打破
case KeyEvent.VK_D:
moveRight=true;
打破
//按Esc键关闭程序
case KeyEvent.VK_转义:
系统出口(0);
打破
}
}
@凌驾
公共无效密钥已释放(密钥事件e)
{
int keyCode=e.getKeyCode();
开关(钥匙代码)
{
case KeyEvent.VK_W:
向前移动=错误;
打破
case KeyEvent.VK_A:
moveLeft=false;
打破
case KeyEvent.VK_S:
向后移动=错误;
打破
case KeyEvent.VK_D:
moveRight=false;
打破
}
}
@凌驾
public void keyTyped(KeyEvent e){}
@凌驾
公共空间