gamescreen.java

来自「J2ME MIDP_Example_Applications」· Java 代码 · 共 393 行

JAVA
393
字号
// Copyright 2002 Nokia Corporation.
//
// THIS SOURCE CODE IS PROVIDED 'AS IS', WITH NO WARRANTIES WHATSOEVER,
// EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS
// FOR ANY PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE
// OR TRADE PRACTICE, RELATING TO THE SOURCE CODE OR ANY WARRANTY OTHERWISE
// ARISING OUT OF ANY PROPOSAL, SPECIFICATION, OR SAMPLE AND WITH NO
// OBLIGATION OF NOKIA TO PROVIDE THE LICENSEE WITH ANY MAINTENANCE OR
// SUPPORT. FURTHERMORE, NOKIA MAKES NO WARRANTY THAT EXERCISE OF THE
// RIGHTS GRANTED HEREUNDER DOES NOT INFRINGE OR MAY NOT CAUSE INFRINGEMENT
// OF ANY PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OWNED OR CONTROLLED
// BY THIRD PARTIES
//
// Furthermore, information provided in this source code is preliminary,
// and may be changed substantially prior to final release. Nokia Corporation
// retains the right to make changes to this source code at
// any time, without notice. This source code is provided for informational
// purposes only.
//
// Nokia and Nokia Connecting People are registered trademarks of Nokia
// Corporation.
// Java and all Java-based marks are trademarks or registered trademarks of
// Sun Microsystems, Inc.
// Other product and company names mentioned herein may be trademarks or
// trade names of their respective owners.
//
// A non-exclusive, non-transferable, worldwide, limited license is hereby
// granted to the Licensee to download, print, reproduce and modify the
// source code. The licensee has the right to market, sell, distribute and
// make available the source code in original or modified form only when
// incorporated into the programs developed by the Licensee. No other
// license, express or implied, by estoppel or otherwise, to any other
// intellectual property rights is granted herein.


package example.tictactoe;

import java.util.Random;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


