OOP없이 게임을하는 방법? [닫은]


10

저는 현재 게임 개발을 공부하고 게임을 만드는 연습을하고 있습니다.

게임에서 OOP를 많이 사용합니다. 예를 들어, 발사되는 각 미사일은 Missile객체 의 인스턴스이며 객체 목록에 추가됩니다 Missile. 게임의 각 탱크는 Tank개체입니다. 기타.

프로그램의 전체 디자인은이를 기반으로합니다. 예를 들어, Missile객체 목록을 가지고 있으면 매 프레임마다 미사일을 움직이거나 그릴 수 있습니다. Tank모든 탱크 에 대해 객체 인스턴스를 가지면 각 탱크가 무언가 등과 충돌하는지 확인할 수 있습니다.

POO-Man보다 복잡한 게임을 비 OO 언어로 프로그래밍하는 방법을 상상하기는 어렵습니다. (물론 비 OO 프로그래머에게는 무관심). 시간이 오래 걸리는 것뿐만 아니라 게임을 이런 식으로 어떻게 설계 할 수 있는지에 관한 것입니다.

게임 프로그램을 디자인하는 방법에 대한 나의 모든 이해는 OOP를 기반으로하기 때문에 객체 지향 프로그래밍을 사용하지 않고 게임을 디자인하는 것을 상상할 수 없습니다.

저는 묻고 싶습니다 : 오늘, 위에서 설명한 것과 비슷한 방식으로 OOP를 사용하여 프로그래밍되지 않은 게임이 있습니까? 개발 과정에서 OOP를 주요 요소로 사용하지 않는 '전문가'게임이 있습니까?

그렇다면 OOP없이 탱크와 N 개의 미사일 사이의 충돌 탐지를 어떻게 구현할 수 있는지에 대한 아이디어를 제공해 주시겠습니까?


6
이것은 철학적 인 질문입니까? 탱크를 "객체"라고 부르지 않더라도 "엔터티", "배우자", "에이전트", "구조체"또는 같은 아이디어에 대한 다른 이름 을 원할 것 입니다. 포탑으로 회전하는 입방체를 구성하는 속성과 행동으로, 탱크라고 불리는 것을 발사 할 수 있습니다. 프로그래밍 언어는 이와 동일한 아이디어를 공식화하는 다양한 방법을 갖지만 결국에는 탱크가 될 것입니다.
Anko

이 답변에 설명 된대로 많은 게임에서 구성 요소 기반 시스템을 사용합니다. gamedev.stackexchange.com/a/31491/9366
John McDonald

범위가 좁아 져서 고칠 수있는 범위가 넓고 게임 개발에만 국한되지는 않습니다 (OO 기술이없는 소프트웨어 구축은 게임 개발자가 다른 소프트웨어 개발자보다 더 나은 답변을 제공하지 않기 때문에). 여기서 주제를 벗어난 것 같습니다.

StackOverflow에 적합하거나 도움말 센터 를 확인하여 게임 개발 관련 사이트 (예 : GDNet)에서 광범위한 토론 중심 주제를 선택할 수있는 사이트를 찾을 수 있습니다. 행운을 빕니다!

답변:


16

게임 프로그램을 디자인하는 방법에 대한 나의 모든 이해는 OOP를 기반으로하기 때문에 객체 지향 프로그래밍을 사용하지 않고 게임을 디자인하는 것을 상상할 수 없습니다.

그런 다음 비 OO 스타일로 일부 프로그램을 작성해 보는 것이 좋습니다. 이것이 실용적이지 않다는 것을 알게 되더라도 앞으로 도움이 될 많은 방법을 배우게 될 것입니다.

OO 스타일은 게임이 거의 항상 상태 저장 객체의 조작에 관한 것이므로 게임에 매우 적합합니다. 레이저 빔이 로봇을 때리고 로봇의 상태는 동일하게 유지되면서 로봇의 상태는 변합니다.

