原文見:http://today.java.net/pub/a/today/2005/07/07/j2me3.html?page=2

          構建一個J2ME游戲:從GameCanvas類開始

          GameCanvas類繼承自Canvas,提供了一個屏幕后端的緩沖區,所有的繪制操作都先在這個緩沖區里進行。當所有繪制操作完成后,我們調用flushGraphics()方法將緩沖區內容輸出到屏幕。這種雙緩沖機制可以使圖像的移動更加平滑,避免圖像的閃爍。緩沖區大小等于屏幕的大小,而且每一個GameCanvas實例有且僅有一個緩沖區。

          GameCanvas類提供一種存儲按鍵狀態的機制,我們可以通過它方便的了解用戶與游戲的交互。這種機制可以跟蹤用戶按特殊鍵的次數,調用getKeyStates()方法返回所有游戲鍵按鍵狀態的二進制表示,1代表上次調用方法后按過該鍵,0表示上次調用后還沒有按過該鍵。我們可以跟蹤的游戲狀態有(這里的鍵都是在Canvas類里定義的):DOWN_PRESSED, UP_PRESSED, RIGHT_PRESSED, LEFT_PRESSED, FIRE_PRESSED, GAME_A_PRESSED, GAME_B_PRESSED, GAME_C_PRESSED和GAME_D_PRESSED。

          首先擴展GameCanvas類,定制一個游戲畫布,代碼見清單1。清單2是運行例子的MIDlet。

          package com.j2me.part3;

          import javax.microedition.lcdui.Image;
          import javax.microedition.lcdui.Display;
          import javax.microedition.lcdui.Graphics;
          import javax.microedition.lcdui.game.GameCanvas;

          import java.io.IOException;

          public class MyGameCanvas
              
          extends GameCanvas
              
          implements Runnable
          {
              
          public MyGameCanvas()
              
          {
                  
          super(true);
              }

              
              
          public void start()
              
          {
                  
          try
                  
          {
                      
          //導入couple圖片,坐標定位在屏幕中央
                      coupleImg = Image.createImage("/couple.gif");
                      coupleX 
          = CENTER_X;
                      coupleY 
          = CENTER_Y;
                  }

                  
          catch(IOException ioex)
                  
          {
                      System.err.println(ioex);
                  }

                  
                  Thread runner 
          = new Thread(this);
                  runner.start();
              }

              
              
          public void run()
              
          {
                  
          //獲取畫布的graphics對象
                  Graphics g = getGraphics();
                  
                  
          while(true//無窮循環
                  {
                      
          //基于上一個代碼清單列出的結構
                      
                      
          //首先檢查游戲狀態
                      verifyGameState();
                      
                      
          //檢查用戶輸入
                      checkUserInput();
                      
                      
          //更新屏幕
                      updateGameScreen(getGraphics());
                      
                      
          //休息一下,控制刷新頻率
                      try
                      
          {
                          Thread.currentThread().sleep(
          30);
                      }

                      
          catch(Exception e)
                      
          {}
                  }

              }

              
              
          private void verifyGameState()
              
          {
                  
          //現在先不做任何操作
              }

              
              
          private void checkUserInput()
              
          {
                  
          //獲取按鍵信息
                  int keyState = getKeyStates();
                  
                  
          //計算x軸位置
                  calculateCoupleX(keyState);
              }

              
              
          private void updateGameScreen(Graphics g)
              
          {
                  
          //清空屏幕背景
                  g.setColor(0xffffff);
                  g.fillRect(
          00, getWidth(), getHeight());
                  
                  
          //將couple圖片繪制到當前坐標位置
                  g.drawImage(
                      coupleImg, coupleX, coupleY, Graphics.HCENTER 
          |
                      Graphics.BOTTOM);
                  
                  flushGraphics();
              }

              
              
          private void calculateCoupleX(int keyState)
              
          {
                  
          //判斷移動方向
                  if((keyState & LEFT_PRESSED) != 0)
                  
          {
                      coupleX 
          -= dx;
                  }

                  
          else if((keyState & RIGHT_PRESSED) != 0)
                  
          {
                      coupleX 
          += dx;
                  }

              }

              
              
          private Image coupleImg;
              
          private int coupleX;
              
          private int coupleY;
              
          private int dx = 1//移動量
              
              
          //屏幕中心
              public final int CENTER_X = getWidth() / 2;
              
          public final int CENTER_Y = getHeight() / 2;
          }

          清單 1. MyGameCanvas:游戲畫布的第一個版本

          清單 2 是使用這個游戲畫布的MIDlet:

          package com.j2me.part3;

          import javax.microedition.lcdui.Display;
          import javax.microedition.midlet.MIDlet;

          public class GameMIDlet extends MIDlet
          {
              MyGameCanvas gCanvas;
              
              
          public GameMIDlet()
              
          {
                  gCanvas 
          = new MyGameCanvas();
              }

              
              
          public void startApp()
              
          {
                  Display d 
          = Display.getDisplay(this);
                  gCanvas.start();
                  
                  d.setCurrent(gCanvas);
              }

              
              
          public void pauseApp()
              
          {}
              
              
          public void destroyApp(boolean unconditional)
              
          {}
          }

          清單 2. 運行游戲示例的MIDlet類

          使用Wireless工具建立一個工程,導入這兩個類,然后生成并運行工程。確保你的工程目錄res中有這個圖片文件couple.gif,并保證名稱為couple.gif, 圖1是運行結果。

          j2me3_figure1.gif
          圖1. 構建一個游戲:使用GameCanvas類

          使用設備的方向鍵可以左右移動屏幕中的小圖像,這是通過從checkUserInput()里取得按鍵狀態,然后調用calculateCoupleX(),通過將按鍵狀態與GameCanvas里預定義的按鍵值進行與操作(&),得到用戶當前按的鍵,然后將實例變量更新,最終反映到設備屏幕上。

          圖像是在updateGameScreen()方法里被繪制到屏幕上的。這個方法使用傳入的Graphics對象進行繪制,每一個GameCanvas只有一個Graphics對象。方法首先擦除上次繪制的圖像,然后基于當前的coupleX值(還有一直不變的coupleY值)繪制couple.gif圖像,最后將緩沖區的數據輸出到屏幕。

          run()方法里的循環體遵循我們剛開始提出的游戲結構。循環每30毫秒檢查一次用戶輸入并刷新屏幕。你可以試著將這個值改變一下,這會改變刷新的頻率。

          最后,注意MyGameCanvas的構造器里調用了父類GameCanvas的構造方法,傳入的參數為true,這表示從Canvas類繼承的按鍵事件機制被抑制了,因為我們的代碼不需要這些通知機制。我們的游戲狀態用GameCanvas里自帶的按鍵信息(由getKeyStates()方法取得)來處理已經足夠了。通過抑制“keyPressed”、“keyReleased”和“keyRepeated”等通知機制,可以提高游戲的性能。



          版權所有 羅明
          posted on 2005-12-08 18:01 羅明 閱讀(2604) 評論(3)  編輯  收藏 所屬分類: JavaJ2ME
          Comments
          • # 好好學習
            ken
            Posted @ 2005-12-09 10:55
            package com.j2me.part3;

            import javax.microedition.lcdui.Display;
            import javax.microedition.midlet.MIDlet;

            這個地方看不懂,清單1和清單2怎么兩個相同的包名在,不是引用么  回復  更多評論   
          • # re: J2ME Tutorial, Part 3: 探究MIDP 2.0的游戲API(二)
            Andy luo
            Posted @ 2005-12-09 11:28
            這兩個類是放在一起的(一個包中),只不過清單2是主類,包含了一個清單1的實例。項目運行時執行清單2的MIDlet,然后清單1執行相應的繪制操作。  回復  更多評論   
          • # Meta-Tegi
            Meta-Tegi
            Posted @ 2009-05-18 03:37
            Hello everyone. Eat a third and drink a third and leave the remaining third of your stomach empty. Then, when you get angry, there will be sufficient room for your rage.
            I am from Pakistan and too bad know English, tell me right I wrote the following sentence: "Seo best practices innovations from chicago based seo consultant and resolution media associate director of search engine optimization, bryson meunier.In addition to pure seo services and web marketing, I have a lot of experience."

            Best regards :), Patricia.  回復  更多評論   
           
          主站蜘蛛池模板: 汝州市| 元江| 江山市| 行唐县| 凤城市| 柘荣县| 六安市| 富蕴县| 习水县| 翼城县| 台山市| 北流市| 同心县| 岳普湖县| 宁晋县| 深州市| 河南省| 堆龙德庆县| 麻城市| 连平县| 开江县| 海口市| 绥宁县| 确山县| 定陶县| 三明市| 荣成市| 乌鲁木齐县| 香港 | 崇礼县| 娄底市| 盘山县| 神木县| 沭阳县| 都兰县| 睢宁县| 汉寿县| 英德市| 泸定县| 沙坪坝区| 都安|