class { /*------------ | Constants | ------------*/ // General commands const int CMD_BACK = 1; const int CMD_NEW_GAME = 10; const int CMD_HELP = 11; const int CMD_ABOUT = 12; // Fixed point constants const int SHIFT = 16; // 16:16 FP const int ONE_F = 1 << SHIFT; const int WORLD_SIZE_F = 32 << SHIFT; // 32x32 units // Menu items final MenuItem MENU_BACK = new MenuItem(CMD_BACK, "Back"); final MenuItem MENU_OPTIONS = new MenuItem(OPEN_MENU, "Options"); // Game options menu Menu MENU = new Menu() .add(CMD_NEW_GAME, "New game") .add(CMD_HELP, "Help") .add(CMD_ABOUT, "About"); /*------------ | Variables | ------------*/ // UI Shell gameShell; Flow gameFlow; Canvas gameCanvas; int screenWidth; int screenHeight; int viewportSize; int scale; // Pixels per world unit /*------------------------ | Fixed-point functions | ------------------------*/ // Multiply (input limit 6:16) int ml(int x, int y) { return ((x >> 6) * (y >> 6)) >> 4; } // Divide (input limit 6:16) int dv(int x, int y) { return ((x << 6) / (y >> 6)) << 4; } // Integer to FP int i2f(int x) { return x << SHIFT; } // Fixed-point to integer int f2i(int x) { return x >> SHIFT; } /*------------ | Functions | ------------*/ // Calculate viewport size (and determine scale factor) void calculateViewport(int sw, int sh) { screenWidth = sw; screenHeight = sh; // Viewport is square viewportSize = min(sw, sh); viewportSize -= viewportSize % f2i(WORLD_SIZE_F); // Recompute UI layout gameFlow.setPreferredSize(sw, sh); gameCanvas.setPreferredSize(viewportSize, viewportSize); // Square viewport gameShell.computeLayout(); // Pixels per world unit scale = viewportSize / f2i(WORLD_SIZE_F); // How many pixels per world unit? setBubble(null, "Pixels per world unit = " + scale); } // Cleanup (stop timers, free resources etc.) void cleanup() { gameCanvas = null; gameFlow = null; gameShell = null; } /*------------------- | System callbacks | -------------------*/ // Paint the game canvas void paint(Component c, Graphics g, Style s, int width, int height) { // Determine if orientation has changed? // E.g. landscape <-> portrait int sw, int sh = getScreenSize(); if(sw != screenWidth) calculateViewport(sw, sh); // Display a simple message g.setColor(0xFFFFFF); g.drawString("Paddle Game", width / 2, height / 2, BOTTOM | HCENTER); } // Softkey mapping MenuItem getSoftKey(Shell shell, Component focused, int key) { if(key == SOFTKEY_BACK) return MENU_BACK; else if(key == SOFTKEY_OK) return MENU_OPTIONS; return null; } // Get the current menu Menu getMenu(Shell shell, Component source) { return MENU; } // Key event handler boolean keyAction(Component source, int op, int code) { return false; } // Action event handler void actionPerformed(Shell shell, Component source, int action) { switch(action) { case CMD_NEW_GAME: setBubble(null, "New game..."); break; case CMD_HELP: setBubble(null, "Help..."); break; case CMD_ABOUT: setBubble(null, "Paddle Game"); break; case CMD_BACK: // Exit popShell(shell); break; } } // Start widget (create minimised view) void startWidget() { Flow flow = createView("viewMini", getStyle("default")); setMinimizedView(flow); } // Open widget (create maximised view) Shell openWidget() { // Setup UI gameCanvas = new Canvas(getStyle("gameCanvas")); gameFlow = new Flow(getStyle("gameFlow")); gameFlow.add(gameCanvas); gameShell = new Shell(gameFlow); // Determine viewport size and game unit scaling calculateViewport(getScreenSize()); return gameShell; } // Stop widget void stopWidget() { cleanup(); } // Close widget void closeWidget() { cleanup(); } }