Gra HTML5 (Canvas) - techniki interfejsu użytkownika?

23

Jestem w trakcie tworzenia gry JavaScript / HTML5 (przy użyciu Canvas) na urządzenia mobilne (Android / iPhone / WebOS) z PhoneGap. Obecnie próbuję ustalić, jak powinien wyglądać interfejs użytkownika i plansza do gry, a także jak powinny one ze sobą współdziałać, ale nie jestem pewien, jakie jest najlepsze rozwiązanie. Oto, co mogę wymyślić -

Zbuduj interfejs użytkownika bezpośrednio w obszarze roboczym za pomocą takich funkcji, jak drawImage i fillText Zbuduj części interfejsu użytkownika poza obszarem roboczym, używając zwykłych obiektów DOM, a następnie umieść div nad obszarem roboczym, gdy elementy interfejsu użytkownika będą zachodzić na obszar roboczy. Czy są jakieś inne techniki, których mogę użyć do stworzenia interfejsu gry, o których nie myślałem? Ponadto, który z nich można uznać za „standardowy” (wiem, że gry HTML5 nie są zbyt popularne, więc prawdopodobnie nie ma jeszcze „standardowego” sposobu)? I w końcu, w jaki sposób poleciłbyś / użyłbyś?

Z góry bardzo dziękuję!

Jason L.
źródło
Pamiętaj, że Canvas nie jest jeszcze obsługiwany w IE (podobno będzie w IE9) ... więc usuwa ogromny udział w rynku dla twojej gry. Jest łata javascript, która próbuje sprawić, by działała w IE, ale nie działa dobrze (SPOWOLNIJ jak cholera ... nie warto).
1
@Adam - Zobacz flashcanvas: flashcanvas.net
ehsanul
Używam elementów dom jako gui, wiele pływających elementów div jako „windows” z jednym oknem zawierającym element canvas (rzeczywista gra). I zawsze jest taka opcja: developer.mozilla.org/en-US/docs/HTML/Canvas/… :)
Kikaimaru

Odpowiedzi:

18

Oba rozwiązania (rysowanie na płótnie VS. tradycyjny HTML / CSS) są całkowicie poprawne i będą działać dobrze. Kilka rzeczy do rozważenia:

  • Jeśli już korzystasz z biblioteki opartej na kanwie, kod może być bardziej przejrzysty / lepiej zorganizowany przez dalsze używanie kanwy zamiast posiadania dodatkowych (opartych na DOM) metod dla interfejsu użytkownika.
  • Jeśli twój interfejs użytkownika jest bardzo obciążony tekstem (z oknami dialogowymi itp.), Może być łatwiej zaimplementować za pomocą HTML / CSS. Na przykład, przepływ tekstu w elemencie DOM (z zawijaniem i odstępami akapitów) jest dość trywialny i stosunkowo trudny do wdrożenia w obszarze roboczym.
  • W zależności od używanej biblioteki, może być znacznie łatwiej zaimplementować obsługę kliknięć na elementach DOM niż w obszarze roboczym. Na przykład, jeśli chcesz wykryć kliknięcie przycisku „Ok”, to proste zadanie w świecie HTML / JS. Ale w obszarze roboczym musisz usłyszeć kliknięcie innego elementu i sprawdzić jego współrzędne, aby zobaczyć, gdzie miało miejsce kliknięcie.
  • Niektóre programy klienckie (zwłaszcza urządzenia mobilne) mogą być trudne przy użyciu elementów DOM zawierających tekst. Na przykład Mobile Safari może chcieć wyświetlić modal z narzędziami do kopiowania / wklejania. Zapobieganie takiemu zachowaniu może być trudne i prawdopodobnie łatwiejsze na lądzie.

Niektóre z nich będą subiektywne; programista, którego znam, zawsze woli używać płótna, ponieważ po prostu uważa DOM za brzydki i gadatliwy. Ponieważ każde z tych rozwiązań będzie działać dobrze, wybiorę prosty pojedynczy ekran w Twojej aplikacji, szybko opracuję go osobno, używając obu metod i zobaczę, które z nich jest łatwiejsze / lepsze.

Powodzenia!

richtaur
źródło
Dzięki za odpowiedź! Bardzo dobre punkty. Właśnie buduję teraz własny silnik. Uruchomiłem go przy użyciu Canvas, ale zamierzam go nieco zmodyfikować, aby przetestować CSS3 / WebKit. Jedynym powodem, dla którego buduję własne, jest to, że gra jest zbyt „prosta” jak na „prawdziwy” silnik. Nie mamy nawet tak naprawdę głównej pętli gry. Jedyny powód, dla którego istnieje, to animacja, ale biorąc pod uwagę, jak często się to zdarza, prawdopodobnie moglibyśmy po prostu uruchomić / zatrzymać timery w razie potrzeby :)
Jason L.
5

Używam sztalugi do interakcji z płótnem.

Jest całkiem dobry i ułatwia solidny projekt. Jedną z kluczowych cech, które skłoniły mnie do wyboru, była możliwość synchronizacji położenia twoich obiektów na płótnie i elementów dom.

Ułatwia to wykonywanie CSS mowy bąbelków i statycznych elementów interfejsu użytkownika, takich jak ramka hud i tego typu rzeczy.

Zaletą dla przeglądarek jest to, że dostajesz bogate płótno, ale możesz zastawić mniejsze i statyczne rzeczy do domu, aby utrzymać wydajność pod kontrolą.

