GameCanvas类

网页游戏开发基础——Canvas基本图形绘制 Canvas是HTML5新增的一个标签,你可以把它翻译为画布,通过它可以绘制二维或三维图形,有了它就可以不用安装flash而实现复杂的动画功能。 阅读详情

GameCanvas类

继承于MIDP 1.0的Canvas类的GameCanvas是一个提供了游戏的基本接口的抽象类,除了完全具备原来Canvas类的功能外,还提供了更多开发游戏的便 利,主要为:提供屏幕缓冲绘制机制,并能直接得到设备键盘的物理状态。

3.2.1  GameCanvas概述

GameCanvas(游戏画布)对象能够提供画布的功能,类的定义为:

public abstract class GameCanvas extends Canvas

GameCanvas类是在Canvas类的基础上派生的,并在此之上增加双缓冲和随时查询按键状态的功能。 因为游戏画布类被定义为虚类,所以必须派生新类。GameCanvas类包含的方法如表3-1所示。

表3-1                                                     类GameCanvas方法说明

方 法 名 称

方法原型与作用

GameCanvas

protected GameCanvas(boolean suppressKeyEvents)

构造方法,参数 suppressKeyEvents 表示是否需要处理游戏按键之外的其他按键事件。例如数字键,如果此参数为false,那么按键事件处理方法keyPressed、 keyRepeated、keyReleased在程序运行过程中不会被调用,这样可以提高速度和性能

getGraphics

protected Graphics getGraphics( )

得到画布中脱机屏幕上用于绘制的 Graphics 对象

flushGraphics

public void flushGraphics( )

要求刷新屏幕,这时脱机屏幕上的图像会被绘制到真实屏幕上

flushGraphics

public void flushGraphics(int x, int y, int width, int height)

要求刷新屏幕上指定区域,这时脱机屏幕上指定区域的图像会被绘制到真实屏幕上

getKeyStates

public int getKeyStates()

得到当前按键状态

3.2.2  绘制双缓冲区

要创建一个新的GameCanvas实例,需要通过继承并调用父类的构造函数,如下所示。

protected GameCanvas(boolean suppressKeyEvents);

GameCanvas为这个类的每个实例提供了惟一的图形缓冲区,所有的图形创建和修改都在缓冲区上进行,缓 冲区的大小和GameCanvas全屏幕时的大小一样,但是存在的Ticker或者Command等控件都会影响到GameCanvas的大小。 GameCanvas的当前大小可以通过调用getWidth()和getHeight()方法获得。缓冲区的颜色初始化为白色。

开发者可以调用从GameCanvas实例获得其对应的Graphics对象,而且只有对Graphics对 象操作,才会修改缓冲区的内容,外部资源如其他的MIDlet或者系统级的通知都不会导致缓冲区内容改变。

每一个GameCanvas所拥有的缓冲区都是独立的,考虑到尽量少地使用对象堆栈,最好在游戏中仅仅创建一 个GameCanvas,并且重复利用。

为了将缓冲区中的内容刷新到屏幕上,所需要做的只是先调用getGraphics()方法,获得用来绘制缓冲 区的Graphics对象。刚创建的Graphics对象具有以下默认属性。

n     绘制目标是这个GameCanvas的缓冲区。

n     绘制区域覆盖整个缓冲区。

n     当前颜色是黑色。

n     字体和调用Font.getDefaultFont()返回的相同。

n     绘图模式为SOLID。

n     坐标系统的原点定位在缓冲区的左上角。

返回的Graphics对象将用于绘制属于这个GameCanvas的后备屏幕缓冲区(off-screen buffer),但是绘制后的结果不会立即显示出来,直到调用flushGraphics()方法,将缓冲区中的内容一起绘制到屏幕上去。

注意

每一次调用getGraphics()都会返回一个新的Graphics 对象,对于同一个GameCanvas,返回的Graphics 对象都是针对同一个缓冲区,所以应当在游戏运行前获得并保存Graphics 对象,然后在游戏运行时重复使用。getGraphics()返回一个用以绘制GameCanvas缓冲区的Graphics 对象,对于缓冲区的绘制不会改变屏幕的内容,只有调用flushGraphics()才将缓冲区中的内容绘制到屏幕上去。

flushGraphics()方法将后备屏幕缓冲区的内容输出到显示屏幕上,输出的区域大小和 GameCanvas的大小相同。

