📄 cubepanel.java
字号:
/*
* Java Virtual Cube
* -----------------
*
* Copyright 1996, Song Li
* URL: http://www.cs.umbc.edu/~sli2
*
*
* You can use the code for any nonprofittable use. But remember to mention
* the authors' names in your revised program. You are also encouraged to
* improve the program or give your comments and bug reports. If there are
* further questions, please contact me and I'll be glad to help. My E-Mail
* address is: sli2@gl.umbc.edu.
*
*/
import java.awt.* ;
import java.applet.AudioClip ;
public class CubePanel extends Panel implements Runnable {
private Thread CubeThread = null;
private CubeSystem CubeSys ;
private CubeStack SpinStack ;
private Button ButtonSolve ;
private boolean Automatic = false ;
public static AudioClip BadSound ;
public static AudioClip SpinSound ;
private boolean moveEnabled = false ;
Image OffScreen;
Graphics OffGraphics;
Dimension OffScreenSize;
CubePanel (Label steptext) {
CubeSys = new CubeSystem (new Vertex (60, 60, 60)) ;
SpinStack = new CubeStack (steptext) ;
OffScreen = createImage (200, 200) ;
if (OffScreen == null)
System.out.println ("failed") ;
else
System.out.println ("succeeded") ;
}
public void DefineBound () {
CubeSys.DefineBound (getSize().width, getSize().height);
}
private boolean Ready = false ;
public void Start () {
if (CubeThread == null) {
CubeThread = new Thread (this);
CubeThread.start ();
CubeThread.suspend ();
Ready = true ;
}
}
public void Stop () {
CubeThread.stop();
CubeThread = null;
}
public void run () {
while (! Ready) ;
while (CubeThread != null) {
do {
if (Automatic) {
CubeAction action = SpinStack.ForceUndo () ;
if (action != null) {
try {CubeThread.sleep (100);} catch (InterruptedException e) {}
CubeSys.SpinBegin (action.GetAxis(),
action.GetPlane(),
! action.GetDir()) ;
}
else {
Automatic = false ;
ButtonSolve.setLabel ("Solve") ;
break ;
}
}
for (int i=0; i<5; i++) {
CubeSys.Spin (1) ;
repaint ();
try {
CubeThread.sleep (100) ;
} catch (InterruptedException e) {}
}
CubeSys.SpinEnd () ;
repaint ();
} while (Automatic) ;
CubeThread.suspend () ;
}
CubeThread = null;
}
public boolean CommandAction (Event event) {
if ("New".equals (event.arg)) {
CubeSys.NewGame () ;
SpinStack.Clear () ;
repaint () ;
}
if ("Undo".equals (event.arg)) {
CubeAction action = SpinStack.Undo () ;
if (action != null) {
CubeSys.SpinBegin (action.GetAxis(), action.GetPlane(), ! action.GetDir()) ;
CubeThread.resume () ;
}
}
if ("Redo".equals (event.arg)) {
CubeAction action = SpinStack.Redo () ;
if (action != null) {
CubeSys.SpinBegin (action.GetAxis(), action.GetPlane(), action.GetDir()) ;
CubeThread.resume () ;
}
}
if ("Scramble".equals (event.arg)) {
CubeSys.NewGame () ;
SpinStack.Clear () ;
int newaxis, axis = -1 ;
int newplane, plane = -1 ;
boolean newdir, dir = false ;
SpinStack.EnableUpdate (false) ;
for (int i=0; i<60; i++) {
do {
newaxis = (int) (Math.random () * 3) ;
newplane = (int) (Math.random () * 3) ;
newdir = Math.random () > 0.5 ;
} while (newaxis>2 || newplane>2 ||
(newaxis==axis && newplane==plane && newdir==!dir)) ;
axis = newaxis ;
plane = newplane ;
dir = newdir ;
SpinStack.Do (new CubeAction (axis, plane, dir)) ;
CubeSys.SpinMap (axis, plane, dir) ;
}
SpinStack.SetWatermark () ;
SpinStack.EnableUpdate (true) ;
CubeSys.SetCubeMap () ;
repaint () ;
}
if ("Stop".equals (event.arg)) {
Automatic = false ;
ButtonSolve.setLabel ("Solve") ;
}
if ("Solve".equals (event.arg)) {
ButtonSolve = (Button) event.target ;
Automatic = true ;
ButtonSolve.setLabel ("Stop") ;
CubeThread.resume () ;
}
if (event.target instanceof Checkbox)
moveEnabled = (((Checkbox) event.target).getState ()) ;
return true ;
}
int PrevX, PrevY ;
Vertex PrevHotpoint = null ;
public boolean mouseDown (Event event, int x, int y) {
//!! if (event.controlDown () || event.metaDown ()) {
if (moveEnabled) {
PrevHotpoint = CubeSys.Unproject (x - getSize().width/2, getSize().height/2 - y) ;
//!! if (PrevHotpoint == null && moveEnabled)
//!! BadSound.play () ;
}
else {
PrevX = x;
PrevY = y;
}
return true;
}
public boolean mouseUp (Event event, int x, int y) {
//!! if (event.controlDown () || event.metaDown ()) {
if (moveEnabled) {
if (PrevHotpoint == null)
return true ;
Vertex hotpoint = CubeSys.Unproject (x - getSize().width/2, getSize().height/2 - y) ;
int spinparam = CubeSystem.ComputeSpin (PrevHotpoint, hotpoint) ;
if (spinparam == 9999 && moveEnabled) {
//!! BadSound.play () ;
PrevHotpoint = null ;
return true ;
}
int axis = spinparam>0 ? (spinparam-1)/3 : (-spinparam-1)/3 ;
int plane = spinparam>0 ? (spinparam-1)%3 : (-spinparam-1)%3 ;
boolean dir = spinparam>0 ;
//!! if (moveEnabled)
//!! SpinSound.play () ;
CubeSys.SpinBegin (axis, plane, dir) ;
SpinStack.Do (new CubeAction (axis, plane, dir)) ;
CubeThread.resume () ;
PrevHotpoint = null ;
}
return true ;
}
public boolean mouseDrag (Event event, int x, int y) {
//!! if (event.controlDown () || event.metaDown ())
if (moveEnabled)
return true ;
double xtheta = (PrevY - y) * 2 * Math.PI / getSize().width;
double ytheta = (PrevX - x) * 2 * Math.PI / getSize().height;
CubeSys.XRotateView (xtheta);
CubeSys.YRotateView (ytheta);
repaint();
PrevX = x;
PrevY = y;
return true;
}
/* Double buffering for update */
public void paint (Graphics graph) {
update (graph) ;
}
public synchronized void update (Graphics graph) {
Dimension dim = getSize ();
if ((OffScreen == null) ||
(dim.width != OffScreenSize.width) ||
(dim.height != OffScreenSize.height)) {
OffScreen = createImage (dim.width, dim.height);
OffScreenSize = dim;
OffGraphics = OffScreen.getGraphics();
OffGraphics.setFont (getFont ());
}
OffGraphics.setColor (Color.lightGray) ;
OffGraphics.fillRect (0, 0, dim.width, dim.height);
if (CubeSys != null) {
CubeSys.Paint (OffGraphics, dim.width, dim.height);
graph.drawImage (OffScreen, 0, 0, null);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -