เกม HTML5 (Canvas) - เทคนิค UI?


23

ฉันกำลังสร้างเกม JavaScript / HTML5 (ใช้ Canvas) สำหรับมือถือ (Android / iPhone / WebOS) ด้วย PhoneGap ขณะนี้ฉันกำลังพยายามออกแบบวิธีการสร้าง UI และกระดานเล่นและวิธีที่พวกเขาควรโต้ตอบ แต่ฉันไม่แน่ใจว่าทางออกที่ดีที่สุดคืออะไร นี่คือสิ่งที่ฉันคิดได้ -

สร้าง UI ลงในผืนผ้าใบโดยใช้สิ่งต่าง ๆ เช่น drawImage และ fillText Build ส่วนต่าง ๆ ของ UI ที่อยู่ด้านนอกของผืนผ้าใบโดยใช้วัตถุ DOM ปกติแล้วลอย div บนผืนผ้าใบเมื่อองค์ประกอบ UI จำเป็นต้องซ้อนผ้าใบในกระดาน มีเทคนิคใดที่เป็นไปได้อื่น ๆ ที่ฉันสามารถใช้ในการสร้าง UI เกมที่ฉันไม่ได้คิด? นอกจากนี้เกมประเภทใดที่ถือว่าเป็น "มาตรฐาน" (ฉันรู้ว่าเกม HTML5 ไม่เป็นที่นิยมมากดังนั้นอาจจะยังไม่มีวิธี "มาตรฐาน") และในที่สุดคุณจะแนะนำ / ใช้วิธีไหน

ขอบคุณมากล่วงหน้า!


โปรดทราบว่า Canvas ยังไม่ได้รับการสนับสนุนใน IE (จะถูกกล่าวหาว่า IE9) ... ดังนั้นจะเป็นการลบส่วนแบ่งการตลาดขนาดใหญ่สำหรับเกมของคุณ มีตัวแก้ไขจาวาสคริปต์ที่พยายามทำให้มันทำงานได้ใน IE แต่มันทำงานได้ไม่ดีเท่าที่ควร (ช้าอย่างที่คิด ... ไม่คุ้มกับมัน)

1
@Adam - ดู flashcanvas: flashcanvas.net
ehsanul

ฉันใช้องค์ประกอบ dom เป็น gui, divul mulitple แบบลอยตัวเป็น "windows" ที่มีองค์ประกอบผ้าใบหนึ่งผืนต่อเนื่อง (เกมจริง) และมีตัวเลือกนี้อยู่เสมอ: developer.mozilla.org/en-US/docs/HTML/Canvas/
......

คำตอบ:


18

วิธีแก้ปัญหาทั้งสอง (วาดบนผ้าใบเทียบกับ HTML แบบดั้งเดิม / CSS) ของคุณนั้นใช้ได้จริงและจะใช้ได้ดี บางสิ่งที่ควรพิจารณา:

  • หากคุณใช้ไลบรารี่ที่ใช้ไลบรารี่อยู่แล้วรหัสของคุณอาจสะอาดกว่า / เป็นระเบียบมากขึ้นโดยใช้แคนวาสต่อไปแทนที่จะใช้เมธอดเพิ่มเติม (DOM-based) สำหรับ UI
  • หาก UI ของคุณมีข้อความมากเป็นพิเศษ (พร้อมกล่องโต้ตอบ ฯลฯ ) การดำเนินการผ่าน HTML / CSS อาจทำได้ง่ายกว่า ตัวอย่างเช่นมันค่อนข้างน่าสนใจสำหรับข้อความที่จะไหลในองค์ประกอบ DOM (ด้วยสิ่งต่าง ๆ เช่นการตัดและการเว้นวรรคย่อหน้า) และค่อนข้างยากที่จะนำไปใช้ใน Canvas
  • การใช้การจัดการการคลิกกับองค์ประกอบ DOM นั้นขึ้นอยู่กับไลบรารีที่คุณใช้อย่างหนักอาจจะง่ายกว่าการใช้ Canvas ตัวอย่างเช่นหากคุณต้องการตรวจจับการคลิกที่ปุ่ม "ตกลง" นั่นเป็นงานที่ไม่สำคัญในโลก HTML / JS แต่ใน Canvas คุณจะต้องฟังการคลิกที่องค์ประกอบอื่นและตรวจสอบพิกัดเพื่อดูว่าการคลิกเกิดขึ้นที่ใด
  • ตัวแทนผู้ใช้บางคน (โดยเฉพาะอุปกรณ์พกพา) อาจยุ่งยากเมื่อใช้องค์ประกอบ DOM ที่มีข้อความ ตัวอย่างเช่น Safari มือถืออาจต้องการป๊อปอัปด้วยเครื่องมือในการคัดลอก / วาง การป้องกันพฤติกรรมนี้อาจเป็นเรื่องยากและอาจจะง่ายขึ้นในผืนผ้าใบ

บางส่วนจะเป็นอัตวิสัย นักพัฒนาที่ฉันรู้จักใช้ผ้าใบเสมอเพราะเขาเพิ่งพบว่า DOM นั้นน่าเกลียดและ verbose เนื่องจากโซลูชันทั้งสองจะทำงานได้ดีฉันจะเลือกหน้าจอเดียวที่เรียบง่ายในแอปของคุณพัฒนาแยกจากกันโดยใช้ทั้งสองวิธีอย่างรวดเร็ว

ขอให้โชคดี!


ขอบคุณสำหรับการตอบกลับของคุณ! จุดที่ดีมาก ตอนนี้ฉันกำลังสร้างเครื่องยนต์ของตัวเองแล้ว เริ่มใช้ Canvas แต่จะทำการแก้ไขเล็กน้อยเพื่อทดสอบสิ่ง CSS3 / WebKit เหตุผลเดียวที่ฉันสร้างของตัวเองเป็นเพราะเกมนั้นง่ายเกินไปสำหรับเครื่องมือที่ 'จริง' เราไม่ได้มีวงเกมหลักจริงๆ เหตุผลเดียวก็จะยิ่งมีสำหรับการเคลื่อนไหว แต่พิจารณาว่านาน ๆ เหล่านั้นเกิดขึ้นเราอาจจะเพียงแค่เริ่มต้น / หยุดจับเวลาตามความจำเป็น :)
เจสันลิตร

5

ฉันใช้easeljsสำหรับการโต้ตอบบนผืนผ้าใบ

มันค่อนข้างดีและอำนวยความสะดวกในการออกแบบที่มั่นคง หนึ่งในคุณสมบัติที่สำคัญที่ทำให้ฉันเลือกมันคือความสะดวกในการซิงค์ตำแหน่งของวัตถุผ้าใบและองค์ประกอบ dom ของคุณ

สิ่งนี้ทำให้ CSS พูดฟองและองค์ประกอบ UI แบบคงที่ได้ง่ายเช่นเฟรมฮัดและสิ่งนั้น

ข้อได้เปรียบสำหรับเบราว์เซอร์นี้คือคุณได้รับผืนผ้าใบที่สมบูรณ์ แต่คุณจะต้องจำนำสิ่งเล็ก ๆ และไม่เปลี่ยนแปลงให้กับ dom เพื่อรักษาประสิทธิภาพเอาไว้


4

Canvas นั้นช้าบนแพลตฟอร์มมือถืออย่างน้อย Safari มือถือก็อยู่แล้วดังนั้นคุณจะต้องใช้การวางตำแหน่ง CSS ตามวัตถุบนสิ่งเหล่านั้น ใช้ "translate3d" โดยเฉพาะซึ่งจะเปิดการเรนเดอร์การเร่งความเร็วของวัตถุ

ลองไปที่คลัง CAAT เพื่อดูผืนผ้าใบมันเร็วและคุณสามารถใช้ CSS "นักแสดง" และไม่เปลี่ยนตรรกะของเกม

ฉันสามารถเชื่อมโยงไม่ได้โพสต์เลย แต่ที่นี่มีบางลิงค์ที่หลอก http://labs.hyperandroid.com/animation


ฉันคิดว่าลิงก์ repo บนหน้าของ CAAT ชี้ไปที่อันเก่าดังนั้นให้แน่ใจว่าคุณใช้อันนี้แทน! repo: github.com/hyperandroid/CAAT
onedayitwillmake

(ขออภัยฉันสามารถเพิ่มได้เพียงหนึ่งลิงค์ต่อโพสต์ในปัจจุบัน) นี่คือตัวอย่างที่ฉันสร้างขึ้นซึ่งมีแม่แบบสวัสดีโลกสำหรับ CAAT - onedayitwillmake.com/CAATCirclePack
onedayitwillmake

