C 언어 판 flappybird 실현

18760 단어 C/C++
실험 설명
1.환경 소개
이 실험 환경 은 데스크 톱 이 있 는 Ubuntu Linux 환경 을 사용 합 니 다.실험 에 서 는 데스크 톱 프로그램 을 사용 합 니 다.
LX 터미널(LXTerminal):Linux 명령 행 터미널 입 니 다.열 면 Bash 환경 에 들 어가 Linux 명령 을 사용 할 수 있 습 니 다
GVim
2.환경 사용
GVim 편집기 로 실험 에 필요 한 코드 및 파일 을 입력 하고,LX 터미널(LXTerminal)에서 필요 한 명령 을 실행 하여 작업 합 니 다.실험 을 마 친 후 데스크 톱 위의'실험 캡 처'를 클릭 하여 실험 결 과 를 웨 이 보 에 저장 하고 공유 하여 친구 에 게 자신의 학습 진 도 를 보 여줄 수 있 습 니 다.실험 건물 은 백 스테이지 시스템 캡 처 를 제공 하여 당신 이 이미 실험 을 완성 했다 는 것 을 진실 하고 효과적으로 증명 할 수 있 습 니 다.실험 기록 페이지 는'나의 홈 페이지'에서 볼 수 있 습 니 다.그 중에서 매번 실험의 캡 처 와 노트,그리고 매번 실험의 효과 적 인 학습 시간(실험 데스크 톱 에서 조작 하 는 시간 을 말 합 니 다.조작 하지 않 으 면 시스템 은 멍 때 리 는 시간 으로 기록 합 니 다)을 포함 합 니 다.이것들 은 모두 당신 이 배 운 진실성 증명 입 니 다.본 과정 중의 모든 소스 코드 는 다음 과 같은 방식 으로 다운로드 할 수 있다.
프로젝트 소개
이번 우리 의 프로젝트 는 flappy bird 게임 입 니 다.이번 에는 당신 의 키 보드 를 칠 준 비 를 하 세 요.최종 효과 도 는 이 렇 습 니 다.
3.프로젝트 실전
1.기초 지식
우리 의 프로젝트 는 데이터 구조의 지식 을 사 용 했 고 Liux 의 일부 시스템 호출 과 관련 되 어 우리 가 Liux 의 프로그램 디자인 에 대한 깊 은 이 해 를 강화 하 는 데 도움 이 되 었 다.그 밖 에 우 리 는 텍스트 인터페이스의 화면 그래 픽 라 이브 러 리 ncurses 를 사 용 했 습 니 다.컴 파일 할 때-lcurses 옵션 을 추가 해 야 합 니 다.
1.1.ncurses 라 이브 러 리 설치
     sudo apt-get install libncurses5-dev

2.디자인 사고
우리 의 flappy bird 게임 에서 가장 중요 한 두 가 지 는 키보드 입력 과 정시 그림 그리 기 에 응답 하 는 것 입 니 다.이것 은 Liux 가 제공 하 는 시스템 함수 와 우리 가 사용 하 는 ncurses 라 이브 러 리 를 결합 하여 완성 해 야 합 니 다.또 다른 문 제 는 bird 가 앞으로 날 아 가 는 것 처럼 보이 게 하 는 방법 이다.bird 를 계속 움 직 이면 화면 범 위 를 넘 어 설 수 밖 에 없다.bird 가 제자리 에 있 고 배경 이 bird 방향 으로 계속 움 직 일 수 있 도록 거꾸로 생각해 보 자.이렇게 해서 마치 bird 가 계속 앞으로 이동 하 는 효 과 를 가 져 왔 다.
3.시작
우 리 는 먼저 기본 적 인 작업 을 완성 합 니 다.우 리 는 터미널 문자 인터페이스 이기 때문에 모든 것 이 ASCII 문자 와 떨 어 질 수 없습니다.우 리 는 상수 들 을 정의 해 야 합 니 다.우 리 는 배경 에 있 는 기둥 을'*'로 표시 하고'O'로 bird 를 표시 합 니 다.자,코드 는 다음 과 같 습 니 다.
include 
include 
include 
include 

define CHAR_BIRD 'O'
define CHAR_STONE '*'
define CHAR_BLANK ' '

배경 에 있 는 기둥 은 링크 구조 로 구조 체 로 다음 과 같이 정의 합 니 다.
typedef struct node {
    int x, y;
    struct node *next;
}node, *Node;

전역 변수 가 몇 개 더 필요 합 니 다.
Node head, tail;
int bird_x, bird_y;
int ticker;

호출 이 편리 하도록 하기 위해 서,우 리 는 먼저 우리 가 정의 한 함 수 를 설명 합 니 다.
void init();
void init_bird();
void init_draw();
void init_head();
void init_wall();
void drop(int sig);
int set_ticker(int n);

4.정시 문제
이제 배경 을 정시 에 움 직 이 는 문 제 를 해결 합 시다.Liux 시스템 은 우리 에 게 신호 라 는 개념 을 제공 하여 우리 의 문 제 를 해결 할 수 있다.신호 가 뭔 지 몰라 요?괜 찮 습 니 다.말하자면 Liux 커 널 에 타이머 가 있 습 니 다.일정 시간 마다 우리 프로그램 에 신 호 를 보 냅 니 다.우리 의 신호 수신 함 수 는 자동 으로 실 행 됩 니 다.우 리 는 신 호 를 받 는 함수 에서 배경 을 이동 하면 됩 니 다.커 널 에서 보 내 는 신호 이기 때문에 우리 키보드 가 차단 되 어 막 히 지 않 습 니 다.어 때,쉽 지 않 아?다음은 우리 의 코드 를 쓰 겠 습 니 다.
    int set_ticker(int n_msec)
    {
        struct itimerval timeset;
        long n_sec, n_usec;

        n_sec = n_msec / 1000;
        n_usec = (n_msec % 1000) * 1000L;

        timeset.it_interval.tv_sec = n_sec;
        timeset.it_interval.tv_usec = n_usec;

        timeset.it_value.tv_sec = n_sec;
        timeset.it_value.tv_usec = n_usec;

        return setitimer(ITIMER_REAL, &timeset, NULL);
    }

               ,            :

