2010-07-21 11 views
5

Jako mój pierwszy projekt WPF staram się zbudować aplikację do gry w karty podobną do Magic the Gathering. Nie jest dla mnie jasne, jak rozłożyć główny obszar gry. Możesz zobaczyć kilka przykładów, które są podobne do tego, co próbuję, patrząc na example 1 lub example 2. Obszary czatu/informacji po prawej stronie będą osobnymi kontrolkami użytkownika.Układ WPF dla złożonej gry karcianej

Karty muszą zachowywać proporcje, a każdy obszar gry powinien zaczynać się od 10 kolumn i dwóch rzędów kart. W miarę rozgrywania większej liczby kart liczba kolumn i/lub rzędów może się zmienić. Każdy obszar gracza może mieć inną liczbę kolumn i/lub rzędów. Karty mogą się nakładać i mogą być umieszczane na boki (stukane). Karty we wszystkich obszarach powinny mieć ten sam rozmiar (chociaż mogą być przycięte w niektórych obszarach). Karty nie muszą leżeć dokładnie na siatce (niekoniecznie przyciągają do siatki).

Gdy użytkownik najedzie myszą na kartę, powinien rozwinąć się do znacznie większego rozmiaru za pomocą animacji. Karta w obszarze jednego gracza może ulec rozszerzeniu na obszar innego gracza (ale tylko tak długo, jak wisi myszka).

Biorąc pod uwagę te wymagania, mam pokusę, aby użyć jednej dużej kontroli użytkownika uzyskanej z płótna z obiektami obrazu dla każdej karty (wraz z innymi kształtami, aby nakreślić obszary). Oznacza to, że wykonam dużo pracy podczas zdarzenia OnRenderSizeChanged, aby umieścić elementy potomne w obszarze roboczym (układ ręczny).

Używanie siatki nie wydaje mi się możliwe ze względu na swobodne umieszczanie i nakładanie się.

Dekompozycja obszaru gry na mniejsze elementy sterowania użytkownika wykorzystałaby możliwości układu WPF, ale wydaje się, że dekompozycja uniemożliwiłaby rozszerzenie kart do sąsiednich kontrolek użytkownika podczas przesuwania kursora myszy, więc nie wydaje się to możliwe.

Czy istnieje lepsza alternatywa dla jednego dużego kontrolera opartego na płótnie? Wydaje się niewłaściwe robienie ręcznego układu w WPF, ale nie widzę alternatywy.

Odpowiedz

0

Polecam spojrzeć na this guys project. W języku Java wiem, ale gdybym miał iść na drogę budowania gry karcianej. To byłby to, na co miałbym ochotę.

+0