그러나 기능적인 스타일로 게임을 프로그래밍 할 수 있습니다. 기능적 스타일에서는 상태 자체가 변경되지 않습니다. 객체는 불변입니다. 개체를 변경하는 대신 이것을 변경하면 우주가 어떻게 다른지 질문 합니다. 그런 다음 속성이 변경된 완전히 새로운 우주를 만듭니다. 물론, 기존의 많은 우주 는 불변이기 때문에 재사용 할 수 있습니다 .

함수형 프로그래밍에서 모든 함수는 전달 된 정보에서만 반환 값을 계산해야합니다. "글로벌 상태"에서 읽지 않습니다.

이 작업을 수행하는 경우 모든 업데이트가 비파괴 적이 라는 문제를 해결해야합니다 . 레이저가 로봇에 닿아도 로봇의 상태는 바뀌지 않습니다. 궁극적으로 로봇의 상태가 다르다는 점을 제외하면 이전 유니버스와 동일한 완전히 새로운 유니버스를 계산합니다. 그 오래된 우주가 필요하다면 여전히 남아 있습니다.

이 일련의 블로그 기사는 기능적인 스타일로 게임을 작성하는 것에 대해 더 많은 생각을합니다.

http://prog21.dadgum.com/23.html

이 기사는 "쉘이 탱크에 부딪히는"질문에 대해 구체적으로 설명합니다.

http://prog21.dadgum.com/189.html

실제로 블로그 전체를 읽으십시오. 거기에 좋은 물건이 있고 기사가 짧습니다.


12

모든 객체 지향 프로그램은 모든 클래스를 구조로 바꾸고 모든 멤버 함수를 this인수로 사용할 객체를 취하는 독립형 함수로 변환하여 절차 프로그램으로 리팩토링 할 수 있습니다 .

그래서

 missile.setVelocity(100);

된다

 setMissileVelocity(missile, 100);

또는 그 기능이 사소한 경우에는

 missile.velocity = 100;

객체 지향 프로그래밍과 절차 적 프로그래밍의 주요 차이점은 데이터를 처리하는 방법입니다. OOP에서는 데이터가 똑똑 합니다. 자체를 관리하고 조작합니다. 그러나 절차 적 프로그래밍에서 데이터는 바보 입니다. 자체적으로 아무것도하지 않으며 외부에서 조작해야합니다.

구조가 너무 객체 지향적이라고 생각할 때 하나의 구조 배열을 여러 배열로 바꿀 수 있습니다. 하나는 미사일의 변수가 될 수 있습니다. 그래서

struct Missile {
     int x;
     int y;
     int velocity;
}

Missile missiles[256];

된다

int missileX[256];
int missileY[256];
int missileVelocities[256];

이 설계에서 동일한 미사일에 여러 속성이 포함 된 작업을 수행하는 함수는 이제 구조에 대한 참조 대신 배열 인덱스를 가져옵니다. 구현은 다음과 같습니다.

function updateMissilePosition(int index) {
     missileX[index] += missileVelocity[index];
}

1
그러나 missile개체의 인스턴스입니다. 비 OOP에는 인스턴스가 없습니다. 맞습니까? 그렇다면 어떻게 MissileVelocity (missile, 100)을 설정할 수 있습니까?
user3150201

1
@ user3150201 당신은 완전히 정확하지 않습니다. 대부분의 비 OOP 언어 (그리고 진지한 게임 개발에 적합한 언어는 거의 논쟁의 여지가 있습니다)는 구조를 지원합니다. 구조는 일종의 클래스와 비슷하지만 공용 변수를 제외하고는 아무것도 포함하지 않습니다. 그것은 당신이 유형 만들 수있는 것입니다 그래서 Missile구조는 여러 분야 등으로 인, x, y, anglevelocity.
Philipp

@ user3150201 구조없이 수행하는 방법에 대한 섹션으로 답변이 업데이트되었습니다.
Philipp

좋은 답변 Philipp, 비록 Object-Oriented를 프로그래밍하고 싶지 않은 이유를 이해하지 못합니다. 비 OOP 언어를 읽는 것은 실제로 어렵고 혼란 스러울 수 있습니다. 코드는 순식간에 엉망이 될 수 있습니다.
Zhafur

