热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android游戏开发:游戏框架的搭建(4)

6.游戏框架所有的基础工作做完后,我们最后来探讨一下游戏框架本身。我们看下为了运行我们的游戏,还需要什么样的工作要做:游戏被分为不同的屏幕(screen),每个屏幕执行着相同的任务:判断用户输入,

6.游戏框架

  所有的基础工作做完后,我们最后来探讨一下游戏框架本身。我们看下为了运行我们的游戏,还需要什么样的工作要做:

  • 游戏被分为不同的屏幕(screen),每个屏幕执行着相同的任务:判断用户输入,根据输入渲染屏幕。一些节目或许不需要任何用户输入,但会过段时间后切换到下一屏幕.(如Splash界面)
  • 屏幕需要以某种方法被管理(如我们需要跟踪当前的屏幕并且能随时切换的下一屏幕)
  • 游戏需要允许屏幕访问不同的模块(比如图像模块、音频模块、输入模块等),这样屏幕才能加载资源,获取用户输入,播放声音,渲染缓冲区等。因为我们的游戏是实时游戏,我们需要当前的屏幕快速的更新。我们因此需要一个主循环来实现。主循环在游戏退出时结束。每次循环迭代成为一帧,每秒帧的次数我们成为帧速(FPS).
  • 游戏需要追踪窗口的状态(如是否暂停游戏或者恢复等),并通知产生相应的处理事件。
  • 游戏框架需要处理窗口的建立、UI组件的创建等

  下面看下一些代码:

createWindowAndUIComponent();

Input input = new Input();

Graphics graphics = new Graphics();

Audio audio = new Audio();

Screen currentScreen = new MainMenu();

Float lastFrameTime = currentTime();


while( !userQuit() ) {

  float deltaTime = currentTime() – lastFrameTime;

  lastFrameTime = currentTime();

  currentScreen.updateState(input, deltaTime);

  currentScreen.present(graphics, audio, deltaTime);

}

cleanupResources();

  代码首先创建了游戏的窗口和UI组件(createWindowAndUIComponent()方法),接着我们实例化了基本的组件,这些能保证游戏基本功能的实现。我们又实例化了我们的起始屏幕,并把它作为当前的屏幕。然后记下当前的时间。

  接着我们进入了主循环,当用户想退出时我们可以结束主循环。在主循环里面,计算上一帧和当前帧的时间差,用来计算FPS。最后,我们更新了当前屏幕的状态并呈现给用户。updateState方法依赖时间差和输入状态,present方法包括渲染屏幕的状态到framebuffer,播放音频等。present方法也需要知道上次调用到现在的时间差。

  当主循环结束后,我们就需要清理和释放各种资源了。

  这就是游戏工作的流程:处理用户的输入、更新状态、并呈现给用户。

游戏和显示接口

  下面是游戏运行时需要的接口:

  • 建立窗口进和UI,并建立相应的事件机制
  • 开启游戏的主循环
  • 跟踪当前的屏幕显示,在每次主循环中让其更新
  • 把UI线程中的事件转移到主线程中,并把这些事件传递给当前显示界面,以便同步变化。
  • 确保能访问所有的游戏基本模块,如Input, FileIO,Graphics, 和 Audio.

下面是游戏接口的代码:

package com.badlogic.androidgames.framework;

public interface Game {

  public Input getInput();

  public FileIO getFileIO();

  public Graphics getGraphics();

  public Audio getAudio();

  public void setScreen(Screen screen);

  public Screen getCurrentScreen();

  public Screen getStartScreen();

}

  如上述所示,代码中有一些getter方法,用来返回模块的实例。

  The Game.getCurrentScreen()方法返回当前激活的屏幕,之后我们会用一个抽象的类AndroidGame来实现这个接口,这个方法会实现除了Game.getStartScreen()之外所有的方法。实际游戏中如果我们创建AndroidGame的实例,我们需要继承AndroidGame并且重载Game.getStartScreen()方法,返回初次显示屏幕的一个实例。

  为了让大家了解到通过上述方法构建一个游戏是如何简单,下面是一个例子(假定我们已经实现了AndroidGame类):

public class MyAwesomeGame extends AndroidGame {

  public Screen getStartScreen () {

    return new MySuperAwesomeStartScreen(this);

  }
}

  很简单是吧?所有我们要做的就是执行我们游戏显示的起始屏幕。我们继承的AndroidGame类来做其他工作。从这点来看,AndroidGame 类会要求MySuperAwesomeStartScreen在主循环中更新和重新渲染自己。注意我们把MyAwesomeGame的实例传递给了MySuperAwesomeStartScreen。

   

  下面是抽象类Screen,之所是抽象类而不是接口,是因为我们可以提前在里面写一些子类都用到的方法,减轻子类的实现。代码如下:

//The Screen Class

package com.badlogic.androidgames.framework;

public abstract class Screen {

  protected final Game game;

  public Screen(Game game) {

    this.game = game;

  }

  public abstract void update(float deltaTime);

  public abstract void present(float deltaTime);

  public abstract void pause();

  public abstract void resume();

  public abstract void dispose();
}

  构造函数接收Game实例,并把它存到一个所有子类可以访问的final变量中。通过这种机制我们可以完成达成两件事情:

  我们可以通过Game类的实例播放音频、绘制平面、获取用户输入和读写文件。

  在合适时候我们可以通过调用Game.setScreen()设置一个新的当前平面显示。

  方法 Screen.update() 和 Screen.present():它们会更新平面并同步地显示。Game实例会在主循环中调用它们。

  方法 Screen.pause() 和 Screen.resume()在游戏暂停和恢复时被调用,同样这两个方法也是被Game的实例调用的,并通知给当前的平面显示。

  方法Screen.dispose(),当Game.setScreen()方法被调用时,Screen.dispose()被Game的实例调用。通过这个方法Game的实例会销毁当前的显示屏幕,同时让其释放所有相关的系统资源,以便为新的屏幕窗口提供最大的内存。Screen.dispose()也是内容持久化的最后一个方法。

 


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • 本文详细探讨了在Android 8.0设备上使用ChinaCock的TCCBarcodeScanner进行扫码时出现的应用闪退问题,并提供了解决方案。通过调整配置文件,可以有效避免这一问题。 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
author-avatar
飞轶尘埃_130
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有