⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boardcanvas.java

📁 --- --- --- 基于J2ME的游戏程序--------很有技巧性的程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
   */
  public void updateCursor()
  {
    if (m_cursorAnimation != null)
    {
      m_cursorAnimation.stop();
      m_cursorAnimation = null;
    } 
    if (m_cursor >= 0 &&
      BoardMediator.countPossibleMoves() > 0 &&
      isUserMovable())
    {
      int src = BoardMediator.getPossibleMoves()[m_cursor][BoardState.PM_SOUR];
      int dst = BoardMediator.getPossibleMoves()[m_cursor][BoardState.PM_DEST];
      m_cursorAnimation = new CursorAnim(
        src, dst,
        BoardMediator.countStatePieces(src), BoardMediator.countStatePieces(dst),
        BoardMediator.isCurrentPlayerWhite());
      m_animationEngine.addAnimation(m_cursorAnimation);
    }
  }
  
  /**
   * Enables/disables the possibility for user to perform a undo,
   * depending on game state.
   */
  public void updateUndoCommand()
  {
    if (!BoardMediator.isGameFinished() && !m_undoOn &&
      BoardMediator.countUndoableMoves() > 0)
    {
      m_undoOn = true;
    }
    else if (BoardMediator.isGameFinished() ||
      m_undoOn && BoardMediator.countUndoableMoves() == 0)
    {
      m_undoOn = false;
    }
    m_softbuttons.enable(CMD_UNDO, m_undoOn);
  }
  
  /**
   * Sets whether the canvas accepts any interaction or not.
   * @param allow  enable/disable interaction.
   */
  public void allowInteraction(boolean allow)
  {
    m_allowInteraction = allow;
  }
  
  /**
   * Sets the dice values to be drawn and
   * resets consume status
   * @param dice1  value of dice 1 (0-5)
   * @param dice2  value of dice 2 (0-5)
   */
  public void setDiceValues(int dice1, int dice2)
  {
    m_diceValues[0] = dice1;
    m_diceValues[1] = dice2;
    m_consumeStatuses[0] = 0;
    m_consumeStatuses[1] = 0;
  }
  
  /**
   * Enables/Disables drawing of dice values.
   * @param enable  True when dice values should be drawn,
   * 				falsw when dice values should not be drawn.
   */
  public void setDrawDiceValues(boolean enable)
  {
    m_drawDiceValues = enable;
    repaint();
  }
  
  // Interaction
  
  /**
   * Handles user interaction.
   * @param keyCode  Representation of pressed key.
   */
  protected void keyPressed(int keyCode)
  {
    try
    {
      // Do softbuttons
      m_softbuttons.keyPressed(keyCode);
      // Check if any popup is open
      if (m_popup != null && m_popup.isActive())
      {
        getPopup().keyPressed(keyCode, getGameAction(keyCode));
        repaint();
        return;
      }
      // Report to current local player
      boolean consumed = false;
      int gameCode = getGameAction(keyCode);
      if (m_player != null)
      {
        consumed = m_player.keyPressed(keyCode, gameCode);
      }
      if (keyCode == Canvas.KEY_POUND &&
          Bluegammon.getGameType() != Bluegammon.GAME_TYPE_LOCAL)
      {
        LocalPlayer p = BoardMediator.getLocalPlayer();
        Bluegammon.getStringInput(
          Resources.getString(Resources.TXT_MESSAGE) + " " +
          new String(BoardMediator.getOpponentPlayer().getName()),
          null, 1024, TextField.ANY, p);
      }
      repaint();
    }
    catch (Throwable t)
    {
      System.err.println("Error in board interaction thread");
      t.printStackTrace();
    }
  }
  

  /**
   * Handles command invokations from <code>SoftButtonControl</code>.
   * @param c the command.
   * @param d the displayable.
   */
  public void commandAction(Command c, Displayable d)
  {
    boolean consumed = false;
    // Report to current local player
    if (!BoardMediator.isRemoteTurn())
    {
      consumed = BoardMediator.getLocalPlayer().commandAction(c);
    }
    if (!consumed && c == CMD_EXIT)
    {
      // Exit, can be invoked without being user's turn
      consumed = BoardMediator.getLocalPlayer().commandAction(c);
    }
    repaint();
  }
 
  // Cursor interaction logic methods
  
  /**
   * Moves to nearest cursor index after a change in possible
   * moves.
   * @param  oldIndex    old index before change
   * @param  oldTarget    old target index before change
   */
  public void cursorNearestIndex(int oldIndex, int oldTarget)
  {
    int posMoves[][] = BoardMediator.getPossibleMoves();
    int diffSource = Integer.MAX_VALUE, curDiffSource;
    int diffTarget = Integer.MAX_VALUE, curDiffTarget;
    int newIndex = -1;
    for (int i = 0; i < BoardMediator.countPossibleMoves(); i++)
    {
      curDiffSource = Math.abs(posMoves[i][BoardState.PM_SOUR] - oldIndex);
      if (curDiffSource <= diffSource)
      {
        curDiffTarget = Math.abs(posMoves[i][BoardState.PM_SOUR] - oldTarget);
        if (diffSource == curDiffSource)
        {
          if (curDiffTarget < diffTarget)
          {
            diffSource = curDiffSource;
            diffTarget = curDiffTarget;
            newIndex = i;
          }
        }
        else
        {
          diffSource = curDiffSource;
          diffTarget = curDiffTarget;
          newIndex = i;
        }
      }
    }
    m_cursor = newIndex;
  }
  
  /**
   * Moves cursor to nearest matching cursor index on opposite
   * side of board, given current cursor position.
   */
  public void cursorSwapSide()
  {
    if (m_cursor < 0) return;
    int posMoves[][] = BoardMediator.getPossibleMoves();
    int diffSource = Integer.MAX_VALUE, curDiffSource;
    int diffTarget = Integer.MAX_VALUE, curDiffTarget;
    int newIndex = m_cursor;
    int oldIndex =  Board.POS_BOARD - posMoves[m_cursor][BoardState.PM_SOUR];
    int oldTarget = Board.POS_BOARD - posMoves[m_cursor][BoardState.PM_DEST];

    for (int i = 0; i < BoardMediator.countPossibleMoves(); i++)
    {
      if ((oldIndex < 12  && posMoves[i][BoardState.PM_SOUR] > 11 ||
           oldIndex > 11  && posMoves[i][BoardState.PM_SOUR] < 12) &&
          (oldTarget < 12 && posMoves[i][BoardState.PM_DEST] > 11 ||
           oldTarget > 11 && posMoves[i][BoardState.PM_DEST] < 12))
      {
        continue;
      }
      curDiffSource = Math.abs(posMoves[i][BoardState.PM_SOUR] - oldIndex);
      if (curDiffSource <= diffSource)
      {
        curDiffTarget = Math.abs(posMoves[i][BoardState.PM_SOUR] - oldTarget);
        if (diffSource == curDiffSource)
        {
          if (curDiffTarget < diffTarget)
          {
            diffSource = curDiffSource;
            diffTarget = curDiffTarget;
            newIndex = i;
          }
        }
        else
        {
          diffSource = curDiffSource;
          diffTarget = curDiffTarget;
          newIndex = i;
        }
      }
    }
    m_cursor = newIndex;
  }
  
  /**
   * Steps forward amongst cursor indices.
   */
  public void cursorNextIndex()
  {
    if (BoardMediator.countPossibleMoves() > 0)
      m_cursor = (m_cursor + 1) % BoardMediator.countPossibleMoves();
    else
      m_cursor = -1;
  }
  
  /**
   * Steps backward amongst cursor indices.
   */
  public void cursorBackIndex()
  {
    int newIndex = m_cursor - 1;
    if (newIndex < 0) newIndex = BoardMediator.countPossibleMoves() - 1;
    m_cursor = newIndex;
  }
  
  /**
   * Returns whether there is a valid cursor or not.
   * 
   * @return  True if there is a valid cursor, false otherwise.
   */
  public boolean isCursorValid()
  {
    return m_cursor >= 0;
  }
  
  // Graphic methods
  
  /**
   * Paints the backgammon board, any surrounding
   * graphics and all current animations.
   * 
   * @param g Graphics context.
   */
  protected void paint(Graphics g)
  {
    try
    {
      // Clear background
      g.setColor(COL_BOARD_DK);
      g.fillRect(0,m_boardH,m_width, m_height - m_boardH);
      // Draw backgammon board
      drawBoard(g);
      // Draw dice values if necessary
      if (!BoardMediator.isGameFinished() && m_drawDiceValues)
      {
        drawDiceValues(g,
          BoardMediator.isCurrentPlayerWhite(),
          m_diceValues, m_consumeStatuses);
      }
      // Draw animations
      m_animationEngine.paint(g);
      // Draw softbuttons
      m_softbuttons.paint(g);
      // Draw popup if necessary
      if (m_popup != null && m_popup.isActive())
      {
        m_popup.paint(g);
      }
    }
    catch (Throwable t)
    {
      System.err.println("Error in board paint thread");
      t.printStackTrace();
    }
  }
  
  /**
   * Returns the actual height of the board in pixels
   * @return the board height
   */
  public int getBoardHeight()
  {
    return m_boardH;
  }
  
  /**
   * Adds a piece animation when there is a winner. Selects
   * among existing pieces on board.
   * @param white	True to animate white pieces, false for black.
   * @param winAnim	The comprising winning animation.
   */
  public void addWinningPieceAnimation(boolean white, WinnerAnim winAnim)
  {
    // Find a piece to animate
    int src = -1;
    if (getPieces(white, Board.POS_GUARD) > 0)
    {
      src = Board.POS_GUARD;
    }
    else
    {
      for (int i = 0; src == -1 && i <= Board.POS_BOARD; i++)
      {
        if (getPieces(white, i) > 0)
        {
          src = i;
        }
      }
    }
    if (src >= 0)
    {
      int x = (src > Board.POS_BOARD / 2) ? 0 : getWidth();
      m_animationEngine.addAnimation(
        new WinnerPieceMoveAnim(winAnim, white, src, x, getHeight()/2, getPieces(white, src)-1)
      );
    }
  }
  
  /**
   * Draws the backgammon game board. Does partial redraw depending on
   * what is changed since last draw.
   * @param g    Graphics context to draw to or null if just
   *             updating static graphics.
   */
  protected void drawBoard(Graphics g)
  {
    Graphics staticGraphics = m_pieceBoardImg.getGraphics();
    for (int i = 0; i < Board.MAX_POS; i++)
    {
      if (m_dirtyRows[i])
      {
          // Repaint dirty region
        staticGraphics.setClip(
              m_boardRegions[i][0], 
              m_boardRegions[i][1],
              m_boardRegions[i][2],
              m_boardRegions[i][3]);
        staticGraphics.drawImage(m_cleanBoardImg, 0, 0, Graphics.TOP | Graphics.LEFT);
        staticGraphics.setClip(0,0,m_width, m_height);
        drawPieces(staticGraphics, i);
      }
    }
    if (g != null)
    {
      g.drawImage(m_pieceBoardImg, 0, 0, Graphics.TOP | Graphics.LEFT);
    }
  }
  
  /**
   * Draws both dice values.
   * @param g				Graphics context to draw to.
   * @param white			True for white dicevalues, false for vlack.
   * @param diceVals		Array for the actual dice values.
   * @param consumeStatus	Array of the consume status of each dice value.
   */
  protected void drawDiceValues(Graphics g,
    boolean white,
    int[] diceVals,
    int[] consumeStatus)
  {
    int totalW = 2 * (m_diceValueUnit * 8 ) - m_diceValueUnit;
    int x = (m_width - totalW) / 2;
    int y = m_boardH - m_diceValueUnit * 7 - 1;
    for (int i = 0; i < 2; i++)
    {
      drawDiceValue(g, white, diceVals[i], consumeStatus[i], x, y);
      x += m_diceValueUnit * 8;
    }
  }
  
  /**
   * Draws one dice value.
   * @param g				Graphics context to draw to.
   * @param white			True for white dicevalues, false for vlack.
   * @param diceVal  		The actual dice value (0-5).
   * @param consumeStatu	The consume status of the dice value.
   * @param x				X-coordinate of the dicevalue.
   * @param y				Y-coordinate of the dicevalue.
   */
  protected void drawDiceValue(
    Graphics g, boolean white, int diceVal, int consumeStatus,
    int x, int y)
  {
    int[] backCols = COL_WHITE_DICE_VAL, ptCols = COL_BLACK_DICE_VAL;
    if (!white)
    {
      backCols = COL_BLACK_DICE_VAL; ptCols = COL_WHITE_DICE_VAL;
    }
    int backCol = backCols[consumeStatus];
    int fxCol = backCols[3];
    int ptCol = ptCols[consumeStatus];
    g.setColor(fxCol);
    g.fillRect(x+1,y+1,m_diceValueUnit * 7, m_diceValueUnit * 7);
    g.setColor(backCol);
    g.fillRect(x,y,m_diceValueUnit * 7, m_diceValueUnit * 7);
  
    g.setColor(ptCol);
    int[][] pts = m_diceValPts[diceVal-1];
    for (int i = 0; i < pts.length; i++)
    {
      g.fillRect(x + pts[i][0], y + pts[i][1], m_diceValueUnit, m_diceValueUnit);
    }
  }
    
  /**
   * Returns an image of a clean backgammon board (without pieces).
   * @return  A backgammon board image.
   */  
  public synchronized Image getBoardImage()
  {
    if (m_cleanBoardImg == null)
    {
      m_cleanBoardImg = Image.createImage(m_width, m_boardH);
      Graphics ig = m_cleanBoardImg.getGraphics();
      ig.setColor(COL_BOARD);
      ig.fillRect(0,0,m_width,m_boardH);
      int diag = 0;
      int index = 0;
      int tmpCol, col1 = COL_WHITE_DIAG, col2 = COL_BLACK_DIAG;
      for (int y = 0; y < m_height - m_diagH; y += m_diagH)
      {
        diag ++;
        switch (diag)
        {
          // out
          case 1:
          // guard
          case 8:
          // bottom
          case 15:
          {
            y++;
            ig.setColor(COL_BOARD_LT);
            ig.drawLine(0,y,m_width-1,y);
            ig.drawLine(0,y,0,y+m_diagH);
            ig.setColor(COL_BOARD_DK);
            ig.drawLine(0,y+m_diagH,m_width-1,y+m_diagH);
            ig.drawLine(m_width-1,y,m_width-1,y+m_diagH);
            y++;
            break;
          }
          default:
          {
            m_boardRegions[index][0] = 0;
            m_boardRegions[index][1] = y;
            m_boardRegions[index][2] = m_width/2;
            m_boardRegions[index][3] = m_diagH;

            m_boardRegions[Board.POS_BOARD - index][0] = m_width/2 + 1;
            m_boardRegions[Board.POS_BOARD - index][1] = y;
            m_boardRegions[Board.POS_BOARD - index][2] = m_width/2;
            m_boardRegions[Board.POS_BOARD - index][3] = m_diagH;
            
            index ++;
            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -