Skocz do zawartości

Witaj!

Zaloguj lub Zarejestruj się aby uzyskać pełny dostęp do forum.

Zdjęcie
- - - - -

Wiele przycisków czy wykrywanie tapnięcia na jednym obrazku?


  • Zaloguj się, aby dodać odpowiedź
7 odpowiedzi w tym temacie

#1 sebastiankamut

sebastiankamut
  • 57 postów

Napisano 15 października 2011 - 21:15

Witam, od pewnego czasu myślę nad aplikacją i staję przed pewnym dylematem. Mam to być coś na zasadzie wskazywania elementów. Powiedzmy mam obrazek twarzy i chcę rozpoznawać co użytkownik dotknął (czy są oczy czy nos itp.), w przypadku twarzy jest mała liczba elementów więc stworzenie np. 10 przycisków i ich odpowiednie ustawienie nie będzie problemem, ale co gdy elementów jest bardzo dużo. Jak do tego podejść? Czy lepiej się bawić w tworzenie każdego elementu oddzielnie (nieregularne kształty przycisku to jedno) i wykrywanie później który został naciśnięty czy wykrywanie współrzędnych dotknięcia na obrazku (o ile się w ogóle da coś takiego zrobić) i na podstawie tych współrzędnych dopasowywać je do elementu?

#2 ishadow

ishadow
  • 288 postów

Napisano 15 października 2011 - 21:41

o ile się w ogóle da coś takiego zrobić
Pamiętaj, że w iOS masz bezpośredni dostęp do OpenGL ES i w każdej chwili możesz sprawdzić stan eventów dotykowych. Zatem możesz zrobić cokolwiek tylko chcesz i na co pozwoli hardware. Od strony software'u nie ma ograniczeń.