绘制实际屏幕的操作不会改变后备屏幕的内容,这个方法会一直等到绘制操作完成后才返回,因此,当这个方法返回 时,应用程序可以立刻对缓冲区进行下一帧后备屏幕的绘制。

如果GameCanvas当前没有显示,或者系统忙而不能执行绘制请求,该方法不进行任何操作就立刻返回。

这种“双缓冲”的机制将使得游戏动画更加流畅自然。此外,如果知道屏幕上哪些部分需要重新绘制,还可以调用 flushGraphics(int x, int y, int width, int height)方法在自定义的区域内进行绘制,而这会使得代码更加高效。

作为试验,笔者把GameCanvas中的对getGraphics()和flushGraphics()方 法的调用换成Canvas中repaint()以及serviceRepaints()方法的调用,两者没有什么明显的区别,但是如果程序包含了很多复杂 的图形,GameCanvas无疑是一个明智的选择。

3.2.3  实现游戏主循环

一个游戏可能提供自己的线程来运行游戏循环:一个典型的循环将检查输入、实现游戏逻辑,然后绘制更新后的用户 界面。

通常,在MIDP 2.0游戏中,GameCanvas充当了游戏“控制器”的功能。GameCanvas除了完成绘制屏幕的功能外,还负责等待并获得用户的输入,进行相应 的处理(改变游戏的状态和移动图层),绘制改变后的游戏界面。下面给出了一个在MIDP 2.0中使用GameCanvas实现游戏循环的代码框架:

//GameCanvas 的实现的游戏线程

Graphics g = getGraphics();                 //获得Graphics对象来绘制后备屏幕缓冲

while (true) {

  int keyState = getKeyStates();            //检查是否有用户输入

  if ((keyState & LEFT_PRESSED) != 0) {      //游戏左键被按下

      sprite.move(-1, 0);                    //进行游戏逻辑操作,这里精灵向左移动

  }

  else if ((keyState & RIGHT_PRESSED) != 0) {   //游戏右键被按下

      sprite.move(1, 0);                     //进行游戏逻辑操作,这里精灵向右移动

  }

  g.setColor(0xFFFFFF);                     //将背景填充为白色

  g.fillRect(0,0,getWidth(), getHeight());

  sprite.paint(g);                          //绘制精灵

  flushGraphics();                          //将缓冲区的内容绘制到真实的设备屏幕上

}

3.2.4  获取键盘状态

前面已经提到,GameCanvas和Canvas的按键状态的响应是不一样的。在Canvas时代,如果想 知道按键状态,必须实现keyPressed()/keyReleased()/keyRepeated(),每当有按键被按下时,这个方法就被调用,而 在GameCanvas时代,如果要检查特定的按键是否被按下,只需要将getKeyStates()返回的值与这些键值进行按位与(&),并根 据计算结果来判断即可。

getKeyStates()返回的bit数据分别代表了不同的按键(例如Up、Down、Fire等)。当 按下某个物理键盘时,其对应的位设置为1,否则将被设置为0,这样做的好处是,无论游戏主循环执行得多慢,键盘事件都不会被忽略。

注意

除非GameCanvas当前可见(通过调用Display.isShown()方法),否则此方 法返回值为0。一旦GameCanvas变为可见,将初始化所有键为未按下状态(0)。

每一次getKeyStates()方法的调用都会清除当前键盘缓冲区,因此理论上说,连续调用两次 getKeyStates(),前一次会清除之前锁定的键盘状态,而后一次会得到反映当前键盘状态的理想值。

当然getKeyStates()的返回值会在另外一个线程中被更新,所以在游戏主循环中最好稍微等一会儿, 以保证这个值被更新。GameCanvas中获得用户输入的代码:

protected void input() {

int keyState = getKeyStates();                    //获得键盘状态

if ((keyState & LEFT_PRESSED) != 0) {             //如果左键被按下

// do something

}

if ((keyState & RIGHT_PRESSED) != 0) {            //如果右键被按下

// do something

}

if ((keyState & FIRE_PRESSED) != 0) {             //如果确定键被按下

// do something

}

}

文本框:图3-7  WTK 2.2中的DefaultColorPhone键盘映射关系

 

 

 

 

 

 

 

 

如图3-7所示,将WTK的模拟器中游戏的A、B、C、D键分别映射到 1、3、7、9这4个键上,而Nokia模拟器将A、B、C、D键映射到7、9、#、*这4个键上。这里并没有使用处理按键事件的方式来得到按键输入,如 果采用这种方法获得按键输入,则一定要调用getGameAction()将按键代码转换为游戏代码。

