Exemple #1
0
 public void performMove(Move move)
 {
     // perform move stored in Move object
     performMove(move.face, move.twist);
 }
 public void updateHighlights(Move move)
 {
     // update any changes in rotated piece highlights
     bool[,,] oldHighlights = (bool[,,]) pieceHighlighted.Clone();
     for(int i = 0; i < 3; i++)
         for(int j = 0; j < 3; j++)
             switch(move.twist) {
                 case CubeMove.Clockwise:
                     switch(move.face) {
                         case FaceID.Front:
                             pieceHighlighted[2 - j, i, 0] = oldHighlights[i, j, 0];
                             break;
                         case FaceID.Back:
                             pieceHighlighted[j, 2 - i, 2] = oldHighlights[i, j, 2];
                             break;
                         case FaceID.Left:
                             pieceHighlighted[0, 2 - j, i] = oldHighlights[0, i, j];
                             break;
                         case FaceID.Right:
                             pieceHighlighted[2, j, 2 - i] = oldHighlights[2, i, j];
                             break;
                         case FaceID.Top:
                             pieceHighlighted[j, 0, 2 - i] = oldHighlights[i, 0, j];
                             break;
                         case FaceID.Bottom:
                             pieceHighlighted[2 - j, 2, i] = oldHighlights[i, 2, j];
                             break;
                     }
                     break;
                 case CubeMove.Double:
                     switch(move.face) {
                         case FaceID.Front:
                             pieceHighlighted[2 - i, 2 - j, 0] = oldHighlights[i, j, 0];
                             break;
                         case FaceID.Back:
                             pieceHighlighted[2 - i, 2 - j, 2] = oldHighlights[i, j, 2];
                             break;
                         case FaceID.Left:
                             pieceHighlighted[0, 2 - i, 2 - j] = oldHighlights[0, i, j];
                             break;
                         case FaceID.Right:
                             pieceHighlighted[2, 2 - i, 2 - j] = oldHighlights[2, i, j];
                             break;
                         case FaceID.Top:
                             pieceHighlighted[2 - i, 0, 2 - j] = oldHighlights[i, 0, j];
                             break;
                         case FaceID.Bottom:
                             pieceHighlighted[2 - i, 2, 2 - j] = oldHighlights[i, 2, j];
                             break;
                     }
                     break;
                 case CubeMove.AntiClockwise:
                     switch(move.face) {
                         case FaceID.Front:
                             pieceHighlighted[j, 2 - i, 0] = oldHighlights[i, j, 0];
                             break;
                         case FaceID.Back:
                             pieceHighlighted[2 - j, i, 2] = oldHighlights[i, j, 2];
                             break;
                         case FaceID.Left:
                             pieceHighlighted[0, j, 2 - i] = oldHighlights[0, i, j];
                             break;
                         case FaceID.Right:
                             pieceHighlighted[2, 2 - j, i] = oldHighlights[2, i, j];
                             break;
                         case FaceID.Top:
                             pieceHighlighted[2 - j, 0, i] = oldHighlights[i, 0, j];
                             break;
                         case FaceID.Bottom:
                             pieceHighlighted[j, 2, 2 - i] = oldHighlights[i, 2, j];
                             break;
                     }
                     break;
             }
 }
        protected void update()
        {
            // called on every step in idle application time
            float correction = 1.0F; // initial time correction value
            if(timer.IsRunning) {
                timer.Stop();
                correction = (float) timer.ElapsedTicks / 3000F; // get the difference in time between this step and the last and create compensation for it
            }

            viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, -7 + zoom), new Vector3(0, 0, 0), new Vector3(0, -1, 0)); // update matrices for new zoom and new viewport if changed
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 300.0f);

            if(!paused) { // if not paused update any rotations on the cube
                if(moveQueue.Count > 0 && delaySoFar == 0 && faceAngle <= 0.0F) { // no move currently being performed so start a new one
                    Move move = moveQueue.Dequeue(); // get the next move
                    delaySoFar = (int) (performDelay / correction); // set up the delay for this move
                    if(animateFaces) { // if animate the faces then set up a slow face rotation
                        verticesChanged[(int) move.face] = true; // invalidate the relevant faces for refreshing
                        for(int i = 0; i < 6; i++)
                            if(areAdjacent(move.face, (FaceID) i))
                                verticesChanged[i] = true;

                        rotatingBackwards = move.twist == CubeMove.AntiClockwise; // update the current rotation
                        rotatingFace = move.face;
                        faceAngle = rotatePerStep;
                        if(move.twist == CubeMove.Double) rotatingTo = MathHelper.Pi;
                        else rotatingTo = MathHelper.PiOver2;
                        lastMove = move;
                    }
                    else { // faces not animated so perform rotation instantly
                        verticesChanged[(int) move.face] = true;
                        for(int i = 0; i < 6; i++)
                            if(areAdjacent(move.face, (FaceID) i))
                                verticesChanged[i] = true;
                        cube.performMove(move);
                        updateHighlights(move);
                        lastMove = move;

                        if(moveQueue.Count == 0) // update when sequence has finished
                            onSequenceFinish();
                    }
                }
                if(delaySoFar > 0) delaySoFar--; // update delay between rotations
                if(faceAngle > 0.0F) { // face currently being rotated so continue it
                    verticesChanged[(int) lastMove.face] = true; // invalidate faces
                    for(int i = 0; i < 6; i++)
                        if(areAdjacent(lastMove.face, (FaceID) i))
                            verticesChanged[i] = true;

                    faceAngle += rotatePerStep * correction; // update rotation with correction for time differences
                }
                if(faceAngle >= rotatingTo) { // if rotation is finished, end it
                    verticesChanged[(int) lastMove.face] = true; // invalidate faces
                    for(int i = 0; i < 6; i++)
                        if(areAdjacent(lastMove.face, (FaceID) i))
                            verticesChanged[i] = true;

                    faceAngle = 0.0F; // reset face angle, perform latest move on actual cube stored, and update changes in pieces highlighted
                    cube.performMove(lastMove);
                    updateHighlights(lastMove);

                    if(moveQueue.Count == 0) // update when sequence has finished
                        onSequenceFinish();
                }
            }

            KeyboardState kb = Keyboard.GetState(); // get current user input data
            MouseState ms = Mouse.GetState();

            Point vms = this.PointToClient(new Point(ms.X, ms.Y));

            if(ms.LeftButton == ButtonState.Pressed && inBounds(vms) && inBounds(prevMs)) { // if mouse is within control bounds and was in control bounds last step with the mouse button held
                angleX += (vms.Y - prevMs.Y) * 0.01F / (float) Height * 365F; // update rotations of entire cube
                angleY += (prevMs.X - vms.X) * 0.01F / (float) Width * 805F * (angleX > MathHelper.PiOver2 || angleX < -MathHelper.PiOver2 ? -1 : 1);
            }
            angleX = angleX % (float) (2 * Math.PI); // ensure angleX doesn't exceed -2*pi or 2*pi when not necessary (for above rotation logic)

            prevKb = kb; // input finished with so update input from last step
            prevMs = vms;

            if(!timer.IsRunning) // restart step timer
                timer.Restart();
        }
 public void performMove(Move move)
 {
     // queue up move
     moveQueue.Enqueue(move);
 }