하스 스톤은 관련성이 있고 정직하게 일하는 것 같습니다. 유연성을 달성하는 가장 좋은 방법은 데이터 지향 디자인의 ECS 엔진을 이용하는 것입니다. 귀환석 복제품을 만들려고했지만 그렇지 않다는 것이 증명되었습니다. 모든 에지 케이스. 이 이상한 경우를 많이 접하고 있다면 아마도 가장 좋은 방법 일 것입니다. 나는이 기술을 시도한 최근의 경험에서 꽤 편견입니다.
편집 : 원하는 유연성과 최적화의 종류에 따라 ECS가 필요하지 않을 수도 있습니다. 이것을 달성하는 한 가지 방법 일뿐입니다. 국방부 나는 많은 관련이 있지만 절차 적 프로그래밍으로 잘못 생각했습니다. 내가 말하고 싶은 건. OOP를 완전히 또는 대부분 제거하는 것을 고려해야하며 대신 데이터 및 데이터 구성 방식에주의를 집중하십시오. 상속과 방법을 피하십시오. 대신 공공 데이터 (시스템)에 집중하여 카드 데이터를 조작하십시오. 각 작업은 템플릿 화 된 것 또는 어떤 종류의 논리가 아니라 원시 데이터입니다. 시스템이 로직을 수행하기 위해 사용하는 곳. 함수 스위치 배열에 액세스하기 위해 정수 스위치 케이스 또는 정수를 사용하면 입력 데이터에서 원하는 논리를 효율적으로 파악할 수 있습니다.
따라야 할 기본 규칙은 데이터와 직접 로직을 묶는 것을 피하고, 가능한 한 서로 데이터에 의존하게 만드는 것을 피해야하며 (예외가 적용될 수 있음), 도달 할 수없는 유연한 로직을 원할 때 ... 데이터로 변환하는 것을 고려하십시오.
이렇게하면 이점이 있습니다. 각 카드는 그들의 행동을 나타내는 열거 형 값 또는 문자열을 가질 수 있습니다. 이 인턴을 사용하면 텍스트 또는 json 파일을 통해 카드를 디자인하고 프로그램에서 자동으로 카드를 가져올 수 있습니다. 플레이어 액션을 데이터 목록으로 만들면 특히 카드가 하스 스톤과 같은 과거의 논리에 의존하거나 어떤 시점에서 게임이나 게임의 재생을 저장하려는 경우 더욱 융통성이 있습니다. AI를보다 쉽게 만들 수있는 잠재력이 있습니다. 특히 "동작 트리"대신 "유틸리티 시스템"을 사용하는 경우. 다형성 개체 전체를 와이어로 전송하는 방법과 사실 이후 직렬화가 어떻게 설정되는지를 파악할 필요가 없기 때문에 네트워킹도 쉬워졌습니다. 이미 게임 오브젝트를 가지고있는 것은 단순한 데이터에 지나지 않습니다. 마지막으로 확실히 코드를 걱정하는 대신 데이터를 더 잘 정리할 수 있으므로 프로세서가 처리하는 데 시간이 더 걸리기 때문에 더 쉽게 최적화 할 수 있습니다. 파이썬은 여기에 문제가있을 수 있지만 "캐시 라인"과 게임 개발자와의 관련성을 찾으십시오. 프로토 타입 제작에는 중요하지 않지만 길을 따라 가면 편리하게 사용할 수 있습니다.
유용한 링크들.
참고 : ECS를 사용하면 런타임에 변수 (구성 요소)를 동적으로 추가 / 제거 할 수 있습니다. ECS가 어떻게 "모여"보이는지에 대한 예제 c 프로그램 (그 방법은 매우 다양합니다).
unsigned int textureID = ECSRegisterComponent("texture", sizeof(struct Texture));
unsigned int positionID = ECSRegisterComponent("position", sizeof(struct Point2DI));
for (unsigned int i = 0; i < 10; i++) {
void *newEnt = ECSGetNewEntity();
struct Point2DI pos = { 0 + i * 64, 0 };
struct Texture tex;
getTexture("test.png", &tex);
ECSAddComponentToEntity(newEnt, &pos, positionID);
ECSAddComponentToEntity(newEnt, &tex, textureID);
}
void *ent = ECSGetParentEntity(textureID, 3);
ECSDestroyEntity(ent);
텍스처 및 위치 데이터를 사용하여 여러 엔티티를 만들고 결국 텍스처 컴포넌트 배열의 세 번째 인덱스에있는 텍스처 컴포넌트를 가진 엔티티를 제거합니다. 기발한 것처럼 보이지만 일을하는 한 가지 방법입니다. 다음은 텍스처 구성 요소가있는 모든 것을 렌더링하는 방법의 예입니다.
unsigned int textureCount;
unsigned int positionID = ECSGetComponentTypeFromName("position");
unsigned int textureID = ECSGetComponentTypeFromName("texture");
struct Texture *textures = ECSGetAllComponentsOfType(textureID, &textureCount);
for (unsigned int i = 0; i < textureCount; i++) {
void *parentEntity = ECSGetParentEntity(textureID, i);
struct Point2DI *drawPos = ECSGetComponentFromEntity(positionID, parentEntity);
if (drawPos) {
struct Texture *t = &textures[i];
drawTexture(t, drawPos->x, drawPos->y);
}
}