较早前LGame示例下载地址:http://loon-simple.googlecode.com/files/LGame-Simple-0.2.5.7z

最新版LGame(0.2.6)下载地址:http://loon-simple.googlecode.com/files/LGame-0.2.6.rar

1、如何启动LGame

目前的LGame提供有J2SE以及Android两个开发版本,两版的主要类及函数虽然相同,但由于Android版对应于手机环境,而J2SE版对应于PC环境,所以依旧有少许的差别。

J2SE版:

在J2SE环境下,只需要在Main函数中构造如下内容即可。

public static void main(String[] args) { // 获得一个游戏窗体 GameScene frame = new GameScene("窗体名", 480, 320); // 得到此窗体所对应的游戏部署器 Deploy deploy = frame.getDeploy(); // 设定此游戏屏幕(在任何时候都可以通过Screen中的setScreen函数切换游戏屏幕) deploy.setScreen(new Game()); // 是否显示FPS deploy.setShowFPS(true); // 是否显示框架logo deploy.setLogo(false); // 允许的最大刷新率 deploy.setFPS(100); // 开始游戏主循环 deploy.mainLoop(); // 显示游戏画面 frame.showFrame(); }

Android版:

而在Android版中,我们则需要分两步走,一是需要配置相关的AndroidManifest.xml 文档。

如下所示:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.loon.test" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Main" android:configChanges="orientation|keyboardHidden" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> <uses-permission android:name="android.permission.INTERNET"/> </manifest>

而调用的方法如下:

package org.loon.test; import org.loon.framework.android.game.LAD; import org.loon.framework.android.game.LGameAndroid2DActivity; import org.loon.framework.android.game.core.LSystem; import android.os.Bundle; public class Main extends LGameAndroid2DActivity { public void onCreate(Bundle icicle) { // 有Admob广告,纵屏显示,广告居于屏幕下方,广告ID为“XXXXXXXX”,广告刷新速度为60秒 this.initialization(icicle,false,LAD.BOTTOM, "XXXXXXXX",60); // 无Admob广告,纵屏显示 // this.initialization(icicle,false); // 使用游戏窗体Game this.setScreen(new Game()); // 设定FPS为60 this.setFPS(60); // 不显示游戏Logo(设定Logo为setLogo) this.setShowLogo(false); // 显示FPS this.setShowFPS(true); // 显示游戏画面 this.showScreen(); } }

这时LGame框架就会根据我们所实现的不同Screen,来展示我们的游戏了(很简单吧)。

2、如何构建Screen类

Screen是一个抽象类,也是LGame框架所提供的游戏界面展示器,其中封装了基本的图形接口与相关的操作设备交互函数,在LGame框架中,可以直接作为游戏界面进行展示的Screen共有三种。

一、Screen

即最基本的Screen,包含了最基本的Screen函数,默认自动刷新游戏画面(根据FPS所设定的速度),不提供repaint以及getLGraphics方法,是提供LGame框架调用的最基本Screen形态。

J2SE版使用方式如下:

import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import org.loon.framework.game.simple.core.graphics.Screen; import org.loon.framework.game.simple.core.graphics.device.LGraphics; public class ScreenExample extends Screen { // draw中LGraphics会根据设定的FPS自动刷新,使用上与标准的J2SE Graphics以及J2ME Graphics接口没有区别(API为二者的综合) public void draw(LGraphics g) { } // 鼠标左键 public void leftClick(MouseEvent e) { } // 鼠标中间键 public void middleClick(MouseEvent e) { } // 鼠标右键 public void rightClick(MouseEvent e) { } // 键盘按下 public void onKey(KeyEvent e) { } // 键盘放开 public void onKeyUp(KeyEvent e) { } }

另外,在 Screen 中还有一个重要的 alter 函数,我们可以通过重载 alter 函数实现最简单的定时操作,譬如 :

// 设定计时器,每隔 1 秒允许执行一次

LTimer timer = new LTimer(LSystem. SECOND );

// 重载 alter 函数

public void alter(LTimerContext context){

if ( timer .action(context.getTimeSinceLastUpdate())){

}

}

Android版使用方式如下:

Android Screen API 与使用方法基本等价于 J2SE 版,但由于手机与 PC 间功能有所差别,所以具体的 API 名及函数有所不同。

import org.loon.framework.android.game.core.graphics.Screen; import android.view.KeyEvent; import android.view.MotionEvent; public class ScreenExample extends Screen{ // 与J2SE版相同,draw中LGraphics会根据设定的FPS自动刷新,使用上与标准的J2SE Graphics以及J2MEGraphics接口没有区别(API为二者的综合) public void draw(LGraphics g) { } //键盘按下 public boolean onKeyDown(int keyCode, KeyEvent e) { return true; } //键盘放开 public boolean onKeyUp(int keyCode, KeyEvent e) { return true; } //触摸屏按下 public boolean onTouchDown(MotionEvent e) { return true; } //手指在触摸屏上移动 public boolean onTouchMove(MotionEvent e) { return true; } //触摸屏放开 public boolean onTouchUp(MotionEvent e) { return true; } }

关于 alter 函数部分完全一致。

二、ThreadScreen

J2SE版:

ThreadScreen 是一个实现了 Runnable 接口的 Screen ,它采用 double buffer 方式将绘图与业务线程分离, gameLoop 函数中即是一个独立的线程。

import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import org.loon.framework.game.simple.core.graphics.ThreadScreen; import org.loon.framework.game.simple.core.graphics.device.LGraphics; public class ThreadScreenExample extends ThreadScreen { public ThreadScreenExample () { // ThreadScreen及CanvasScreen都允许变更游戏图形界面大小,下例重载参数为最初(实际)的界面大小。 super(300, 450); // 设定显示时图像大小,此时游戏将以320x480的大小运行(视原有界面不同,会有不同程度的失真) resizeScreen(320, 480); } // ThreadScreen绘图器,为标准Screen中draw函数的封装,区别在于ThreadScreen的修改仅在repaint时生效,而且ThreadScreen不会自动清除原有的图像内容。 public void drawScreen(LGraphics g) { } // gameLoop的刷新速度可以通过setSynchroFPS函数调整。 public void gameLoop() { } // 鼠标左键 public void leftClick(MouseEvent e) { } // 鼠标中间键 public void middleClick(MouseEvent e) { } // 鼠标右键 public void rightClick(MouseEvent e) { } // 键盘按下 public void onKey(KeyEvent e) { } // 键盘放开 public void onKeyUp(KeyEvent e) { } }

与标准 Screen 的其它区别在于, ThreadScreen 可以通过 getLGraphics getDraw Draw 类为 LGraphics 的简化封装)函数直接获得对 LGraphics 的操作权,并非一定要通过 drawScreen 函数绘图。

Android版:

J2SE Android 版的差别仅仅在于鼠标、键盘等设备函数上,其它细节相同。

import org.loon.framework.android.game.core.graphics.ThreadScreen; import android.view.KeyEvent; import android.view.MotionEvent; public class ThreadScreenExample extends ThreadScreen { public ThreadScreenExample () { // ThreadScreen及CanvasScreen都允许变更游戏图形界面大小,下例重载参数为最初(实际)的界面大小。 super(300, 450); // 设定显示时图像大小,此时游戏将以320x480的大小运行(视原有界面不同,会有不同程度的失真) resizeScreen(320, 480); } // ThreadScreen绘图器,为标准Screen中draw函数的封装,区别在于drawScreen的修改仅在repaint时生效,而且drawScreen不会自动清除原有的图像内容。 public void drawScreen(LGraphics g) { } // gameLoop的刷新速度可以通过setSynchroFPS函数调整。 public void gameLoop() { } //键盘按下 public boolean onKeyDown(int keyCode, KeyEvent e) { return true; } //键盘放开 public boolean onKeyUp(int keyCode, KeyEvent e) { return true; } //触摸屏按下 public boolean onTouchDown(MotionEvent e) { return true; } //手指在触摸屏上移动 public boolean onTouchMove(MotionEvent e) { return true; } //触摸屏放开 public boolean onTouchUp(MotionEvent e) { return true; } }

三、CanvasScreen

CanvasScreen 0.2.6 版中最新提供的 Screen 实现,模拟 J2ME Canvas 而成(也混合了 GameCanvas API ),相关函数在 J2SE Android 版中完全一致。

import org.loon.framework.game.simple.core.graphics.CanvasScreen; import org.loon.framework.game.simple.core.graphics.device.LGraphics; public class CanvasScreenExample extends CanvasScreen { public CanvasScreenExample(){ //与ThreadScreen相同,CanvaScreen允许改变游戏图像大小。 //以下参数分为别原始的图像宽与高(300x450),要求显示的宽与高(320x480) super(300,450,320,480); } // CanvasScreen绘图器,与标准Screen中draw函数的区别在于paint的修改仅在repaint时生效,而且paint不会自动清除原有的图像内容。 public void paint(LGraphics g) { } // 键盘按下 public void keyPressed(int keyCode) { } // 键盘放开 public void keyReleased(int keyCode) { } // 触摸屏或鼠标移动 public void pointerMove(double x, double y) { } // 触摸屏或鼠标按下 public void pointerPressed(double x, double y) { } // 触摸屏或鼠标放开 public void pointerReleased(double x, double y) { } }

与标准 Screen 的其它区别在于, CanvasScreen 可以通过 getLGraphics 函数直接获得对 LGraphics 的操作权,并非一定要通过 paint 函数绘图。另外,由于 CanvasScreen Paint 函数并不直接关联父类的 draw 函数,所以 LGame 中提供的精灵或组件无法直接通过 add 函数加载显示,而是只能在 paint 中手动调用相应组件的绘图器进行绘制(关于这点,用惯 J2ME 的朋友应该没什么不习惯的。另外 LGame 提供有配套的 j2me 精灵类包可供使用,为 1 1 仿 J2ME 原有 API 实现)。

以下是一个CanvasScreen的使用示例:

//初始化时的精灵动画

//移动时的精灵动画

//背景图片

请注意,为了演示图像扩大机制,示例所用的精灵以及游戏背景图像都非常之小,而实际开发中并非一定要使用图像扩充,更不是只能使用此比例的图像。


下面我制作一个 Sword.java ,这是一个自定义的精灵类,用以显示上图所示的“骷髅剑士”。(在不重新实现 ISprite 的基础上,我们也可以直接使用现成的 Sprite 类来完成此例。但是,关于动作细节部分就只能在精类外部设定或者重载 Sprite update 函数来实现(和实现 ISprite 没什么区别了 ||| ))。

import org.loon.framework.game.simple.action.map.RectBox; import org.loon.framework.game.simple.action.sprite.Animation; import org.loon.framework.game.simple.action.sprite.ISprite; import org.loon.framework.game.simple.action.sprite.SpriteImage; import org.loon.framework.game.simple.core.LObject; import org.loon.framework.game.simple.core.LSystem; import org.loon.framework.game.simple.core.graphics.device.LGraphics; import org.loon.framework.game.simple.core.timer.LTimer; public class Sword extends LObject implements ISprite { /** * */ private static final long serialVersionUID = 1L; // 精灵移动范围的最大宽度(即背景图实际宽,为240) private static final int WIDTH = 240; private boolean init, right, flag, visible; private int randX; private Animation animation; private LTimer time; private static final String kName1 = "res/s1.png", kName2 = "res/s2.png"; public Sword() { // 加载怪物剑士的“出土”动画(以下参数为图像所在地址、图像宽、图像高、播放间隔) this.animation = Animation.getDefaultAnimation(kName1, 18, 18, 150); // 设定计时器间隔为10豪秒 this.time = new LTimer(10); // 设定精灵初始位置(x轴随机,y轴48(立于相对于背景视觉的“地面”上)) this.setLocation(LSystem.random.nextInt(WIDTH), 48); // 随机决定精灵剑士向左或向右冲锋 this.right = LSystem.random.nextInt(2) == 0 ? true : false; // 随机决定精灵剑士以匀速或两倍速前进 this.flag = LSystem.random.nextInt(2) == 0 ? true : false; // 随机决定精灵剑士的“冲锋”停止点 this.randX = LSystem.random.nextInt(70); // 当前精灵可见 this.visible = true; } // 设定精灵绘图器内容 public void createUI(LGraphics g) { if (animation != null) { // PS:Android版中没有提供序列化保存SpriteImage的方法,直接getImage即可,而没有serializablelImage。 // 反转图像 if (right) { g.drawMirrorImage(animation.getSpriteImage().serializablelImage .getImage(), x(), y()); // 正向 } else { g.drawImage(animation.getSpriteImage().serializablelImage .getImage(), x(), y()); } } } // 当前精灵宽 public int getWidth() { SpriteImage si = animation.getSpriteImage(); if (si == null) { return -1; } return si.getWidth(); } // 当前精灵高 public int getHeight() { SpriteImage si = animation.getSpriteImage(); if (si == null) { return -1; } return si.getHeight(); } // 精灵计时器,用以在timer满足条件时变更精灵样式 public void update(long timer) { if (time.action(timer)) { animation.update(timer); // 当动画没有播放时 if (!animation.isRunning()) { // 初始化动画精灵(以下参数为图像所在地址、图像宽、图像高、播放间隔) animation = Animation.getDefaultAnimation(kName2, 26, 18, 50); } else if (animation.isRunning() && init) { // 向左 if (!right && (x() + randX) > 0) { if (flag) { // 精灵向左移动 move_left(); } else { // 精灵向左移动(速度x2) move_left(2); } if ((x() - randX) <= 0) { right = true; } // 向右 } else if (right && (x() + animation.getSpriteImage().getWidth() - randX) <= WIDTH) { if (flag) { // 精灵向右移动(速度x2) move_right(2); } else { // 精灵向右移动 move_right(); } // 当达到屏幕边缘时,改变移动方向 if ((x() + animation.getSpriteImage().getWidth() + randX) >= WIDTH) { right = false; } } } // 当精灵动画结束时,设定init=true(精灵动画播放完毕) if (!init && animation.getTotalFrames() - 1 == animation .getCurrentFrameIndex()) { animation.setRunning(false); init = true; } } } // 透明度 public float getAlpha() { return 0; } // 碰撞盒 public RectBox getCollisionBox() { return new RectBox(Math.round(x()), Math.round(y()), getWidth(), getHeight()); } // 显示状态 public boolean isVisible() { return visible; } // 是否显示精灵 public void setVisible(boolean visible) { this.visible = visible; } }

设定一个 CanvasScreenExample.java ,用以继承 CanvasScreen

import org.loon.framework.game.simple.GameScene; import org.loon.framework.game.simple.action.sprite.Sprites; import org.loon.framework.game.simple.core.graphics.CanvasScreen; import org.loon.framework.game.simple.core.graphics.Deploy; import org.loon.framework.game.simple.core.graphics.LImage; import org.loon.framework.game.simple.core.graphics.device.LGraphics; public class CanvasScreenExample extends CanvasScreen implements Runnable { // 设定精灵组,显示范围为宽240,高80(此为实际背景图大小) private Sprites sprs = new Sprites(240, 80); // 设定背景图像 private LImage background = LImage.createImage("res/background.png"); // 是否允许线程运行 private boolean running; // 刷新间隔 private long speed = 30; public CanvasScreenExample() { // 重载游戏画面大小,将240x80的实际游戏图像大小,扩大为480x160的显示大小 super(240, 80, 480, 160); // 创建五个骷髅剑士的精灵 Sword[] sw = new Sword[5]; //循环载入 for (int i = 0; i < sw.length; i++) { // 将精灵载入精灵管理器 sprs.add(sw[i] = new Sword()); } // 允许线程运行 this.running = true; // 启动线程 this.callEvent(new Thread(this)); } // 当切换不同的Screen,或者游戏结束时,会触发此函数 public void dispose() { this.running = false; } // 在绘图器中绘制背景图以及相关精灵 public void paint(LGraphics g) { // 绘制背景图像到位置(0,0) g.drawImage(background, 0, 0); // 绘图精灵组中所有精灵(默认位置(0,0),也允许通过setLocation或setViewWindow变更显示位置及显示范围) sprs.createUI(g); } public void run() { while (running) { // 刷新游戏画面 this.repaint(); // 间隔30豪秒 this.pause(speed); // 刷新精灵组 sprs.update(speed); } } public void keyPressed(int keyCode) { } public void keyReleased(int keyCode) { } public void pointerMove(double x, double y) { } public void pointerPressed(double x, double y) { } public void pointerReleased(double x, double y) { } }

此时,我们只需要根据需要实例化相关的Screen(也就是setScreen),就会得到如下效果:

实际运行效果如下( Android 版效果与此相同, PC 版中窗体实际大小被设定为 480x320

PS: CanvasScreen 中也允许完全照搬 J2ME Canvas(GameCanvas) 与相关精灵(内置有 API 1:1 的精灵类相关实现)的构建方式,可以将任何 J2ME 游戏代码平移其中。简单的讲,您在只掌握 J2ME 技术的情况下也可以使用 LGame ,而无需单独学习任何 LGame 框架本身的构建方式。

较早前LGame示例(仅PC版)下载地址:http://loon-simple.googlecode.com/files/LGame-Simple-0.2.5.7z

最新版LGame(0.2.6)下载地址:http://loon-simple.googlecode.com/files/LGame-0.2.6.rar

更多相关文章

  1. Android(安卓)Binder机制 - defaultServiceManager()源码分析
  2. Android中文API(125) ―― VideoView
  3. android中的onInterceptTouchEvent和onTouchEvent
  4. Android(安卓)USB gadget
  5. OpenCV Android解决相机旋转90度及全屏问题
  6. Android上下文服务管理查询过程
  7. Android(安卓)平台上,界面元素在定时器的响应函数里刷新。
  8. android 退出activity 转吖转
  9. 箭头函数的基础使用

随机推荐

  1. 开始使用Android和Kotlin
  2. ubuntu9.10安装android SDK
  3. Android(安卓)学习笔记
  4. ListView的一些属性
  5. 【Android】Android处理Home键方法小结
  6. Android禁止横屏竖屏切换
  7. Android(安卓)Instrumentation Test
  8. Android中垃圾回收日志信息
  9. 在Android中实现全屏显示的方法
  10. Android常用方法——获取系统信息