零打碎敲学Android(四)—跳跃的火之意志!

来源:互联网 发布:网络乞丐麦词 编辑:程序博客网 时间:2024/04/30 08:47

 http://blog.csdn.net/cping1982/archive/2009/10/25/4725076.aspx

动作游戏(ACT),作为在N早以前的红白机时代,便已经大量普及的经典游戏类型,它强调玩家的反应能力和手眼的配合,属于快节奏游戏的典型。相对而言,动作游戏的剧情一般也比较简单,主要通过熟悉操作技巧就可以进行游戏,多以2D为主潮流。在游戏中,玩家控制的角色不仅可以走、跑、跳,甚至可以俯身、爬行、翻滚、飞行、甚至爬墙(见附图:《忍者龙剑传》)。

 

ACT游戏的武器也多种多样,近程、远程、定时,还可以使用大量的辅助道具,譬如:吊索(例如《蜘蛛侠》)。加之种种场景的地形效果,流沙、冰地、履带、齿轮等等,配合场景中的种种机关,如墙上的开关、灯控、钉板等等,使游戏过程千变万化。即使是3D仿真技术发达的今天,相信仍有不少玩家流连这类ACT游戏吧?

任何一款ACT游戏,从根本上说,都会设定有自己的游戏背景。策划人员在设计这部分内容时,可以充分发挥自己的想象力。游戏的背景可以为数千年前的原始神话时代的《火之鸟》、《彩虹岛》,也可以是神秘奇幻的中世纪《圆桌武士》、《恶魔城》、《波斯王子》,甚至回到雄壮激荡的中国古代,作出《天地吞食》、《杨家将》,乃至于未来时代的《魂斗罗》,或者以著名故事、漫画为原型的《蜘蛛侠》、《梦幻岛》等,乃至于从来没有过的时间、空间、物种。故事需要尽可能的离奇或是感人,这样才能有效地抓住玩家,事实证明,在这样的游戏中,完全可以在游戏过程中加入情节的,譬如《恶魔城·月夜狂想曲》就是一个非常好的例子,在ACT为主的游戏过程中,角色会遇到很多人,为他提供信息,在一定条件下给予其道具,可以中途买卖物品。相信随着游戏的发展,这类多元化游戏将会越来越受欢迎。

而在游戏设计中,操作感也非常重要,矛头直指游戏的上手性。在PC或Android上玩这类游戏,更是对操作要求极高,游戏玩家玩的是否舒服,也全在这一步。举个例子,如我们控制一个角色去跳过一个很宽的沟。步骤应该为:跑——>快跑——>跳跃。初步设定“跑”“加速”“跳跃”必须设到“S”“D”“F”三个键上,通常情况就应该依次把“S”“D”“F”三个相邻的键设为“加速”“跑” “跳跃”。这样,平时玩家在游戏过程中,可以始终按住“D”键不放,需要加速时,无名指按着“S”,过沟大跳跃时,只需要食指点下“F”键就可以了,除此之外,其它的排列都将很别扭,可自己一试。

另外从键盘和鼠标的功能来说,有的东西已经是成规范性的东西了。对应相关的游戏软件我们也可以找到规律,并力图靠近它。做为策划,永远也不要霸道的要求玩家去适应你的规律,找到大众都喜欢都适应的规律才是为策划之正道。

牵扯到ACT游戏,自然免不了会有关卡的概念,所谓关卡就是游戏过程中一个又一个的小节。在这里也是同样可以发挥策划的想象力的好地方,每一关可以设计不同的特色,我想大家一定不会忘记古旧而精典的ACT游戏《魂斗罗》吧,记得履带+下砸钉锤那一关么?记得最后一关会飞起来的毒蝎么?这就是有特色而让人难忘的精典呀。

 

这一部分可以说是ACT游戏的核心。

至于游戏的规则设定,比如在什么情况下,角色会死亡?在什么情况下,敌NPC会OVER?角色在什么状态下可以躲过敌人飞行道具?角色在情况下会飞行?每一种道具的作用?都是需要设计者费心的,比如有的游戏,在规则上会设计一些独创的内容,如上面提到的《天地吞食》,某角色击打时如果同时按着“下”,就会把击打对象举起来并抛出。

