/* * Copyright © 2011 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See LICENSE.TXT for license information. */ package com.nokia.example.battletank; import com.nokia.example.battletank.game.Game; import com.nokia.example.battletank.game.ProtectedContentException; import com.nokia.example.battletank.game.audio.AudioManager; import com.nokia.example.battletank.menu.HelpMenu; import com.nokia.example.battletank.menu.AboutMenu; import com.nokia.example.battletank.menu.BattleTankMenu; import com.nokia.example.battletank.menu.BuyMenu; import com.nokia.example.battletank.menu.Menu; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import javax.microedition.lcdui.AlertType; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.game.GameCanvas; import javax.microedition.rms.RecordEnumeration; import javax.microedition.rms.RecordStore; import javax.microedition.rms.RecordStoreException; public class BattleTankCanvas extends GameCanvas { private static final int MAX_RENDERING_FPS = 20; private static final int MAX_LOGIC_FPS = 40; private static final int LEFT_SOFTKEY = -6; private static final int RIGHT_SOFTKEY = -7; private volatile int pointerKeyState = 0; private Main main; private BattleTankMenu menu; private BuyMenu buyMenu; private HelpMenu helpMenu; private AboutMenu aboutMenu; private Game game; private PointerEventHandler pointerEventHandler; private Timer renderLoop; private Timer gameLogicLoop; public BattleTankCanvas(Main main) { super(false); setFullScreenMode(true); this.main = main; } protected void showNotify() { if(menu == null) createMenu(); if(game == null) createGame(); if(buyMenu == null) createBuyMenu(); if(helpMenu == null) createHelpMenu(); if(aboutMenu == null) createAboutMenu(); if(!Main.isTrial()) hideBuyOption(); if(pointerEventHandler == null) createPointerEventHandler(); startRendering(); showMenu(); } protected void hideNotify() { AudioManager.disableSounds(); stopRendering(); stopGameLogic(); } protected void sizeChanged(int w, int h) { if(menu != null) menu.setSize(w, h); if(buyMenu != null) buyMenu.setSize(w, h); if(helpMenu != null) helpMenu.setSize(w, h); if(aboutMenu != null) aboutMenu.setSize(w, h); if(game != null) game.setViewportSize(w, h); if(pointerEventHandler != null) pointerEventHandler.setSize(w, h); } protected void keyPressed(int key) { if(buyMenu.visible) { switch(getGameAction(key)) { case UP: buyMenu.selectPrev(); break; case DOWN: buyMenu.selectNext(); break; case FIRE: buyMenu.clickSelected(); break; } } else if(helpMenu.visible) { switch(getGameAction(key)) { case UP: helpMenu.selectPrev(); break; case DOWN: helpMenu.selectNext(); break; case FIRE: helpMenu.clickSelected(); break; } } else if(aboutMenu.visible) { switch(getGameAction(key)) { case UP: aboutMenu.selectPrev(); break; case DOWN: aboutMenu.selectNext(); break; case FIRE: aboutMenu.clickSelected(); break; } } else if(menu.visible) { switch(getGameAction(key)) { case UP: menu.selectPrev(); break; case DOWN: menu.selectNext(); break; case FIRE: menu.clickSelected(); break; } } switch(key) { case LEFT_SOFTKEY: leftSoftkey(); break; case RIGHT_SOFTKEY: rightSoftkey(); break; } } protected void pointerPressed(int x, int y) { if(buyMenu.visible) buyMenu.pointerEvent(Menu.POINTER_PRESSED, x, y); else if(helpMenu.visible) helpMenu.pointerEvent(Menu.POINTER_PRESSED, x, y); else if(aboutMenu.visible) aboutMenu.pointerEvent(Menu.POINTER_PRESSED, x, y); else if(menu.visible) menu.pointerEvent(Menu.POINTER_PRESSED, x, y); else pointerEventHandler.pointerPressed(x, y); } protected void pointerDragged(int x, int y) { if(buyMenu.visible) buyMenu.pointerEvent(Menu.POINTER_DRAGGED, x, y); else if(helpMenu.visible) helpMenu.pointerEvent(Menu.POINTER_DRAGGED, x, y); else if(aboutMenu.visible) aboutMenu.pointerEvent(Menu.POINTER_DRAGGED, x, y); else if(menu.visible) menu.pointerEvent(Menu.POINTER_DRAGGED, x, y); else pointerEventHandler.pointerDragged(x, y); } protected void pointerReleased(int x, int y) { if(buyMenu.visible) buyMenu.pointerEvent(Menu.POINTER_RELEASED, x, y); else if(helpMenu.visible) helpMenu.pointerEvent(Menu.POINTER_RELEASED, x, y); else if(aboutMenu.visible) aboutMenu.pointerEvent(Menu.POINTER_RELEASED, x, y); else if(menu.visible) menu.pointerEvent(Menu.POINTER_RELEASED, x, y); else pointerEventHandler.pointerReleased(x, y); } private void leftSoftkey() { if(!menu.visible && game != null) { stopRendering(); try { stopGameLogic(); game.leftSoftkeyPressed(); startGameLogic(); } catch (ProtectedContentException e) { newGame(); showBuyMenu(); } catch(IOException e) { main.showAlertMessage("Level loading failed", Messages.LEVEL_LOAD_ERROR, AlertType.ERROR); } startRendering(); } } private void rightSoftkey() { if(buyMenu.visible) { hideBuyMenu(); } else if(helpMenu.visible) { hideHelpMenu(); } else if(aboutMenu.visible) { hideAboutMenu(); } else if(menu.visible) { hideMenu(); } else { showMenu(); } } private void startRendering() { stopRendering(); final Graphics g = getGraphics(); renderLoop = new Timer(); renderLoop.schedule(new TimerTask() { public void run() { if(buyMenu.visible) buyMenu.render(g); else if(helpMenu.visible) helpMenu.render(g); else if(aboutMenu.visible) aboutMenu.render(g); else if(menu.visible) menu.render(g); else game.render(g); flushGraphics(); } }, 0, 1000/MAX_RENDERING_FPS); } private void startGameLogic() { stopGameLogic(); gameLogicLoop = new Timer(); gameLogicLoop.schedule(new TimerTask() { public void run() { game.update(getKeyStates()); } }, 0, 1000/MAX_LOGIC_FPS); } public int getKeyStates() { int keyStates = super.getKeyStates(); if(keyStates != 0) { pointerKeyState = 0; } else { keyStates = pointerKeyState; if(pointerKeyState == FIRE_PRESSED) pointerKeyState = 0; } return keyStates; } private void stopRendering() { if(renderLoop != null) renderLoop.cancel(); } private void stopGameLogic() { if(gameLogicLoop != null) gameLogicLoop.cancel(); } private void createMenu() { menu = new BattleTankMenu(getWidth(), getHeight(), new Menu.Listener() { public void itemClicked(int item) { switch(item) { case BattleTankMenu.RESUME: hideMenu(); break; case BattleTankMenu.NEWGAME: newGame(); hideMenu(); break; case BattleTankMenu.FULL_VERSION: showBuyMenu(); break; case BattleTankMenu.SOUNDS: game.soundsEnabled = menu.toggleSounds(); break; case BattleTankMenu.HELP: showHelpMenu(); break; case BattleTankMenu.ABOUT: showAboutMenu(); break; case BattleTankMenu.EXIT: main.close(); break; } } }); menu.setBuy(Main.isTrial()); } public void showMenu() { if(menu.visible) return; stopGameLogic(); menu.setSounds(game.soundsEnabled); menu.selectItem(hasPointerEvents() ? -1 : 0); menu.visible = true; } public void hideMenu() { hideBuyMenu(); if(!menu.visible) return; menu.visible = false; if(AudioManager.areSoundsEnabled() != game.soundsEnabled) { AudioManager.setSoundEnabled(game.soundsEnabled); } startGameLogic(); } private void createBuyMenu() { buyMenu = new BuyMenu(getWidth(), getHeight(), new Menu.Listener() { public void itemClicked(int item) { switch(item) { case BuyMenu.BUY: if(Main.purchaseFullVersion()) buyMenu.showWaitIndicator(); break; case BuyMenu.RESTORE: if(Main.restoreFullVersion()) buyMenu.showWaitIndicator(); break; case BuyMenu.BACK: hideBuyMenu(); break; } } }); } public void showBuyMenu() { showMenu(); buyMenu.selectItem(hasPointerEvents() ? -1 : 0); buyMenu.visible = true; } public void hideBuyMenu() { buyMenu.visible = false; } public void hideBuyMenuWaitIndicator() { buyMenu.hideWaitIndicator(); } public void hideBuyOption() { menu.setBuy(false); } private void createHelpMenu() { helpMenu = new HelpMenu(getWidth(), getHeight(), hasPointerEvents(), new Menu.Listener() { public void itemClicked(int item) { switch(item) { case HelpMenu.BACK: hideHelpMenu(); break; } } }); } public void showHelpMenu() { showMenu(); helpMenu.selectItem(hasPointerEvents() ? -1 : 0); helpMenu.visible = true; } public void hideHelpMenu() { helpMenu.visible = false; } private void createAboutMenu() { aboutMenu = new AboutMenu(getWidth(), getHeight(), new Menu.Listener() { public void itemClicked(int item) { switch(item) { case AboutMenu.BACK: hideAboutMenu(); break; } } }); } public void showAboutMenu() { showMenu(); aboutMenu.selectItem(hasPointerEvents() ? -1 : 0); aboutMenu.visible = true; } public void hideAboutMenu() { aboutMenu.visible = false; } private void createGame() { game = new Game(getWidth(), getHeight()); try { //RecordStore.deleteRecordStore("GameState"); // Clear state data for testing purposes RecordStore gameState = RecordStore.openRecordStore("GameState", true); if(gameState.getNumRecords() == 0 || !game.load(gameState.getRecord(getRecordId(gameState)))) { newGame(); } gameState.closeRecordStore(); } catch (RecordStoreException e) { newGame(); } } private void newGame() { try { game.newGame(); } catch(ProtectedContentException e) { //should not happen as there should be at least one trial level throw new RuntimeException("No levels."); } catch(IOException e) { //should not happen as there should be at least one trial level throw new RuntimeException("No levels."); } } public void saveGame() { if(game == null) return; try { RecordStore gameState = RecordStore.openRecordStore("GameState", true); if(gameState.getNumRecords() == 0) gameState.addRecord(null, 0, 0); byte[] data = game.getState(); gameState.setRecord(getRecordId(gameState), data, 0, data.length); gameState.closeRecordStore(); } catch (Exception e) { try { RecordStore.deleteRecordStore("GameState"); } catch (RecordStoreException rse) { } } } private int getRecordId(RecordStore store) throws RecordStoreException { RecordEnumeration e = store.enumerateRecords(null, null, false); try { return e.nextRecordId(); } finally { e.destroy(); } } private void createPointerEventHandler() { pointerEventHandler = new PointerEventHandler(getWidth(), getHeight(), new PointerEventHandler.Listener() { public void onMoveLeft() { pointerKeyState = LEFT_PRESSED; } public void onMoveRight() { pointerKeyState = RIGHT_PRESSED; } public void onMoveUp() { pointerKeyState = UP_PRESSED; } public void onMoveDown() { pointerKeyState = DOWN_PRESSED; } public void onFire() { pointerKeyState = FIRE_PRESSED; } public void onLeftSoftKey() { leftSoftkey(); } public void onRightSoftKey() { rightSoftkey(); } }); } }