2015-03-22 13 views
6

GUI elements example imageograniczające proporcje elementów GUI w Spritekit gry

góry przepraszam z powodu ogromnego postu, ale wszyscy, którzy kiedykolwiek próbowali jakąś uniwersalną aplikacją wie, że jest to dość problematyczne rzeczy, więc proszę być łatwo na me ...

celem

Co staram się osiągnąć (pokazany na powyższym zdjęciu) jest użycie @ 2x aktywów zarówno iPhone 5 i 6, i utrzymać ten sam wygląd aplikacji. I jeśli to możliwe, aby to zrobić bez ręcznego obliczania właściwości skali i położenia węzłów na podstawie wykrytego urządzenia ... Krótko mówiąc, w jaki sposób osiągnąć tę aplikację automatycznie ograniczać proporcje elementów (i sceny)? Chciałbym mieć taki sam wygląd aplikacji na iPhone 6+ przy użyciu zasobów @ 3x, ale ze względu na prostotę skoncentrowałem się tylko na iPhonie 5 i 6.

Co znalazłem w sieci to, że niektórzy ludzie mówiąc, że to (próbkowanie) odbywa się automatycznie przez iOS, na przykład sugerują to:

„Make @ 2x aktywów w rozmiarze dla iPhone 6, a następnie iOS zrobi downscaling automatycznie dla iPhone 5”.

Ale to oczywiście nie jest prawda, jeśli chodzi o scenę Spritekit, lub czegoś brakuje.

Problem

Chociaż iPhone 6 i iPhone 5 ma ten sam format i tę samą PPI, przy użyciu tego samego zasobu nie będą wyglądać tak samo w stosunku do wielkości sceny (menu wygląd ikonki na 1 i 2 obraz w porównaniu z rozmiarem sceny), ponieważ PPI są powiązane z gęstością pikseli, a iPhone 6 ma więcej miejsca (większa przekątna, więcej cali), co oznacza, że ​​ma więcej pikseli niż iPhone 5. I tu właśnie pojawia się mój problem, a ja nie wiem, Wiesz, jaki byłby skuteczny sposób radzenia sobie z tym.

co zrobiłem do tej pory

Drugi obraz nie jest problemem dla GUI, ale na gry, w moim przypadku jest to, bo chcę sam wygląd i na różnych urządzeniach. Wystarczy spojrzeć na pierwszy i trzeci obraz.

Dzięki sugestii udało mi się uzyskać taki sam wygląd aplikacji na wszystkich urządzeniach iPhone 5 w systemach 7.1 lub 8.1, a także na iPhonie 6. Problem polega więc na tym, jak dostosować ten kod do działa z iPhone 6+ przy użyciu tekstur @ 3x, a także na iPhone'ach 4s. Oto rozwiązanie dla iPhone 5 i 6:

Zobacz controller.m

GameScene *scene = [GameScene sceneWithSize:CGSizeMake(375,677)];//fixed instead of view.bounds.size 
scene.scaleMode = SKSceneScaleModeAspectFill; 

Więc scena zawsze stałym rozmiarze w iPhone 6 wymiarów i rozmiar zmienia się w zależności od urządzenia. Korzystam z katalogu zasobów dla obrazów uruchamiania, a nie z pliku xib. Zdjęcia mają rozmiar zalecany - 640x960px dla 4s, 640x1136px dla 5, 750x1334px dla 6 i 1242x2208 dla modelu 6+. Zasoby mają rozmiar dla iPhone'a 6, więc dla tego modelu nie ma żadnego skalowania.

Powiązany z modelem 4s, kiedy używam tej metody opisanej powyżej, są dwa czarne paski z każdej strony ...

Do tej pory testowałem to tylko na symulatorze i urządzeniu iPhone 6 (to, co widzę wygląda jak na pierwszym obrazie na urządzeniu lub symulatorze).

Pytanie