ขอบคุณสำหรับลิงค์ฉันจะ def ตรวจสอบมัน ฉันเคยได้ยินเสียง rumblings ของ Canvas ช้า แต่ฉันเป็นคนที่มักจะต้องเห็นสิ่งต่าง ๆ ด้วยตัวเอง :) ฉันควรทราบด้วยว่าเกมที่ฉันกำลังสร้างนั้นมีแสงมากในภาพเคลื่อนไหว อย่าทำงานมากกว่าหนึ่งหรือสองอย่างในเวลาเดียวกันและเป็นช่วง ๆ ทุกๆ 5-10 วินาทีต่อนาทีในแต่ละครั้ง ไม่มีอะไรบ้า นอกจากนี้ในการตรวจสอบคุณแนะนำให้ไม่ใช้ Canvas เลย แต่ใช้วัตถุ DOM เก่ากับ CSS / translate3d หรือไม่
Jason L.

พูดตามตรงฉันไม่สามารถพูดในสถานการณ์เฉพาะของคุณได้หรือไม่ อย่างไรก็ตามหากคุณต้องการกำหนดเป้าหมายไปที่มือถือ - ซาฟารีโดยเฉพาะคุณควรใช้ CSS กับ divs มันเร็วมากเมื่อเทียบกับการวาดซ้ำผ้าใบจากประสบการณ์ของฉัน ฉันสามารถสไปรต์ที่มีรูปภาพ 45 รูปเคลื่อนที่ไปรอบ ๆ ที่ 30FPS โดยใช้ 'translate3d' เพื่อย้ายไปไว้ที่เดิม ตรวจสอบให้แน่ใจว่าได้วางสิ่งนี้ลงใน CSS สำหรับวัตถุที่คุณวางแผนจะเคลื่อนที่ด้วย 'transform3d' มิฉะนั้น webkit จะทำให้วัตถุเหล่านั้นเคลื่อนไหวไปยังตำแหน่งที่ระบุไว้แทนที่จะวาง -webkit-transition: transform3d 0s เป็น Linear
onedayit จะทำให้

2

ต้องยอมรับเกี่ยวกับความเชื่องช้าของ Canvas บน iPhone 4 ค่อนข้างแน่ใจว่า GL ของซาฟารีไม่ได้รับการสนับสนุนจาก GL เกม cheezy ของฉันทำงานได้อย่างรวดเร็วบน iPhone 3GS และ android แต่บน iPhone 4 ฉันคิดว่าจอแสดงผลเรตินามีพิกเซลมากเกินไปหรือถ้าผ้าใบไม่ได้ขี่บน GL นี่จะอธิบายได้ว่าทำไมมันถึงน่าเบื่อ ฉันชอบโมเดลการพัฒนาแคนวาสยังไม่ได้ลองตัวเลือก css translate3d โดยเฉพาะฉันใช้ GWT และ gwt-g2d canvas wrapper (optimization / obfuscation) http://www.photonjunky.com/shootout.html


1

ฉันขอแนะนำให้คงการควบคุมของคุณไว้เป็นองค์ประกอบ html เช่นmenuและcommandเพื่อเหตุผลในการเข้าถึง การใช้ CSS สักเล็กน้อยคุณสามารถแสดงองค์ประกอบต่างๆบนผืนผ้าใบและไม่ทำให้ฟังก์ชั่น HTML ที่สร้างไว้ล่วงหน้าหายไป


1

ฉันรู้ว่านี่เป็นคำถามเก่า แต่วันนี้ (มีนาคม 2013) เรารู้ดีกว่า ฉันตัดสินใจที่จะตอบในกรณีที่คนอื่นสะดุดที่นี่เหมือนฉัน ฉันต้องไม่เห็นด้วยกับคำตอบส่วนใหญ่ มันอาจจะใช้ได้สำหรับการพัฒนาเว็บเบราว์เซอร์ แต่ไม่ใช่สำหรับมือถือ มันสร้างความแตกต่างอย่างมากในเส้นทางที่คุณเลือก (DOM หรือภาพเคลื่อนไหวบนผืนผ้าใบ) webview ของ Android นั้นไม่มีประโยชน์อย่างสมบูรณ์ (ช้า, พูดติดอ่าง) ในตัวมันเองซึ่งทำให้ 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) {
  // ...
}

ด้วยวิธีนี้ฉันสามารถแยกออกจากการวาดเกมและกิจกรรมเกมจากการวาดเมนูและกิจกรรมเมนู นอกจากนี้ยังทำให้ฉันมีเวลามากขึ้นในการใช้องค์ประกอบของเกม / แอนิเมชั่นในเมนูของฉันถ้าฉันต้องการทำให้มันดูสวย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.