class GameScreen
    extends Canvas
    implements CommandListener
{
    private static final int BLACK = 0x00000000;
    private static final int WHITE = 0x00FFFFFF;
    private static final int RED   = 0x00FF0000;
    private static final int BLUE  = 0x000000FF;
    private static final int NO_MOVE  = -1;

    private final TicTacToeMIDlet midlet;
    private final Game game;
    private final Command exitCommand;
    private final Command newGameCommand;
    private final Random random = new Random();

    private int screenWidth, screenHeight;
    private int boardCellSize, boardSize, boardTop, boardLeft;

    private boolean playerIsCircle;
    private boolean computerIsCircle;
    private int preCursorPosition, cursorPosition;
    private int computerMove = NO_MOVE;
    private int playerMove = NO_MOVE;
    private int computerGamesWonTally = 0;
    private int playerGamesWonTally = 0;
    private boolean isRestart;


    public GameScreen(TicTacToeMIDlet midlet, boolean playerIsCircle)
    {
         this.midlet = midlet;
         this.playerIsCircle = playerIsCircle;
         computerIsCircle = !playerIsCircle;

         game = new Game(random);

         initializeBoard();

         // configure Screen commands
         exitCommand = new Command("Exit", Command.EXIT, 1);
         newGameCommand = new Command("New", Command.SCREEN, 2);
         addCommand(exitCommand);
         addCommand(newGameCommand);
         setCommandListener(this);

         // begin the game play
         initialize();
    }


    // Initialize the Game and Game screen. Also used for game restarts.
    private void initialize()
    {
        game.initialize();

        preCursorPosition = cursorPosition = 0;
        playerMove = NO_MOVE;

        boolean computerFirst = ((random.nextInt() & 1) == 0);
        if (computerFirst)
        {
            computerMove = game.makeComputerMove();
        }
        else
        {
            computerMove = NO_MOVE;
        }

        isRestart = true;
        repaint();
    }


    public void paint(Graphics g)
    {
        if (game.isGameOver())
        {
            paintGameOver(g);
        }
        else
        {
            paintGame(g);
        }
    }


    private void paintGame(Graphics g)
    {
        if (isRestart)
        {
            // clean the canvas
            g.setColor(WHITE);
            g.fillRect(0, 0, screenWidth, screenHeight);

            drawBoard(g);
            isRestart = false;
        }

        drawCursor(g);

        if (playerMove != NO_MOVE)
        {
            drawPiece(g, playerIsCircle, playerMove);
        }

        if (computerMove != NO_MOVE)
        {
            drawPiece(g, computerIsCircle, computerMove);
        }
    }


    private void paintGameOver(Graphics g)
    {
        String statusMsg = null;
        if(game.isComputerWinner())
        {
            statusMsg = "I win !";
            computerGamesWonTally++;
        }
        else if (game.isPlayerWinner())
        {
            statusMsg = "You win";
            playerGamesWonTally++;
        }
        else
        {
            statusMsg = "Stalemate";
        }
        String tallyMsg = "You:" + playerGamesWonTally +
                          " Me:" + computerGamesWonTally;

        Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
                                 Font.SIZE_MEDIUM);
        int strHeight = font.getHeight();
        int statusMsgWidth = font.stringWidth(statusMsg);
        int tallyMsgWidth = font.stringWidth(tallyMsg);
        int strWidth = tallyMsgWidth;
        if (statusMsgWidth > tallyMsgWidth)
        {
            strWidth = statusMsgWidth;
        }

        // Get the {x, y} position for painting the strings.
        int x = (screenWidth - strWidth) / 2;
        x = x < 0 ? 0 : x;

        int y = (screenHeight - 2 * strHeight) / 2;
        y = y < 0 ? 0 : y;

        // clean the canvas
        g.setColor(WHITE);
        g.fillRect(0, 0, screenWidth, screenHeight);

        // paint the strings' text
        g.setColor(BLACK);
        g.drawString(statusMsg, x, y, (Graphics.TOP | Graphics.LEFT));
        g.drawString(tallyMsg,  x, (y + 1 + strHeight),
                     (Graphics.TOP | Graphics.LEFT));
    }


    public void commandAction(Command c, Displayable d)
    {
        if (c == exitCommand)
        {
            midlet.quit();
        }
        else if (c == newGameCommand)
        {
            initialize();
        }
    }


    private void initializeBoard()
    {
        screenWidth = getWidth();
        screenHeight = getHeight();

        if (screenWidth > screenHeight)
        {
            boardCellSize = (screenHeight - 2) / 3;
            boardLeft = (screenWidth - (boardCellSize * 3)) / 2;
            boardTop = 1;
        }
        else
        {
            boardCellSize = (screenWidth - 2) / 3;
            boardLeft = 1;
            boardTop = (screenHeight - boardCellSize * 3) / 2;
        }
    }


    protected void keyPressed(int keyCode)
    {
        // can't continue playing until the player restarts
        if (game.isGameOver())
        {
            return;
        }

        int gameAction = getGameAction(keyCode);

        switch (gameAction)
        {
        case FIRE:
            doPlayerMove();
            break;

        case RIGHT:
            doMoveCursor(1, 0);
            break;

        case DOWN:
            doMoveCursor(0, 1);
            break;

        case LEFT:
            doMoveCursor(-1, 0);
            break;

        case UP:
            doMoveCursor(0, -1);
            break;

        default:
            break;
        }
    }


    private void doPlayerMove()
    {
        if (game.isFree(cursorPosition))
        {
            // player move
            game.makePlayerMove(cursorPosition);
            playerMove = cursorPosition;

            // computer move
            if (!game.isGameOver())
            {
                computerMove = game.makeComputerMove();
            }

            repaint();
        }
    }


    private void doMoveCursor(int dx, int dy)
    {
        int newCursorPosition = cursorPosition + dx + 3 * dy;

        if ((newCursorPosition >= 0) && (newCursorPosition < 9))
        {
            preCursorPosition = cursorPosition;
            cursorPosition = newCursorPosition;
            repaint();
        }
    }


    // Draw a CIRCLE or CROSS piece on the board
    private void drawPiece(Graphics g, boolean isCircle, int pos)
    {
        int x = ((pos % 3) * boardCellSize) + 3;
        int y = ((pos / 3) * boardCellSize) + 3;

        if (isCircle)
        {
            drawCircle(g, x, y);
        }
        else
        {
            drawCross(g, x, y);
        }
    }


    // Draw blue CIRCLE onto the board image
    private void drawCircle(Graphics g, int x, int y)
    {
        g.setColor(BLUE);
        g.fillArc(x + boardLeft, y + boardTop,
                  boardCellSize - 4, boardCellSize - 4, 0, 360);

        g.setColor(WHITE);
        g.fillArc(x + 4 + boardLeft, y + 4 + boardTop,
                  boardCellSize - 4 - 8, boardCellSize - 4 - 8, 0, 360);
    }


    // Draw red CROSS onto the board image
    private void drawCross(Graphics g, int x, int y)
    {
        g.setColor(RED);
        for (int i = 0; i < 4; i++)
        {
            g.drawLine(x + 1 + i + boardLeft, y + boardTop,
                       x + boardCellSize - 4 - 4 + i + boardLeft,
                       y + boardCellSize - 5 + boardTop);
            g.drawLine(x + 1 + i + boardLeft, y + boardCellSize - 5 + boardTop,
                       x + boardCellSize - 4 - 4 + i + boardLeft,
                       y + boardTop);
        }
    }


    // Visually indicates a Player selected square on the board image
    private void drawCursor(Graphics g)
    {
        // draw cursor at selected Player square.
        g.setColor(WHITE);
        g.drawRect(((preCursorPosition % 3) * boardCellSize) + 2 + boardLeft,
                   ((preCursorPosition/3) * boardCellSize) + 2 + boardTop,
                   boardCellSize - 3,
                   boardCellSize - 3);

        // draw cursor at selected Player square.
        g.setColor(BLACK);
        g.drawRect(((cursorPosition % 3) * boardCellSize) + 2 + boardLeft,
                   ((cursorPosition/3) * boardCellSize) + 2 + boardTop,
                   boardCellSize - 3,
                   boardCellSize - 3);
    }


    private void drawBoard(Graphics g)
    {
        // clean the board
        g.setColor(WHITE);
        g.fillRect(0, 0, screenWidth, screenHeight);

        // draw the board
        g.setColor(BLACK);
        for (int i = 0; i < 4; i++)
        {
            g.fillRect(boardLeft, boardCellSize * i + boardTop,
                       (boardCellSize * 3) + 2, 2);
            g.fillRect(boardCellSize * i + boardLeft, boardTop,
                       2, boardCellSize * 3);
        }
    }
}


⌨️ 快捷键说明

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