Problem można rozwiązać na wiele sposobów. Jeśli obrazy mają być statyczne, to można wygenerować drugi obrazek jako maskę tj. każdemu pikselowi przypisać kolor odpowiadający pewnemu działaniu. Przykładowo oczy będą na masce zamalowane na czerwono (#ff0000), a nos na zielono (#00ff00). Gdy użytkownik dotknie ekranu, to dostaniemy eventa, który przekaże nam współrzędne, potem wystarczy znaleźć odpowiadający im piksel maski.
Metoda o tyle dobra, że maski można generować wewnątrz programu za pomocą jakiegoś algorytmu lub nawet przygotować je wcześniej w programie graficznym, a kod odpowiedzialny za wykrywanie dotknięć nie będzie ulegał żadnym zmianom.

Drugi sposób, to dzielimy obraz na warstwy tak jak to robią programy graficzne, a każda warstwa jest np. samoświadomym obiektem, który oczekuje na dotyk i przekazuje dalej delegat, że została wywołana. Oczywiście musimy zadbać o wykrywanie dotyku "per pixel" na warstwach. Do tego możemy dodać wczytywanie plików bezpośrednio z PSD, z którego będziemy pobierać informacje o poszczególnych warstwach. Zatem również tym sposobem da radę tworzyć obrazki, wraz z interaktywnymi elementami bezpośrednio w programie graficznym.

Oczywiście są jeszcze inne sposoby, ale to wszystko zależy od konkretnego zastosowania, bo zależnie od tego, czy będą tylko obrazki wrzucone w trakcie tworzenia programu, czy może program będzie również przetwarzał grafikę użytkownika problem rozwiążę się trochę inaczej. Pierwszy sposób jest bardzo dobry do statycznych obrazów, drugi zaś pozwala w łatwy sposób dodać animacje na warstwach, ale korzystanie z warstw będzie wymagało więcej mocy obliczeniowej.

#3 sebastiankamut

sebastiankamut
  • 57 postów

Napisano 15 października 2011 - 22:26

Kwestia tego, że to może być spory obrazek który będzie powiększany/pomniejszany w zależności od potrzeb. Myślałem o ScrollView, tam umieścić obrazek / buttony i dopiero wtedy wykrywać. Tylko jeżeli to będzie x buttonów to czy zapanuję nad przesunięciami w ScrollView. Gdzieś czytałem, że można wykrywać współrzędne zdarzenia na obrazku chociaż podzielenie obrazka na poszczególne elementy i ich rozstawienie wydaje mi się jakoś intuicyjnie lepsze, ale czy kontrolowanie tych współrzędnych będzie do uzyskania to już inna sprawa. PS Drugi sposób wydaje się bardzo ciekawe, ale pierwszy raz słyszę, że można wczytywać PSD i pobierać info o warstwach - możesz podać link do jakiś konkretniejszych informacji jak to robić bo brzmi bardzo ciekawie. Dzięki

#4 ishadow

ishadow
  • 288 postów

Napisano 16 października 2011 - 18:42

Kwestia tego, że to może być spory obrazek który będzie powiększany/pomniejszany w zależności od potrzeb.

Zależy jak zorganizujemy kod. Ja kiedyś pisałem klasę która wyświetla teksturę i eventy dotykowe konwertuje na współrzędne jej tekseli, co umożliwia m.in. zmianę koloru wskazanego elementu. Obroty, skalowania i przesunięcia miałem za darmo, bo klasa dziedziczy z CCNode przy wykorzystaniu Cocos2D, a tam jest hierarchia obiektów i każdy obiekt ma lokalny układ współrzędnych, na które można konwertować współrzędne UITouch.

pierwszy raz słyszę, że można wczytywać PSD i pobierać info o warstwach

Specyfikacja PSD jest ogólnie znana. Są otwarte biblioteki parsujące ten format. Są też programy konwertujące go do xml'a, więc jest wiele sposobów, żeby w miarę bezboleśnie zintegrować go w aplikacji. Do tego potrzeba tylko podstawowych funkcji PSD, tj. odczytania poszczególnych warstw zapisanych jako bitmapa z kanałem alfa. Właściwie to dowolny format graficzny z warstwami da radę, nie trzeba koniecznie korzystać z PSD. W ostateczności można napisać skrypt, który konwertuje warstwy PSD do PNG i tworzy plik XML z informacjami o nich. Wczytanie czegoś takiego nie byłoby już trudne, gdyż do XML mamy wiele różnych bibliotek, a standardowy UIImage radzi sobie doskonale z PNG.

Co więcej można wykorzystać nazwy warstw, aby program na ich podstawie wykonywał określone czynności. Powiedzmy aktywując warstwę na obrazie, klasa nią zarządzająca wysyła delegata do jakiejś nadrzędnej klasy z nazwą warstwy. Przykładowo jeśli warstwa nazywała się "Next", to program wczyta kolejny obrazek itd.

#5 pio11

pio11
  • 1 700 postów

Napisano 16 października 2011 - 21:31

jeśli to ma być duży wciąż skalowany obraz polecam zrobić to co mówił iShadow. Masz dwa obrazki: ten który widać i ukrytą warstwę na której będziesz sprawdzał współrzędne. Po dotknięciu sprawdzasz, który piksel dotknąłeś na oryginalnym obrazku, następnie sprawdzasz jaki kolor masz na ukrytej warstwie. Kolor będzie odpowiadał akcji jaka ma być wykonana po dotknięciu. Jeśli nie będzie więcej niż 128 akcji polecam skalę szarości. Zajmuje mniej pamięci i powinno wystarczyć. Mniej zasobożernym sposobem jest zaznaczenie kształtem wybranych miejsc a potem sprawdzanie czy w danym miejscu zawierają się współrzędne dotyku.

#6 sebastiankamut

sebastiankamut
  • 57 postów

Napisano 17 października 2011 - 08:57

Faktycznie pomysł z ukrytą warstwą wydaje się być najlepszym pomysłem. Jednak jeszcze kwestia samego podświetlenia obszaru, bo w ramach testów chcę zrobić mapę (powiedzmy europy) z samych obrysów i wskazywać poszczególne państwa (po kliknięciu obszaru państwa powinna się pojawiać nazwa państwa). Myślałem żeby używać MapKit, ale nie wiem czy jest sens się w tym męczyć czy lepiej zrobić obrazek i tak jak radziliście ukrytą warstawę. Bo nie wiem czy MapKit da radę powiększać/pomniejszać i rozpoznawać które państwo się kliknęło (nie chcę żeby była widoczna jego nazwa tylko sam obrys) no i działanie offline.

#7 sebastiankamut

sebastiankamut
  • 57 postów

Napisano 17 października 2011 - 19:21

Udały się pierwsze testy, faktycznie pomysł z ukrytą warstwą jest odpowiedni, sprawdzi się świetnie. Jednak mam jeszcze jedną zagwozdkę odnośnie tego, chciałbym mieć podświetlane elementy które zaznaczę, czyli np. dotknę palcem oczu to chciałbym żeby się one podświetliły albo migały (będzie odpowiedni komunikat czy chcesz zaznaczyć daną część ciała), czy wykrywać pixel po pixelu dany kolor i potem z tego robić obrazek czy podświetlenie? To chyba trochę będzie obciążało sprzęt, macie jakiś pomysł na łatwiejszy sposób?

#8 pio11

pio11
  • 1 700 postów

Napisano 18 października 2011 - 01:07

Porozmieszczać obrazki "podświetlone" po całej mapie, nadać im alpha = 0 i po wywołaniu metody ustawić alpha = 1 :P. Chyba najprościej.




Użytkownicy przeglądający ten temat: 1

0 użytkowników, 1 gości, 0 anonimowych