Na razie, jak powiedziałem, wszystko działa na iPhone 4s (z dwoma czarnymi pasami z powodu różnych proporcjach), 5, 6, stosując @ 2x aktywów, ale jak zrobić wszystko, aby pracować z iPhone 6 + używając zasobów @ 3x? Jeśli używam 375x667 wymiary na scenie, to wszystko jest ustawione prawidłowo i ma dobre proporcje, ale jakość cierpi (ze względu na skalowanie @ 2x)

+0

Czy kiedykolwiek próbowałeś skalować węzeł na podstawie urządzenia, kiedy go po raz pierwszy dodajesz? Każda kolejna animacja (zmiany tekstury) będzie miała ustawiony wstępnie ustawiony współczynnik skali. – sangony

+0

Pewnie, i tego właśnie staram się unikać, jeśli to możliwe, ale z pewnością jest to jedna z możliwości poradzenia sobie z tym. Po prostu znajduję łatwiejsze/automatyczne rozwiązanie, które pozwoli mi zaoszczędzić wiele obliczeń/ręczne ustawienie właściwości skali na podstawie urządzenia itp. – Whirlwind

+0

Czy w ogóle skalujesz swoją scenę, czy też scena i widok mają takie same rozmiary (np. Brak skalowania). –

Odpowiedz

4

Uniform GUI i Game Play

O ile mogę powiedz najlepszy sposób na obsługę jednolitego GUI, a gra jest ustawianie rozmiaru sceny (niezależnie od urządzenia) i wypuszczanie skala SpriteKit.

GameScene *scene = [GameScene sceneWithSize:CGSizeMake(375,677)];//fixed instead of view.bounds.size 
scene.scaleMode = SKSceneScaleModeAspectFill; 

To punkty dla iPhone 6. Ponieważ SpriteKit pracuje w punktach ale urządzenia wyświetlane w pikselach rozmiar scena będzie 750px x 1354px pikseli dla @ 2x urządzeń i 1125px x 2031px dla iPhone 6+ (the urządzenie w pikselach to rzeczywiste 1080 x 1920).

Jak to działa z aktywami?

Dobrze działa dość dobrze dla 1x i 2x zasobów w folderze .atlas. Ponownie, ponieważ wszystko jest konwertowane na punkty, możesz mieć przycisk.png i [email protected] w atlasie tekstury, a pozycjonowanie będzie takie samo i będzie wyglądało tak samo dla wszystkich iPhone'ów.

Co z @ 3x?

To jest lepsze pytanie dla Apple. Wygląda na to, że SpriteKit nie obsługuje obrazów @ 3x w atlasie tekstur. Jest już kilka pytań na temat SO, które próbowały rozwiązać ten problem.

Jednym z przykładów ...

Spritekit - not loading @3x images from SKTextureAtlas

Wydaje się, że nie została ustalona w Xcode 6.2 albo. Jeśli czytasz to i chcesz @ 3x, warto złożyć radar z Apple. Należy zauważyć, że nigdzie nie widziałem w dokumentach, które twierdzą, że atlasy tekstur mają wspierać @ 3x (lub nawet 2x), gdy są one wspierane, nie będziesz musiał wprowadzać żadnych zmian w kodzie . Wystarczy rzucić zasoby @ 3x do folderów .atlas.

Co mogę/powinienem zrobić z zasobami @ 3x?

Moja rada to nie przejmować się tym i uruchamiać 2x aktywów. SpriteKit wykonuje przyzwoite skalowanie obrazów i istnieje wiele aplikacji, które nie obsługują @ 3x. Jako właściciel iPhone'a 6+ jest to coś, z czym w tej chwili nauczyłem się żyć. Mam nadzieję, że Apple wkrótce obsługuje obrazy @ 3x w folderze .atlas.

Ostrzeżenia

