2010-07-22 3 views
8

나는 오래된 학교의 ASCII 도스 프롬프트 게임을 쓰고있다. 솔직히 ZZT를 에뮬레이션하여이 브랜드의 게임 디자인에 대해 자세히 알기 위해 노력하고 있습니다. (심지어 구식이라 할지라도)ASCII 도스 게임 - 렌더링 방법

나는 잘하고 있고, 전체 화면 텍스트 모드가 작동하며 세계를 만들고 움직일 수 있습니다. 주위에 문제없이하지만 내 렌더링을위한 적당한 타이밍 방법을 찾을 수 없습니다.

delay() 또는 (clock() - renderBegin)/CLK_TCK 검사를 time.h에서 추가하지 않으면 렌더링 속도가 매우 빠르기 때문에 내 렌더링 및 사전 렌더링 코드가 빠르다는 것을 알고 있습니다.

delay()를 사용하고 싶지 않습니다. 내 지식 플랫폼에서 특정 지연 시간 동안 (사용자 입력 및 처리처럼) 코드를 실행할 수 없기 때문에 지연을 사용하고 싶지 않습니다. 그래서 저는 다음과 같이하기로했습니다 :

do { 
    if(kbhit()) { 
     input = getch(); 
     processInput(input); 
    } 

    if(clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval) { 
     renderTimer = clock(); 
     render(); 
     ballLogic(); 
    } 
}while(input != 'p'); 

"이론"은 잘 작동해야합니다. 문제는이 코드를 실행할 때 (RenderInterval을 0.0333 또는 30fps로 설정하면) 아무 것도 30fps에 가깝지 않게되고, 최대 18 개 정도가됩니다.

RenderInterval을 0.0으로 설정하면 성능이 올라 갔는지 알 수있을 것 같았습니다 ... 그렇지 않았습니다. 저는 (RenderInterval이 0.0 인) 최대 ~ 18-20fps로 증가했습니다.

나는이 모든 clock()과 "divide by this that"메서드를 사용하여 무언가 무서운 CPU 속도를 늦추고 있었기 때문에 어쩌면 그렇게했을지 모르겠다.하지만 render와 ballLogic에서 if 문의 괄호 RenderInterval을 0.0으로 설정합니다. 다시 말해서, 놀랍도록 빠른 렌더링을 얻습니다.

내가 체크 인을 남겨두면 느리게 실행하면 안되니? 나는 여전히

BTW

내가 볼랜드의 터보 C로 컴파일하고있어 ++ V1.01 모든 계산을 수행하는 의미

+1

ZZT를! 나는 그 게임을 좋아했다. – caf

+0

너와 나 둘 다, caf. ('#throwstar seek'). @ Parad0x13 : 도스에서 벗어나도 괜찮다면 SDL에서 지원하는 모든 플랫폼에서이 그래픽 스타일을 에뮬레이트 할 수있는 라이브러리를 작성했습니다 : http://libfake437.googlecode.com –

+0

'clock()에서 결과를 저장하면) '그것을 저장하고 할당 된 값을 지정하면 호출을 저장합니다 (가장 빠른 코드는 호출하지 않는 코드입니다). 그러면 더 정확해질 것입니다 (그렇지 않으면 처음에'clock() ' , 모든 수학을했고 지부를 다루었 다.) 이러한 정확성의 상실로 더 이상 CPU 사용량을 극대화하지 않더라도 원하는만큼 느리게 게임이 실행됩니다. (편집 : 하하, 그냥 이것에 날짜를 보았다, 오 잘) –

답변

1
clock()-renderTimer > RenderInterval * CLOCKS_PER_SEC 

당신이 경우 가능성도 빨리 RenderInterval * CLOCKS_PER_SEC 부분을 사전에 계산, 빠른 비트를 계산하는 것 .

+0

답장을 보내 주셔서 감사합니다, 내가 최적화를 참조하십시오. 심지어 그 문제는 여전히 존재합니다. 그냥 시도해 보았습니다 – Parad0x13

+0

컴파일러는 (특히 분기가 포함 된 경우) 특성을 생성 할 수있는 루프에 대한 모든 종류의 최적화를 수행합니다. 두 경우 모두 생성 된 코드를 살펴 봅니다. 사실, 프로세서는 몇 가지 유사한 작업을 수행합니다 (분기 예측 예측). – Ofir

+0

전 처리기를 검사했지만 활성화 된 최적화를 찾을 수 없습니다. – Parad0x13

0

이 부분에 대해 : x (= clock()) y (= renderTimer)에서 뺍니다. 두 x와 y는 CLOCKS_PER_SEC로 나누어되고있다 : 나는 부서에보고

(clock() - renderTimer) > RenderInterval 

매우 첫 번째 문제는 않을거야이었다 :

clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval 

그것은 MOR efficiente가 작성하지 않을까요 두 개의 long int 사이에서 발생하기 때문에 실수를 얻으려고합니다. secons 문제는 RenderInterval * CLOCKS_PER_SEC을 곱하는 것이 더 효율적이어서 작업을 단순화하는 방법입니다.

대괄호를 추가하면 가독성이 높아집니다. 그리고 아마이 phormula를 단순화함으로써 당신은 잘못된 일이 더 쉽게 될 것입니다.

+0

대신 이러한 수식 최적화를 시도했지만 동일한 결과가 계속되었습니다. – Parad0x13

+0

RenderInterval = 1로 설정하면 어떨까요? – Baltasarq

0

가장 최근의 질문을 발견 했으므로 CLOCKS_PER_SEC은 약 18 개로 제한됩니다. 클럭의 이산 값 당 하나의 프레임이 나오는데, 이는 18fps로 제한됩니다.이 "찢어"피한다로

당신은 타이밍 화면 수직 블랭킹 간격을 사용할 수

,이 게임을 위해 기존의 IT가되지 않은 이유

0

내가 알아 낸 (여기서 반 화면이 하나 개의 프레임을 보여주고 절반은 다른 표시) 렌더링 즉시, 내가 만든 타이머는 문제가됩니다. 실제 clock_t는 .054547XXX 정도이므로 18fps 만 렌더링 할 수 있습니다. 이 문제를 해결할 수있는 방법은 더 정확한 시계를 사용하는 것입니다 ... 다른 이야기 전체입니다.

2

일반적으로 최상의 게임 경험은 모니터의 수직 귀선조와 동기화하여 이루어집니다. 타이밍을 제공하는 것 외에도 CRT 모니터가 컴퓨터에 연결되어있는 경우 화면에서 게임이 원활하게 실행됩니다.

80x25 텍스트 모드에서 수직 리트 렉션 (VGA)은 초당 70 회 발생합니다. 주파수가 EGA/CGA에서 동일했는지는 기억이 나지 않지만 Hercules 및 MDA에서 50 Hz임을 확신합니다. 말하자면, 20 프레임의 지속 시간을 측정함으로써, 당신은 당신이 다루고있는 주파수에 대한 충분한 견적을 가지고 있어야합니다.

메인 루프가 someting 같이하자 :

while (playing) { 
    do whatever needs to be done for this particular frame 
    VSync(); 
    } 

    ... /* snip */ 

    /* Wait for vertical retrace */ 
    void VSync() { 
    while((inp(0x3DA) & 0x08)); 
    while(!(inp(0x3DA) & 0x08)); 
    } 
관련 문제