为了使程序能在不同的设备上运行,就一定要考虑不同设备间键盘布局的特点,在开发程序时不能假设按键的布局方 式。具体的映射关系如表3-2所示。

表3-2                                              getKeyState()方法所返回的键盘值

键    值

相对应的KeyStates值

UP_PRESSED

0x0002 = 2

DOWN_PRESSED

0x0040 = 64

LEFT_PRESSED

0x0004 = 4

RIGHT_PRESSED

0x0020 = 32

FIRE_PRESSED

0x0100 = 256

GAME_A_PRESSED

0x0200 = 512(并非所有设备支持)

GAME_B_PRESSED

0x0400 = 1024(并非所有设备支持)

GAME_C_PRESSED

0x0800 = 2048(并非所有设备支持)

GAME_D_PRESSED

0x1000 = 4096(并非所有设备支持)

注意

不同的设备对于getKeyStates()方法的调用会略有不同,主要体现在:有的设备支持检测 多个键同时按下的情况,而有的设备的不支持getKeyStates()方法,仅仅是通过调用keyPressed()/keyReleased()方法 来代替,因此会产生一定的时延。

由于GameCanvas能够通过getKeyStates()方法主动查询键盘状态,因此也提供了是否抑制 传统键盘事件的选择。

如果希望当游戏运行时,禁止调用KeyPressed()/keyReleased() /KeyRepeated()方法,那么就可以在构造GameCanvas时,在super()中传入true值。如果传入false值,那么一旦按键按 下,就会调用传统的键盘事件处理方法。

注意