Pytasz wszystkie urządzenia do skalowania w dół z wyjątkiem iPhone 6 (i zwiększenia iPhone 6+), w większości przypadków nie należy zauważyć dużą różnicę w swojej dziedzinie (lub wydajność z moich testów), ale jak wiesz, jeśli zmniejszasz obrazy, mogą wyglądać nieco inaczej. Jest także kwestia czarnego paska na 4s, której nie mam w tej chwili dla ciebie rozwiązania.

Zamykanie Punkty

Dostaniesz dokładnie taki sam wygląd w swojej aplikacji na wszystkich urządzeniach, jeśli ustawić wielkość sceny i ustawić scenę SKSceneScaleModeAspectFill jednak prosicie starszych urządzeń do skalowania w dół. Oszczędza to mnóstwo czasu i planowanie z drobnymi rewersami, o ile widzę.

Mam nadzieję, że pomoc i szczęście w Twojej aplikacji.

+0

Dzięki za odpowiedź Skyler, tak teraz wydaje się, że coś jest nie tak z symulatorem iPhone'a 6+, jeśli chodzi o użycie atlasów. Prawda jest taka, że ​​różnice nie są tak widoczne w przypadku zasobów @ 2x, ale byłoby lepiej, gdyby zostało to naprawione, ponieważ w przypadku skalowania wysokiej jakości obrazu bitmapowego mogą wystąpić artefakty. Próbowałem rozwiązań z tych linków i wielu innych, ale nawet przy użyciu Texturepackera, który właściwie generuje atlasy lub wybierając właściwy atlas w oparciu o współczynnik skali ekranu, wydaje się, że symulator iPhone'a 6+ lubi tylko obrazy x2. – Whirlwind

+0

Aby uniknąć artefaktów podczas skalowania, planuję użyć wektora generowania dynamicznych obrazów. Najpierw tworzę obrazy przy pomocy PaintCode. Następnie odpowiedni kod jest eksportowany, aby wygenerować widok dostosowany do potrzeb. W końcu z tego widoku tworzony jest plik PNG, a następnie wykorzystywany w teksturach. – Domsware

+0

W rzeczywistości ostatnia wersja programu PaintCode 2.3.2 już przynosi fazę generowania! – Domsware

5

Wygląda na to, że głównymi problemami są obsługa różnych rozmiarów ekranu w odniesieniu do zasobów obrazu i współrzędnych obiektu ekranu.

Moim rozwiązaniem jest napisanie kodu tak, jakbyś kodował iPhone'a 6 plus. Zrób wszystkie zdjęcia o rozmiarze 3x i współrzędne ekranu ekranu dla ekranu iPhone'a 6.

Przy odrobinie kodu udało mi się uzyskać jednolity układ dla iPhone'a 6 plus, 6, 5 i 4 rozmiarów ekranu. Załączam zrzuty ekranu dla każdego z nich. Obraz postaci ma wymiary 300 x 300. Zdjęcia z 2 przyciskami mają rozmiar 100x100.

static const float kIphone6PlusScaleFactorX = 1.0; 
static const float kIphone6PlusScaleFactorY = 1.0; 
static const float kIphone6ScaleFactorX = 0.9; 
static const float kIphone6ScaleFactorY = 0.9; 
static const float kIphone5ScaleFactorX = 0.772; 
static const float kIphone5ScaleFactorY = 0.772; 
static const float kIphone4ScaleFactorX = 0.772; 
static const float kIphone4ScaleFactorY = 0.652; 

#import "GameScene.h" 

@implementation GameScene { 
    float scaleFactorX; 
    float scaleFactorY; 

    SKSpriteNode *node0; 
    SKSpriteNode *node1; 
    SKSpriteNode *node2; 
    SKLabelNode *label0; 
} 

