2010-12-29 4 views
1

나는 카드 게임을 작성하려고합니다. 플레이어가 카드를 쌓을 수 있습니다. 예 : 에이스, 둘, 셋..Net windows는 사용자 정의 레이아웃 엔진을 형성합니다

에이스 카드가 두 카드로 부분적으로 덮여 있고 두 카드가 세 카드로 부분적으로 덮여있는 카드 스택을 시각화하고 싶습니다. 3 장의 카드가 완전히 보입니다.

쉽습니다. 나는 나의 카드를 추가하는 곳에서 사용자 컨트롤을 만든다 : Controls.Add (ace); Controls.Add (2);

그런 다음 내 컨트롤을 배치 할 수있는 것이 필요하므로 사용자 정의 LayoutEngine (LayoutEngine에서 파생 됨)을 작성했습니다. 첫 번째 테스트는 컨트롤을 50 픽셀 이상 이동하지 않습니다.

솔루션을 실행 한 후 Z 순서가 잘못되었음을 발견했습니다.

에이스 카드> 두 카드> 세 카드 : 에이스 카드가 최고 두 카드에있는 에이스 카드 세 가지 카드 중입니다 대신에 세 개의 카드 상단에있는의, 에이스 카드는 다음과 같이 찾고 위에 있었다 두 카드 아래에 있습니다.

그래서 WinForms에서 Z 순서를 변경하는 방법을 찾기 시작했고 단순히 "사용할 수 없다"는 것을 알게되었습니다. .. 어?!

대안 (MS에서 제공)은 컨트롤에 ChildIndex를 설정하여 Z 순서를 변경할 수 있다는 것입니다. Jikes, 즉 목록을 훑어보고 내 응용 프로그램의 동작을 변경합니다. 가는 길 MS ...

어쨌든 모든 것을 시도했지만 트릭을 수행하는 레이아웃 엔진을 작성하는 것은 불가능한 것처럼 보입니다.

저는 하루 종일 google-d를 보았으므로 아무런 유용성이 없습니다. 나는 GUI 전문가가 아니기 때문에이 절름발이 문제에 매달려있다. 누가 나를 도울 수 있습니까?

많은 감사를드립니다!

Bas

+2

Windows 용 카드 게임 스타터 키트를 보셨습니까?http://msdn.microsoft.com/en-us/vcsharp/aa336742 – MattDavey

답변

5

가장 좋은 방법은 컨트롤을 완전히 사용하지 않는 것입니다. 그들은 A) 성능이 떨어지며 B) 히트 테스트/드로잉을 복잡하게합니다.

테이블의 상태를 나타내는 객체를 만들고 (CardContainer 객체 사용) 간단하게 Graphics.DrawImage를 사용하여 페인트 이벤트 중에 모든 카드를 그립니다. 다른 UI 요소를 추가해야하는 경우 전체 테이블에 대해 단일 컨트롤을 사용할 수 있습니다.

이렇게하면 애니메이션을 추가하기로 결정한 경우 카드 애니메이션을보다 간단하게 애니메이션으로 만들 수 있습니다.

나는이 대답을 확장하는 것을 의미하지만, 멀리 불렀다 단순히 내가 가진 무엇을 게시

업데이트되었습니다. 다음은 유용한 정보입니다. 나는 "solitaire game engine"을 만들었다. 엔진은 한 번에 하나의 솔리테어 게임을 호스트합니다 (클론 다이크, 거미, 전략 등). 그것은 각 게임에 대한 통계를 추적하고 개별 게임의 재생 및 편집을 허용합니다. 게임은 새로운 게임을 비교적 쉽게 추가 할 수있는 IronPython 스크립트입니다.

내 CardContainer는 0 개 이상의 카드가있는 객체입니다.

카드 배치 방법을 결정하는 LieDirection (없음, 위, 아래, 왼쪽, 오른쪽)이 있습니다.

LieDirection에 그려지는 카드의 수를 제한하는 MaximumDepth가 있습니다. 이것은 클론 다이크 (Cloondike)와 같은 게임에서 가장 많이 쓰이는 카드를 보여주고 싶을 때 편리합니다.

