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

📄 maincanvas.java

📁 A very smaller script interpretor that java based system. Can work on j2se / j2me / win C++ platform
💻 JAVA
字号:
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Graphics;

//import com.nokia.mid.ui.FullCanvas;



final class MainCanvas

    extends Canvas
    implements Runnable {
  //______________公用的控制变量及常量__________________________
  static private final int MILLIS_PER_TICK = 120;
  public a aMidlet = null;
  public int screenW = 0, screenH = 0; //屏幕宽高
  public final int CHARW = 17, CHARH = 17; //单个字的宽高
  public Font font;
  public static final byte
      STATE_NONE = 0
      , STATE_ERROR = 1
      , STATE_LODING = 2
      , STATE_SPLASH = 3
      , STATE_MENU = 4
      , STATE_GAMERUN = 5
      , STATE_EXIT = 7
      , STATE_HELP = 8
      , STATE_OPTION = 9
      , STATE_ABOUT = 10
      ;

  long timeTaken; //run()的一个周期所用的时间

  private volatile Thread self;

  //各种不同的按键状态
  static public final byte //在isPressed()中作为参数使用
      MASK_NUM0 = 0
      , MASK_NUM1 = 1
      , MASK_NUM2 = 2
      , MASK_NUM3 = 3
      , MASK_NUM4 = 4
      , MASK_NUM5 = 5
      , MASK_NUM6 = 6
      , MASK_NUM7 = 7
      , MASK_NUM8 = 8
      , MASK_NUM9 = 9
      , MASK_LEFT = 10
      , MASK_UP = 11
      , MASK_RIGHT = 12
      , MASK_DOWN = 13
      , MASK_FIRE = 14
      , MASK_STAR = 15
      , MASK_POUND = 16
      , MASK_SOFT1 = 17
      , MASK_SOFT2 = 18
      , MASK_SOFT3 = 19
      ;

  int keyFlag = 0; //用来存放键是否被按下,用位来表示,当键按下时把相应位置1,直到按键释放才置0

  int keyFlagIm = 0;


  //_______________用户自定义的变量及常量_________________________
  TicTacToe pg;
//--------------------------------------------------------------------------------------
//                                           方法
//--------------------------------------------------------------------------------------

  /**
   * 构造方法
   * @param aMidlet a 向当前画布传入一个MIDlet实例
   */
  public MainCanvas(a aMidlet) {
    this.aMidlet = aMidlet;
    screenW = this.getWidth();
    screenH = this.getHeight();

    font = Font.getDefaultFont(); //moto303

    //做相应的初始化操作
    pg = new TicTacToe(this);
  }

  /**
   * 启动线程
   */
  synchronized public void begin() {
    self = new Thread(this);
    self.start();
  }

  /**
   * 结束线程
   */
  synchronized public void stop() {
    self = null;
  }

  /**
   * 线程体
   */
  public void run() {
    final Thread currentThread = Thread.currentThread(); //
    while (currentThread == self) {
      try {
        final long startTime = System.currentTimeMillis();

        if (isShown()) {
          repaint(); //所有游戏的绘制和逻辑均在里面实现
          serviceRepaints(); //写屏
        }
        timeTaken = System.currentTimeMillis() - startTime;
        if (timeTaken < MILLIS_PER_TICK) {
          synchronized (this) {
            wait(MILLIS_PER_TICK - timeTaken); //使每个周期大致相等
          }
        }
        else {
          currentThread.yield(); //让出控制权,防止饿死其它线程
        }
      }
      catch (Exception ex) {
        // won't be thrown
      }
    }
    //release
  }

  /**
   * 绘制方法
   * @param g Graphics 系统调度线程调度时传入的图像句柄
   */
  public void paint(Graphics g) { //由此触发Canvas的重绘。
    try {
      g.setColor(0x000000);
      g.fillRect(0, 0, screenW, screenH); //清屏

      pg.draw(g);

      //debug
      int drawY = 10;
      g.setColor(0x0000ff);
      g.drawString("MSPF:" + timeTaken, 0, drawY += 18, g.TOP | g.LEFT);
      g.drawString("keyFlag:" + keyFlag, 0, drawY += 18, g.TOP | g.LEFT);
      g.drawString("keyFlagIm:" + keyFlagIm, 0, drawY += 18, g.TOP | g.LEFT);
      //end debug
    }
    catch (Exception e) {}
    finally {
      keyFlagIm = 0; //在每个paint()的最后,把临时键标志强行复位,因为下个周期,他已不再有作用
    }
  }

  //;----------------------------------------------------------------------
  //;                按键处理机制 a simple key process arch
  //;----------------------------------------------------------------------
  /**
   * 实现的按键方法 ,override Canvas keyPressed
   * @param keyCode int 系统事件调度线程传入的键码
   */
  protected void keyPressed(int keyCode) {
    switch (keyCode) {
      case Canvas.KEY_NUM0:
        keyFlag |= (0x00000001 << MASK_NUM0); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM1:
        keyFlag |= (0x00000001 << MASK_NUM1); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM2:
        keyFlag |= (0x00000001 << MASK_NUM2); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM3:
        keyFlag |= (0x00000001 << MASK_NUM3); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM4:
        keyFlag |= (0x00000001 << MASK_NUM4); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM5:
        keyFlag |= (0x00000001 << MASK_NUM5); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM6:
        keyFlag |= (0x00000001 << MASK_NUM6); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM7:
        keyFlag |= (0x00000001 << MASK_NUM7); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM8:
        keyFlag |= (0x00000001 << MASK_NUM8); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM9:
        keyFlag |= (0x00000001 << MASK_NUM9); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_STAR:
        keyFlag |= (0x00000001 << MASK_STAR); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_POUND:
        keyFlag |= (0x00000001 << MASK_POUND); // 向左移N位后,即该位置1
        break;

    }
    switch (getGameAction(keyCode)) {
      case Canvas.UP:
        keyFlag |= (0x00000001 << MASK_UP); // 向左移N位后,即该位置1
        break;
      case Canvas.DOWN:
        keyFlag |= (0x00000001 << MASK_DOWN); // 向左移N位后,即该位置1
        break;
      case Canvas.LEFT:
        keyFlag |= (0x00000001 << MASK_LEFT); // 向左移N位后,即该位置1
        break;
      case Canvas.RIGHT:
        keyFlag |= (0x00000001 << MASK_RIGHT); // 向左移N位后,即该位置1
        break;
      case Canvas.FIRE:
        keyFlag |= (0x00000001 << MASK_FIRE); // 向左移N位后,即该位置1
        break;
    }
    //给即时按键标志赋值,用这个变量可在isPressed()中检测到是否有短时按键产生
    //set temp key flag value
    keyFlagIm = keyFlag;

  }

  /**
   * 释放键的方法, override Canvas keyReleased method
   * @param keyCode int
   */
  protected void keyReleased(int keyCode) {

    switch (keyCode) {
      case Canvas.KEY_NUM0:
        keyFlag &= ~ (0x00000001 << MASK_NUM0); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM1:
        keyFlag &= ~ (0x00000001 << MASK_NUM1); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM2:
        keyFlag &= ~ (0x00000001 << MASK_NUM2); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM3:
        keyFlag &= ~ (0x00000001 << MASK_NUM3); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM4:
        keyFlag &= ~ (0x00000001 << MASK_NUM4); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM5:
        keyFlag &= ~ (0x00000001 << MASK_NUM5); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM6:
        keyFlag &= ~ (0x00000001 << MASK_NUM6); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM7:
        keyFlag &= ~ (0x00000001 << MASK_NUM7); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM8:
        keyFlag &= ~ (0x00000001 << MASK_NUM8); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_NUM9:
        keyFlag &= ~ (0x00000001 << MASK_NUM9); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_STAR:
        keyFlag &= ~ (0x00000001 << MASK_STAR); // 向左移N位后,即该位置1
        break;
      case Canvas.KEY_POUND:
        keyFlag &= ~ (0x00000001 << MASK_POUND); // 向左移N位后,即该位置1
        break;

    }
    switch (getGameAction(keyCode)) {
      case Canvas.UP:
        keyFlag &= ~ (0x00000001 << MASK_UP); // 向左移N位后,即该位置1
        break;
      case Canvas.DOWN:
        keyFlag &= ~ (0x00000001 << MASK_DOWN); // 向左移N位后,即该位置1
        break;
      case Canvas.LEFT:
        keyFlag &= ~ (0x00000001 << MASK_LEFT); // 向左移N位后,即该位置1
        break;
      case Canvas.RIGHT:
        keyFlag &= ~ (0x00000001 << MASK_RIGHT); // 向左移N位后,即该位置1
        break;
      case Canvas.FIRE:
        keyFlag &= ~ (0x00000001 << MASK_FIRE); // 向左移N位后,即该位置1
        break;
    }

  }

  /**
   * 用来标示是否某个键被按了,这里采用增加一个标志位,可以有效防止在tick()栓测的过程中,短暂按键不能被程序知道的问题 参考岳振的思想
   * to determine what key pressed in this game cycle
   *
   * @param keyLabel int
   * @return boolean
   */
  public boolean isPressed(byte keyLabel) {
    if ( ( (keyFlagIm >>> keyLabel) & 0x00000001) == 1) { //曾按过也返回真
      keyFlagIm &= (~ (0x00000001 << keyLabel)); //把相应的位置为0;
//      keyFlagIm = 0; //取一次后把所有的位置0,这种处理方式不支持多键同按的系统,否则应使用上面一句
      return true;
    }
    if ( ( (keyFlag >>> keyLabel) & 0x00000001) == 1) { //如果此标志位为1则返回真
      return true;
    }
    return false;
  }

  /**
   * 复位键状态,在使用这个键后,有时候,我们并不想这个键值在下一个循环中仍有效,因此我们将其复位,防止后
   * 面的操作也被这个键值所作用。
   *
   * reset all key flags
   */
  public final void resetKey() {
    keyFlag = keyFlagIm = 0;
  }

}

⌨️ 快捷键说明

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