-(void)didMoveToView:(SKView *)view { 
self.backgroundColor = [SKColor blackColor]; 

    if(view.frame.size.height == 736) { 
     NSLog(@"iPhone 6 plus"); 
     scaleFactorX = kIphone6PlusScaleFactorX; 
     scaleFactorY = kIphone6PlusScaleFactorY; 
    } 
    if(view.frame.size.height == 667) { 
     NSLog(@"iPhone 6"); 
     scaleFactorX = kIphone6ScaleFactorX; 
     scaleFactorY = kIphone6ScaleFactorY; 
    } 
    if(view.frame.size.height == 568) { 
     NSLog(@"iPhone 5"); 
     scaleFactorX = kIphone5ScaleFactorX; 
     scaleFactorY = kIphone5ScaleFactorY; 
    } 
    if(view.frame.size.height == 480) { 
     NSLog(@"iPhone 4"); 
     scaleFactorX = kIphone4ScaleFactorX; 
     scaleFactorY = kIphone4ScaleFactorY; 
    } 

    node0 = [SKSpriteNode spriteNodeWithImageNamed:@"Pic"]; 
    node0.position = CGPointMake(self.size.width/2, self.size.height/2); 
    [node0 setScale:scaleFactorX]; 
    [self addChild:node0]; 

    node1 = [SKSpriteNode spriteNodeWithImageNamed:@"button0"]; 
    node1.position = CGPointMake(100*scaleFactorX, 100*scaleFactorY); 
    [node1 setScale:scaleFactorX]; 
    [self addChild:node1]; 

    node2 = [SKSpriteNode spriteNodeWithImageNamed:@"button1"]; 
    node2.position = CGPointMake(314*scaleFactorX, 100*scaleFactorY); 
    [node2 setScale:scaleFactorX]; 
    [self addChild:node2]; 

    label0 = [SKLabelNode labelNodeWithFontNamed:@"HelveticaNeue-Bold"]; 
    label0.text = @"Big Game Menu"; 
    label0.fontSize = 48*scaleFactorX; 
    label0.fontColor = [SKColor whiteColor]; 
    label0.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; 
    label0.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter; 
    label0.position = CGPointMake(207*scaleFactorX,690*scaleFactorY); 
    [self addChild:label0]; 
} 

iPhone 4

enter image description here

iPhone 5

enter image description here

iPhone 6

enter image description here

iPhone 6+

enter image description here

Wskazówki jak nawet etykieta tekst jest skalowana w dół poprawnie nie tylko ze względu na rozmiar czcionki, ale także lokalizacji.

Dla twojego odniesienia, użyłem standardowego kodu w moim GameViewController, ponieważ łatwiej jest pracować z prostszą wersją. To jest kod, którego użyłem do przedstawienia mojego SKView:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    SKView * skView = (SKView *)self.view; 
    SKScene *scene = [GameScene sceneWithSize:skView.bounds.size]; 
    scene.scaleMode = SKSceneScaleModeAspectFill; 
    [skView presentScene:scene]; 
} 
+1

Przyjemne rozwiązanie. Jedynym problemem jest to, że musisz używać scaleFactorX i scaleFactorY dla każdej pozycji. Myślisz, że kategoria uczyniłaby to jeszcze łatwiejszym? –

+0

@Sangony Czy chcesz utworzyć wszystkie obrazy z przyrostkiem 3x? Lub po prostu zrobić je w rozmiarach 3x obrazów i używać standardowego nazewnictwa jak na 1x? Podoba mi się rozwiązanie, ponieważ wydaje się, że pozycjonowanie i skalowanie odbywa się prawidłowo, a nawet na 4s wszystko wygląda tak, jak powinno (brak czarnych pasków). Jedyną wadą jest zużycie pamięci ze względu na 3-krotne zasoby i trochę więcej kodowania, ale przetestuję to również, by zobaczyć wyniki. – Whirlwind

+0

@Whirlwind - Brak przyrostka obrazu 3x. Po prostu utwórz wszystkie rozmiary obrazów, tak jakby były przeznaczone do 3x. Skalowanie kodu zajmuje się resztą bez zauważalnej utraty rozdzielczości. Pozwala to również na użycie atlasu tekstury przy użyciu tej metody. – sangony