게임 소스 텍스트(240). Linux용 C로 게임을 작성하기 위한 간단한 엔진 알아야 할 사항

나는 아직도 과일이다. 최근 제가 참여한 개인 게임 프로젝트는 모두 "바닐라" C로 작성되었습니다. 다른 누구도 그렇게 하지 않으므로 제가 왜 그런 선택을 했는지 궁금하실 것 같습니다.
다음 내용에는 귀하가 좋아하지 않을 수 있는 프로그래밍 언어에 대한 의견이 포함되어 있습니다. 나는 경고했다.

내 혀에는 무엇이 필요합니까?

일부 요구 사항은 논의하거나 타협할 수 없습니다. 첫째, 언어는 신뢰할 수 있어야 합니다. 나는 내가 저지르지 않은 실수를 찾기 위해 시간을 낭비할 여유가 없습니다.

저는 Flash로 많은 게임을 작성했지만 Flash는 죽었습니다. 나는 오래된 게임을 최신 플랫폼으로 포팅하는 데 시간을 낭비하고 싶지 않고 새로운 게임을 만들고 싶습니다. 지속 가능하다고 확신할 수 있는 플랫폼이 필요합니다.

제가 꼭 원하는 것은 특정 OS에 대한 의존성을 피하는 것입니다. 이상적으로는 콘솔용으로도 개발이 가능할 것입니다. 따라서 언어가 작성된 내용을 쉽게 이식할 수 있고 크로스 플랫폼 라이브러리를 잘 지원하는 것이 중요합니다.

나는 혀로부터 무엇을 원하는가?

필수는 아니지만 가장 중요한 요구 사항은 단순성입니다. 나는 언어의 기능과 그 놀라운 "스마트" API를 연구하는 것이 엄청나게 지루하다는 것을 알았습니다. 이상적인 언어를 한 번 배우고 나면 해당 문서를 다시는 사용하지 않을 수 있습니다.

버그를 찾아 수정하면 창의성이 저하됩니다. 버그를 적게 남기고 싶기 때문에 강력한 타이핑, 고품질 오류 메시지 및 정적 코드 분석을 원합니다. 나는 오류를 더 쉽게 찾고 싶고, 따라서 좋은 디버깅 도구와 동적 분석을 원합니다.

나는 아름답고 사실적인 그림에는 관심이 없지만 성능에는 관심이 있습니다. 리소스 요구 사항이 줄어들수록 구현에 사용할 수 있는 가능성의 범위가 확장됩니다. 개발자가 성능에 대해 생각하지 않을 때 현대의 강력한 컴퓨터에 무슨 일이 일어나는지 관찰하는 것은 특히 흥미롭습니다.

나는 컴파일러의 속도에 대해 더욱 걱정하고 있습니다. 나는 불교 수행자가 아니며 10초 이상 기다리는 것은 아깝다. 더 나쁜 것은 흐름에서 벗어나게 한다는 것입니다. 그냥 트위터만 보다가 5분이 어디론가 사라진 것 같네요.

나는 OOP 추종자가 아닙니다. 대부분의 시간은 클래스와 객체 작업에 소비되었습니다. 하지만 더 나아갈수록 코드와 데이터를 그렇게 엄격하게 결합해야 하는 이유를 점점 더 이해하지 못하게 됩니다. 나는 데이터를 데이터로 작업하고 주어진 상황에 가장 적합한 코드를 작성하고 싶습니다.

대안

C++는 계속해서 게임 개발을 위한 가장 일반적인 언어로 자리잡고 있으며 그럴 만한 이유가 있습니다. 오늘날까지 내 맞춤 프로젝트의 대부분은 이 언어로 작성되는데 마음에 들지 않습니다.

C++는 내 요구 사항을 충족하지만 원하는 것을 충족시키지 못합니다. 그것은 매우 복잡합니다. 적합한 도구가 있음에도 불구하고 교활한 실수를 저지르기는 쉽습니다. 또한 C에 비해 컴파일 속도가 느립니다. C++는 성능이 뛰어나고 C에 없는 기능을 제공하지만 이는 내가 원하는 것이 아니며 많은 복잡성을 대가로 치르게 됩니다.

C#과 Java에도 비슷한 문제가 있습니다. 장황하고 복잡한 몬스터들이지만, 작고 단순한 동물이 필요해요. 두 언어 모두 프로그래머를 OOP의 심연으로 곧바로 보내는 데 저는 반대합니다. 대부분의 고급 언어와 마찬가지로 복잡한 내용이 많이 숨겨져 있으므로 실수로 발에 총을 쏘는 일이 없습니다.

저는 바둑을 정말 좋아해요. 여러 면에서 C는 비록 대중에게 공개되기까지 몇 년 동안 제작이 진행되었지만 재창조된 C입니다. Go를 사용하고 싶지만 한 가지 큰 함정이 있습니다. 바로 가비지 수집입니다. Go의 게임 개발은 가비지 수집기가 개발자가 감당할 수 없는 전체 게임 세계를 일시 중지하기 때문에 의심스럽습니다. 또한 게임 라이브러리의 모든 것이 좋지 않습니다. 그리고 이 작업을 위해 언제든지 C 라이브러리를 적용할 수 있으며 문제 없이 사용할 수 있지만 여전히 불필요한 작업이 많이 발생합니다. 게다가 나는 전망에 대해 의구심을 가지고 있습니다. Go는 웹에 적합하지만 빠르게 변화하는 환경입니다. 이것은 특히 Flash의 죽음으로 느껴졌습니다.

저는 자바스크립트를 전혀 좋아하지 않습니다. 그것은 너무 많은 자유를 제공하므로 사람들이 어떻게 복잡한 프로젝트를 작성하는지 이해할 수 없습니다. 그리고 나는 그것을 시도하고 싶지도 않습니다.

Haxe는 이 목록에 있는 다른 언어보다 훨씬 더 유망해 보입니다. 그는 도서관에 문제가 없습니다. 웹에 다시 글을 쓰기 시작하면 확실히 웹에 대해 더 잘 알게 될 것입니다. 언어의 상대적인 젊음은 다소 걱정스럽습니다. 과연 살아남을 수 있을까요? 더 이상 추가할 것이 없습니다; 더 깊이 들어가지 않고 Haxe를 조금 가지고 놀았습니다.

조나단 블로우(Jonathan Blow)는 자신의 언어를 씁니다. 그 자신이 사용하고 싶은 언어. 나는 그의 결정을 존경하고 때로는 나 자신도 같은 일을한다는 생각에 흥분됩니다. 하지만 기존 라이브러리를 모두 버리지 마세요. 그러나 이들과의 완전한 호환성을 달성하는 것은 그리 쉽지 않습니다. 그리고 일반적으로 어렵습니다. 프로그래밍 언어보다는 게임 작성을 계속하는 것을 선호합니다.

C가 나에게 최선의 선택인 이유

C는 위험하지만 신뢰할 수 있습니다. 야채를 자르듯 쉽게 손가락을 잘라버릴 수 있는 매우 날카로운 칼입니다. 그러나 그것은 간단하며 올바르게 사용하는 방법을 배우는 것은 어렵지 않습니다.

안녕하세요 빠르네요 그리고 컴파일에 있어서는 어떤 언어도 이 작업을 더 빠르게 할 수 있다고는 상상할 수 없습니다.
어디에서나 작동하도록 코드를 작성하는 것이 가능합니다. 그리고 일반적으로 비교적 쉽습니다. 언젠가 이것이 바뀔 것이라고 상상하기는 어렵습니다.

라이브러리와 도구에 대한 탁월한 지원이 있습니다.

조금 슬프지만 C는 여전히 나에게 최고의 언어입니다.

나는 "야, 너도 C를 써야 해" 같은 말을 하고 싶지는 않다. 나는 내 선호가 매우 구체적이라는 것을 알고 있습니다. 게다가, 내가 작성한 다른 언어의 양에 있어서는 "바닐라" C 코드가 선두 자리를 차지하고 있기 때문에 이것은 이미 나의 안락한 영역의 일부입니다.

그렇습니다. C가 저에게는 최선의 선택입니다.

번역가로부터

번역은 부분적으로 상당히 무료이지만 의미나 내용을 손상시키지는 않습니다.

저는 금요일을 위해 특별히 번역을 준비했는데, 제 생각에는 오늘이 특히 적절하다고 생각합니다. 원문의 저자가 진지하게 쓴 것 같지만... 읽어보면 모든 것을 스스로 이해하게 됩니다. 당신이 읽은 내용을 진실로 받아들여서는 안 됩니다.

평소와 같이 PM에 제안, 소망, 의견을 담으세요.

비디오 게임은 게임 플레이와 그래픽 기능을 시작으로 고급 인공 지능 시스템과 개발자가 제공한 자료에 대한 사용자 인식에 이르기까지 30년 넘게 활발하게 개발되어 왔습니다. e스포츠는 수백만 달러의 상금과 수십억 달러의 매출액을 자랑하는 본격적인 스포츠입니다. 그리고 비디오 게임 산업 자체는 지속적으로 추진력을 얻고 있으며 엔터테인먼트 산업에서 가장 높은 수익을 올리고 인기 있는 부문 중 하나입니다. 그리고 인류는 오실로스코프에서 시작된 가장 원시적인 "테니스" 구현에서 이 모든 것을 얻었습니다.


신입생으로서 나는 C/C++의 기본 콘솔 기능을 연구하는 과정에서 플레이어가 빠르게 생각하고, 게임과 지속적으로 상호작용하며, 간단한 조작법을 요구하는 "전통적인" ASCII 게임을 프로그래밍하는 것이 가능하다고 결정했습니다. 플레이어가 일종의 3차원 이미지로 해석할 수 있는 그래픽 부분입니다.


이러한 솔루션의 시각적 원시성에도 불구하고 플레이어는 확실히 옛날 게임에 대한 향수를 불러일으킵니다.

영감

흑백 디스플레이를 탑재한 휴대폰 시장이 등장하기 시작하면서 노키아 기기의 펌웨어인 '스페이스 임팩트' 게임이 눈에 띄었습니다. 이는 당시 휴대폰의 제한된 기능에 완벽하게 들어맞았습니다. 휴대폰에 간단한 게임이 도입된 이후 디바이스 판매량이 급격하게 증가하면서 모바일 게임이 점차 대중화되면서 이제는 '성인용' AAA 프로젝트 업계와 경쟁하게 됐다.


'스페이스 임팩트'는 2000년대 초반에 실행하기 쉽고 인기가 많았기 때문에 첫 게임의 기반이 되었습니다.

'스페이스 인베이더'의 특징

우선, 프로그램의 가벼움입니다. 실행 파일은 100kb 미만을 차지하며 Visual C++ 패키지가 포함된 Windows OS를 실행하는 거의 모든 컴퓨터에서 의도한 대로 작동합니다.


둘째, 이식성 - POSIX 시스템용 소스 코드를 몇 분 안에 다시 만들 수 있으므로 여러 기능을 교체하고 적절한 컴파일러에서 프로그램을 다시 빌드하는 것만으로 UNIX 및 Mac 운영 체제에서 작동성을 보장할 수 있습니다.