2
@Zhafur 당신은 당신의 진술이 거대한 불꽃 미끼라는 것을 알고 있습니까?
Philipp

6

나는 다음과 같이한다 :

  • 모든 OOP 클래스 / 메소드에 액세스 할 수 this있습니다. this비 OO 접근 방식 으로 활용 this하려면 첫 번째 매개 변수로 다음 인스턴스를 참조하십시오 .
  • 예를 들어 structs를 함수에 전달할 this수는 있지만 엔티티 또는 입자와 같이 많은 객체에 대해 우수한 캐시 성능을 얻는 가장 좋은 방법은 단일 인덱스를 여러 기본 배열에 전달하는 것입니다. 작은 structS. 따라서이 인덱스는 원래 클래스의 각 개별 데이터 멤버에 사용됩니다. 예를 들어

...

class Entity //let's say you had 100 instances of this
{
   int a;
   char b;
   function foo() 
   {
      .../*can access 'this' herein*/
   }
}

당신은 그것을

int a[100];
char b[100];
function foo(int index);

따라서 이제는 일반적으로하는 것을 얻기 위해 인덱스를 함수에 전달합니다 this.

좋은 캐시 위치 (참조의 지역성)를 위해 데이터를 인터리빙하는 방법에 따라 위와 같은 기본 배열 또는struct s 배열을 사용할 수 있습니다 . 물론 적절한 캐시 성능은 특히 코드를 작성하는 언어 / 플랫폼보다 훨씬 더 많은 것에 의존하지만 Java와 같은 VM 기반의 동적으로 할당 된 언어조차도 큰 선형 배열의 프리미티브 배열 객체 인스턴스보다 더 나은 성능 특성을 표시합니다. 이것의 주된 이유는 객체가 참조로 액세스되기 때문에 메모리 전체에서 데이터에 액세스하여 큰 배열에서 연속적으로 프리미티브에 액세스하는 것보다 비효율적입니다.

구조체 또는 기본 요소의 배열로 엔티티 등을 빌드하는 방법에 대한 자세한 내용은 Mick West의 Evolve your Hierarchy를 참조하십시오 .


0

기존 답변 외에도 절차 적 언어로 다형성을 수행하는 방법을 알고 싶을 수도 있습니다.

두 가지 접근 방식이 있습니다.

타입 저장

이 경우 구조체에는 형식 식별자에 대한 필드가있을 수 있습니다.이 열거 형은 switch형식 별 작업을 수행해야 할 때 문을 사용하여 검사 됩니다.

다른 방법은 다음과 같습니다.

함수 포인터 저장

어떤 프로그래밍 언어를 경험했는지 언급하지 않았지만 다양한 언어에서는 콜백, 델리게이트, 이벤트 또는 고차 함수 또는 단순히 함수 객체라고도합니다.

이 경우 유형을 저장하지 않고 특정 동작을 수행하는 함수에 대한 포인터 / 참조를 저장합니다. 유형별 작업을 수행해야하는 경우이 함수를 호출하면됩니다. 이것은 일반적인 가상 방법과 매우 비슷합니다.

각 기능을 독립적으로 설정하면 전략 패턴이 자유 롭습니다.


충돌 감지와 함께 마지막 단락에 대해. 아마 여러 종류의 전차가 있고 여러 종류의 미사일이 있고 충돌 할 때 각 조합마다 다른 결과를 낼 수 있다고 생각합니다. 이것이 당신이 찾는 것이라면, OOP 언어조차도 아직 해결되지 않은 문제가 있습니다. 여러 this유형의 매개 변수를 가질 수있는 다중 디스패치 및 다중 방법 . 이 문제에 대해 다시 두 가지 대안이 있습니다.

  • 탱크와 미사일의 각 조합에 대한 중첩 스위치.
  • 탱크와 미사일의 각 조합에 대한 함수에 대한 포인터를 포함하는 2 차원 디스패치 배열.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.