private void sendBoardToDisplay(MITrisBoard board, Display2D display, double brightness) { int width = display.getWidth(); int height = display.getHeight(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Piece p = board.getPosition(x, y); Color c = p == null ? Color.BLACK : p.getColor(board.getLevel(), gameDisplayTime); float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), new float[3]); hsb[2] *= brightness; display.setPixelHSB(x, height - 1 - y, hsb[0], hsb[1], hsb[2]); } } }
@Override protected void loop() { Display2D display = getDisplay(); byte userInput = getUserInput(); Graphics2D g = display.getGraphics(); switch (gameState) { case IDLE: animTime = 0; animTimeLastStep = 0; logoPos = 0; gameState = State.IDLE_ANIM; break; case IDLE_ANIM: animTime += timestep; if (animTime - animTimeLastStep >= LOGO_ANIM_STEP) { animTimeLastStep = animTime; logoPos++; if (logoPos > 100) gameState = State.IDLE; } g.drawImage(mitrisLogo, 10 - logoPos, 6, null); switch (userInput) { case 'L': case 'R': case 'U': case 'D': gameState = State.GAME_START; } break; case GAME_START: mitrisGame = new MITrisGame(width, height, timestep); gameState = State.GAME; break; case GAME: // check validity of user move switch (userInput) { case 'L': mitrisGame.moveLeft(); break; case 'R': mitrisGame.moveRight(); break; case 'U': mitrisGame.rotatePiece(); break; case 'D': mitrisGame.dropPiece(); break; case -1: // there was an error in the network socket or no client connected -- "pause" the // game return; } // move piece down if it's time mitrisGame.clockTick(); gameDisplayTime = mitrisGame.getTime(); sendBoardToDisplay(mitrisGame.getDisplayBoard(), display); if (mitrisGame.isGameOver()) { System.out.println( String.format( "Game over! Lines cleared: %d Time: %3.1f", mitrisGame.getDisplayBoard().getNumCleared(), mitrisGame.getTime())); gameState = State.GAME_END_1; gameOverBoard = mitrisGame.getDisplayBoard(); animTime = 0; } break; case GAME_END_1: animTime += timestep; if (animTime > GAME_END_WAIT) { gameState = State.GAME_END_2; animTime = 0; animTimeLastStep = 0; if (gameOverBoard.getLevel() >= 8) { gameState = State.GAME_END_ALT_2; circTime = new double[] {-100, -100, -100, -100, -100}; circX = new double[5]; circY = new double[5]; circHue = new double[5]; circPos = 0; } } sendBoardToDisplay(gameOverBoard, display); break; case GAME_END_2: animTime += timestep; if (animTime - animTimeLastStep >= ANIM_TIME_STEP) { animTimeLastStep = animTime; if (gameOverBoard.isBoardEmpty()) { gameState = State.IDLE; } gameOverBoard = gameOverBoard.shiftBoardDown(); } sendBoardToDisplay(gameOverBoard, display); break; case GAME_END_ALT_2: animTime += timestep; if (animTime >= CIRC_ANIM_FADE_WAIT_TIME) { if (animTime <= CIRC_ANIM_FADE_WAIT_TIME + CIRC_ANIM_FADE_TIME) { double brightness = 1 - (animTime - CIRC_ANIM_FADE_WAIT_TIME) / CIRC_ANIM_FADE_TIME; sendBoardToDisplay(gameOverBoard, display, brightness); } } else sendBoardToDisplay(gameOverBoard, display); if (animTime - animTimeLastStep >= CIRC_ADD_TIME && animTime <= CIRC_ANIM_STOPADD_TIME) { animTimeLastStep = animTime; circX[circPos] = Math.random() * width; circY[circPos] = Math.random() * height; circTime[circPos] = animTime - 0.3; circHue[circPos] = Math.random(); circPos = (circPos + 1) % circX.length; } g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); for (int k = 0; k < circX.length; k++) { g.setColor(new Color(Color.HSBtoRGB((float) circHue[k], 1, 1))); g.setStroke(new BasicStroke(1.5f)); double circH = (animTime - circTime[k]) * 5; double circW = circH / display.getPixelAspect(); g.draw(new Ellipse2D.Double(circX[k] - circW / 2, circY[k] - circH / 2, circW, circH)); } if (animTime >= CIRC_ANIM_TOTAL_TIME) gameState = State.IDLE; } }