键盘抑制只对当前GameCanvas 有效,并且只能抑制Canvas预定义的键盘事件(例如无法抑制手机上的*号键、#号键,以及接听、挂断、Clear等功能键)。


 

 

本文摘自:http://apps.hi.baidu.com/share/detail/31217091

C++中为什么要引入引用变量? C++引用机制的设计哲学在于平衡性能与安全性。它解决了指针的三个痛点:语法噪音、空指针风险和语义模糊,同时保持了指针的效率优势。引用必须绑定有效对象且不可重绑定的特性增强了安全性,其值语义语法更直观。尤其在运算符重载和const引用场景中,引用展现了不可替代的优势。本质上,引用是编译器优化的指针实现,体现了C++"零开销抽象"的核心思想——既保持底层性能,又提供高级抽象。这种设计允许开发者根据场景灵活选择指针或引用,反映了C++多范式共存的语言智慧。 阅读详情

相关推荐

vmware虚拟机网络连接问题

主机:ubuntu14.04 Vitual Network Editor

入门虽易,精通不易,且学且珍惜! 1354

unity | Game界面Canvas模式和相关的相机基础-如何在Game界面上显示两个相机画面

如何在Game界面上显示两个相机画面,相机和画面位置的设置

菌菌兹的博客 2744

爬取信用中国里面的行政处罚

result字段名为行政处罚文书号、处罚决定日期、处罚内容、处罚金额、违法事实、处罚机关、公司名称,行政处罚次数。file_path=r'E:\Data analyze\python\行政处罚爬虫/'#路径需要按实际修改。writer = pd.ExcelWriter('统计.xlsx')# 写入Excel文件。src_workbook=file_path+r'行政处罚(名单).xls' #表格名称也要更改。# keyword = input("输入爬取的公司全称必须是全称")

qq_42863025的博客 1674

GameCanvas全屏尺寸的问题

很多人都问过我这个问题,解释了很多遍,干脆写出来。Q: 为什么我在setFullScreenMode(true)后,调用getWidth(),getHeight()得到的屏幕尺寸比实际尺寸小?A: 因为当Canvas没有被显示时,调用setFullScreenMode(true)后,并不会立即生效。在生效过后,系统会回调sizeChanged(int w, int h) 来通知屏幕大小已经改变。p

Mobile Game 1686

AI大模型实战——模型测评:如何评估大模型的表现

大模型评测体系解析:从数据集到基准测试 本文系统梳理了大模型评测的关键要素。在数据集方面,重点介绍了C-Eval等中文评估套件,强调数据质量需通过人工验证保证。评测维度涵盖自然语言理解、知识推理、代码生成等核心能力。基准测试作为标准化评估方法,Glue、SuperClue等平台提供了公平比较的依据。文章指出厂商自评榜单存在水分问题,建议关注第三方评测。同时解析了少样本和零样本两种prompt模式的应用场景差异。最后解释了"SOTA"这一术语在描述模型最优性能时的应用价值。整体呈现了大模型

小志的博客 895

ArcGIS属性表汉字转拼音

接着我安装了一个编辑器“PyCharm Community Edition 2019.3.3\bin\pycharm64.exe”,在里面添加“pypinyin”包,然后将其设置为arcgis的编辑器和调试程序,还是失败;我在10.6的机器上折腾了上面几步,直到两周后脚本突然运行成功,我也不确定是哪一步导致pypinyin包配置成功,因此将心得体会写出来,如果过一段时间,打开10.2的机器运行脚本成功了,再写后续.......,按照“配置方法1:”进行尝试,显示配置失败。

2301_77413856的博客 1295

用HTML5制作精美战机游戏

其中的background bullet这些图片你可用使用自己想要图片进行替换。代码和图片压缩包完整下载链接---☄️爬虫JS逆向系列专栏 -☄️python系列专栏 -话不多说直接上代码!

ZTLJQ的博客 7896

基于表面肌电信号sEMG的手势识别——以Ninapro DB1数据集使用CNN网络识别为例

本文实验采用公共数据集Ninapro。该数据集数据量大,采集的动作丰富,每个单位数据集里面包括表面肌电信号、加速度计、手部运动学和动态数据等,记录了67名完整受试者和11名进行了至少50 次手部运动的截肢者的数据。NinaproDB1数据集包括27名完整的受试者(7 名女性和20名男性,其中2个左手和25 个右手) 的肌电信号。信号采集频率为100Hz。

树下一朵云的博客 2295

java canvas类_java 手机游戏中 Game Canvas类

Public abstract class GameCanvas extends CanvasGameCanvas类提供了基本游戏用户界面。除此之外继承了Canvas类的功能(commands,input 事件,等等),它也提供特定的游戏功能,比如离屏缓冲区和查询按键状态的能力。每一个GameCanvas类的实例都会创建一个专用的缓冲区。一旦为每个GameCanvas实例提供了唯一的缓冲区,它更适...

weixin_39593427的博客 295

pyecharts在jupyter notebook中不能够渲染图表问题。

在使用jupyter notebook中使用pyecharts绘制可视化图表的时候,发现图表不能渲染到页面中,生成的html是没问题的,本文主要解决在jupyter notebook中不能渲染这个问题。

猿小白的博客 1164

使用 Simulink 进行电力电子系统的小信号模型仿真

电力电子系统(Power Electronics System)包括各种功率转换器(如 DC-DC 转换器、逆变器等)。这些设备中的关键组件(如 MOSFET、IGBT、电容器、电感器等)不仅影响系统的性能,还直接关系到系统的稳定性、效率和可靠性。因此,在设计阶段进行详细的建模和仿真至关重要。小信号模型仿真的目的是通过线性化非线性系统来评估其动态特性,包括增益、相位裕度、带宽等指标。通过本教程,我们介绍了如何使用 Simulink 进行电力电子系统的小信号模型仿真。背景介绍。

xiaoheshang_123的博客 480

J2me低级UI界面中Canvas类与GameCanvas类

关于MIDlet类中destroyApp(参数)问题: 在destroyApp()方法中的参数为Boolean类型,destroyApp是一个callback,它是一个接口或者说一个协议。 当参数为false时,被调用MIDlet可以选择是否被关闭。如果选择被关闭,那么MIDlet就应该在destroyApp返回之前做好被关闭的准备,否则就抛出MIDletStateChange...

邪道少年 216

【100%通过率】2023华为od机试C卷【电脑病毒感染】C语言 实现

一个局域网内有很多台电脑,分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用t 表示。其中网络内一台电脑被病毒感染,求其感染网络内所有的电脑最少需要多长时间。如果最后有电脑不会感染,则返回-1.

MISAYAONE的博客 1042

构建一个J2ME游戏:从GameCanvas类开始

构建一个J2ME游戏:从GameCanvas类开始GameCanvas类继承自Canvas,提供了一个屏幕后端的缓冲区,所有的绘制操作都先在这个缓冲区里进行。当所有绘制操作完成后,我们调用flushGraphics()方法将缓冲区内容输出到屏幕。这种双缓冲机制可以使图像的移动更加平滑,避免图像的闪烁。缓冲区大小等于屏幕的大小,而且每一个GameCanvas实例有且仅有一个缓冲区。GameCanva

BigL的专栏 1495

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

使用GameCanvas制作星空效果

MIDP2.0中提供了游戏开发专用的API,比如GameCanvas等类。他们位于javax.microedition.lcdui.game包内。本文介绍GameCanvas的基本使用方法并实现一种滚动星空的效果。您可以参考Game Canvas Basic获得更详细的信息。    GameCanvas是Canvas的子类,因此他同样继承了Canvas类的一些特性,比如showNotify()

977

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

J2ME Tutorial, Part 3: 探究MIDP 2.0的游戏API(二)

承接第一部分,介绍小游戏的具体实现,实现第一个版本,并介绍GameCanvas类的使用及运行机制。原文见:http://www.blogjava.net/Andyluo/archive/2005/12/08/23003.html

Azting的专栏 1386

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

利用GameCanvas的offscreen_buffer

MIDP2.0增加了GameCanvas类,其中包含了一个offscreen_buffer,可以随时调用flushGraphics()来把它画到屏幕上,游戏的结构也可以变得简单一些。但是,为了移植方便,大多数时候还是用的MIDP1.0的结构。GameCanvas中是这样定义的:private Image offscreen_buffer;我们无法得到这个Image的reference,但是可以通过

Mobile Game 1174

J2ME游戏画布

GameCanvas类     继承于MIDP 1.0的Canvas类的GameCanvas是一个提供了游戏的基本接口的抽象类,除了完全具备原来Canvas类的功能外,还提供了更多开发游戏的便利,主要为:提供屏幕缓冲绘制机制,并能直接得到设备键盘的物理状态。GameCanvas概述     GameCanvas(游戏画布)对象能够提供画布的功能,类的定义为:public abstr

lengyuhong的专栏 1027

GameCanvas与Sprite-----转

GameCanvas与Sprite    这一讲我们来学习MIDP2.0的新增功能GameAPI。   GameAPI?从名称上面看是游戏用的API么?

974

GameCanvas绘制进度条

//于com.sk.model包创建ProgressCanvas,需要Display对象,以便绘制ProgressCanvas package com.sk.model;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdu

391

java手机游戏开发 4 综合GameCanvas,Sprite开发UFO游戏

  GameCanvas是Canvas的子类本例程将用到Display,Sprite,GameCanvas,Runnable等Sprite:精灵类,可以把Sprite看作游戏中的某角色(如主角),Sprite可实现角色便移动,便改变自身形象1.于 com.sk.model 建立UFOCanvas 类,继承GameCanvas,实现Runnable接口package com.sk

590

《Java 手机/PDA 程序设计入门》读书笔记10--Game API

Game API由5个类构成GameCanvas--LayerManager--LayerSpriteTiledLayerGameCanvas继承Canvas,具有Canvas所有的功能。而且GameCanvas直接提供了 getKeyStates(),检测同一时间,按键被按下的情形。GameCanvas还提供了 flushGraphics(),将Off-Screen内容显示到屏幕上,它并不产生重

智在居士草堂 1333

welcome to enigma blog

public class Game extends java.awt.Frame{    public Game()    {        setTitle("俄罗斯方块游戏 - Ghost Valley");        addWindowListener(new java.awt.event.WindowAdapter(){            public void windowClo

愿某天一起编织理想 愿某天彼此心中太阳 1003

J2ME游戏开心药丸开发过程(二)

文章来源:J2ME开发网接着我们来设计Piece这个类,它的作用是什么呢,它是存储单个方块信息的类,(我们的药丸由两个方块组成,即两个Piece的随机组合)该类的核心之一便是如何判断在方块落下之后和左右上下相邻的方块之间的颜色是否相同,相同即消去之间的边界线,不相同即需要在它们之间描绘上一条边界线。这样一个设计需要4个布尔值来进行判断,还需要定义好方块的高度和宽度(不同的手机的屏幕大小不一,在实际

mobilechannel的专栏 849

J2ME游戏API简介

1 游戏API简介    MIDP 2.0相对于1.0来说,最大的变化就是新添加了用于支持游戏的API,它们被放在javax.microedition.lcdui.game包中。游戏API包提供了一系列针对无线设备的游戏开发类。由于无线设备仅有有限的计算能力,因此许多API的目的在于提高Java游戏的性能,并且把原来很多需要手动编写的代码如屏幕双缓冲、图像剪裁等都交给API间接调用本地代码来实

逍遥剑客 5568
上一篇: Tracert命令详解
下一篇: HTTP协议分析
VS_URL
博客等级 码龄15年 12粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值