HTML5游戏(画布)-UI技术?


23

我正在使用PhoneGap开发用于移动设备(Android / iPhone / WebOS)的JavaScript / HTML5游戏(使用Canvas)。我目前正在尝试设计UI和游戏板的构建方式以及它们之间的交互方式,但我不确定最佳解决方案是什么。这是我能想到的-

使用drawImage和fillText之类的东西将UI正确地构建到画布中。使用常规DOM对象在画布外部构建UI的一部分,然后在UI元素需要与游戏面板画布重叠时在画布上浮动div。还有其他我可能没有想到的可用于构建游戏UI的技术吗?另外,以下哪一种将被视为“标准”方式(我知道HTML5游戏不是很流行,因此可能还没有“标准”方式)?最后,您会推荐/使用哪种方式?

提前谢谢了!


请记住,IE中尚不支持Canvas(据称将支持IE9)...这样就为您的游戏赢得了巨大的市场份额。有一个JavaScript修补程序试图使其在IE中正常工作,但效果欠佳(速度慢,不值得……)。

1
@Adam-参见flashcanvas:flashcanvas.net
ehsanul 2011年

我将dom元素用作gui,将多个浮动div用作“ windows”,其中一个窗口包含canvas元素(实际游戏)。总是有这个选项:developer.mozilla.org/en-US/docs/HTML/Canvas/… :)
Kikaimaru 2013年

Answers:


18

两种解决方案(在您的画布上绘制,以及传统的HTML / CSS上绘制)都是完全有效的,并且可以正常工作。要考虑的一些事情:

  • 如果您已经在使用基于画布的库,则可以通过继续使用画布而不是为UI使用其他(基于DOM)方法来使代码更简洁/更有条理。
  • 如果您的UI非常繁重(带有对话框等),则通过HTML / CSS实施可能会更简单。例如,文本在DOM元素中流动(带有诸如换行和段落间距之类的东西)非常简单,并且在画布中实现起来相对困难。
  • 在很大程度上取决于您使用的库,在DOM元素上实现点击处理比在画布内实现点击处理要容易得多。例如,如果您要检测对“确定”按钮的单击,那么在HTML / JS世界中这是一项琐碎的任务。但是在画布中,您需要收听对其他元素的单击,并检查其坐标以查看单击发生的位置。
  • 使用包含文本的DOM元素时,某些用户代理(尤其是移动设备)可能会比较棘手。例如,Mobile Safari可能希望弹出带有复制/粘贴工具的模式。防止这种行为可能很困难,在画布上可能会更容易。

其中一些将是主观的。我认识的开发人员总是喜欢使用canvas,因为他发现DOM丑陋且冗长。由于这两种解决方案都可以正常工作,因此我会在您的应用中选择一个简单的屏幕,使用两种方法分别快速开发它,然后看看哪种方法更容易/更好。

祝你好运!


感谢您的回复!非常好点。我实际上正在构建自己的引擎。使用Canvas启动了它,但是要对其进行一些修改以测试CSS3 / WebKit的东西。我构建自己的游戏的唯一原因是游戏对于“真实”引擎而言过于“简单”。我们甚至没有真正的主游戏循环。甚至只有动画的唯一原因,但是考虑到发生这些事件的
Jason L.

5

我一直在使用easyljs进行画布交互。

它非常好,可以简化设计。使我选择它的关键功能之一是可以同步画布对象和dom元素的位置的功能。

这样可以很容易地实现CSS气泡和诸如hud框架之类的静态UI元素。

这对浏览器的好处是,您可以获得丰富的画布,但可以将dom的较小和静态的东西当掉,以保持性能。


4

在移动平台上Canvas速度很慢,无论如何至少在移动Safari上是这样,因此您需要在这些对象上使用基于CSS的对象定位。具体使用“ translate3d”,它将打开硬件加速的对象渲染。

不过,请签出画布的CAAT库,它很快,并且您可以使用CSS支持的“角色”,而无需更改游戏逻辑。

我还不能发布链接,但是这里有一些伪链接 http://labs.hyperandroid.com/animation


我认为CAAT页面上的回购链接指向旧的链接,因此请确保使用此链接!回购:github.com/hyperandroid/CAAT
onedayitwillmake 2011年