void drop(int sig)
{
    int j;
    Node tmp, p;
//draw bird
    move(bird_y, bird_x);
    addch(CHAR_BLANK);
    refresh();
    bird_y++;
    move(bird_y, bird_x);
    addch(CHAR_BIRD);
    refresh();
    if((char)inch() == CHAR_STONE) {
        set_ticker(0);
        sleep(1);
        endwin();
        exit(0);
    }
//first wall out of screen?
    p = head->next;
    if(p->x < 0) {
        head->next = p->next;
        free(p);
        tmp = malloc(sizeof(node));
        tmp->x = 99;
        do {
            tmp->y = rand() % 16;
        } while(tmp->y < 5);
        tail->next = tmp;
        tmp->next = NULL;
        tail = tmp;
        ticker -= 10;  //speed up!
        set_ticker(ticker);
    }
//draw new walls
    for(p = head->next; p->next != NULL; p->x--, p = p->next) {
        for(j = 0; j < p->y; j++) {
            move(j, p->x);
            addch(CHAR_BLANK);
            refresh();
        }
        for(j = p->y+5; j <= 23; j++) {
            move(j, p->x);
            addch(CHAR_BLANK);
            refresh();
        }

        if(p->x-10 >= 0 && p->x < 80) {
            for(j = 0; j < p->y; j++) {
                move(j, p->x-10);
                addch(CHAR_STONE);
                refresh();
            }
            for(j = p->y + 5; j <= 23; j++) {
                move(j, p->x-10);
                addch(CHAR_STONE);
                refresh();
            }
        }
    }
    tail->x--;
}

우 리 는 신호 수신 함수 에서 배경 을 한 열 앞으로 이동 시 키 고 bird 를 한 줄 아래로 떨 어 뜨 렸 으 며,bird 가 기둥 에 부 딪 혔 는 지 확인 하려 면 game over 입 니 다.
5.주 함수
코드 먼저 보기:
int main()
{
    char ch;

    init();
    while(1) {
        ch = getch();
        if(ch == ' ' || ch == 'w' || ch == 'W') {
            move(bird_y, bird_x);
            addch(CHAR_BLANK);
            refresh();
            bird_y--;
            bird_y--;
            move(bird_y, bird_x);
            addch(CHAR_BIRD);
            refresh();
            if((char)inch() == CHAR_STONE) {
                set_ticker(0);
                sleep(1);
                endwin();
                exit(0);
            }
        }
        else if(ch == 'z' || ch == 'Z') {
            set_ticker(0);
            do {
                ch = getch();
            } while(ch != 'z' && ch != 'Z');
            set_ticker(ticker);
        }
        else if(ch == 'q' || ch == 'Q') {
            sleep(1);
            endwin();
            exit(0);
        }
    }

    return 0;
}

우 리 는 main 에서 먼저 초기 화 를 한 후에 순환 중 에 키보드 입력 을 받는다.w 나 스페이스 바 가 눌 리 면 우리 bird 는 위로 두 줄 을 날 고,q 가 눌 리 면 게임 을 종료 하고,z 가 눌 리 면 게임 을 중단 합 니 다.다음은 init 함수:
void init()
{
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    srand(time(0));
    signal(SIGALRM, drop);

    init_bird();
    init_head();
    init_wall();
    init_draw();
    sleep(1);
    ticker = 500;
    set_ticker(ticker);
}

init 함 수 는 먼저 화면 을 초기 화하 고 ncurses 가 제공 하 는 함 수 를 호출 한 다음 각 하위 함 수 를 호출 하여 초기 화 합 니 다.신호 수신 함수 drop 을 설치 하고 시간 을 정 했 습 니 다.각 초기 화 자 함 수 는 다음 과 같다.bird 위치 초기 화:
void init_bird()
{
    bird_x = 5;
    bird_y = 15;
    move(bird_y, bird_x);
    addch(CHAR_BIRD);
    refresh();
    sleep(1);
}

배경 에 있 는 기둥 링크 구조 초기 화:
void init_head()  //with header
{
    Node tmp;

    tmp = malloc(sizeof(node));
    tmp->next = NULL;
    head = tmp;
    tail = head;
}

void init_wall()
{
    int i;
    Node tmp, p;

    p = head;
    for(i = 19; i <= 99; i += 20) {
        tmp = malloc(sizeof(node));
        tmp->x = i;
        do {
            tmp->y = rand() % 16;
        }while(tmp->y < 5);
        p->next = tmp;
        tmp->next = NULL;
        p = tmp;
    }
    tail = p;
}

화면 초기 화:
void init_draw()
{
    Node p;
    int i, j;

    for(p = head->next; p->next != NULL; p = p->next) {
        for(i = p->x; i > p->x-10; i--) {
            for(j = 0; j < p->y; j++) {
                move(j, i);
                addch(CHAR_STONE);
                refresh();
            }
            for(j = p->y+5; j <= 23; j++) {
                move(j, i);
                addch(CHAR_STONE);
                refresh();
            }
        }
        sleep(1);
    }
}

6.컴 파일
gcc flappy_bird.c -o flappy_bird -lcurses

여기까지,우리 flappybird 게임 이 완성 되 었 습 니 다.

좋은 웹페이지 즐겨찾기