而说起ACT游戏的代表作,那么便首推《超级马里奥》,这款家喻户晓的动作游戏,不但在当时,甚至对后世游戏界产生了无法估量的巨大影响。

截止到2008年,马里奥游戏分别在不同的机种上发布了116种,当中包括马力奥自己为主角的游戏和其他如任天堂大乱斗等游戏上,成为了吉尼斯世界纪录大全中,发行最多款电子游戏的电子游戏角色。

那么,对于这款地球人都知道的游戏,我们可不可以将它移植到Android之上,甚至再加上少许变化,令它成为一款全新的游戏呢?答案是肯定的。

相关知识点说了很多。下面,我将分别给出PC以及Android两个版本的马里奥类游戏实现,让大家对基本业务流程有一个初步了解。

源码下载地址:http://code.google.com/p/loon-simple/downloads/list


PC版实现:

view plaincopy to clipboardprint?
package org.loon.game.test;  
import java.awt.Color;  
import java.awt.Graphics2D;  
import java.awt.event.KeyEvent;  
import java.awt.event.MouseEvent;  
import java.util.Iterator;  
import java.util.LinkedList;  
import org.loon.framework.game.simple.GameScene;  
import org.loon.framework.game.simple.core.Deploy;  
import org.loon.framework.game.simple.core.LTimer;  
import org.loon.framework.game.simple.core.LTimerContext;  
import org.loon.framework.game.simple.core.Screen;  
/** 
 *  
 * Copyright 2008 - 2009 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy of 
 * the License at 
 *  
 * http://www.apache.org/licenses/LICENSE-2.0 
 *  
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations under 
 * the License. 
 *  
 * @project loonframework 
 * @author chenpeng 
 * @email:ceponline@yahoo.com.cn 
 * @version 0.1 
 */ 
public class Main extends Screen {  
    public static final int WIDTH = 320;  
    public static final int HEIGHT = 480;  
    private LTimer delay;  
    private Map map;  
    private Hero hero;  
    private ActionKey goLeftKey;  
    private ActionKey goRightKey;  
    private ActionKey jumpKey;  
    private double x, y;  
    // 键盘事件记录器  
    class ActionKey {  
        static final int PRESS_ONLY = 1, STATE_RELEASED = 0, STATE_PRESSED = 1,  
                STATE_WAITING_FOR_RELEASE = 2;  
        int mode, amount, state;  
        public ActionKey() {  
            this(0);  
        }  
        public ActionKey(int mode) {  
            this.mode = mode;  
            reset();  
        }  
        public void reset() {  
            state = STATE_RELEASED;  
            amount = 0;  
        }  
        public void press() {  
            if (state != STATE_WAITING_FOR_RELEASE) {  
                amount++;  
                state = STATE_PRESSED;  
            }  
        }  
        public void release() {  
            state = STATE_RELEASED;  
        }  
        public boolean isPressed() {  
            if (amount != 0) {  
                if (state == STATE_RELEASED) {  
                    amount = 0;  
                } else if (mode == PRESS_ONLY) {  
                    state = STATE_WAITING_FOR_RELEASE;  
                    amount = 0;  
                }  
                return true;  
            }  
            return false;  
        }  
    }  
    public Main() {  
        delay = new LTimer(20);  
        goLeftKey = new ActionKey();  
        goRightKey = new ActionKey();  
        jumpKey = new ActionKey(ActionKey.PRESS_ONLY);  
        initialize();  
    }  
    private void initialize() {  
        map = new Map("map.txt");  
        hero = new Hero("hero.gif", 192, 32, 40, 40, map);  
    }  
    public void alter(LTimerContext timer) {  
        if (delay.action(timer.getTimeSinceLastUpdate())) {  
            if (goLeftKey.isPressed()) {  
                // 向左移动  
                hero.left();  
            } else if (goRightKey.isPressed()) {  
                // 向右移动  
                hero.right();  
            } else {  
                // 暂停  
                hero.stop();  
            }  
            if (jumpKey.isPressed()) {  
                // 跳跃  
                hero.jump();  
            }  
            // 更新角色状态  
            hero.update(timer.getTimeSinceLastUpdate());  
            // 遍历精灵集合  
            LinkedList sprites = map.getSprites();  
            for (Iterator it = sprites.iterator(); it.hasNext();) {  
                Sprite sprite = (Sprite) it.next();  
                // 更新所有精灵状态  
                sprite.update(timer.getTimeSinceLastUpdate());  
                // 碰撞测试  
                if (hero.isCollision(sprite)) {  
                    // 遇敌  
                    if (sprite instanceof Enemy) {  
                        Enemy e = (Enemy) sprite;  
                        // 踩踏敌人  
                        if ((int) hero.getY() < (int) e.getY()) {  
                            sprites.remove(e);  
                            hero.setForceJump(true);  
                            hero.jump();  
                            break;  
                        } else {  
                            // 重新开始  
                            initialize();  
                        }  
                        // 食物  
                    } else if (sprite instanceof Food) {  
                        Food f = (Food) sprite;  
                        sprites.remove(f);  
                        break;  
                        // 加速宝物  
                    } else if (sprite instanceof Speed) {  
                        sprites.remove(sprite);  
                        Speed speedUp = (Speed) sprite;  
                        speedUp.use(hero);  
                        break;  
                        // 跳跃宝物  
                    } else if (sprite instanceof Jump) {  
                        sprites.remove(sprite);  
                        Jump jump = (Jump) sprite;  
                        jump.use(hero);  
                        break;  
                    }  
                }  
            }  
        }  
    }  
    /** 
     * 绘制游戏界面 
     */ 
    public void draw(Graphics2D g) {  
        g.setColor(Color.BLACK);  
        g.fillRect(0, 0, getWidth(), getHeight());  
        int offsetX = Main.WIDTH / 2 - (int) hero.getX();  
        offsetX = Math.min(offsetX, 0);  
        offsetX = Math.max(offsetX, Main.WIDTH - map.getWidth());  
        int offsetY = Main.HEIGHT / 2 - (int) hero.getY();  
        offsetY = Math.min(offsetY, 0);  
        offsetY = Math.max(offsetY, Main.HEIGHT - map.getHeight());  
        map.draw(g, offsetX, offsetY);  
        hero.draw(g, offsetX, offsetY);  
        LinkedList sprites = map.getSprites();  
        for (Iterator it = sprites.iterator(); it.hasNext();) {  
            Sprite sprite = (Sprite) it.next();  
            x = Map.pixelsToTiles(sprite.getX());  
            y = Map.pixelsToTiles(sprite.getY());  
            // 精灵绘制限制在可见区域内  
            if (x > map.getFirstTileX() && x < map.getLastTileX()  
                    && y > map.getFirstTileY() && y < map.getLastTileY()) {  
                sprite.draw(g, offsetX, offsetY);  
            }  
        }  
    }  
    public void leftClick(MouseEvent arg0) {  
    }  
    public void middleClick(MouseEvent arg0) {  
    }  
    public void rightClick(MouseEvent arg0) {  
    }  
    public void onKey(KeyEvent e) {  
        int key = e.getKeyCode();  
        if (key == KeyEvent.VK_LEFT) {  
            goLeftKey.press();  
        }  
        if (key == KeyEvent.VK_RIGHT) {  
            goRightKey.press();  
        }  
        if (key == KeyEvent.VK_UP) {  
            jumpKey.press();  
        }  
    }  
    public void onKeyUp(KeyEvent e) {  
        int key = e.getKeyCode();  
        if (key == KeyEvent.VK_LEFT) {  
            goLeftKey.release();  
        }  
        if (key == KeyEvent.VK_RIGHT) {  
            goRightKey.release();  
        }  
        if (key == KeyEvent.VK_UP) {  
            jumpKey.release();  
        }  
    }  
    public static void main(String[] args) {  
        GameScene frame = new GameScene("火影忍者", WIDTH, HEIGHT);  
        Deploy deploy = frame.getDeploy();  
        deploy.setScreen(new Main());  
        deploy.setShowFPS(true);  
        deploy.setLogo(false);  
        deploy.setFPS(100);  
        deploy.mainLoop();  
        frame.showFrame();  
    }  

package org.loon.game.test;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import java.util.LinkedList;
import org.loon.framework.game.simple.GameScene;
import org.loon.framework.game.simple.core.Deploy;
import org.loon.framework.game.simple.core.LTimer;
import org.loon.framework.game.simple.core.LTimerContext;
import org.loon.framework.game.simple.core.Screen;
/**
 *
 * Copyright 2008 - 2009
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * @project loonframework
 * @author chenpeng
 * @email:ceponline@yahoo.com.cn
 * @version 0.1
 */
public class Main extends Screen {
 public static final int WIDTH = 320;
 public static final int HEIGHT = 480;
 private LTimer delay;
 private Map map;
 private Hero hero;
 private ActionKey goLeftKey;
 private ActionKey goRightKey;
 private ActionKey jumpKey;
 private double x, y;
 // 键盘事件记录器
 class ActionKey {
  static final int PRESS_ONLY = 1, STATE_RELEASED = 0, STATE_PRESSED = 1,
    STATE_WAITING_FOR_RELEASE = 2;
  int mode, amount, state;
  public ActionKey() {
   this(0);
  }
  public ActionKey(int mode) {
   this.mode = mode;
   reset();
  }
  public void reset() {
   state = STATE_RELEASED;
   amount = 0;
  }
  public void press() {
   if (state != STATE_WAITING_FOR_RELEASE) {
    amount++;
    state = STATE_PRESSED;
   }
  }
  public void release() {
   state = STATE_RELEASED;
  }
  public boolean isPressed() {
   if (amount != 0) {
    if (state == STATE_RELEASED) {
     amount = 0;
    } else if (mode == PRESS_ONLY) {
     state = STATE_WAITING_FOR_RELEASE;
     amount = 0;
    }
    return true;
   }
   return false;
  }
 }
 public Main() {
  delay = new LTimer(20);
  goLeftKey = new ActionKey();
  goRightKey = new ActionKey();
  jumpKey = new ActionKey(ActionKey.PRESS_ONLY);
  initialize();
 }
 private void initialize() {
  map = new Map("map.txt");
  hero = new Hero("hero.gif", 192, 32, 40, 40, map);
 }
 public void alter(LTimerContext timer) {
  if (delay.action(timer.getTimeSinceLastUpdate())) {
   if (goLeftKey.isPressed()) {
    // 向左移动
    hero.left();
   } else if (goRightKey.isPressed()) {
    // 向右移动
    hero.right();
   } else {
    // 暂停
    hero.stop();
   }
   if (jumpKey.isPressed()) {
    // 跳跃
    hero.jump();
   }
   // 更新角色状态
   hero.update(timer.getTimeSinceLastUpdate());
   // 遍历精灵集合
   LinkedList sprites = map.getSprites();
   for (Iterator it = sprites.iterator(); it.hasNext();) {
    Sprite sprite = (Sprite) it.next();
    // 更新所有精灵状态
    sprite.update(timer.getTimeSinceLastUpdate());
    // 碰撞测试
    if (hero.isCollision(sprite)) {
     // 遇敌
     if (sprite instanceof Enemy) {
      Enemy e = (Enemy) sprite;
      // 踩踏敌人
      if ((int) hero.getY() < (int) e.getY()) {
       sprites.remove(e);
       hero.setForceJump(true);
       hero.jump();
       break;
      } else {
       // 重新开始
       initialize();
      }
      // 食物
     } else if (sprite instanceof Food) {
      Food f = (Food) sprite;
      sprites.remove(f);
      break;
      // 加速宝物
     } else if (sprite instanceof Speed) {
      sprites.remove(sprite);
      Speed speedUp = (Speed) sprite;
      speedUp.use(hero);
      break;
      // 跳跃宝物
     } else if (sprite instanceof Jump) {
      sprites.remove(sprite);
      Jump jump = (Jump) sprite;
      jump.use(hero);
      break;
     }
    }
   }
  }
 }
 /**
  * 绘制游戏界面
  */
 public void draw(Graphics2D g) {
  g.setColor(Color.BLACK);
  g.fillRect(0, 0, getWidth(), getHeight());
  int offsetX = Main.WIDTH / 2 - (int) hero.getX();
  offsetX = Math.min(offsetX, 0);
  offsetX = Math.max(offsetX, Main.WIDTH - map.getWidth());
  int offsetY = Main.HEIGHT / 2 - (int) hero.getY();
  offsetY = Math.min(offsetY, 0);
  offsetY = Math.max(offsetY, Main.HEIGHT - map.getHeight());
  map.draw(g, offsetX, offsetY);
  hero.draw(g, offsetX, offsetY);
  LinkedList sprites = map.getSprites();
  for (Iterator it = sprites.iterator(); it.hasNext();) {
   Sprite sprite = (Sprite) it.next();
   x = Map.pixelsToTiles(sprite.getX());
   y = Map.pixelsToTiles(sprite.getY());
   // 精灵绘制限制在可见区域内
   if (x > map.getFirstTileX() && x < map.getLastTileX()
     && y > map.getFirstTileY() && y < map.getLastTileY()) {
    sprite.draw(g, offsetX, offsetY);
   }
  }
 }
 public void leftClick(MouseEvent arg0) {
 }
 public void middleClick(MouseEvent arg0) {
 }
 public void rightClick(MouseEvent arg0) {
 }
 public void onKey(KeyEvent e) {
  int key = e.getKeyCode();
  if (key == KeyEvent.VK_LEFT) {
   goLeftKey.press();
  }
  if (key == KeyEvent.VK_RIGHT) {
   goRightKey.press();
  }
  if (key == KeyEvent.VK_UP) {
   jumpKey.press();
  }
 }
 public void onKeyUp(KeyEvent e) {
  int key = e.getKeyCode();
  if (key == KeyEvent.VK_LEFT) {
   goLeftKey.release();
  }
  if (key == KeyEvent.VK_RIGHT) {
   goRightKey.release();
  }
  if (key == KeyEvent.VK_UP) {
   jumpKey.release();
  }
 }
 public static void main(String[] args) {
  GameScene frame = new GameScene("火影忍者", WIDTH, HEIGHT);
  Deploy deploy = frame.getDeploy();
  deploy.setScreen(new Main());
  deploy.setShowFPS(true);
  deploy.setLogo(false);
  deploy.setFPS(100);
  deploy.mainLoop();
  frame.showFrame();
 }
}
 

 

Android版实现:

view plaincopy to clipboardprint?
package org.loon.framework.android.game.act;  
import java.util.Iterator;  
import java.util.LinkedList;  
import org.loon.framework.android.game.LAGraphics;  
import org.loon.framework.android.game.LAScreen;  
import org.loon.framework.android.game.LTimerContext;  
import android.graphics.Color;  
import android.view.KeyEvent;  
import android.view.MotionEvent;  
/** 
 *  
 * Copyright 2008 - 2009 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
 * 
 * @project loonframework 
 * @author chenpeng   
 * @email:ceponline@yahoo.com.cn  
 * @version 0.1 
 */ 
public class ScreenTest3 extends LAScreen {  
    public static final int WIDTH = 320;  
    public static final int HEIGHT = 480;  
    // private LTimer delay;  
    private Map map;  
    private Hero hero;  
    private ActionKey goLeftKey;  
    private ActionKey goRightKey;  
    private ActionKey jumpKey;  
    private double x, y;  
    // 键盘事件记录器  
    class ActionKey {  
        static final int PRESS_ONLY = 1, STATE_RELEASED = 0, STATE_PRESSED = 1,  
                STATE_WAITING_FOR_RELEASE = 2;  
        int mode, amount, state;  
        public ActionKey() {  
            this(0);  
        }  
        public ActionKey(int mode) {  
            this.mode = mode;  
            reset();  
        }  
        public void reset() {  
            state = STATE_RELEASED;  
            amount = 0;  
        }  
        public void press() {  
            if (state != STATE_WAITING_FOR_RELEASE) {  
                amount++;  
                state = STATE_PRESSED;  
            }  
        }  
        public void release() {  
            state = STATE_RELEASED;  
        }  
        public boolean isPressed() {  
            if (amount != 0) {  
                if (state == STATE_RELEASED) {  
                    amount = 0;  
                } else if (mode == PRESS_ONLY) {  
                    state = STATE_WAITING_FOR_RELEASE;  
                    amount = 0;  
                }  
                return true;  
            }  
            return false;  
        }  
    }  
    public ScreenTest3() {  
        // delay = new LTimer(20);  
        goLeftKey = new ActionKey();  
        goRightKey = new ActionKey();  
        jumpKey = new ActionKey(ActionKey.PRESS_ONLY);  
        initialize();  
    }  
    private void initialize() {  
        map = new Map("map.txt");  
        hero = new Hero("hero.gif", 192, 32, 40, 40, map);  
    }  
    public void alter(LTimerContext timer) {  
        // PS:虚拟机速度较慢,实机需要开放此部分,否则动作过快  
        // if (delay.action(timer.getTimeSinceLastUpdate())) {  
        if (goLeftKey.isPressed()) {  
            // 向左移动  
            hero.left();  
        } else if (goRightKey.isPressed()) {  
            // 向右移动  
            hero.right();  
        } else {  
            // 暂停  
            hero.stop();  
        }  
        if (jumpKey.isPressed()) {  
            // 跳跃  
            hero.jump();  
        }  
        // 更新角色状态  
        hero.update(timer.getTimeSinceLastUpdate());  
        // 遍历精灵集合  
        LinkedList<Sprite> sprites = map.getSprites();  
        Iterator<Sprite> it = sprites.iterator();  
        while (it.hasNext()) {  
            Sprite sprite = it.next();  
            // 更新所有精灵状态  
            sprite.update(timer.getTimeSinceLastUpdate());  
            // 碰撞测试  
            if (hero.isCollision(sprite)) {  
                // 遇敌  
                if (sprite instanceof Enemy) {  
                    Enemy e = (Enemy) sprite;  
                    // 踩踏敌人  
                    if ((int) hero.getY() < (int) e.getY()) {  
                        sprites.remove(e);  
                        hero.setForceJump(true);  
                        hero.jump();  
                        break;  
                    } else {  
                        // 重新开始  
                        initialize();  
                    }  
                    // 食物  
                } else if (sprite instanceof Food) {  
                    Food f = (Food) sprite;  
                    sprites.remove(f);  
                    break;  
                    // 加速宝物  
                } else if (sprite instanceof Speed) {  
                    sprites.remove(sprite);  
                    Speed speedUp = (Speed) sprite;  
                    speedUp.use(hero);  
                    break;  
                    // 跳跃宝物  
                } else if (sprite instanceof Jump) {  
                    sprites.remove(sprite);  
                    Jump jump = (Jump) sprite;  
                    jump.use(hero);  
                    break;  
                }  
            }  
        }  
        // }  
    }  
    public void draw(LAGraphics g) {  
        g.setColor(Color.BLACK);  
        g.fillRect(0, 0, getWidth(), getHeight());  
        int offsetX = WIDTH / 2 - (int) hero.getX();  
        offsetX = Math.min(offsetX, 0);  
        offsetX = Math.max(offsetX, WIDTH - map.getWidth());  
        int offsetY = HEIGHT / 2 - (int) hero.getY();  
        offsetY = Math.min(offsetY, 0);  
        offsetY = Math.max(offsetY, HEIGHT - map.getHeight());  
        map.draw(g, offsetX, offsetY);  
        hero.draw(g, offsetX, offsetY);  
        LinkedList<Sprite> sprites = map.getSprites();  
        for (Iterator<Sprite> it = sprites.iterator(); it.hasNext();) {  
            Sprite sprite = it.next();  
            x = Map.pixelsToTiles(sprite.getX());  
            y = Map.pixelsToTiles(sprite.getY());  
            // 精灵绘制限制在可见区域内  
            if (x > map.getFirstTileX() && x < map.getLastTileX()  
                    && y > map.getFirstTileY() && y < map.getLastTileY())  
                sprite.draw(g, offsetX, offsetY);  
        }  
    }  
    public boolean onKeyDown(int keyCode, KeyEvent e) {  
        int key = e.getKeyCode();  
        if (key == KeyEvent.KEYCODE_DPAD_LEFT) {  
            goLeftKey.press();  
        }  
        if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {  
            goRightKey.press();  
        }  
        if (key == KeyEvent.KEYCODE_DPAD_UP) {  
            jumpKey.press();  
        }  
        return false;  
    }  
    public boolean onKeyUp(int keyCode, KeyEvent e) {  
        int key = e.getKeyCode();  
        if (key == KeyEvent.KEYCODE_DPAD_LEFT) {  
            goLeftKey.release();  
        }  
        if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {  
            goRightKey.release();  
        }  
        if (key == KeyEvent.KEYCODE_DPAD_UP) {  
            jumpKey.release();  
        }  
        return false;  
    }  
    public boolean onTouchDown(MotionEvent e) {  
        return false;  
    }  
    public boolean onTouchMove(MotionEvent e) {  
        return false;  
    }  
    public boolean onTouchUp(MotionEvent e) {  
        return false;  
    }  

package org.loon.framework.android.game.act;
import java.util.Iterator;
import java.util.LinkedList;
import org.loon.framework.android.game.LAGraphics;
import org.loon.framework.android.game.LAScreen;
import org.loon.framework.android.game.LTimerContext;
import android.graphics.Color;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
 *
 * Copyright 2008 - 2009
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @project loonframework
 * @author chenpeng 
 * @email:ceponline@yahoo.com.cn
 * @version 0.1
 */
public class ScreenTest3 extends LAScreen {
 public static final int WIDTH = 320;
 public static final int HEIGHT = 480;
 // private LTimer delay;
 private Map map;
 private Hero hero;
 private ActionKey goLeftKey;
 private ActionKey goRightKey;
 private ActionKey jumpKey;
 private double x, y;
 // 键盘事件记录器
 class ActionKey {
  static final int PRESS_ONLY = 1, STATE_RELEASED = 0, STATE_PRESSED = 1,
    STATE_WAITING_FOR_RELEASE = 2;
  int mode, amount, state;
  public ActionKey() {
   this(0);
  }
  public ActionKey(int mode) {
   this.mode = mode;
   reset();
  }
  public void reset() {
   state = STATE_RELEASED;
   amount = 0;
  }
  public void press() {
   if (state != STATE_WAITING_FOR_RELEASE) {
    amount++;
    state = STATE_PRESSED;
   }
  }
  public void release() {
   state = STATE_RELEASED;
  }
  public boolean isPressed() {
   if (amount != 0) {
    if (state == STATE_RELEASED) {
     amount = 0;
    } else if (mode == PRESS_ONLY) {
     state = STATE_WAITING_FOR_RELEASE;
     amount = 0;
    }
    return true;
   }
   return false;
  }
 }
 public ScreenTest3() {
  // delay = new LTimer(20);
  goLeftKey = new ActionKey();
  goRightKey = new ActionKey();
  jumpKey = new ActionKey(ActionKey.PRESS_ONLY);
  initialize();
 }
 private void initialize() {
  map = new Map("map.txt");
  hero = new Hero("hero.gif", 192, 32, 40, 40, map);
 }
 public void alter(LTimerContext timer) {
  // PS:虚拟机速度较慢,实机需要开放此部分,否则动作过快
  // if (delay.action(timer.getTimeSinceLastUpdate())) {
  if (goLeftKey.isPressed()) {
   // 向左移动
   hero.left();
  } else if (goRightKey.isPressed()) {
   // 向右移动
   hero.right();
  } else {
   // 暂停
   hero.stop();
  }
  if (jumpKey.isPressed()) {
   // 跳跃
   hero.jump();
  }
  // 更新角色状态
  hero.update(timer.getTimeSinceLastUpdate());
  // 遍历精灵集合
  LinkedList<Sprite> sprites = map.getSprites();
  Iterator<Sprite> it = sprites.iterator();
  while (it.hasNext()) {
   Sprite sprite = it.next();
   // 更新所有精灵状态
   sprite.update(timer.getTimeSinceLastUpdate());
   // 碰撞测试
   if (hero.isCollision(sprite)) {
    // 遇敌
    if (sprite instanceof Enemy) {
     Enemy e = (Enemy) sprite;
     // 踩踏敌人
     if ((int) hero.getY() < (int) e.getY()) {
      sprites.remove(e);
      hero.setForceJump(true);
      hero.jump();
      break;
     } else {
      // 重新开始
      initialize();
     }
     // 食物
    } else if (sprite instanceof Food) {
     Food f = (Food) sprite;
     sprites.remove(f);
     break;
     // 加速宝物
    } else if (sprite instanceof Speed) {
     sprites.remove(sprite);
     Speed speedUp = (Speed) sprite;
     speedUp.use(hero);
     break;
     // 跳跃宝物
    } else if (sprite instanceof Jump) {
     sprites.remove(sprite);
     Jump jump = (Jump) sprite;
     jump.use(hero);
     break;
    }
   }
  }
  // }
 }
 public void draw(LAGraphics g) {
  g.setColor(Color.BLACK);
  g.fillRect(0, 0, getWidth(), getHeight());
  int offsetX = WIDTH / 2 - (int) hero.getX();
  offsetX = Math.min(offsetX, 0);
  offsetX = Math.max(offsetX, WIDTH - map.getWidth());
  int offsetY = HEIGHT / 2 - (int) hero.getY();
  offsetY = Math.min(offsetY, 0);
  offsetY = Math.max(offsetY, HEIGHT - map.getHeight());
  map.draw(g, offsetX, offsetY);
  hero.draw(g, offsetX, offsetY);
  LinkedList<Sprite> sprites = map.getSprites();
  for (Iterator<Sprite> it = sprites.iterator(); it.hasNext();) {
   Sprite sprite = it.next();
   x = Map.pixelsToTiles(sprite.getX());
   y = Map.pixelsToTiles(sprite.getY());
   // 精灵绘制限制在可见区域内
   if (x > map.getFirstTileX() && x < map.getLastTileX()
     && y > map.getFirstTileY() && y < map.getLastTileY())
    sprite.draw(g, offsetX, offsetY);
  }
 }
 public boolean onKeyDown(int keyCode, KeyEvent e) {
  int key = e.getKeyCode();
  if (key == KeyEvent.KEYCODE_DPAD_LEFT) {
   goLeftKey.press();
  }
  if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {
   goRightKey.press();
  }
  if (key == KeyEvent.KEYCODE_DPAD_UP) {
   jumpKey.press();
  }
  return false;
 }
 public boolean onKeyUp(int keyCode, KeyEvent e) {
  int key = e.getKeyCode();
  if (key == KeyEvent.KEYCODE_DPAD_LEFT) {
   goLeftKey.release();
  }
  if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {
   goRightKey.release();
  }
  if (key == KeyEvent.KEYCODE_DPAD_UP) {
   jumpKey.release();
  }
  return false;
 }
 public boolean onTouchDown(MotionEvent e) {
  return false;
 }
 public boolean onTouchMove(MotionEvent e) {
  return false;
 }
 public boolean onTouchUp(MotionEvent e) {
  return false;
 }
}
 

源码下载地址:http://code.google.com/p/loon-simple/downloads/list

——————————————————————————————

 

搞Java的同僚们,有空想着去http://www.java.com/en/store/intl-contact.jsp 申请2010年开通中国区的商店服务吧,别最后搞得和Android Market似的,只能托人“洗钱”……

 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cping1982/archive/2009/10/25/4725076.aspx

原创粉丝点击