카드 간격을 지정하는 속성이 있습니다. 앞면이 위로 향하고 아래로 향하는 카드에는 별도의 간격 값이 있습니다. MaximumLength로 정의 된 영역에 카드를 자동으로 채울 수 있습니다. 각 카드마다 하나씩 '여분의 패드'값이 있습니다. 해당 색인에 카드가 있는지 여부와 상관없이 후자는 모의 마우스를 움직일 때 가리키는 카드를 '펴서'사용자가 명확하게 그 위에있는 카드에 의해 가려 질 수있는 카드를 볼 수 있도록하는 데 사용됩니다. 이는 호버 카드 위에 카드의 '추가 패드'를 설정하여 수행됩니다. 이것은 "호버 카드"와 "호버 스페이싱"속성을 갖춤으로써 단순화 될 수 있었지만, 카드 당 여분의 패딩을 갖게되면 간격이있는 테이블 더미에서 특정 '행'을 강조하는 이상한 종류의 솔리테어 게임을 허용합니다.

주어진 X, Y 위치에서 카드를 반환하는 HitTest 메서드가 있습니다.

이 모든 것은 Card 객체가 테이블에 그려지는 위치에 대한 개념이 없음을 의미합니다. 복잡한 애니메이션 시스템을 가지고 있으므로 카드의 위치는 궁극적으로 애니메이션 엔진에서 발생합니다. 카드에 현재 애니메이션이 적용되지 않으면 애니메이션 시스템은 컨테이너에서 해당 위치를 가져옵니다.

위에서 언급 한 카드의 위치는 엄격히 그리기위한 것입니다. 모든 카드는 항상 정확히 하나의 CardContainer에 연결되며 단순히 하나의 CardContainer로 이동됩니다. 처음에는 모든 카드가 들어있는 덱이라고 불리는 하나의 '특수한'컨테이너가 있습니다. 처음에는 테이블에서 벗어난 위치에 있습니다. 컨테이너에는 Visible 속성이 있습니다. Visible 컨테이너에서 다른 Visible 컨테이너로 카드를 이동하는 경우에만 애니메이션이 재생됩니다. 이렇게하면 필요한 경우 애니메이션없이 카드를 움직일 수 있으며 카드는 테이블 밖으로 배치 된 컨테이너로/밖으로 "날아갈 수"있습니다.

엔진에는 CardContainers를 서로 상대적으로 배치하기위한 기본 레이아웃 시스템도 있습니다. 제가 한 매우 편리한 한 가지는 카드 크기 기준 좌표계를 사용하는 것입니다. 테이블의 '폭'은 정확히 11 개의 카드 폭입니다. 사용자의 크기에 관계없이 너비는 항상 11 개의 카드 폭입니다. 이것은 카드 크기 (사용자가 보았을 때)가 커지고 줄어드는 것을 의미합니다. 높이는 가변적이지만 고정 된 카드 크기 비율 (카드 비트 맵에서 결정)에 의해 결정됩니다. CardContainer에 X 값 1.0을 지정하면 표 왼쪽에서 카드 너비에 하나씩 위치하게됩니다. 값은 0.5로 카드 너비의 1/2을 지정할 수 있도록 부동 소수점입니다. 스크린 좌표를 신경 쓰지 않고도 요소를 스크립트에 배치하는 것이 매우 쉽습니다. 사용자가 화면의 크기를 어떻게 변경하더라도 게임은 똑같은 방식으로 배치됩니다.

엔진에는 실행 취소 및 다시 실행을 무제한으로 설정할 수도 있습니다. 즉, 한 컨테이너에서 다른 컨테이너로의 카드 이동은 기록되어야하지만 모든 속성 변경 사항도 기록됩니다 (카드 및 컨테이너 속성 모두). 시작부터 계획하지 않은 경우 실행 취소 및 다시 실행은 구현하기 어려울 수 있습니다. 스크립트는 Game.LogVariableChange 메서드에 액세스하여 기록 메커니즘을 통해 전역 변수의 값을 변경할 수 있습니다. 이것은 클론 다이크 (Klondike)의 "세 가지 재범"기능과 관련하여 필요합니다. 스크립트는 사용 된 재사용 횟수를 저장해야하지만 사용자가 재검사를 취소 할 경우 해당 변수의 값 변경도 실행 취소해야합니다.

이것은 카드 놀이에서 매우 잘 작동하지만 모든 종류의 카드 게임에서 사용할 수 있습니다. 분명히 처음에는이 모든 것을 수행 할 필요가 없습니다. 나는 당신에게 아이디어를주기 위해 정보를 제시한다.

+1

+1 게임 상태를 UI에서 분리합니다. – Ran

+0

답장을 보내 주셔서 감사합니다! 나는 당신이 제안한 것을 시도했고 매력처럼 작동합니다. 나는 또한 CardContainter를 가지고 있으며 의도 한대로 내 카드를 그립니다! 멋진 것! 다시 한번 감사드립니다. –

+0

@ Ran : 내 생각은 정확하게. –

관련 문제