C language playing airplane games

Keywords: shell less C Windows

C language to achieve a simple small game of playing airplane

Compiling environment: vs2019

Demand:
In the same plane, control the three directions of artillery firing, launch shells in blank space, enemy and friendly aircraft will fly in the sky at random all the time, one point will be added for enemy aircraft flying in the sky, and one point will be deducted for friendly aircraft

Train of thought:
First initialize the program, then draw the description and map, then enter the infinite cycle, in which the aircraft can fly in the sky continuously, control the game content through the awd space bar, and add points when meeting the game conditions.

Practice:
First of all, to achieve the animation effect of the aircraft, the essence is to output a string on three x axes on the console, and make the three strings appear to move at the same time. Here I use the experience of writing horse race: in the first infinite cycle, I will output the first, second and third strings respectively to represent the first step, and then I will add three string x-axis coordinate values automatically. In the second infinite cycle, I will clear the last string movement trace, and then I will output three strings respectively to represent the second step. Because the inner for loop has no sleep function, it looks like the effect of three strings moving at the same time. In this way, the infinite cycle can be used to represent the continuous movement of three aircraft.
The next step is to change the direction (one character) of the cannon muzzle by getch function. When the muzzle point is switched, the initial position of the artillery shell will also change. When pressing the space, the artillery shell (one character) will move continuously along the set route from its initial position. When the horizontal and vertical axis coordinates match the plane coordinates, it is determined whether it is an enemy aircraft, If yes, the score will be increased by one, otherwise the score will be decreased by one.
In addition, there are many details in the program, which are not detailed here.

Difficulties:
It looks like three strings are moving at the same time. This is a kind of algorithm. If you learn it, you should remember it as well as the basic knowledge. After understanding the principle, it is easier to master.

Explain:
This is a simple small program. There are many ways to achieve the same effect in this program. However, I use a large number of arrays to store, count and use various data. In fact, similar effects can also be achieved through a single chain table. The use of arrays and direct output strings in my current understanding has the advantage of simplicity. But it also leads to a fatal defect in display effect.

Be careful:
Because of the compiler, the functions of_kbhit() and_getch() in the program may generate errors when compiling on other compilers. The solution is to remove the "_" in front of the function.

Operation effect:

Code implementation:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string.h>


void HideCursor();          //hide cursor
void gotoxy(int x, int y);  //Cursor location

#define R 26                //Max. x coordinate of random tail of aircraft per time
#define N 20                //Customs score

int ax[3] = { 0 };          //Three aircraft tail coordinates, global
int y[3] = { 3,7,11 };      //Three y-axis, global, look-up table method to determine the y-axis position of the aircraft   
                            //Because the projectile's flight distance is two squares at a time, the y-axis here must be even in order to be even
int i;                      //Cyclic variable
int fd[3];                  //Control aircraft type

void cshcxhs()                              //Initialization function
{
    system("title Play airplane games");           //Title
    system("mode con cols=100 lines=30");   //Width 100, height 30
    HideCursor();                           //Cursor hiding

    gotoxy(46, 12);                         //Introduce the rules of the game
    printf("Rules of the game:");
    gotoxy(36, 14);
    printf("w a d Key control direction, space bar shot");
    gotoxy(26, 16);
    printf("Hit enemy aircraft |---0> Add a point, hit the friendly plane >>>>>> Minus one point");
    gotoxy(40, 18);
    printf("Cumulative score %d End the game",N);
    Sleep(2800);

    system("cls");
    
    int k;                                  //Cyclic variable
    gotoxy(40, R);                          //Initialize turret
    for (k = 0; k < 17; k++)
        printf("_");

    gotoxy(46, R);
    printf("[_O_]");
    gotoxy(48, 25);                         //Middle x:48
    printf("|");

    int j;
    srand((unsigned)time(NULL));            //Initialize random seed
    for (j = 0; j < 3; j++)                 //Initialize the initial x-coordinate of the aircraft, written outside the loop
    {
        ax[j] = rand() % R;
        fd[j] = rand() % 2;
    }

    gotoxy(0, R);
    printf("  Score:");                    //Fractional x coordinate 9
}

void hcfjhs()                       //Drawing airplane functions
{
    gotoxy(ax[i], y[i]);            //First, output the whole aircraft at the tail

    if (fd[i] == 1)         
        printf("|---0>");   
    else                            
        printf(">>>>>>");   

    gotoxy(ax[i] - 1, y[i]);        //Clear the tail of the plane
    printf(" ");

    ax[i]++;                        //Then the coordinates of the aircraft tail will increase automatically, and the whole aircraft will be output from the aircraft tail next time
}

void dhpdxshs()                    //Draw the plane and let it disappear as it flies past the x94
{
    for (i = 0; i < 3; i++)         //One step for each plane
    {
        hcfjhs();

        if (ax[i] + 6 >= 94)        //Judge whether each aircraft head exceeds 94
        {
            gotoxy(94, y[i]);       //Meet the conditions and output space at 94 points of each aircraft
            printf("      ");
            if (ax[i]+6 > 100)      //If the aircraft head of each aircraft exceeds 100, reset a random number
            {
                ax[i] = rand() % R; //Change to a random number less than R
                fd[i] = rand() % 2;
            }
        }
    }
}

int da = 2;           //da = 1 is the leftmost default intermediate turret direction, global variable
int yip = 0;          //Whether to fire or not, 0 can't fire, 1, 2, 3 three directions
int rtde = 1;         //Whether the launching is completed or not, it must wait for the completion of the shell launching