G. Davids
źródło
4

Płótno działa powoli na platformach mobilnych, przynajmniej mobilne safari, więc będziesz chciał użyć pozycjonowania obiektów w oparciu o CSS. W szczególności użyj „translate3d”, który włączy sprzętowo przyspieszone renderowanie obiektów.

Sprawdź bibliotekę CAAT pod kątem płótna, jest szybki i możesz używać „aktorów” wspieranych przez CSS i nie zmieniać logiki gry.

Nie mogę jeszcze publikować linków, ale oto kilka pseudo linków http://labs.hyperandroid.com/animation

onedayitwillmake
źródło
Myślę, że link repo na stronie CAAT wskazuje na stary, więc upewnij się, że używasz tego! repo: github.com/hyperandroid/CAAT
onedayitwillmake
(przepraszam, mogę obecnie dodać tylko jeden link do postu) Oto demo, które stworzyłem, zawiera szablon hello-world dla CAAT - onedayitwillmake.com/CAATCirclePack
onedayitwillmake
Dzięki za linki, zdefiniuję. Sprawdź to. Słyszałem pomruki Canvas, ale jestem tym, który zwykle musi sam widzieć rzeczy :) Powinienem też zauważyć, że tworzona przeze mnie gra jest BARDZO lekka w animacjach. Nigdy więcej niż jeden lub dwa biegające jednocześnie i w odstępach raz na 5-10 sekund przez minutę na raz. Nic szalonego. Ponadto, aby zweryfikować, czy sugerujesz, aby w ogóle nie używać Canvas, ale używać zwykłych starych obiektów DOM z CSS / translate3d?
Jason L.
Szczerze mówiąc, nie mogę powiedzieć o twoim konkretnym scenariuszu, czy nie. Jednak jeśli chcesz celować w safari mobilne w sposób szczególny, to imo tak, chciałbyś użyć CSS z div. Z mojego doświadczenia wynika, że ​​jest to bardzo szybkie w porównaniu do przerysowywania płótna. Byłem w stanie łatwo uzyskać 45 duszków opartych na obrazie poruszających się z prędkością 30 klatek na sekundę, używając „translate3d”, aby przenieść je na miejsce. Pamiętaj, aby umieścić to w CSS dla obiektów, które planujesz przenieść za pomocą „transform3d”, w przeciwnym razie webkit będzie animował te obiekty tam, gdzie określono, zamiast umieszczać. -webkit-przejście: transform3d 0s liniowy;
onedayitwillmake
2

Muszę się zgodzić co do powolności płótna na iPhonie 4. Dość pewności, że GL nie popiera płótna safari. Moja tandetna gra działa szybko na iPhone 3GS i Androidzie, ale na iPhonie 4 Myślę, że wyświetlacz siatkówki ma zbyt wiele pikseli lub jeśli płótno nie jedzie na GL, to wyjaśniałoby, dlaczego się przeciąga. Podoba mi się model programistyczny canvas, jeszcze nie wypróbowałem opcji css translate3d. W szczególności użyłem GWT i owijarki brezentowej gwt-g2d (optymalizacja / zaciemnianie). http://www.photonjunky.com/shootout.html


źródło
1

Sugeruję zachowanie kontroli jako elementów HTML takich jak menui commandze względu na dostępność. Za pomocą odrobiny CSS możesz wyświetlać elementy na kanwie i nie tracić na wbudowanej funkcjonalności HTML.

zzzzBov
źródło
1

Wiem, że to stare pytanie, ale dzisiaj (marzec 2013 r.) Wiemy lepiej. Postanowiłem odpowiedzieć na wypadek, gdyby ktoś inny wpadł tutaj tak jak ja. Muszę się nie zgadzać z większością innych odpowiedzi. Są one prawdopodobnie ważne dla rozwoju przeglądarki internetowej, ale nie dla urządzeń mobilnych. To robi wielką różnicę, którą ścieżkę wybierzesz (animacja DOM lub płótno). Widok sieci Android jest całkowicie bezużyteczny (powolny, jąkający się) sam w sobie, co sprawia, że ​​Phonegap jest bezużyteczny do tworzenia gier na Androida, chyba że możesz zastosować przyspieszenie sprzętowe, które jest obecnie możliwe tylko przy użyciu animacji płótna i odpowiedniej ramy. Aby uzyskać więcej informacji, zobacz tę odpowiedź .

Na Quested Aronsson
źródło
0

Możesz to zrobić na milion sposobów. Jednak czujesz się najbardziej komfortowo, a twoi inżynierowie są najbardziej pewni siebie.

Jeśli szukasz inspiracji lub przykładowego kodu, oto jeden ze sposobów, w jaki to robię. Mam funkcję, która wielokrotnie rysuje menu, aż do naciśnięcia przycisku. Po naciśnięciu przycisku gra się ładuje, a nasłuchiwania zdarzeń kliknięcia starego menu są usuwane, a nasłuchiwania zdarzeń klikania gry dodawane. Kończę także starą pętlę losowania w menu i rozpoczynam nową pętlę losowania. Oto kilka wybranych fragmentów, które pomogą Ci zrozumieć, jak to zrobić:

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) {
  // ...
}

W ten sposób jestem w stanie oddzielić rysowanie gier i wydarzenia od rysowania menu i wydarzeń w menu. Daje mi również swobodę korzystania z elementów gry / animacji w menu, jeśli chcę, aby wyglądały naprawdę ładnie.

Simon Sarris
źródło