(对不起,我目前只能为每个帖子添加一个链接)这是我创建的一个演示,其中包含CAAT的hello-world模板-onedayitwillmake.com/CAATCirclePack
onedayitwillmake 2011年

感谢您提供的链接,我将进行定义。看看这个。我听说Canvas的声音很慢,但是我是一个通常自己要看一下东西的人:)我还应该注意,我正在制作的游戏在动画上非常亮。一分钟内一次或两次,每5-10秒一次,间隔不超过一个或两个。没什么疯狂的。另外,要验证一下,您是否建议完全不使用Canvas,而是将普通的旧DOM对象与CSS / translate3d一起使用?
詹森·L。

老实说,我不能说你的具体情况。但是,如果您想特定地定位移动浏览器,那么imo yeah,您可能希望将CSS与div一起使用。与根据我的经验重画画布相比,这样做的速度非常快。我能够轻松地使用“ translate3d”将45个基于图像的精灵以30FPS的速度移动到位。请确保将其放置在CSS中,以供您计划通过“ transform3d”移动的对象使用,否则webkit会将这些对象设置为指定位置的动画,而不是放置。-webkit-transition:transform3d 0s线性;
onedayitwillmake 2011年

2

必须就iPhone 4上的画布缓慢度达成共识。我的时髦游戏在iPhone 3GS和android上运行很快,但在iPhone 4上,我认为视网膜显示屏上的像素过多,或者如果画布未在GL上骑行,这将解释为什么它会拖拽。我喜欢canvas开发模型,还没有尝试过css translation3d选项。特别是,我使用了GWT和gwt-g2d帆布包装器(优化/模糊处理)。 http://www.photonjunky.com/shootout.html


1

我建议您将控件保留为html元素,例如menucommand出于可访问性原因。使用一点CSS,您可以在画布上显示元素,而不会失去HTML的预构建功能。


1

我知道这是一个老问题,但是今天(2013年3月)我们知道的更多了。我决定回答,以防其他人像我一样跌倒在这里。我不得不不同意大多数其他答案。它们可能对Web浏览器开发有效,但对移动设备无效。选择哪种路径(DOM或画布动画)会产生很大的不同。除非您可以应用硬件加速(目前仅使用画布动画和合适的框架才能实现),否则Android Webview本身完全是无用的(缓慢,断断续续),这使Phonegap无法用于Android游戏开发。有关更多信息,请参见此回复


0

您可以做到一百万种方式。但是,您会感到最舒适,工程师也会感到最有信心。

如果您正在寻找灵感或代码示例,那么这就是我的一种方法。我有一个反复绘制菜单直到按下按钮的功能。当按下按钮时,将加载游戏,并删除旧的菜单单击事件侦听器,并添加新的游戏单击事件侦听器。我还结束了菜单的旧绘制循环并开始了新的游戏绘制循环。以下是一些精选的片段,让您了解其操作方法:

Game.prototype.loadMenu = function() {
  var game = this;
  var can = this.canvas;

  // now we can use the mouse for the menu
  can.addEventListener('click', game.menuClickEvent, false);
  can.addEventListener('touchstart', game.menuClickEvent, false);

  // draw menu
  this.loop = setInterval(function() { game.drawMenu() }, 30);
};

Game.prototype.drawMenu = function() {
  // ... draw the menu
}

Game.prototype.loadLevel = function(levelstring) {
  // unload menu
  var can = this.canvas;
  var game = this;
  can.removeEventListener('click', game.menuClickEvent, false);
  can.removeEventListener('touchstart', game.menuClickEvent, false);

  if (this.loop) clearInterval(this.loop);

  // ... other level init stuff


  // now we can press keys for the game
  //can.addEventListener('click', game.gameClickEvent, false);
  can.addEventListener('touchstart', game.gameClickEvent, false);
  can.addEventListener('keydown', game.gameKeyDownEvent, false);

  this.loop = setInterval(function() { game.tick() }, 30);
}

// called from tick()
Game.prototype.draw = function(advanceFrame) {
  // ...
}

这样,我就可以将游戏绘图和游戏事件与菜单绘图和菜单事件分开。如果我想让菜单看起来更漂亮,这也让我有余地在菜单中使用游戏/动画元素。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.