Dzięki za link, ale forge jest napisany w Javie i jest bardziej skupiony na uzyskaniu sztucznej inteligencji (AI) do gry (o wiele trudniejszy problem). Moim celem jest umożliwienie dwóm osobom gry przez połączenie internetowe. Istnieje podobny projekt oparty na WPF (http://moxdev.wordpress.com/), w którym powstał pomysł rozszerzenia karty. Używa też płótna (jak sądzę), ale nadal wydaje się nieco niewłaściwe nadużywanie płótna w ten sposób. – Doug

0

Wiele płócien w siatce może ci w tym pomóc, płótno pozwoli na renderowanie zawartości poza jej granice, o ile zmienisz ClipToBounds na false, a otrzymasz większą kontrolę nad dokładnym umieszczeniem kart niż w przypadku innych schematów. Otrzymasz także potężną funkcjonalność kontrolki siatki, co pozwoli Ci dodawać i usuwać kolumny i wiersze w razie potrzeby (choć będziesz musiał również dynamicznie dodawać i usuwać płótna, ale nie jest to zbyt trudne

Jeśli "martwisz się zawartością swojej" karty "poruszającej się po przeskalowaniu skrzyni, otoczy ją w okienku widokowym, będzie ona zarządzała wszystkimi twoimi skalami i zapewni, że twoja karta zużywa tyle nieruchomości, ile może dostać. może użyć RenderTransform, ale wiele z nich może spowolnić twój program (Eksperci: czy widok działa za pomocą RenderTransforms? Jeśli tak, to jest dyskusyjny)

Aby upewnić się, że karty zachowują swój współczynnik proporcji, upewnij się, że każdy z nich ma atrybut Rozciągnięcie obrazu jest ustawione na "Jednolite", dzięki czemu wszystkie są zachowywane taki sam rozmiar można by zrobić, wyznaczając kartę główną i wiążąc wysokości i szerokości wszystkich kolejnych kart do tej oryginalnej karty, chociaż jest to nieco zbędne i nie pozwala na rozwinięcie kart. Innym rozwiązaniem jest ręczne ustawienie pojedynczego rozmiaru dla każdej karty, animowanie tego, gdy chcesz powiększyć lub zmniejszyć.

+0

Jeśli używa formatu RenderTransform, treść może być renderowana poza jego granicami, bez potrzeby ustawiania innych właściwości. Poza tym powinien raczej używać ItemsControls zamiast dynamicznych płócien, ponieważ mógłby wtedy użyć silnika wiążącego i związać się z kolekcjami, zamiast stale aktualizować i tworzyć nowe płótna w kodzie. – Charlie

+0

Dobry pomysł, ale nadal będzie musiał użyć kanwy do dokładnego rozmieszczenia przedmiotów, tłumaczenie ich z punktów stałych może być zbyt skomplikowane. Chociaż płótna mogą być tworzone jako część ItemsTemplate dla kontroli nadrzędnej. –

2

To brzmi jak świetny scenariusz dla aplikacji złożonych ala Prism.Zapewnia solidne ramy dla wdrażania regionów, modułów, wysyłania wiadomości między modułami itp. Od patrzenia na zrzuty ekranu, tworzenie powłoki z różnymi regionami i wrzucanie do nich modułów prawdopodobnie przyniosłoby wiele korzyści Twojemu układowi. Co do samych kart, być może one również mogą być modułami?

Check out: http://msdn.microsoft.com/en-us/library/ff649780.aspx

Particualy dobre przykłady pochodzą z pobranego pakietu zawierającego giełdzie jak i aplikacji agregatora zdarzenie np.

+0

Nie jestem pewien, czy posiadanie kart jako modułów byłoby bardzo wydajne, ale poza tym Prism bardzo by pomógł. –

+0

Spojrzałem trochę na pryzmat i przyznaję, że trochę się zgubiłem. Nie jest dla mnie jasne, w jaki sposób mogłoby to pomóc, ponieważ koordynacja rozmiarów kart między regionami wydaje się trudna, gdy okno zmienia rozmiar. Posiadanie karty, która przepełnia swój region i nakłada się na inny region podczas ekspansji myszką, również wydaje się trudne. – Doug

+0

Może to być przydatne, ale prawdopodobnie po prostu doda niepotrzebną złożoność do problemu, który jest w stanie obsłużyć samodzielnie. – Charlie

2

Mówiłeś:

Dekomponowanie plac zabaw na mniejsze kontroli użytkownik może wykorzystać możliwości układu WPF, ale wydaje się, że rozkład by zapobiec ekspansji na sąsiednie kontroli użytkownika podczas myszą karty, więc to też nie wydaje się wykonalne.

Ale to nie jest poprawne. Decomposition jest absolutnie właściwym podejściem do podjęcia, a to nie przeszkodzi, by karty rozszerzyły się na sąsiednie kontrole użytkowników. Powodem jest to, że możesz użyć numeru RenderTransform zamiast LayoutTransform. Zobacz this example autorstwa Charlesa Petzolda lub this article, aby zwizualizować różnicę. Ponieważ RenderTransform zostanie zastosowany po tym, jak układ już się pojawi, twoje karty będą mogły rozwijać się poza ich granicami.

Biorąc pod uwagę, że dekompozycja jest właściwym podejściem, uporządkowałbym twoje różne kolekcje kart w Grid, przy czym każda kolekcja to ItemsControl. Model ItemsControl powinien powiązać swoją właściwość ItemsSource z pewną kolekcją, a następnie można udostępnić niestandardowy ItemTemplate, który wyświetli obraz i wszelkie inne informacje. Byłbym niezdecydowany, aby użyć Canvas, ponieważ ograniczyłoby to do twardego kodowania pozycji dla kart (co jest bardzo podobnym do WinForms rozwiązaniem problemu, który może być znacznie bardziej elegancko rozwiązany). Skorzystaj z fantastycznego układu graficznego WPF i użyj zagnieżdżonych siatek i elementów sterujących, aby stworzyć dynamiczny układ. Zapewni to, że Twoja plansza wygląda dobrze w każdej rozdzielczości i przy rozciąganiu do różnych rozmiarów.

+0

Dziękujemy za pomocne informacje. RenderTransform powinien rozwiązać problem z przepełnieniem karty. Kolejnym problemem związanym z dekompozycją jest utrzymywanie kart tej samej wielkości we wszystkich dzieciach. Jako przykład można rozważyć kontrolę nad rodzicielską i dwie kontrolki podrzędne (jedną dla kart każdego gracza). Kiedy rozmiar okna zewnętrznego zostanie zmieniony, muszę obliczyć nowe rozmiary kart w zależności od tego, który obszar ma najwięcej kart. Czy istnieje zdarzenie, które mogę podłączyć do kontenera po ustawieniu dzieci (i ich rozmiarach), aby móc obliczyć rozmiar karty i przesłać ją dzieciom? – Doug

+4

Zamiast wtykać w wydarzenie, należy powiązać rozmiar karty (dla wszystkich kart) z jedną spójną właściwością w modelu widoku. Następnie, gdy obszar podrzędny zyskuje lub traci kartę, przelicza się tę właściwość wielkości, a wszystkie wiązania są aktualizowane automatycznie. – Charlie

Powiązane problemy