Wstęp
Latem 2010 roku stworzyliśmy Sand Trap, grę, do której wzięliśmy udział w konkursie o gry HTML5 na telefony komórkowe. Jednak większość telefonów komórkowych wyświetlała tylko część gry lub sprawiała, że gra była zbyt mała. Wzięliśmy więc udział w płynnym dostosowywaniu gry do dowolnej rozdzielczości. Po przeprogramowaniu i wykorzystaniu pomysłów przedstawionych w tym artykule stworzyliśmy grę, która sprawdzi się w każdej nowoczesnej przeglądarce – zarówno na komputerze, jak i na urządzeniu mobilnym.
Ta metoda sprawdziła się w przypadku Sand Trap, więc zastosowaliśmy ją w naszej najnowszej grze Thwack!. Gra automatycznie dostosowuje rozdzielczość ekranu, tak aby pasowały do pełnego ekranu i okna o niestandardowych rozmiarach, jak widać na poniższych zrzutach ekranu.
Wdrożenie tych rozwiązań wymagało użycia zarówno CSS, jak i JavaScriptu. Wypełnienie całego ekranu za pomocą CSS jest banalne, ale CSS nie umożliwia utrzymania takiego samego współczynnika szerokości do wysokości, co zapobiega rozciągnięciu obszaru roboczego i obszaru gry. Właśnie tu do akcji wkracza JavaScript. Możesz przeskalować elementy dokumentu za pomocą JavaScriptu i wywołać zmianę rozmiaru w przypadku zdarzeń okna.
Przygotowywanie strony
Pierwszym krokiem jest wyznaczenie na stronie obszaru, w którym toczy się rozgrywka. Jeśli dodasz ten blok, możesz w nim umieścić inne tagi lub element canvas. Po prawidłowym skonfigurowaniu te elementy podrzędne odziedziczą skalowanie z nadrzędnego bloku div.
Jeśli obszar gry składa się z 2 części: obszaru zabawy i strefy na bieżąco, może on wyglądać tak:
<div id="gameArea">
<canvas id="gameCanvas"></canvas>
<div id="statsPanel"></div>
</div>
Po uzyskaniu podstawowej struktury dokumentu możesz dodać tym elementom kilka właściwości CSS, aby przygotować je do zmiany rozmiaru. Wiele właściwości CSS związanych z „gameArea” jest manipulowanych bezpośrednio przez JavaScript, ale aby działały, skonfiguruj kilka innych właściwości CSS, zaczynając od nadrzędnego bloku div gameArea:
#gameArea {
position: absolute;
left: 50%;
top: 50%;
}
W ten sposób lewy górny róg obszaru roboczego zostanie umieszczony na środku ekranu. Opisana w następnej sekcji funkcja automatycznego zmiany rozmiaru JavaScriptu modyfikuje dodatkowe właściwości CSS, aby zmienić rozmiar obszaru gry i wyśrodkować go w oknie.
Rozmiar obszaru gry jest automatycznie zmieniany zgodnie z wymiarami okna, więc wymiary elementów podrzędnych bloku div gameArea nie powinny być wyrażone w pikselach. Zależy Ci na wyrażonej w procentach wartościach procentowych. Wartości pikseli nie pozwalają na skalowanie elementów wewnętrznych wraz z nadrzędnym elementem div po zmianie. Warto jednak zacząć od pikseli, a potem przekonwertować je na wartości procentowe, gdy już uzyskasz układ, który Ci odpowiada.
W tym przykładzie obszar gry ma 300 pikseli wysokości i 400 pikseli szerokości. Obszar roboczy zajmuje cały obszar gry, a półprzezroczysty panel ze statystykami biegnie wzdłuż dolnej krawędzi i ma wysokość 24 pikseli, jak widać na Rysunku 1.
Przełożenie tych wartości na wartości procentowe sprawia, że obszar roboczy ma 100% szerokości i 100% wysokości (obszaru gameArea, a nie okna). Po podzieleniu 24 przez 300 panel statystyk będzie miał wysokość 8%. Ponieważ zakryje on dolną część obszaru gry, będzie on mieć 100%, jak widać na Rysunku 2.
Po określeniu wymiarów obszaru gry i jego elementów podrzędnych możesz przygotować właściwości CSS obu elementów wewnętrznych w ten sposób:
#gameCanvas {
width: 100%;
height: 100%;
}
#statsPanel {
position: absolute;
width: 100%;
height: 8%;
bottom: 0;
opacity: 0.8;
}
Zmiana rozmiaru gry
Teraz możesz utworzyć funkcję do obsługi zmiany rozmiaru okna. Najpierw pobierz odniesienie do nadrzędnego elementu dokumentu gameArea.
var gameArea = document.getElementById('gameArea');
Nie zależy Ci na dokładnej szerokości ani wysokości, więc kolejną informację, jaką musisz podać, jest stosunek szerokości do wysokości. Jak już wspominaliśmy o obszarze gry o szerokości 400 pikseli i wysokości 300 pikseli, wiesz, że zamierzasz ustawić współczynnik proporcji na 4 jednostki szerokości i 3 jednostki wysokości.
var widthToHeight = 4 / 3;
Ponieważ funkcja ta jest wywoływana przy każdym zmianie rozmiaru okna, trzeba też zadbać o nowe wymiary okna, aby dopasować do niego wymiary gry. Aby go znaleźć, użyj właściwości innerWidth i innerHeight okna.
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
Tak jak w przypadku danego współczynnika szerokości do wysokości, możesz teraz określić bieżący stosunek szerokości do wysokości okna:
var newWidthToHeight = newWidth / newHeight;
Pozwala to określić, czy gra ma wypełnić ekran w pionie czy w poziomie, tak jak pokazano na Rysunku 3.
Jeśli wybrany kształt obszaru gry jest szerszy niż okno (a wysokość jest krótsza), musisz wypełnić okno w poziomie i zostawić marginesy u góry i dołu. Jeśli wybrany kształt obszaru gry jest większy niż kształt okna (a szerokość jest węższa), musisz wypełnić okno w pionie i pozostawić marginesy po lewej i prawej stronie.
Aby to zrobić, przetestuj odpowiedni współczynnik szerokości do wysokości z uwzględnieniem stosunku szerokości do wysokości bieżącego okna i wprowadź odpowiednie zmiany w ten sposób:
if (newWidthToHeight > widthToHeight) {
// window width is too wide relative to desired game width
newWidth = newHeight * widthToHeight;
gameArea.style.height = newHeight + 'px';
gameArea.style.width = newWidth + 'px';
} else { // window height is too high relative to desired game height
newHeight = newWidth / widthToHeight;
gameArea.style.width = newWidth + 'px';
gameArea.style.height = newHeight + 'px';
}
Po dostosowaniu szerokości i wysokości obszaru gry musisz wyśrodkować elementy, umieszczając ujemny margines u góry, czyli u góry o połowę wysokości, a po lewej – do połowy szerokości. Pamiętaj, że CSS już umieszcza lewy górny róg elementu div gameArea dokładnie pośrodku okna, dlatego obszar gry jest wyśrodkowany na oknie:
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
Warto też automatycznie dostosować rozmiar czcionki. Jeśli masz wszystkie elementy podrzędne korzystające z takich elementów, możesz po prostu ustawić wartość właściwości CSS fontSize bloku div gameArea na wartość określoną przez jego rozmiar.
gameArea.style.fontSize = (newWidth / 400) + 'em';
Na koniec chcesz, aby wymiary rysunków na płótnie były zgodne z jej nową szerokością i wysokością. Pamiętaj, że reszta kodu gry musi oddzielić wymiary silnika gry od wymiarów obszaru roboczego, aby uzyskać zgodność z dynamiczną rozdzielczością obszaru roboczego.
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
Ukończona funkcja zmiany rozmiaru może więc wyglądać tak:
function resizeGame() {
var gameArea = document.getElementById('gameArea');
var widthToHeight = 4 / 3;
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
var newWidthToHeight = newWidth / newHeight;
if (newWidthToHeight > widthToHeight) {
newWidth = newHeight * widthToHeight;
gameArea.style.height = newHeight + 'px';
gameArea.style.width = newWidth + 'px';
} else {
newHeight = newWidth / widthToHeight;
gameArea.style.width = newWidth + 'px';
gameArea.style.height = newHeight + 'px';
}
gameArea.style.marginTop = (-newHeight / 2) + 'px';
gameArea.style.marginLeft = (-newWidth / 2) + 'px';
var gameCanvas = document.getElementById('gameCanvas');
gameCanvas.width = newWidth;
gameCanvas.height = newHeight;
}
Teraz chcesz, aby te korekty były wykonywane automatycznie po każdej zmianie rozmiaru okna lub, w przypadku urządzeń mobilnych, zmianie orientacji ekranu. Aby zareagować na te zdarzenia, wywołaj funkcję changeGame() w ten sposób:
window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);
Jeśli rozmiar okna jest zbyt duży lub orientacja ekranu jest pionowa, ustawiasz szerokość 100% okna, a jeśli rozmiar okna jest za szeroki lub orientacja ekranu jest pozioma, wysokość okna jest ustawiana na 100%. Rozmiar pozostałego wymiaru jest dopasowywany zgodnie z wcześniej określonym współczynnikiem proporcji szerokości do wysokości.
Podsumowanie
Studio Gopherwood Studios używa tej struktury we wszystkich naszych grach w formacie HTML5. Okazało się, że jest on bardzo przydatny w obsłudze różnych rozdzielczości ekranu i urządzeń mobilnych. Co więcej, dzięki przeglądarce pełnoekranowej nasze gry internetowe są bardziej wciągające niż w wielu innych grach na komputery. Czekamy na kolejne innowacje w grach internetowych, ponieważ HTML5 i technologie internetowe wciąż ewoluują.