세 번째 장점은 프로그램이 이식 가능하고 추가 파일이 필요하지 않다는 것입니다. 필요한 경우 모든 추가 파일은 실행 파일이 있는 디렉터리에 자동으로 생성됩니다.


설명이나 사용 지침이 필요하지 않은 가장 간단하고 직관적인 인터페이스입니다.


  • 하위 항목 "새 게임" - 새 게임 세션을 시작합니다.
  • 하위 항목 "계속" - 실행 파일 디렉터리의 바이너리 파일에서 마지막으로 저장된 게임을 로드하고 수신된 데이터를 사용하여 게임 세션을 시작합니다.
  • "도움말" 항목 - 응용 프로그램 작업에 대한 지침 및 설명입니다. 키보드의 화살표를 눌러 스크롤합니다.
  • "명예의 전당" 항목은 게임 세션 리더 목록으로, 실행 파일 디렉터리의 바이너리 파일에서 로드되고 형식화된 출력을 콘솔에 표시합니다.
  • 항목 "종료" - 응용 프로그램을 종료합니다.
  • 역동적인 속도로 왼쪽으로 이동하는 '세계'. "World"에는 상단과 하단에 1~2자 두께의 임의 필드가 포함되어 있습니다. 또한 필드 사이에 "우주 잔해"가 무작위로 나타나며 "¤" 기호로 표시되어 플레이어에게 장애물이 됩니다.
  • 창문의 왼쪽 가장자리에 "우주선"이 눌려져 있습니다. 배는 키보드의 위쪽 및 아래쪽 화살표를 사용하여 이동하고 스페이스바를 누르면 접촉 시 "우주 잔해"를 파괴하는 발사체를 발사합니다.
  • 콘솔 상단의 "대시보드"에는 이동 거리, 현재 속도 및 남은 시도 횟수가 표시됩니다.
  • 스페이스 인베이더는 어떻게 작동하나요?

    애플리케이션이 시작되면 스플래시 애니메이션이 나타납니다. 이는 200ms마다 변경되는 미리 형식화된 6개의 문자 배열로 구성됩니다.


    시작 화면 – 마지막 슬라이드


    다음은 매개변수 1(정수)을 사용하여 주 메뉴 기능을 호출합니다. 이 함수는 꺾쇠 괄호 안에 강조 표시된 메뉴 항목이 있는 메뉴를 표시합니다. 그 숫자는 입력 매개변수와 일치합니다. 메뉴에는 각각 4개의 항목이 있으며 입력 매개변수는 1에서 4까지 다양합니다. 아래쪽 화살표를 누르면 입력 매개변수가 4보다 작으면 증가된 입력 매개변수에 재귀적으로 액세스되고, 입력 매개변수가 4보다 작으면 매개변수 1에 액세스합니다. 은 4와 같습니다. Space 또는 Enter를 누르면 강조 표시된 메뉴 항목에 해당하는 기능에 액세스합니다.


    void StartMenu(int switcher) ( system("cls"); 스위치(switcher) ( 사례 1: cout<< "\n\n\n << ИГРАТЬ! >> << "\n\n\n ИГРАТЬ!\n\n << ПОМОЩЬ! >> << "\n\n\n ИГРАТЬ!\n\n ПОМОЩЬ!\n\n << ЗАЛ СЛАВЫ >> << "\n\n\n ИГРАТЬ!\n\n ПОМОЩЬ!\n\n ЗАЛ СЛАВЫ\n\n << ВЫХОД >>"; break; ) int 선택 = _getch(); if (선택 == 224) 선택 = _getch(); if (선택 == 72) if (전환기 != 1) StartMenu(전환기 - 1); else StartMenu( 4); if (선택 == 80) if (전환기 != 4) StartMenu(전환기 + 1); else StartMenu(1); if (선택 == 13 || 선택 == 32) ( if (전환기 == 1 ) GameMenu(1); if (전환기 == 2) Help(0); if (전환기 == 3) TopChart(); if (전환기 == 4) _exit(0); ) )


    주 메뉴(매개변수 1로 입력된 기능)


    “게임” 항목에 해당하는 기능에 접근하면 기능적으로는 유사한 기능이 실행되지만, 선택 항목은 2개뿐입니다. 따라서 입력 매개변수는 1 또는 2가 되며 화살표(위 또는 아래)를 누를 때 숫자를 "반대"로 변경하기만 하면 됩니다. 가장 최적화된 옵션은 3(3 – 1 = 2, 3 – 2 = 1)에서 입력 매개변수를 빼는 것입니다.


    void GameMenu(int switcher) ( system("cls"); if (switcher == 1) cout<< "\n\n\n\n\n << НОВАЯ ИГРА! >> << "\n\n\n\n\n НОВАЯ ИГРА!\n\n << ПРОДОЛЖИТЬ! >>"; int 선택 = _getch(); if (선택 == 224) 선택 = _getch(); if (선택 == 72 || 선택 == 80) GameMenu(3 - 전환기); if (선택 == 27) StartMenu(1); if (선택 == 13 || 선택 == 32) 게임(전환기); )


    추가 메뉴(파라미터 1로 입력된 기능)


    이제 가장 중요한 것은 게임 프로세스입니다. "새 게임" 하위 항목을 선택하면 새 게임 세션이 시작됩니다. 14행 x 50열 크기의 2차원 배열이 생성됩니다. 첫 번째 줄은 대시보드 아래에 할당됩니다. 첫 번째 장치는 이동한 킬로미터의 수이며 콘솔 업데이트 수와 같습니다(초기 콘솔은 80ms마다 한 번씩 업데이트되며 각 업데이트마다 이 매개변수는 값이 25에 도달할 때까지 감소합니다).


    int odometerBuf = 주행 거리계, 주행 거리계DigitLength; for (odometerDigitLength = 0; odometerBuf != 0; odometerBuf /= 10, odometerDigitLength++);//주행 거리계의 자릿수 계산 for (int i = odometerDigitLength, odometerBuf = 주행 거리계; i >= 0; i--, scr [i] = odometerBuf % 10 + "0", odometerBuf /= 10);//대시보드에 주행거리계 그리기 scr = "K"; scr = "M";//주행거리계 "KM" 추가++;//주행거리 증가

    두 번째 장치인 현재 속도는 1000/콘솔 업데이트 속도라는 공식입니다. 속도는 초당 킬로미터 단위로 측정됩니다. 따라서 처음에는 선박이 12km/s의 속도로 이동하고 얼마 후 40km/s에 도달합니다.


    speed = 1000 / 타이머;//속도계 업데이트 int speedBuf = 속도; for (int i = 42; speed != 0; i--, scr[i] = speed % 10 + "0", speed /= 10);//대시보드에 속도계 그리기 scr = "K"; scr = "M"; scr = "/"; scr = "S";//"KM/S" 추가

    세 번째 장치는 남은 시도 횟수를 표시하며, 처음에는 3회입니다. 시도 횟수는 "&" 기호와 함께 표시됩니다.


    for (int i = 50; 생명 > 0; i--, 생명--, scr[i] = "&");


    게임 세션 시작 시 대시보드


    마지막 2줄과 마찬가지로 다음 2줄은 게임 필드입니다. 필드 장식은 랜덤으로 선택되며, 3자 또는 공백으로 구성할 수 있습니다. 가장 바깥쪽 줄은 항상 완전히 채워지고 두 번째 줄과 끝에서 두 번째 줄에는 이러한 문자가 다른 문자에서 "성장"하는 위치에만 공백 이외의 문자가 포함됩니다.


    char borderSymbols = ( "†", "‡", "¤", " " ); for (int 위Below = 0; 위아래< 50; aboveBelow++)//прорисовка верхнего и нижнего полей (2 + 2) { scr = borderSymbols; if (scr == "‡") scr = "¤"; scr = borderSymbols; if (scr == "‡") scr = "¤"; }


    게임 세션 시작 시 대시보드 및 필드


    플레이 공간의 중앙선에서 왼쪽 가장자리를 누르면 플레이어가 제어할 우주선이 그려집니다.


    scr = "\\"; scr = "\\";//배 그리기 scr = "3"; scr = "="; scr = "="; scr = "/"; scr = "/";

    위쪽 및 아래쪽 화살표로 제어할 수 있습니다.


    if (_kbhit())//키를 누른 경우 ( control = _getch();//변수는 해당 값을 가져옵니다. if (control == 224) control = _getch(); ) if (control == 72)/ /배를 위로 이동할 때 if (scr == "\\" || scr == "\\" && scr == "¤" || scr == "\\" && scr == "¤")//if 배가 상단 필드에 충돌했습니다. - 게임 종료 if (lifes > 1) ( cout<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 2; i < 13; i++)//корабль смещается на элемент выше for (int j = 0; j < 49; j++) if (scr[i][j] == "3" || scr[i][j] == "\\" || scr[i][j] == "=" || scr[i][j] == "/") { scr[j] = scr[i][j]; scr[i][j] = " "; } weaponPos--; } if (control == 80)//при движении корабля вниз if (scr == "/" || scr == "/" && scr == "¤" || scr == "/" && scr == "¤")//если корабль врезался в нижнее поле - игра окончена if (lifes >1) (쿠우트<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 12; i > < 49; j++) if (scr[i][j] == "3" || scr[i][j] == "\\" || scr[i][j] == "=" || scr[i][j] == "/") { scr[j] = scr[i][j]; scr[i][j] = " "; } weaponPos++; }


    위쪽 화살표를 두 번 누르면 배송 위치


    시각화에서 벗어나 선박과 함께 선박의 "배럴"을 담당하는 배열 요소를 위아래로 이동한다는 점에 주목할 가치가 있습니다. 따라서 스페이스바를 누르면 발사체를 발사할 수 있습니다.


    그러나 필드나 발사체는 모두 움직이지 않으므로 게임 플레이를 "소생"시키기 위해 화면 다시 그리기 타이머가 만료된 후 "세계"는 왼쪽으로 한 열 이동하고 발사체는 오른쪽으로 한 열 이동합니다. 배는 플레이어가 달리 원할 때까지 제자리에 남아 있습니다. 그러나 다시 그린 후에는 이제 하나의 빈 열이 나타납니다. 발사체나 함선의 측면 범퍼에 의해 격추될 수 있는 필드와 "우주 잔해"로 무작위로 채우겠습니다.


    for (int i = 1; i< 14; i++)//все "космические" элементы смещаются на элемент влево for (int j = 0; j < 49; j++) { if (scr[i][j] == "\\" && scr[i] == "¤" || scr[i][j] == "=" && scr[i] == "¤" || scr[i][j] == "/" && scr[i] == "¤") if (lifes >1) (쿠우트<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); if (scr[i][j] != "3" && scr[i][j] != "\\" && scr[i][j] != "=" && scr[i][j] != "/" && scr[i][j] != "-" && scr[i] != "-") scr[i][j] = scr[i]; if (scr[i][j] == "¤") scr[i] = " "; } for (int i = 1; i < 14; i++)//все снаряды смещаются на элемент вправо for (int j = 48; j > < 12; i++)//рандомное появление космического мусора { if (rand() % 10 == 1) scr[i] = "¤"; }

    이때 함선이 위아래로 움직일 때 우주 잔해물은 함선에 손상을 주지 않고 파괴될 것이다. 이는 모두 범퍼 덕분이다.



    이때 아래쪽 화살표로 잔해를 피하지 않으면 선박이 파괴됩니다.


    함선에서 발사되는 발사체는 경로에 있는 모든 것을 쓸어버릴 수 있도록 설계되었습니다. 결과적으로 한 발의 포탄을 발사하면 한 줄의 복도가 지워집니다.


    그러나 필드는 우주 잔해와 유사한 물질로 구성되어 있지만 임팩터에 의해 파괴될 수는 없습니다. 배의 일부가 들판과 접촉하면 불가피한 붕괴가 발생합니다. 우주선 앞부분에 부딪히는 우주 잔해와 같습니다. 그러한 순간에 대시보드에 최소 한 번 이상의 "시도"가 표시되면 게임이 다시 시작되는 것처럼 보이지만 점수는 유지되고 한 번의 "시도"는 손실됩니다. 속도는 초기값인 12km/s로 재설정됩니다.


    플레이어가 충돌하고 남은 시도가 없으면 게임 세션이 종료되고 플레이어는 "명예의 전당"에 결과를 저장하기 위해 자신의 이름을 입력하라는 요청을 받습니다.



    "명예의 전당"에 결과를 저장하려면 플레이어에게 이름을 입력하라는 메시지가 표시됩니다.


    애플리케이션은 2개의 파일을 처리합니다.

    • "TopChart.bin"은 리더보드를 저장하기 위한 바이너리 파일입니다. 데이터는 구조(플레이어 닉네임, 점수, 게임 세션 종료 날짜)에 저장됩니다. 데이터는 게임이 끝나면 파일 끝에 기록됩니다. "명예의 전당" 항목을 불러오면 편집 기능이 있는 읽기용 파일이 열립니다. 다음으로, 파일의 데이터가 다시 작성된 구조의 동적 배열이 선언된 후 배열이 정렬되고 콘솔에 형식이 지정됩니다(가능한 최대 결과 수는 12입니다. 배열에 13개의 결과가 포함된 경우 마지막 하나는 정렬 후 폐기됩니다. 다음으로, 결과 구조의 배열로 파일을 덮어쓴 후 배열이 삭제됩니다.
    • "CurrentSave.bin"은 저장된 게임을 저장하기 위한 바이너리 파일입니다. "게임" 항목의 "계속" 하위 항목이 실행될 때 읽기를 위해 호출됩니다. 완료되지 않은 게임 세션 하나를 복원하기 위한 데이터가 포함될 수 있습니다. 배의 뱃머리가 포함된 줄 번호, 이동한 킬로미터 수, 남은 시도 횟수, 화면에 있는 개체의 위치. 이 데이터를 사용하여 완료되지 않은 게임 세션을 정확하게 반복하는 게임 세션이 형성됩니다. 불공정한 플레이를 방지하기 위해 파일에서 세션을 로드하면 해당 파일이 삭제됩니다. 게임 중에 Esc 키를 누르면 이 파일이 생성되고 게임 세션을 성공적으로 계속하기 위해 필요한 모든 데이터가 여기에 기록됩니다.

    주 메뉴 항목 "도움말"은 0부터 22까지의 매개변수를 허용하는 기능으로, 입력 매개변수에서 다음 12줄(50자)을 표시합니다. 제어는 위쪽 및 아래쪽 화살표를 사용하여 반복적으로 수행됩니다.


    void Help(int switcher) ( system("cls"); cout<< "ПРОКРУТКА: СТРЕЛКИ ВВЕРХ/ВНИЗ | ВЕРНУТЬСЯ: ESCAPE\n"; char arr = { " УПРАВЛЕНИЕ В МЕНЮ Передвигаться по пунктам – СТРЕЛКИ ВВЕРХ/ВНИЗ Выбрать пункт – ПРОБЕЛ или ENTER Вернуться в предыдущее меню – ESCAPE УПРАВЛЕНИЕ В ИГРЕ Передвигаться вверх/вниз – СТРЕЛКИ ВВЕРХ/ВНИЗ Сделать выстрел – ПРОБЕЛ Вернуться в меню, сохранив игру – ESCAPE БРИФИНГ Вы – пилот космического корабля, попавшего в космическую бурю. Вам необходимо не разбиться и пролететь как можно большее расстояние. Корабль оборудован динамическим управлением. Чем быстрее вы летите – тем острее поворачивает судно. Корабльавтоматически постепенно разгоняется до 40 км/с. Вы можете сбивать космический мусор с помощью магнитной пушки, встроенной в судно, а также боковыми отбойниками. При управлении кораблем на щитке приборов отображается пройденная дистанция, текущая скорость и количество оставшихся «ячеек отката» (отображаются символом «&»), изначально их 3. Если решите прекратить игру – просто нажмите ESCAPE. Игра сохранится, и вы сможете ее продолжить даже после перезапуска приложения с помощью пункта «ПРОДОЛЖИТЬ!». В главном меню можно посмотреть таблицу почетных пилотов. Добейтесь своего права там оказаться! АВТОРСТВО Svjatoslav Laskov – AUTHOR Igor Marchenko – COACH National Technical University «Kharkiv Polytechnic Institute» 2016" }; for (int i = 0, buf = switcher; i < 13; i++) { for (int j = buf * 50; j < buf * 50 + 50; j++) cout << arr[j]; if (i != 12) cout << endl; buf++; } int controller = _getch();//получить значение нажатой клавиши if (controller == 224)//если была нажата стрелка controller = _getch();//то определить какая именно if (controller == 72)//если стрелка вверх if (switcher > < 22) Help(switcher + 1); else Help(22); if (controller == 27)//если Escape StartMenu(2); }

    메인 메뉴 항목 "종료" - 애플리케이션을 종료합니다.


    사용자 설명서

    메뉴 컨트롤
    o 항목 간 이동 - 위쪽/아래쪽 화살표
    o 항목 선택 – 스페이스바 또는 Enter
    o 이전 메뉴로 돌아가기 – ESCAPE
    게임 컨트롤
    o 위/아래로 이동 – 위쪽/아래쪽 화살표
    o 사진 찍기 - 스페이스바
    o 게임을 저장한 후 메뉴로 돌아가기 – ESCAPE
    요약 보고
    당신은 우주 폭풍에 휘말린 우주선의 조종사입니다. 충돌을 피하고 최대한 멀리 비행해야 합니다.


    선박에는 동적 제어 장치가 장착되어 있습니다. 더 빨리 날수록 배는 더 날카롭게 회전합니다. 선박은 자동으로 40km/s까지 가속됩니다.


    함선에 내장된 자기총과 측면 범퍼를 사용하여 우주 잔해를 격추할 수 있습니다.
    선박을 제어할 때 계기판에는 이동 거리, 현재 속도 및 남은 "롤백 셀"("&" 기호로 표시됨) 수가 표시되며 처음에는 3개가 있습니다.


    재생을 중단하려면 ESCAPE를 누르세요. 게임은 저장되며, "CONTINUE!" 항목을 사용하여 애플리케이션을 다시 시작한 후에도 계속할 수 있습니다.


    메인 메뉴에서 명예 조종사 표를 볼 수 있습니다. 거기에 있을 권리를 얻으세요!

    결론

    개인적으로 저는 이렇게 작은 프로젝트를 개발하면서 많은 즐거움을 얻었습니다. 특히 표준 콘솔은 게임용이 아닌 정보 표시용으로 설계되었기 때문입니다. 이로 인해 응용 프로그램이 실행되는 컴퓨터에 관계없이 프레임 속도가 매우 제한됩니다.


    또한 사용자의 키 입력에 대한 보다 정확한 응답을 위해 애플리케이션을 여러 스레드로 나누고 싶었지만 다음 프로젝트에서는 C++로 스레드를 구현할 예정입니다.


    원천

    #include "conio.h" #include "windows.h" #include "ctime" #include 네임스페이스 std 사용; struct player//완료된 게임 세션의 결과에 대한 데이터를 저장하는 구조 정의( char 이름, int 점수, int mday, int mon, int year; ); struct save//완료되지 않은 게임 세션에 대한 데이터를 저장하는 구조 정의( int WeaponPos; int timer; int odometer; int Lives; char scr; ); void ScreenOutput(char scr)//배열의 요소별 콘솔 출력 기능( system("cls"); for (int i = 0; i< 14; i++) { for (int j = 0; j < 50; j++) cout << scr[i][j]; if (i != 13) cout << endl; } } //блок прототипов функций void StartMenu(int switcher);//функция, вызывающаяся из главного меню, содержит пункты "ИГРА" и "ПРОДОЛЖИТЬ" void GameMenu(int switcher);//функция главного меню void GameStart(char scr, int lifes, int *timer);//функция, определяющая начальный символьный массив при запуске нового игрового сеанса void Game(int var);//функция игровго сеанса void GameOver(int score);//функция, спрашивающая имя игрока, и записывающая его результат в бинарный файл void Help(int switcher);//функция помощи игроку void TopChart();//функция "ЗАЛ СЛАВЫ" - отображает список лидеров void Help(int switcher) { system("cls"); cout << "ПРОКРУТКА: СТРЕЛКИ ВВЕРХ/ВНИЗ | ВЕРНУТЬСЯ: ESCAPE\n"; char arr = { " УПРАВЛЕНИЕ В МЕНЮ Передвигаться по пунктам – СТРЕЛКИ ВВЕРХ/ВНИЗ Выбрать пункт – ПРОБЕЛ или ENTER Вернуться в предыдущее меню – ESCAPE УПРАВЛЕНИЕ В ИГРЕ Передвигаться вверх/вниз – СТРЕЛКИ ВВЕРХ/ВНИЗ Сделать выстрел – ПРОБЕЛ Вернуться в меню, сохранив игру – ESCAPE БРИФИНГ Вы – пилот космического корабля, попавшего в космическую бурю. Вам необходимо не разбиться и пролететь как можно большее расстояние. Корабль оборудован динамическим управлением. Чем быстрее вы летите – тем острее поворачивает судно. Корабльавтоматически постепенно разгоняется до 40 км/с. Вы можете сбивать космический мусор с помощью магнитной пушки, встроенной в судно, а также боковыми отбойниками. При управлении кораблем на щитке приборов отображается пройденная дистанция, текущая скорость и количество оставшихся «ячеек отката» (отображаются символом «&»), изначально их 3. Если решите прекратить игру – просто нажмите ESCAPE. Игра сохранится, и вы сможете ее продолжить даже после перезапуска приложения с помощью пункта «ПРОДОЛЖИТЬ!». В главном меню можно посмотреть таблицу почетных пилотов. Добейтесь своего права там оказаться! АВТОРСТВО Svjatoslav Laskov – AUTHOR Igor Marchenko – COACH National Technical University «Kharkiv Polytechnic Institute» 2016" }; for (int i = 0, buf = switcher; i < 13; i++) { for (int j = buf * 50; j < buf * 50 + 50; j++) cout << arr[j]; if (i != 12) cout << endl; buf++; } int controller = _getch();//получить значение надатой клавиши if (controller == 224)//если была нажата стрелка controller = _getch();//то определить какая именно if (controller == 72)//если стрелка вверх if (switcher >0) 도움말(전환기 - 1); 그렇지 않으면 도움말(0); if (컨트롤러 == 80)//if 아래쪽 화살표 if (스위처< 22) Help(switcher + 1); else Help(22); if (controller == 27)//если Escape StartMenu(2); } void StartMenu(int switcher) { system("cls"); switch (switcher) { case 1: cout << "\n\n\n << ИГРАТЬ! >>\n\n도와주세요!\n\n명예의 전당\n\n종료"; 중단; 사례 2: cout<< "\n\n\n ИГРАТЬ!\n\n << ПОМОЩЬ! >>\n\n명예의 전당\n\nEXIT"; 중단; 사례 3: cout<< "\n\n\n ИГРАТЬ!\n\n ПОМОЩЬ!\n\n << ЗАЛ СЛАВЫ >>\n\nEXIT"; 중단; 사례 4: cout<< "\n\n\n ИГРАТЬ!\n\n ПОМОЩЬ!\n\n ЗАЛ СЛАВЫ\n\n << ВЫХОД >>"; break; ) int 선택 = _getch(); if (선택 == 224) 선택 = _getch(); if (선택 == 72) if (전환기 != 1) StartMenu(전환기 - 1); else StartMenu( 4); if (선택 == 80) if (전환기 != 4) StartMenu(전환기 + 1); else StartMenu(1); if (선택 == 13 || 선택 == 32) ( if (전환기 == 1 ) GameMenu(1); if (전환기 == 2) Help(0); if (전환기 == 3) TopChart(); if (전환기 == 4) _exit(0); ) ) void GameMenu(int 전환기) ( system("cls"); if (스위처 == 1) cout<< "\n\n\n\n\n << НОВАЯ ИГРА! >>\n\n계속하세요!"; 그렇지 않으면 cout<< "\n\n\n\n\n НОВАЯ ИГРА!\n\n << ПРОДОЛЖИТЬ! >>"; int 선택 = _getch(); if (선택 == 224) 선택 = _getch(); if (선택 == 72 || 선택 == 80) GameMenu(3 - 전환기); if (선택 == 27) StartMenu(1); if (선택 == 13 || 선택 == 32) Game(switcher); ) void GameStart(char scr, intlives, int *timer) ( for (int i = 0; i< 14; i++)//очищение от мусора for (int j = 0; j < 50; j++) scr[i][j] = " "; for (int i = 50; lifes >0; i--, 생활--, scr[i] = "&"); *타이머 = 80; char borderSymbols = ( "†", "‡", "¤", " " ); for (int 위Below = 0; 위아래< 50; aboveBelow++)//прорисовка верхнего и нижнего полей (2 + 2) { scr = borderSymbols; if (scr == "‡") scr = "¤"; scr = borderSymbols; if (scr == "‡") scr = "¤"; } scr = "\\"; scr = "\\";//прорисовка корабля scr = "3"; scr = "="; scr = "="; scr = "/"; scr = "/"; } void GameOver(int score) { system("cls"); player newPlayer;//объявляние структуры newPlayer.score = score;//инициализацие поля набранного счета cout << "Поздравляем Вас!\nВы продержались " << score << " километров.\n\n(Пожалуйста, не используйте кириллические символы)\n(Используйте не более 6 символов)\nОставьте свое имя и станьте примером\nдля подражания будущим игрокам: "; cin.getline(newPlayer.name, 7);//инициализацие поля имени time_t timeCur; time(&timeCur); struct tm * timeCurStruct = localtime(&timeCur); newPlayer.mday = timeCurStruct->tm_mday;//게임 종료일 초기화 newPlayer.mon = timeCurStruct->tm_mon; newPlayer.year = timeCurStruct->tm_year; 파일 *topChart; fopen_s(&topChart, "TopChart.bin", "ab+"); fwrite(&newPlayer, 1, sizeof(player), topChart); // 결과를 파일에 추가 fclose(topChart); 탑차트(); ) void TopChart() ( FILE *topChart; fopen_s(&topChart, "TopChart.bin", "rb+"); system("cls"); if (topChart == NULL)//파일을 여는 동안 오류가 발생한 경우 ( system("cls");cout<< "Нет ни единого результата."; Sleep(1000); system("cls"); cout << "Нет ни единого результата.."; Sleep(1000); system("cls"); cout << "Нет ни единого результата..."; Sleep(1000); cout << "\nНажмите любую клавишу, чтобы вернуться."; _getch(); StartMenu(3); } fseek(topChart, 0L, SEEK_END); int playerAmount = ftell(topChart) / sizeof(player); player *temp = new player; fseek(topChart, 0L, SEEK_SET); for (int i = 0; i < playerAmount; i++)//копирование содержиомого файла в структкры fread(&temp[i], 1, sizeof(player), topChart); fclose(topChart); for (int i = 1; i < playerAmount; i++)//сортировка структур по спаданию итоговых счетов if (temp[i].score >temp.score) ( 플레이어 tempAlone; strcpy(tempAlone.name, temp[i].name); tempAlone.score = temp[i].score; tempAlone.mday = temp[i].mday; tempAlone.mon = temp[ i].mon; tempAlone.year = temp[i].year; strcpy(temp[i].name, temp.name); temp[i].score = temp.score; temp[i].mday = 임시. mday; temp[i].mon = temp.mon; temp[i].year = temp.year; strcpy(temp.name, tempAlone.name); temp.score = tempAlone.score; temp.mday = tempAlone.mday ; temp.mon = tempAlone.mon; temp.year = tempAlone.year; if (i > 1) i -= 2; else i = 0; ) if (playerAmount > 12) playerAmount = 12; 시합<< "№ " << "Имя" << "\t" << "Счет" << "\t" << "Дата" << endl;//вывод таблицы лидеров в консоль for (int i = 0; i < playerAmount; i++) { cout << i + 1 << ")" << "\t" << temp[i].name << "\t" << temp[i].score << "\t"; if (temp[i].mday / 10 == 0) cout << "0" << temp[i].mday; else cout << temp[i].mday; cout << " "; switch (temp[i].mon) { case 0: cout << "января"; break; case 1: cout << "февраля"; break; case 2: cout << "марта"; break; case 3: cout << "апреля"; break; case 4: cout << "мая"; break; case 5: cout << "июня"; break; case 6: cout << "июля"; break; case 7: cout << "августа"; break; case 8: cout << "сентября"; break; case 9: cout << "октября"; break; case 10: cout << "ноября"; break; case 11: cout << "декабря"; break; } cout << " " << 1900 + temp[i].year << endl; } fopen_s(&topChart, "TopChart.bin", "wb+"); for (int i = 0; i < playerAmount; i++)//запись таблицы лидеров в бинарный файл fwrite(&temp[i], 1, sizeof(player), topChart); fclose(topChart); delete temp; _getch(); StartMenu(3); } int main() { setlocale(LC_ALL, "Rus");//задание кодировки system("mode con cols=51 lines=14");//задание размеров окна консоли system("title Space Invader");//задание описания окна консоли system("color 0A");//задание цвета консоли (0-задний фон; А-передний фон) HANDLE hCons = GetStdHandle(STD_OUTPUT_HANDLE);//получение хендла CONSOLE_CURSOR_INFO cursor = { 100, false };//число от 1 до 100 размер курсора в процентах; false\true - видимость SetConsoleCursorInfo(hCons, &cursor);//применение заданных параметров курсора int timer = 200; cout << " (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\";//вступительная заставка Sleep(timer); system("cls"); cout << " \\___ \\) __// \\((__) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\\n)(/ /\\ \\/ // \\) D () _)) /";//вступительная заставка Sleep(timer); system("cls"); cout << " / ___)(_ \\ / _\\ / __)(__)\n \\___ \\) __// \\((__) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\\n)(/ /\\ \\/ // \\) D () _)) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";//вступительная заставка Sleep(timer); system("cls"); cout << " ____ ____ __ ___ ____\n / ___)(_ \\ / _\\ / __)(__)\n \\___ \\) __// \\((__) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n\n\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\\n)(/ /\\ \\/ // \\) D () _)) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";//вступительная заставка Sleep(timer); system("cls"); cout << "\n ____ ____ __ ___ ____\n / ___)(_ \\ / _\\ / __)(__)\n \\___ \\) __// \\((__) _)\n (____/(__) \\_/\\_/ \\___)(____)\n\n\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\\n)(/ /\\ \\/ // \\) D () _)) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";//вступительная заставка Sleep(timer); system("cls"); cout << "\n\n ____ ____ __ ___ ____\n / ___)(_ \\ / _\\ / __)(__)\n \\___ \\) __// \\((__) _)\n (____/(__) \\_/\\_/ \\___)(____)\n __ __ _ _ _ __ ____ ____ ____\n ()((\\/)(\\ / _\\ (\\(__)(_ \\\n)(/ /\\ \\/ // \\) D () _)) /\n (__)\\_)__) \\__/ \\_/\\_/(____/(____)(__\\_)";//вступительная заставка cout << "\a"; Sleep(10 * timer);//задержка заставки StartMenu(1); return 0; } void Game(int var) { int weaponPos;//позиция строки дула в массиве int timer;//задержка между перерисовками экрана int odometer;//количество перерисовок экрана, они же итоговые очки int lifes;//количество жизней char control = "&";//переменная управления кораблем int shotPause = 4;//задержка между выстрелами (указывать на одну перерисовку больше) int speed;//скорость корабля char scr; if (var == 1) { weaponPos = 7;//позиция строки дула в массиве odometer = 1;//количество перерисовок экрана, они же итоговые очки lifes = 3;//количество жизней GameStart(scr, lifes, &timer); } else//при восстановлении игрового сеанса из сохранения { FILE *saveBin; fopen_s(&saveBin, "CurrentSave.bin", "rb"); if (!saveBin) { system("cls"); cout << "Нет сохранения."; Sleep(1000); system("cls"); cout << "Нет сохранения.."; Sleep(1000); system("cls"); cout << "Нет сохранения..."; Sleep(1000); Game(1); } fread(&weaponPos, 1, sizeof(int), saveBin); timer = 80; fread(&odometer, 1, sizeof(int), saveBin); fread(&lifes, 1, sizeof(int), saveBin); fread(&scr, 14 * 50, sizeof(char), saveBin); fclose(saveBin); remove("CurrentSave.bin"); } while (true) { int odometerBuf = odometer, odometerDigitLength; for (odometerDigitLength = 0; odometerBuf != 0; odometerBuf /= 10, odometerDigitLength++);//вычисление количества цифр на одометре for (int i = odometerDigitLength, odometerBuf = odometer; i >= 0; i--, scr[i] = odometerBuf % 10 + "0", odometerBuf /= 10);//대시보드에 주행거리계 그리기 scr = "K"; scr = "M";//"KM" 주행거리계 추가++;//주행거리계 속도 증가 = 1000 / 타이머;//속도계 업데이트 int speedBuf = speed; for (int i = 42; speed != 0; i--, scr[i] = speed % 10 + "0", speed /= 10);//대시보드에 속도계 그리기 scr = "K"; scr = "M"; scr = "/"; scr = "C";//"KM/S" 추가 if (_kbhit())//키를 누른 경우( control = _getch();//변수는 해당 값을 사용합니다. if (control == 224) = _getch( ); ) if (control == 13 && ShotPause == 4 || control == 32 && ShotPause == 4)//총이 재장전된 경우 방아쇠를 눌렀을 때 ( scr = "-"; ShotPause = 0; ) if (shotPause< 4)//перезарядка shotPause++; if (control == 27)//при выходе { FILE *saveBin; fopen_s(&saveBin, "CurrentSave.bin", "wb"); fwrite(&weaponPos, 1, sizeof(int), saveBin); fwrite(&odometer, 1, sizeof(int), saveBin); fwrite(&lifes, 1, sizeof(int), saveBin); fwrite(&scr, 14 * 50, sizeof(char), saveBin); fclose(saveBin); GameMenu(2); } if (control == 72)//при движении корабля вверх if (scr == "\\" || scr == "\\" && scr == "¤" || scr == "\\" && scr == "¤")//если корабль врезался в верхнее поле - игра окончена if (lifes >1) (쿠우트<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 2; i < 13; i++)//корабль смещается на элемент выше for (int j = 0; j < 49; j++) if (scr[i][j] == "3" || scr[i][j] == "\\" || scr[i][j] == "=" || scr[i][j] == "/") { scr[j] = scr[i][j]; scr[i][j] = " "; } weaponPos--; } if (control == 80)//при движении корабля вниз if (scr == "/" || scr == "/" && scr == "¤" || scr == "/" && scr == "¤")//если корабль врезался в нижнее поле - игра окончена if (lifes >1) (쿠우트<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); else { for (int i = 12; i >= 2; i--)//배는 (int j = 0; j에 대해 한 요소 아래로 이동합니다.< 49; j++) if (scr[i][j] == "3" || scr[i][j] == "\\" || scr[i][j] == "=" || scr[i][j] == "/") { scr[j] = scr[i][j]; scr[i][j] = " "; } weaponPos++; } for (int i = 1; i < 14; i++)//все "космические" элементы смещаются на элемент влево for (int j = 0; j < 49; j++) { if (scr[i][j] == "\\" && scr[i] == "¤" || scr[i][j] == "=" && scr[i] == "¤" || scr[i][j] == "/" && scr[i] == "¤") if (lifes >1) (쿠우트<< "\a"; lifes--; weaponPos = 7; GameStart(scr, lifes, &timer); Sleep(1000); } else GameOver(odometer); if (scr[i][j] != "3" && scr[i][j] != "\\" && scr[i][j] != "=" && scr[i][j] != "/" && scr[i][j] != "-" && scr[i] != "-") scr[i][j] = scr[i]; if (scr[i][j] == "¤") scr[i] = " "; } for (int i = 1; i < 14; i++)//все снаряды смещаются на элемент вправо for (int j = 48; j >= 0; j--) if (scr[i][j] == "-") if (j != 48) ( scr[i] = "-"; scr[i][j] = " "; ) else scr [i][j] = " "; char borderSymbols = ( "†", "‡", "¤", " " ); scr = " ";//새 가장자리 요소를 무작위로 채움 scr = borderSymbols; if (scr == "‡") scr = "¤"; scr = " "; scr = 국경 기호; if (scr == "‡") scr = "¤"; for (int i = 3; i< 12; i++)//рандомное появление космического мусора { if (rand() % 10 == 1) scr[i] = "¤"; } ScreenOutput(scr);//вывод экрана if (control != "&")//"обнуление" управляющей переменной control = "&"; if (timer >25)//선박 가속 타이머--; Sleep(타이머);//다시 그리기 지연 ) )


    여기에서 실행 파일.exe를 다운로드할 수 있습니다.

    Weaver Framework를 사용하여 Linux 게임 만들기

    이 문서는 Linux용 2D 게임을 만들기 위한 작은 프레임워크인 Weaver Framework에 관한 것입니다. Weaver는 C 프로그래밍 언어로 작성되었습니다. 이를 사용하여 게임을 만들려면 해당 프로그래밍 언어에 대한 최소한의 기본 지식이 필요합니다.

    우선, 프레임워크에는 사운드, 그림 조작, 그래픽 프리미티브 생성, 충돌 감지기 등을 위한 총 70개 정도의 기능이 포함되어 있다고 말해야 합니다. 이 기사를 진행하는 동안 거의 모든 기능에 대해 설명합니다.

    프로젝트 웹사이트는 다음 위치에 있습니다. http://weaver.nongnu.org/ , 거기에서 이미 조립된 .deb 형식 패키지나 데비안 기반이 아닌 시스템용 소스 코드가 포함된 tarball을 얻을 수도 있습니다. 그럼 시작해 보겠습니다.

    설치가 성공적으로 완료되면 즉시 프로젝트 생성을 시작할 수 있습니다. 이렇게 하려면 콘솔을 열고 새 프로젝트가 위치할 디렉터리로 이동하여 다음을 입력해야 합니다.

    직공

    프로젝트를 생성하는 동안 그래픽, 사운드 및 소스 코드 파일을 저장하기 위해 디렉터리 계층 구조가 생성됩니다. 먼저 연습을 위해 테스트 프로젝트를 만들어 보겠습니다. 위버의 능력을 탐구하는 데 사용될 것입니다.

    2.1. 빈 프로젝트 만들기

    위버 테스트

    프로젝트 디렉토리의 내용에 대한 몇 마디.

    시험

    |-글꼴

    |-이미지

    |-음악

    |-소리

    | |-위버

    특허

    메이크파일

    기본적으로 이름은 그 자체로 말합니다. 그냥 언급할게요/src , 여기에는 직접 프로젝트 파일이 모두 포함되어 있습니다(게임.c, 게임.h - 메인) 및 (디렉토리에 있음)/직공 ) 프로젝트의 성공적인 조립에 필요한 프레임워크 자체의 파일입니다.

    /src/game.c 파일을 고려해보세요. 자세한 내용은. 프로젝트의 메인 파일이며 프로그램의 메인 루프가 있는 곳입니다.

    int main(int argc, char **argv)

    Awake_the_weaver(); // Weaver API 초기화

    // 메인 루프

    을 위한(;;)(

    Get_input();

    만약(키보드)(

    부서지다;

    weaver_rest(10000000);

    May_the_weaver_sleep();

    0을 반환합니다.

    기능

    awake_the_weaver()

    may_the_weaver_sleep()

    프레임워크의 기능 사용을 허용하고 금지합니다. 그 사이에는 프로그램의 메인 루프가 있습니다.

    get_input() 키보드와 마우스의 상태를 캡처하는 역할을 합니다. 다음에는 코드 섹션이 나옵니다. 아무 키나 눌러 프로그램을 종료해야 합니다.

    weaver_rest(n) 특정 나노초 동안 프로그램을 일시 중지하도록 설계되었으며 동일한 기능이 FPS도 담당하며 숫자 n이 낮을수록 FPS가 높아집니다.

    프로젝트를 빌드하려면 콘솔에 다음 명령을 입력하세요.만들다 성공적인 완료를 기다립니다.

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/display.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/keyboard.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/Vector2.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/Vector3.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/Vector4.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/weaver.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/sound.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/image.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/weaver/font.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -c src/game.c

    gcc -Wall -O2 -g $(freetype-config --cflags) -g -o 테스트 디스플레이.o 키보드.o 벡터2.o 벡터3.o 벡터4.o 위버.o 사운드.o 이미지.o 글꼴.o 게임. o -lX11 -lXext -lm -lvorbisfile -lasound -lpng -lfreetype $(freetype-config --cflags)

    운. 프로젝트를 시작해보자:

    ./시험

    그게 다야! 아무 키나 누르면 게임이 종료됩니다.

    2.2. 키보드 사용

    키보드 상태에 전역 변수가 포함되어 있습니다.건반 . 다음과 같은 간단한 방법으로 필요한 키가 눌렸는지 확인할 수 있습니다.

    if (키보드[ ])

    // 무언가가 일어난다

    프로그램이 키 조합에 응답해야 하는 경우 논리 AND를 사용하세요.

    if (키보드[ ] && 키보드[ ])

    //뭔가 일어날거야!

    이제 Ctrl-Q를 눌러 종료되도록 프로그램을 변경해 보겠습니다.

    바꿔보자

    if(키보드)

    부서지다;

    ~에

    if(키보드 && 키보드[Q])

    부서지다;

    게임을 조립하고 출시하는 위험을 감수합시다. 이제 종료하려면 Ctrl-Q 키 조합을 눌러야 합니다.

    2.3. 그래픽 프리미티브 그리기

    기본 요소를 그리는 데 사용되는 함수는 다음과 같습니다.

    draw_circle()

    draw_ellipse()

    draw_line()

    draw_point()

    draw_사각형()

    함수는 기본 채우기에 사용됩니다.

    fill_circle()

    fill_ellipse()

    채우기_직사각형()

    대부분의 직조 기능 이름과 마찬가지로 해당 이름은 설명적이므로 자세한 설명이 필요하지 않습니다. 매개변수에만 설명이 필요하지만 기사 마지막 부분에 참조 가이드 링크가 제공됩니다.

    가만히 있지 말고 좌표(x=50, y=150), 크기 125x125로 노란색 정사각형을 그려보자. 메인 루프에 다음 항목을 추가해 보겠습니다.

    draw_사각형(50, 150, 125, 125, 노란색);

    여기서 YELLOW는 사각형의 색상입니다.

    프로젝트를 함께 구성하고 무슨 일이 일어나는지 살펴보겠습니다.

    우리가 기대했던 것과는 다르죠?

    사실 사각형을 그릴 때 색상을 설정할 때 테두리의 색상도 설정하므로 fill_lectangle() 함수를 사용하여 사각형을 채워야 합니다. 이는 사각형을 그리는 명령 뒤에 다음 줄을 추가하여 수행하는 작업입니다.

    fill_사각형(50, 150, 125, 125, 노란색);

    해보고 보자!

    이번에는 성공했습니다. 이제 키보드 사용과 그리기 기본 요소에 대한 지식을 결합해 보겠습니다. 하지만 그 전에 사각형 자체를 변수로 만들어 프로그램을 조금 최적화해 보겠습니다.

    직사각형은 x축(x 매개변수), y축(y 매개변수), 너비(w 매개변수), 높이(z 매개변수) 4개의 매개변수가 있는 구조입니다.

    초기화 후에 weaver를 추가하여 직사각형 유형의 변수를 생성해 보겠습니다. (이것은 awake_the_weaver()입니다.)

    직사각형 ret1;

    그런 다음 매개변수를 초기화합니다.

    직사각형 ret1;

    직사각형1.x=50;

    ret1.y=150;

    REC1.W=REC1.Z=125;

    키 누르기에 대한 처리를 설정해 보겠습니다.<стрелка-влево>그리고<стрелка-вправо>키보드.

    만약 (키보드)

    Rect1.x-=10;

    만약 (키보드)

    직사각형1.x+=10;

    그런 다음 사각형 자체를 그립니다.

    draw_직사각형(직사각형1.x,직사각형1.y,직사각형1.w,직사각형1.z,YELLOW);

    가변 매개변수의 초기화는 메인 드로잉 사이클 이전에 이루어져야 한다는 점에 주목합니다. for(;;).

    프로젝트를 조립하고 실행해 보겠습니다.

    그리고 다시, 우리가 보고 싶은 것이 아닌가?

    사실 그리기는 메인 루프가 반복될 때마다 발생하지만 그게 전부입니다. 이 반복 이전에 그려진 모든 내용은 지워지지 않고 화면에 남아 있습니다. 이 문제는 새로운 화면을 렌더링할 때마다 화면을 지우면 쉽게 해결할 수 있습니다. 화면을 채우려면(이 경우 지우려면) 다음 기능을 사용하세요.

    fill_screen()

    채우기 색상을 매개변수로 사용합니다. 정사각형을 그리기 전에 이를 추가하고 다시 어떤 일이 일어나는지 살펴보겠습니다.

    운! 이미지 로딩 및 그리기로 넘어 갑시다.

    Weaver에서 사용할 수 있는 유일한 이미지 형식은 . png , 우리는 그것을 사용할 것입니다. 모든 이미지가 해당 디렉토리에 있어야 한다는 점을 기억해야 합니다./이미지.

    먼저 이미지를 나타내는 표면 유형에 대한 포인터를 선언하고 초기화하겠습니다.

    표면 *face=new_image("face.png");

    new_image() 함수 하나의 인수, 즉 그래픽 파일 이름을 사용합니다.

    그래픽 파일을 표시하는 기능이 있습니다

    draw_surface()

    표시할 그래픽 파일에 대한 포인터를 인수로 사용합니다(표면 *원점 ), 어디에 대한 포인터(표면 *운명) 및 좌표(x, y).

    그래픽 파일은 다른 그래픽 파일 위에 그릴 수 있습니다. 단순히 화면에 그리려면 window를 운명 매개변수로 지정해야 합니다. 이는 현재 그리기 창에 대한 포인터입니다.

    광장에 대한 불필요한 언급을 제거하고 프로젝트를 조립하여 실행해 보겠습니다.

    우리의 노력의 결과:

    그림을 보다 편리하게 조작하기 위해 그림에 대한 포인터와 화면상의 좌표로 구성된 구조를 만듭니다.

    구조체 그림(

    표면 *fc;

    정수 x;

    정수 y;

    이미지를 다시 만들고 초기화해 보겠습니다.

    얼굴.fc=new_image("얼굴.png");

    얼굴.x=100;

    얼굴.y=100;

    표시되도록 해보자:

    draw_surface(face.fc, window,face.x, 얼굴.y);

    이제 키보드에 대한 지식을 사용하여 이미지의 위치를 ​​제어할 수 있습니다. 나는 당신에게 어떤 힌트도주지 않을 것입니다. 당신이 할 수 있기를 바랍니다.

    2.5.화면에 텍스트 출력하기.

    이 섹션은 아마도 당신을 실망시킬 것이지만 Weaver는 화면에 문자 메시지를 표시할 수 없습니다. 프로젝트에는 텍스트 출력을 담당하는 모듈이 있지만 사용되지 않습니다. 왜? 분명히 저자는 아직 이에 대한 준비가 되어 있지 않습니다. 그러나 그는 스스로 문제에 대한 해결책을 제안했습니다. 텍스트를 표시하기 위해 일종의 팔레트가 사용됩니다. 이미지에 배치된 문자 세트는 필요에 따라 문자를 가져와 화면에 표시합니다. 이 기술은 이전에 오래된(그리 오래되지는 않은) 게임에서 사용되었습니다.

    우리도 그것을 사용할 것입니다. 이를 위해 게임에 이미 입력된 문자가 포함된 사진을 업로드하겠습니다.

    표면 *font=new_image("font2.png");

    그래서 우리는 여러 글자가 놓여 있는 그림을 갖게 되었습니다. 필요한 편지를 어떻게 가져갈 수 있습니까? 이미지의 일부를 표시하기 위해 blit_surface() 함수가 사용됩니다. *src 매개변수는 원본 그래픽 파일에 대한 포인터를 받아들이고, *dest는 이미지 표면에 대한 포인터를 받아들입니다. (x_src, y_src) - 잘라낸 이미지가 시작될 좌표, width - 새 이미지의 너비, 높이 - 높이, (x_dest, y_dest) - 잘라낸 이미지가 표시될 대상 표면의 좌표입니다.

    함수 호출을 추가하고 무슨 일이 일어나는지 살펴보겠습니다.

    blit_surface(글꼴, 창, 0, 0, 90, 100, 500, 500);

    그다지 무섭지는 않지만 한 가지 질문이 남아 있습니다. 사진에는 진한 파란색 배경에 빨간색 글자가 있지만 빨간색 글자만 표시됩니다. 이는 기본적으로 진한 파란색(#00029a)이 투명한 것으로 간주되어 출력되지 않기 때문입니다. 이 특정 색상이 만족스럽지 않으면 transparent_color 변수에 다른 값을 설정하여 색상을 변경할 수 있습니다.

    2.5.사운드

    안타깝게도 오디오 파일 형식에도 제한이 있습니다. Weaver는 Ogg Vorbis 형식 파일만 재생합니다. 사운드를 재생하는 함수에는 play_music()과 play_sound()라는 두 가지 함수가 있습니다. 둘 사이의 차이점은 play_music()이 stop_music()이 호출될 때까지 음악을 반복한다는 것입니다. play_sound() 함수는 음악 파일을 한 번만 재생하며 이 함수의 재생을 제어할 수 없습니다. 분명히, 게임의 배경음을 재생하는 데는 play_music()이 더 좋고, 음향 효과를 재생하는 데는 play_sound()가 더 좋습니다.

    소리를 재현해 봅시다. play_sound()의 경우 파일은 각각 sound 디렉터리에 있어야 하고, play_music()의 경우 music 디렉터리에 있어야 합니다.

    메인 루프 앞에 다음을 추가해 보겠습니다.

    play_sound("sound.ogg");

    그런 다음 평소와 같이 게임을 조립하고 실행하겠습니다. 그런데, 총소리가 들립니다.

    2.6 충돌 감지

    객체 간의 충돌을 확인하기 위해 이름에 접두사가 있는 함수 세트가 사용됩니다.충돌_* . 다른 것만큼 사용하기 쉽습니다. 예를 들어 두 개의 직사각형을 만들어 보겠습니다.

    직사각형 직사각형1, 직사각형2;

    렉트1.x=렉트1.y=50;

    REC1.W=REC1.Z=25;

    렉트2.x=렉트2.y=150;

    렉트2.w=렉트2.z=50;

    그 중 하나가 움직일 것입니다:

    if (키보드)

    Rect1.x-=10;

    if (키보드)

    직사각형1.x+=10;

    if (키보드)

    Rect1.y-=10;

    if (키보드)

    Rect1.y+=10;

    그리고 충돌을 확인하고 이에 반응하는 마지막 부분은 다음과 같습니다.

    if (collision_직사각형_사각형(&Rect1, &Rect2))

    부서지다;

    당연히 명확성을 위해 화면에 직사각형을 표시해야 합니다.

    이제 우리는 우리만의 작은 게임을 작성해 볼 만큼 충분히 알고 있습니다. 장애물은 없지만 적이 있는 매우 단순화된 마리오가 될 것입니다.

    의 시작하자!

    3.1. 프로젝트 이름은 YAM(Yet Another Mario)입니다.

    직공 참마

    모두 훌륭하지만 어디서부터 시작해야 할까요? 우선, 게임의 인터페이스를 생각해낸 다음, 게임의 그래픽 디자인에 필요한 리소스를 찾는 것이 좋습니다. 이게 뭔가요? 이는 캐릭터 스프라이트, 배경 이미지, 문자 팔레트일 수 있습니다.

    인터페이스에 대해. 실제로 게임은 짧은 레벨이므로 한 번에 완료해야 합니다.

    이제 스프라이트에 대해. Wikipedia에서 이에 대한 자세한 내용을 읽을 수 있습니다. 게임에서 추출한 스프라이트와 "이를 기반으로" 만든 원본 스프라이트를 모두 찾을 수 있는 사이트가 많이 있습니다. 최소한 두 가지 유형의 스프라이트가 필요합니다. 하나는 Mario용이고 다른 하나는 상대방용입니다. 인터넷 검색 후 스프라이트 데이터베이스가 있는 여러 사이트를 찾았습니다. 그 중 하나는 단일 이미지에 스프라이트가 배치되어 있고 다른 사이트는 별도의 이미지로 제공되었습니다. 구분되는 위치를 선택해 보겠습니다. 캐릭터 애니메이션을 보다 편리하게 생성하려면 이 정보가 필요합니다.

    3.2. 이동 키를 눌렀을 때 정지된 그림이 움직이는 것뿐만 아니라 최소한 어느 정도 움직이는 것처럼 보이기를 원하므로 캐릭터에 애니메이션을 적용해야 합니다. 이는 일련의 유사한 이미지를 사용하여 수행되며 차이점은 세부 사항에만 있습니다.

    마리오 애니메이션에는 3가지 유형의 스프라이트가 있습니다.

    여러분도 익히 알고 계시리라 생각되는 애니메이션의 원리는 단순히 여러 장의 사진을 연속적으로 이미지화하는 것입니다.

    문자 데이터를 저장할 구조를 만들어 보겠습니다.

    구조체 문자(

    표면 *fc;

    정수 x;

    Int y;);

    Mario에 대한 변수를 초기화해 보겠습니다.

    Mario.x=mario.y=100;

    Mario.fc=new_image("mw1.png");

    Mario.fc=new_image("mw2.png");

    Mario.fc=new_image("mw3.png");

    그리고 마지막으로 캐릭터 애니메이션부터 시작해 보겠습니다. 그런데 화면이 0.01초마다 업데이트되기 때문에 이미지가 매우 자주 바뀌게 됩니다. 이 문제는 FPS 값을 줄이거나, weaver_rest() 함수에 현재 값보다 큰 값을 전달하거나, 주어진 프레임에 어떤 스프라이트가 표시될지 결정하는 프레임 카운터를 사용하여 해결할 수 있습니다. 우리는 카운터 방법을 사용할 것입니다.

    메인 루프 전에 카운터가 될 변수 카운터를 생성합니다.

    정수 카운터=0;

    그리고 메인 루프에서는 카운터를 확인하고 해당 값에 따라 하나 또는 다른 애니메이션 스프라이트가 그려집니다.

    만약(카운터<=10){

    카운터++;

    If (카운터>10 && 카운터<=20){

    Draw_surface(mario.fc, window, mario.x, mario.y);

    카운터++;

    (카운터>20 && 카운터인 경우<=29){

    Draw_surface(mario.fc, window, mario.x, mario.y);

    카운터++;

    (카운터>29)

    카운터=0;

    완료되면 프로젝트를 어셈블하고 시작할 수 있습니다.

    같은 방식으로 마리오의 상대에게도 애니메이션을 적용합니다.

    이제 마리오가 이길 수 있는 기회를 조금이라도 가질 수 있도록 점프 가능성을 구현하겠습니다. 모든 것이 간단합니다. 키를 누르면 수직 좌표 값이 변경됩니다.

    그 후에는 Mario와 상대방 간의 충돌 처리를 시작할 수 있습니다. 이를 위해 게임 캐릭터를 설명하는 구조에 직사각형을 추가하고 교차점을 추적합니다.

    이제 구조는 다음과 같습니다.

    구조체 문자(

    표면 *fc;

    정수 x;

    정수 y;

    직사각형 col_det;);

    문자의 기본 값을 설정하고(원칙적으로 메인 루프에서 업데이트되므로 필요하지 않음) 직사각형을 스프라이트 좌표에 바인딩하기 위해 두 줄을 추가합니다. 명확성을 위해 직사각형이 잠시 동안 빨간색으로 나타나도록 하고 마지막에 이를 제거하겠습니다. 실행하고 무슨 일이 일어나는지 봅시다.

    이제 우리는 직사각형의 교차점에 대한 답을 구현하기 시작할 수 있습니다; 이를 위해 우리는 이미 친숙한 collsion_lectangle_lectangle() 함수를 사용합니다:

    if (collision_직사각형_직사각형(&mario.col_det, &bowser.col_det))

    부서지다;

    그게 다입니다. 캐릭터가 충돌하면 게임이 종료됩니다. 간단하고 쉽게.

    3.3. 이제 게임에 마무리 작업을 추가해야 합니다. 배경 및 음향 효과

    음향 효과와 배경 음악을 추가하기 위해 play_music()/stop_music() 및 play_sound() 함수를 사용하겠습니다.

    컨트롤은 간단합니다 - 왼쪽 화살표 - 오른쪽 화살표 - 이동, 위쪽 화살표 - 점프

    그래서 훌륭한 게임의 불쌍한 패러디가 준비되었습니다. 원한다면 구름, 수풀, 그리고 물론 버섯도 추가할 수 있습니다.

    보시다시피, C만을 사용하여 게임을 작성하는 것은 꽤 쉽지만, 잘하는 것은 훨씬 더 어렵습니다.

    마지막으로 유용한 링크의 작은 목록

    http://weaver.nongnu.org /는 자세한 문서와 코드 예제를 모두 찾을 수 있는 Weaver 프레임워크 웹사이트입니다.

    기사의 예를 반복하려면 게임 소스 코드가 포함된 아카이브 링크를 참조하세요.http://narod.ru/disk/16196657001/yam.tar.gz.html.

    118.0KB 신규

    JavaScript ES6 HTML5, 17레벨로 작성된 2D 게임.

    게시자: xAtom | 자바스크립트 | 모든 OS

  • 스네이크(WinAPI) 255.8Kb

    이 게임은 C++14의 CodeBlocks 17.12(유니코드) 환경에서 WinAPI로 작성된 2D입니다.

    게시자: xAtom | 비주얼 C++ | 윈도우 NT/2000/XP/비스타/7

  • xzGame - 틱택토 3.9 Kb

    맛이 있는 틱택토))
    직접 확인하실 수 있습니다. txt 파일을 꼭 읽어보세요.

    [이메일 보호됨]
    어떤 질문에 대해서도

    게시자: kalandar | C/C++ | 윈도우 NT/2000/XP/비스타/7

  • 501

    지도 주위를 이동하고 카메라를 회전하는 기능을 갖춘 간단한 Raycast 그래픽의 예입니다. 어셈블리 언어에서 FASM 컴파일러는 실제 모드에서 작동합니다. 13h 비디오 모드 BIOS 320x200, 256 컬러 모드가 사용됩니다.

    BIOS 인터럽트가 사용됩니다.
    - 지능 10시간
    - 지능 16시간

    그래픽 셸 기능:
    - 화면 채우기
    - 스프라이트 그리기
    - 직사각형 그리기(간단한 선)
    그래픽 쉘의 특징
    - 가벼운 무게, 단순함
    - 비디오 버퍼를 사용하여 프레임 생성

    이 버전에서는 카메라를 회전할 수 있고, 빔을 던져서 장면을 그릴 수 있으며, 빔이 길수록 장애물이 멀고 멀수록 작아집니다.

    이 소스의 장점:
    - 거의 완벽하게 작동하는 레이캐스트
    - 카메라 회전 가능성
    - 공간 이동 능력.
    단점:
    - 낮은 성능에는 최적화가 필요함

    게임 소스:
    http://catcut.net/CAPB
    유튜브 채널:
    https://www.youtube.com/TypeProgrammer
    프로젝트 웹사이트:
    http://neosoft.pp.ua

    게시자: 유형 프로그래머 | 어셈블러 | 모든 OS

  • ConfigIL2 프로그램 소스 5265.1Kb

    IL-2 게임의 매개변수 설정을 위한 프로그램의 소스 코드입니다. VB6 프로그래밍 언어. 아카이브에는 플러그인 라이브러리를 포함하여 필요한 모든 파일과 리소스가 포함되어 있습니다.

    게시자: Alik044 | 비주얼 베이직 | 윈도우 NT/2000/XP/비스타/7

  • 시티 레이스 12255.4 Kb

    Gravity Games 팀이 일부 실망한 게임인데, 게임이 별로 좋지 않고, 모두 버그가 있습니다. 이 2D 레이스에서는 자동차, 터보 등에 손상이 발생합니다. 이 게임은 Construct 2에서 만들어졌습니다.

    게시자: 관리자 | 문서 | 모든 OS

  • 크롤러 로봇 1637.6Kb

    2D 게임 크롤러 로봇, Android용 Eclipse 환경에서 제작된 12레벨 게임입니다.

    게시자: xAtom | 자바 | 기타 OS

  • 어셈블러 셀룰러 오토마톤, 게임 501

    셀룰러 자동 장치 또는 어셈블러의 "생명" 게임인 FASM 컴파일러는 리얼 모드에서 작동합니다. 13h 비디오 모드 BIOS 320x200, 256 컬러 모드가 사용됩니다. 이 코드는 리얼 모드의 베어메탈에서 실행됩니다.


    http://catcut.net/tihx


    http://catcut.net/7Nqw

    [이메일 보호됨]

    프로젝트 웹사이트:
    http://neosoft.pp.ua

    게시자: 유형 프로그래머 | 어셈블러 | 모든 OS

  • 조립 게임 체커 501

    FASM 컴파일러인 어셈블러에서 체커 게임을 만들기 위한 템플릿은 리얼 모드에서 작동합니다. 13h 비디오 모드 BIOS 320x200, 256 컬러 모드가 사용됩니다.
    이 소스코드에는 승리와 패배의 조건도 없고, 왕도 없습니다.

    운전의 경우:
    W,S,D,A - 경기장을 돌아다니며 이동합니다.
    Enter - 검사기를 선택한 다음 이동해야 하는 셀로 돌아갑니다.

    소스는 여기에서 다운로드할 수 있습니다:
    http://catcut.net/5ZGy
    가끔 새로운 프로그램의 비디오와 소스가 나타나는 프로젝트 채널도 있습니다:
    https://www.youtube.com/channel/UCTVn_Azy0WTDGAh7OYNReJg?view_as=subscriber

    그리고 그렇습니다. 채널에는 소스 코드가 포함된 자체 서버가 있습니다. 소스는 대부분 어셈블러(거의 모든 쓰레기)에 있지만 C++, C 운영 체제 및 Pascal 프로그램에도 있습니다.
    http://catcut.net/7Nqw
    소스를 서버에 추가하려면 이메일로 저에게 편지를 보내주세요.
    [이메일 보호됨]
    (예, 익명성은 제 관심사가 아닙니다...)

    프로젝트 웹사이트:
    http://neosoft.pp.ua

    게시자: 유형 프로그래머 | 어셈블러 | 모든 OS

  • 공의 모험 1537.6 Kb

    2D 게임 볼 어드벤처, 25레벨. Android의 경우 Eclipse를 사용하여 게임을 만들었습니다.

    게시자: xAtom | 자바 | 기타 OS

  • 마지막 경기에서 누가 무승부를 기록하는지 알아보는 어셈블리 언어의 간단한 게임입니다. 501

    2인용 간단한 게임에서는 마지막에 비긴 사람이 패배하게 됩니다.
    (게임은 간단하지만, OS 없이 실행이 가능하다는 장점이 있습니다)

    소스는 여기에서 다운로드할 수 있습니다:
    http://catcut.net/YMqw
    가끔 새로운 프로그램의 비디오와 소스가 나타나는 프로젝트 채널도 있습니다:
    https://www.youtube.com/channel/UCTVn_Azy0WTDGAh7OYNReJg?view_as=subscriber

    그리고 그렇습니다. 채널에는 소스 코드가 포함된 자체 서버가 있습니다. 소스는 대부분 어셈블러(거의 모든 쓰레기)에 있지만 C++, C 운영 체제 및 Pascal 프로그램에도 있습니다.
    http://catcut.net/7Nqw
    소스를 서버에 추가하려면 이메일로 저에게 편지를 보내주세요.
    [이메일 보호됨]
    (예, 익명성은 제 관심사가 아닙니다...)

    게시자: 유형 프로그래머 | 어셈블러 | 기타 OS

  • 어셈블리 언어로 된 간단한 그래픽 게임입니다. 501

    리얼 모드에서 실행되는 어셈블리 언어 FASM 컴파일러의 간단한 게임입니다. 13h 비디오 모드 BIOS 320x200, 256 컬러 모드가 사용됩니다. 너비와 높이의 원시 충돌.

    게임의 본질은 혜성이 우주선에 들어가는 것을 방지하는 것입니다. 이를 위해 프레임까지 왼쪽이나 오른쪽으로만 이동할 수 있으며, 시간이 지남에 따라 게임 속도가 빨라지고 플레이어가 질 때까지 게임이 계속됩니다.

    소스는 여기에서 다운로드할 수 있습니다:
    http://catcut.net/KMqw

    가끔 새로운 프로그램의 비디오와 소스가 나타나는 프로젝트 채널도 있습니다:
    https://www.youtube.com/channel/UCTVn_Azy0WTDGAh7OYNReJg?view_as=subscriber

    그리고 그렇습니다. 채널에는 소스 코드가 포함된 자체 서버가 있습니다. 소스는 대부분 어셈블러(거의 모든 쓰레기)에 있지만 C++, C 운영 체제 및 Pascal 프로그램에도 있습니다.
    http://catcut.net/7Nqw
    소스를 서버에 추가하려면 이메일로 저에게 편지를 보내주세요.
    [이메일 보호됨]
    (예, 익명성은 제 관심사가 아닙니다...)

  • 질문: 처음부터 게임을 만드는 데 어떤 조언이 있나요?


    좋은 시간. 최근 그는 Papers, Please 및 Hotline Miami와 같은 장난감에서 영감을 받았습니다. 나는 게임을 만드는 것에 대한 나만의 아이디어를 가지고 있습니다. 하지만 문제는 무엇을 쓰는 것이 더 좋은지 모른다는 것입니다. PC용으로 3D가 아닌 탑뷰로 게임을 기획했습니다. 업무용으로는 1C로 작성하지만 게임용으로는 작성하지 않습니다. 열심히 노력하면 가능하지만 Java의 기본도 공부했습니다. 기본적인 지식을 얻으려면 먼저 틱택토나 뱀과 같은 간단한 것을 시도해 보는 것이 더 낫다는 것을 이해합니다.
    인터넷에서는 C++ 사용을 제안하지만 C# + XNA 사용도 제안합니다. 게임 제작 경험이 있는 분이라면 문헌을 추천해 주시거나 처음부터 게임 프로그래밍에 대한 조언을 부탁드립니다.

    답변:

    보낸 메시지 몬테크리스토

    문학을 추천하다

    불행히도 러시아어로 된 문헌, 특히 고품질의 문헌은 거의 없습니다. 모든 것이 번역되는 것은 아니며 즉시 번역되지도 않으며 때로는 잘 번역되지 않는 경우도 있습니다. 원작이 출판되고 2년 후에 책이 번역되는데, 원작의 새 버전이 이미 출시되었고 첫 번째 버전은 구식이 되는 경우가 있습니다. 그래서 나는 Lingvo와 Translate.google.com을 사용하여 영어를 공부하고 최신 도서를 번역합니다.

    여기에서 다양한 언어와 기술로 게임 제작에 관한 책을 검색할 수 있습니다.

    그러나 어떤 경우에도 다음 카테고리의 책으로 시작하지 마십시오: 프로그레시브 및 마스터링

    "i"를 클릭하면 섹션의 의미를 확인할 수 있습니다. 등록 후에도 예제를 무료로 다운로드할 수 있습니다. 나는 이것을 그림으로 보여주었다.

    질문: C로 게임을 만드시나요?

    답변: 30분 후에 추가됨

    보낸 메시지 하이프레데터

    일반적으로 C로 모든 것을 작성할 수 있습니다. 욕망, 두뇌, 시간이 있을 것입니다.

    의욕은 있는데 머리가 없어서 때를 찾아보겠다 >< Благодарю!

    보낸 메시지 맥페어

    또한 엔진 없이 OpenGL 학습을 시작하고 몇 가지 Tetris 게임을 만들어 보면 무엇이 무엇인지 확인할 수 있습니다.

    엔진을 직접 작성해야 할 것 같습니다.

    보낸 메시지 맥페어

    7. 완전히 불명확한데, 그림의 일부를 잘라서 큐브 위에 올려놓아야 할까요?

    예, 개체를 그리고 이미지를 오버레이하여 텍스처를 만듭니다.

    보낸 메시지 사이버 사티로스

    예를 들어 GTK는 십자가입니다. 따라서 Venda의 경우 winapi를 사용하면 순전히 간단한 인터페이스를 갖습니다.

    감사합니다! 그게 내 뜻이야

    보낸 메시지 맥페어

    8. 게임, 목표 및 프로그래밍 스타일에 따라 다르며 모든 것을 고려해야 합니다. C와 Sharp에서 동일한 프로젝트를 수행하면 물론 C가 많이 승리하지만 Sharp에서는 개발 속도가 빨라집니다. 내 생각에는 2/3 정도.

    좋은 선택은 아마도 그것들을 결합하는 것입니다. 기본은 샤프로 작성하고 기능은 C로 추가?)

    질문: MMORPG 게임 만들기


    안녕하세요. 저는 최근에 2D 게임 제작에 대해 배운 주제를 여기에서 만들었습니다.
    그래도 나는 어떤 방향으로 공부해야 할지 알아보기로 결심했습니다.
    다음은 2개의 스크린샷입니다.
    http://kape.cc/uploads/posts/2011-05...a630f08343.jpg
    http://mmohuts.com/wp-content/galler..._07.jpg?bb7a3b
    그리고 비디오:

    이런 게임을 만들어야 해요. 일반적으로 위치는 그리드 시스템입니다. 위치는 몇 개의 큐브로 나누어져 있습니다.
    그래픽, 사운드, 사운드 라이브러리가 필요하다는 것은 이해합니다. 하지만 먼저 사운드 라이브러리를 살펴보겠습니다.
    그래픽은 잊어버리세요(일부 있다고 가정해 보겠습니다). 소리가 있습니다.
    ++ + OpenGL과의 조합이 내 요구 사항과 유사한 게임 생성을 충족하는지 묻고 싶습니다. 즉, 애니메이션이 포함된 셀을 통해 개체 이동, 개체 충돌, 스프라이트에서 그래픽 가져오기 + 골격 애니메이션(알몸 캐릭터 + 바인딩 개체 - 그래픽, 캐릭터의 신체(천)).

    답변: 8관찰자8, 나는 물리학이 그렇게 필요하다는 것을 깨닫기 전까지는 결코 물리학을 좋아하지 않았습니다... 그러나 지금, 나는 계획한 게임에 Box2D가 확실히 필요하지 않다는 것을 깨달았습니다... SFML에 대한 문서를 본 다음 오늘은 이전 작업을 둘러보았습니다. 벽과 상호 작용할 수 있었고 얼마나 많은 행복이 있었는지)) 방법을 이해하는 데 약 1~2시간이 걸렸지만 그만한 가치가 있습니다.
    그건 그렇고, 적어도 Bomberman의 첫 번째 레벨을 만들어보고 싶습니다)

    10분 후에 추가됨
    추신 C++도 동시에 배우고 있어요

    질문: 처음부터 끝까지 게임 제작에 관한 문헌을 추천해 주세요.


    처음부터 끝까지 게임 제작에 관한 문헌을 추천하세요. C++에서는 모든 요소를 ​​사용할 수 있습니다. 2010~2015년 출판사에서 나온 신간만

    답변:그림을 그릴 때 DirectX와 OpenGL 중 무엇을 사용하시겠습니까? 게임이론에 관한 일반 서적이 있는지 살펴보았습니다 --> . 2D, 3D, RPG, 슈팅 게임, 레이싱, 체스, 바둑 등 어떤 종류의 게임을 작성하시겠습니까? 이 게임들은 모두 서로 다른 특징을 가지고 있습니다

    질문: 게임을 만드는 중


    안녕하세요 간단한 게임(rpg)을 만들려고 했는데요. 그냥 "나 자신을 위해" 할 거예요. 게임은 정적입니다(문자, 개체 등의 bmb 사진, 아마도 gif). 이것이 일반적으로 어떻게 수행되는지 검색하기 위해 인터넷을 뒤지기 시작했을 때 나는 델파이용으로 미리 만들어진 구성 요소를 많이 발견했습니다(예: delphix) ) 따라서 다음과 같은 것을 사용할 가치가 있는지 질문이 생겼습니다. 아니면 캔버스에 모든 것을 직접 그리는 것이 더 낫습니까?

    답변:

    미스터 드미트리,
    정적 게임? 이것은 건축 프로그램에서 새로운 것입니다.
    그녀가 정말로 그런 사람이라면 TImage로 충분합니다.
    하지만 이것이 역동적인 게임이라면 TPaintBox가 필요할 것입니다.

    아는 사람은 거의 없지만 복수의 Delphi에는 3개의 미니 게임을 포함한 샘플 프로그램이 함께 제공됩니다!

    Windows 7에서는 시작 | 모든 프로그램 | 엠바카데로 RAD Studio XE5 | 견본.

    이 폴더가 있어요
    C:\Users\Public\Documents\RAD Studio\12.0\Samples\

    구성 요소 및 엔진에 관해서.
    구성 요소는 즉시 잊어 버리십시오. 당신을 위해 게임을 만들 구성 요소는 없습니다. 게임은 손과 머리로 작성됩니다.

    엔진에 관해서. 엔진은 개발 속도를 높입니다.
    엔진에서는 이미 만들어진 코드를 찾을 수 있습니다. 게임에 맞는 엔진을 선택해야 합니다.

    엔진에서 수학 및 기하학 라이브러리를 살펴보는 것이 좋습니다. 대륙과 멀티미디어 작업을 위한 도서관입니다. 프로그램은 어떤 파일 형식을 지원합니까?
    카메라 지원. 특수 효과 지원.

    2D나 3D 게임이라고 하지 않으셨는데요.
    스프라이트 및 빌보드 지원 여부. 텍스트 출력.

    14분 34초 후에 추가됨
    나는 당신이 흥미로울 것이라고 생각합니다. 게임을 만들기 위해 방문한 사이트가 있습니다.

    여기에서는 게임에 대한 아이디어와 구현에 대한 아이디어를 모두 엿보고 빌릴 수 있습니다.

    질문: Visual Studio에서 자신만의 언어 만들기


    저는 Visual Studio에서 자신만의 언어를 만드는 방법에 대한 명확한 단계별 예제/강의를 찾고 있습니다.

    언어의 예를 찾았지만 무엇을, 어떻게, 왜 이해해야 하기 때문에... 내 asm은 별로 좋지 않아.

    --
    일반적으로 다음이 필요합니다.
    스튜디오에 있는 ASMA의 "크로스 컴파일러"를 코드 힌트와 함께 Z80 프로세서용 코드로 변환합니다(아직 하드웨어나 에뮬레이터에 로드하는 방법을 찾지 못했습니다. 이것이 다음 단계입니다).

    요구사항:
    편집자 - Sun 자신(2013);
    불필요한 모듈 없이 화면에 어셈블러 Z80 코드가 표시됩니다.
    프로젝트를 생성할 때 언어를 선택합니다(C#, F#, VB.NET 등의 언어 목록이 있음).

    답변:하지만 Studio 2013을 강조하고 표시하도록 어떻게 "말"할 수 있을까요?

    질문: C++ 엔진을 사용하여 게임 만들기


    여러분, C++ 엔진을 사용하여 게임을 만들 수 있도록 도와주세요. Doodle Jump, 아날로그에 감사드립니다. 문제는 제가 이 공부를 시작한 지 얼마 되지 않았다는 것입니다. 그리고 나는 올바른 프로그램을 작성할 수 없습니다. 분명히 나는 ​​여전히 특정한 멍청한 놈입니다. 미리 감사드립니다!
    공유하다: