就是要努力呀 发表于 2020-3-7 17:25:01

这个应该叫飞机打豆豆 不叫飞机大战

本帖最后由 就是要努力呀 于 2020-3-8 12:39 编辑

感觉比昨天写的贪吃蛇差远了
不知道怎么解决在用户没有输入的时候不会卡在scanf那里,后果就是游戏是一帧一帧的,你按一下他就刷新一下
有点赶懒 飞机就是个^ 简单明了
进步就是用了昨天大佬说的gotoxy函数,不再像昨天贪吃蛇那样一直用clear一直清屏了
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define MAX 50
#define RANGE 20        //飞机射程 值越小射程越远
int X = 40;        //飞机x坐标
int Y = 24;        //飞机y坐标
int COUNT = 0;        //得分

void gotoxy(int x, int y);
void printmain(void);        //打印主菜单
void map_set_up(char (*map));        //生成地图
void plane_set_up(char (*map));        //生成飞机
void enemy_set_up(char (*enemymap));        //生成敌机
void print_all(char (*map), char (*enemymap));        //打印所有物品
int get_move(char (*map), char (*enemymap));        //获取指令
void attack(char (*map), char (*enemymap));        //进行攻击
int check_attack(int i, char (*map), char (*enemymap));        //检测攻击是否命中
int do_move(char move, char (*map), char (*enemymap));        //进行移动
int check_plane(char(*map), char (*enemymap));        //检测飞机是否越界或碰到敌机
void reset_plane(char (*map));        //刷新飞机

void gotoxy(int x, int y)
{
        printf("%c[%d;%df", 0x1B, x, y);
}

void reset_plane(char (*map))        //刷新飞机
{
        map = ' ';
}

int check_plane(char(*map), char (*enemymap))        //检测飞机是否越界或碰到敌机
{
        if(enemymap == '*')
        {
                return 0;
        }

        if(X == 0 || X == MAX - 1 || Y == 0 || Y == MAX - 1)
        {
                return 0;
        }

        return 1;
}

int do_move(char move, char (*map), char (*enemymap))        //进行移动
{
        reset_plane(map);

        switch(move)
        {
                case 'w':
                        X--;
                        break;
                case 'a':
                        Y--;
                        break;
                case 's':
                        X++;
                        break;
                case 'd':
                        Y++;
                        break;
        }

        plane_set_up(map);
        return check_plane(map, enemymap);
}

int check_attack(int i, char (*map), char (*enemymap))        //检测攻击是否命中
{
        if(enemymap == '*')
        {
                COUNT++;

                enemymap = ' ';
        }

        print_all(map, enemymap);
}

void attack(char (*map), char (*enemymap))        //进行攻击
{
        int i;
        time_t begin, end;

        begin = clock();

        for(i = 1; i <RANGE && X - i > 0; i++)
        {
                check_attack(i, map, enemymap);

                map = '|';
        }

        end = clock();
       
        print_all(map, enemymap);

        do
        {
                end = clock();
        }
        while((end - begin) <= 80000);

        for(i = 1; i <RANGE && X - i > 0; i++)
        {
                map = ' ';
        }

        print_all(map, enemymap);
}

int get_move(char (*map), char (*enemymap))        //获取指令
{
        char move;

        system("stty raw -echo");

        do
        {
                scanf("%c", &move);
        }
        while(move != 'w' && move != 'a' && move != 's' && move != 'd' && move != ' ' && move != 'q');

        system("stty cooked echo");

        if(move == 'q')
        {
                return 0;
        }

        if(move == ' ')
        {
                attack(map, enemymap);
        }
        else return do_move(move, map, enemymap);
}

void print_all(char (*map), char (*enemymap))        //打印所有物品
{
        int i, j;

        gotoxy(0, 0);
        printf("得分:%d\n", COUNT);

        for(i = 0; i < MAX; i++)
        {
                for(j = 0; j < MAX; j++)
                {
                        if(enemymap != ' ')
                        {
                                printf("%c ", enemymap);
                        }
                        else printf("%c ", map);
                }

                putchar('\n');
        }
}

void enemy_set_up(char (*enemymap))        //生成敌机
{
        int count, i, j;

        srand(time(NULL) + 1.345);

        for(count = 0; count < 5; count++)
        {
                do
                {
                        i = rand()%47 + 1;
                        j = rand()%47 + 1;
                }
                while(i != X && j != Y);
               
                enemymap = '*';
        }
}

void plane_set_up(char (*map))        //生成飞机
{
        map = '^';
}

void map_set_up(char (*map))        //生成地图
{
        int i, j;

        memset(map, ' ', MAX * MAX);

        for(i = 0; i < MAX; i++)
        {
                for(j = 0; j < MAX; j++)
                {
                        if(i == 0 || j == 0 || i == MAX - 1 || j == MAX - 1)
                        {
                                map = '0';
                        }
                }
        }
}

void printmain(void)        //打印主菜单
{
        printf("1.开始游戏\n");
        printf("2.退出游戏\n");
        printf(":");
}

int main(void)
{
        char move;
        char map;
        char enemymap;
        time_t begin, end;

        memset(enemymap, ' ', MAX * MAX);

        do
        {
                printmain();
                scanf("%c", &move);
                getchar();
        }
        while(move != '1' && move != '2');


        if(move == '1')
        {
                map_set_up(map);
                plane_set_up(map);

                system("clear");

                begin = time(NULL);

                do
                {
                        end = time(NULL);

                        if(((end - begin) % 3) == 0)
                        {
                                enemy_set_up(enemymap);
                        }

                        print_all(map, enemymap);
                        gotoxy(52, 0);
                        printf("请输入指令(w/a/s/d/j/q):");
                }
                while(get_move(map, enemymap));
        }

        system("stty cooked echo");
       
        return 0;
}



就是要努力呀 发表于 2020-3-7 17:45:29

空格是攻击
提示里忘记改了

人造人 发表于 2020-3-7 18:20:41

你需要的是非阻塞输入,可以试试ncurses库

#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>

int main(void)
{
    WINDOW *w = initscr();
    cbreak();
    nodelay(w, TRUE);    // 进入非阻塞模式
    noecho();         // 不要回显

    sleep(3);
    mvprintw(10, 5, "hello\n");
    int ch;
    ch = getch();
    printw("%hhx\n", ch);

    // 退出非阻塞模式
    nodelay(w, FALSE);
    getch();
    endwin();
    return 0;
}


这个程序用来测试非阻塞模式是不是正确
你有3秒时间按任意一个键,如果有按键,程序就输出这个按键
如果没有那就输出 ff
阻塞是由sleep(3);实现的,如果没有这个,你根本没有机会按下任何键
程序最后退出非阻塞模式,等待按下一个键后退出

编译这个程序用
gcc -o main main.c -lncurses

我使用的是
gcc -g -Wall -o main main.c -lncurses

-lncurses
这个是关键

值得一提的是之前的gotoxy作废,ncurses中使用mvprintw

还有一件事,你上面的gotoxy拼错了,写成了goutoxy

^_^

就是要努力呀 发表于 2020-3-8 12:37:59

人造人 发表于 2020-3-7 18:20
你需要的是非阻塞输入,可以试试ncurses库




ok谢谢大佬{:10_266:}虽然看完一脸懵逼
页: [1]
查看完整版本: 这个应该叫飞机打豆豆 不叫飞机大战