int shells_x;         //Projectile coordinates
int shells_y;

void ckkzhs()
{
    char ch;
    ch = _getch();

    if (ch == 'd' || ch == 'D')
    {
        gotoxy(49, 25);
        printf("/");                //Battery turn right
        gotoxy(47, 25);
        printf("  ");
        da = 3;                     //Rightmost state
    }
    if (ch == 'A' || ch == 'a')
    {
        gotoxy(47, 25);
        printf("\\");               //Escape escape character
        gotoxy(48, 25);
        printf("  ");
        da = 1;                     //Leftmost state
    }
    if (ch == 'W' || ch == 'w')
    {
        gotoxy(48, 25);
        printf("|");                
        gotoxy(47, 25);
        printf(" ");
        gotoxy(49, 25);
        printf(" ");
        da = 2;
    }

    if (ch == ' '&& rtde == 0)      //The cannon is in the firing completed state, and press the space
    {
        if (da == 2)                //Middle turret orientation
            yip = 2;
        
        if (da == 1)                //Left
        {
            yip = 1;
            shells_x = 45;          //Initialize shell coordinates
        }
        if (da == 3)                //right
        {
            yip = 3;
            shells_x = 51;
        }
        shells_y = 23;             //Initialize shell coordinates
    }
}

void dpfshs()                       //Fire shells in three different directions
{
    rtde = 1;                       //Circulation, when the shell moves, it means that the gun is not fired
    if (yip == 2)
    {
        shells_x = 48;
        gotoxy(shells_x, shells_y-=2);
        printf("o");
        gotoxy(shells_x, shells_y+2);
        printf(" ");
    }
    if (yip == 1)
    {
        gotoxy(shells_x-=2, shells_y-=2);
        printf("o");
        gotoxy(shells_x+2, shells_y+2);
        printf(" ");
    }
    if (yip == 3)
    {
        gotoxy(shells_x+=2, shells_y-=2);
        printf("o");
        gotoxy(shells_x-2, shells_y+2);
        printf(" ");
    }

    if (shells_y <= 1)         //Cannonball out of bounds, eliminate cannonball
    {
        yip = 0;               //The shell is out of bounds. The shell stops
        gotoxy(48, 1);         //And eliminate
        printf(" ");
        gotoxy(23, 1);
        printf(" ");
        gotoxy(73, 1);
        printf(" ");        
        rtde = 0;             //The shell is out of bounds. After firing, the next round of firing can be carried out
    }
}

int score;                  //Score

void pdfsjzhs()             //Determine hit and statistics
{
    
        for (i = 0; i < 3; i++)
        {
            if (shells_x >= ax[i] && shells_x <= ax[i] + 6 && shells_y == y[i])//Hit time
            {
                if(fd[i]==1)
                    score++;                        //Hit once, score plus one
                else
                {
                    score--;
                    if (score <= 0)
                        score = 0;
                }

                rtde = 0;                       //When it hits, it's done

                gotoxy(ax[i]-1, y[i]);          //After hitting, eliminate the aircraft at the tail of the original aircraft
                printf("      ");

                ax[i] = rand() % R;             //Change to a random number less than 10
                fd[i] = rand() % 2;             //Changes in aircraft types

                gotoxy(shells_x, shells_y);     //Output space at the place where the aircraft is hit to eliminate the shell body
                printf(" ");

                shells_x = 0, shells_y = 0;     //The shell hit the aircraft, the shell crossed the boundary, the next space will automatically initialize the shell
            }
        }
    
    gotoxy(9, R);
    printf("%d",score);

    if (score >= N)         //End of game judgment
    {
        system("cls");      //Clean screen
        gotoxy(39,15);      
        printf("You have passed the customs, and the final score is:%d !", N);
        gotoxy(0, 29);
        exit(0);
    }

}

void process()              //Technological process
{
    while (1)
    {
        dhpdxshs();         //Aircraft animation function

        if (_kbhit())       
        {
            ckkzhs();       //Operation function
        }
        
        dpfshs();           //Cannon effect function
        pdfsjzhs();         //Determine hit and statistics

        Sleep(18);
    }
}

int main()
{
    cshcxhs();      //Initializer

    process();      //Technological process

    return 0;
}




void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x, int y)
{
    COORD pos = { x,y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

deficiencies:
When I output the aircraft in the program, I used the writing method of directly outputting the whole aircraft at the tail of the aircraft, which is a very stupid but simple method. This approach makes it impossible to eliminate the fuselage of the aircraft one by one when the aircraft flies over the maximum width of the console. Once the aircraft head crosses the maximum width of the console, there will be a program output error. Therefore, in order to keep the effect of "let the aircraft fly out of the boundary one by one" which makes the aircraft disappear, I have to use the last six x-axis grids of the y-axis of the last aircraft as A similar effect is achieved by blocking the plane's board.
Due to the creativity of the program, it is all written by myself. Due to my limited ability, when I write this program, I vaguely feel that there are a lot of problems in code reusability, structural strictness, and low efficiency in operation. At the same time, many functions and variable identifiers are composed of blind writing and Chinese pinyin.

As a novice of c language, I always have a learning and humble attitude towards the unknown knowledge. I would be very grateful if someone could put forward suggestions on reusability, preciseness and operation efficiency for my program.

Published 1 original article · praised 0 · visited 2
Private letter follow

Posted by Scarum on Fri, 31 Jan 2020 02:35:51 -0800