[PHP] 게임작성 초보자가 PHP로 테토스풍 게임을 만들어 보았다

7420 단어 PHP게임 제작cli

만들어 보았다.



이름은 TETRICE입니다!



리포지토리는 여기

왜?



어떤 질문 사이트에서 PHP로 게임을 만들 수 있습니까? 어떻게 만들 수 있습니까? 라고 Q에 대한 A를 만들 수 없습니다 or Javascript 로 만듭니다 같은 내용 투성이였는데 촉발되었을 뿐.

그건 그렇고, 게임을 만든 적은 거의 없습니다.

갑자기 정리



사용한 적은 없지만 CUI로 그래픽적인 일하고 싶다면 termbox 사용하는 것이 좋다고 생각한다.
(이 기사 전부정)
PHP 라이브러리yum install -y php-pecl-termbox

기타



맞춤법 오류가 아닙니다.
htp // // t-와 피 c-네 ws. 코 m / 테리 s - 코 py 리 ght

[휴가 인용] 도금



이하 시계열로.

표준 입력의 비 블로킹



보통 키보드의 입력 받으려고 하면 그 시점에서 차단되어 버린다.
(키보드 입력 대기 상태)
화면 늘어짐 그대로 표준 입력을 받으려고 하면 non-blocking으로 하지 않으면 안 된다.
  • fcntl ()에서 nonblocking을 시도합니다

  • dio_fcntl() : 참고 :이 함수는 Windows 환경에서 아직 구현되지 않았습니다. 』
  • 다양하게 stream_set_blocking(STDIN, FALSE); 발견했다.
  • 내장해 보는 것도 뭔가 움직이지 않는다.
  • 움직이지 않는 보고서가 가득했습니다.

  • 최종적으로 stream_select 의 타임 아웃을 0 으로 해 표준 입력을 감시하는 방식으로 했다.

    src/app/Controller.php
    <?php
    class Controller implements LoopProcessInterface
    {
        private function readNonBlock(&$data) {
            $read = [STDIN];
            $write = [];
            $except = [];
    
            $result = stream_select($read, $write, $except, 0);
    
            if($result === false) {
                throw new \Exception('stream_select failed');
            }
    
            // Cygwinだとここが必ず1になるから`stream_get_contents`でブロック状態になってしまう・・・
            if($result === 0) {
                return false;
            }
    
            $data = stream_get_contents(STDIN);
    
            return true;
        }
    
        public function loopProcess()
        {
            $data = "";
            if ($this->readNonBlock($data)) {
                echo $data;
            }
        }
    }
    
    stream_select에서 변경이 있으면 1, 변경이 없으면 0이 반환됩니다.
    1시에 입력 내용을 취득해 블록 상태가 되지 않게 하고 싶었지만, Cygwin상이라면 반드시 1이 돌려준다/(^o^)\(미해결)

    사용자 입력 값 제어


  • 표준 입력을 엔터 누를 때까지가 아니라 눌러 한 단계에서 취하고 싶다
  • 사용자 입력을 콘솔에 보내지 않음

  • 오른쪽이나 왼쪽이라면 아직도 스페이스라든지 입력한 값을 표시해 버리면 화면 표시시에 어긋나 버린다. 그래서 비밀번호를 입력할 때처럼 사용자의 입력값을 숨기고 싶다.

    솔직히 기분 나쁘지만 stty 커맨드 호출해 대응・・・shell_exec("stty -icanon -echo")
    프로그램 종료시에 원래의 터미널로 돌아가도 적용된 채이므로 실행 취소하는 처리를 내장.try - finally로 되돌릴 경우 개발 중에 exit했을 때라든가 finally가 불리지 않는다.
    다만 소멸자는 불리기 때문에 그쪽에 편입했다.

    화면 그리기



    우선 화면 클리어해서 쓰면 좋을까 생각하고 clear 하고 echo 했는데 깜박임과 출력 로그 대량같은 것이 되었다. 하고 싶은 일로서는 top 커맨드에 가까운 느낌이므로 표준 출력의 내용을 커서 이동해 재기록하는 형태로 했다.

    이런 식으로 ANSI 이스케이프 시퀀스로 돌아가서 덮어쓸 수 있습니다.

    sample.php
    <?php
    for ($i = 1; $i <= 5; $i++) {
        $str = "--- {$i}/5 ---\n";
        echo $str;
    
        // カーソルを一つ上にずらす
        echo "\e[1A";
    
        sleep(1);
    }
    



    이 부분 재기록+flush()를 구사하는 것으로 의도대로 깨끗하게 나오게 되었다.

    그 밖에도 ANSI 이스케이프 시퀀스 로 블록의 색을 표현하기도 했다.
    (스페이스 2개 + 배경색을 변경)

    기타


  • 게임 부분 실장을 꽤 야츠케로 만들어 버린 느낌이 있다.
    테트리스의 알고리즘 제대로 하면 꽤 하지만 그렇네요.
  • 블록의 종류적으로 1색 부족했다···
  • 완전하게 프로토 타입 만들면서이므로 Unit 테스트가 꽤 후발이 되어 버렸다.
  • TravisCI + Coveralls 소개
  • 좋은 웹페이지 즐겨찾기