鱼C论坛

 找回密码
 立即注册
查看: 1203|回复: 3

[技术交流] 这个应该叫飞机打豆豆 不叫飞机大战

[复制链接]
发表于 2020-3-7 17:25:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 就是要努力呀 于 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)[MAX]);        //生成地图
void plane_set_up(char (*map)[MAX]);        //生成飞机
void enemy_set_up(char (*enemymap)[MAX]);        //生成敌机
void print_all(char (*map)[MAX], char (*enemymap)[MAX]);        //打印所有物品
int get_move(char (*map)[MAX], char (*enemymap)[MAX]);        //获取指令
void attack(char (*map)[MAX], char (*enemymap)[MAX]);        //进行攻击
int check_attack(int i, char (*map)[MAX], char (*enemymap)[MAX]);        //检测攻击是否命中
int do_move(char move, char (*map)[MAX], char (*enemymap)[MAX]);        //进行移动
int check_plane(char(*map)[MAX], char (*enemymap)[MAX]);        //检测飞机是否越界或碰到敌机
void reset_plane(char (*map)[MAX]);        //刷新飞机

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

void reset_plane(char (*map)[MAX])        //刷新飞机
{
        map[X][Y] = ' ';
}

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

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

        return 1;
}

int do_move(char move, char (*map)[MAX], char (*enemymap)[MAX])        //进行移动
{
        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)[MAX], char (*enemymap)[MAX])        //检测攻击是否命中
{
        if(enemymap[X - i][Y] == '*')
        {
                COUNT++;

                enemymap[X - i][Y] = ' ';
        }

        print_all(map, enemymap);
}

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

        begin = clock();

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

                map[X - i][Y] = '|';
        }

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

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

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

        print_all(map, enemymap);
}

int get_move(char (*map)[MAX], char (*enemymap)[MAX])        //获取指令
{
        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)[MAX], char (*enemymap)[MAX])        //打印所有物品
{
        int i, j;

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

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

                putchar('\n');
        }
}

void enemy_set_up(char (*enemymap)[MAX])        //生成敌机
{
        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[i][j] = '*';
        }
}

void plane_set_up(char (*map)[MAX])        //生成飞机
{
        map[X][Y] = '^';
}

void map_set_up(char (*map)[MAX])        //生成地图
{
        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[i][j] = '0';
                        }
                }
        }
}

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

int main(void)
{
        char move;
        char map[MAX][MAX];
        char enemymap[MAX][MAX];
        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;
}



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-3-7 17:45:29 | 显示全部楼层
空格是攻击
提示里忘记改了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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

^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-8 12:37:59 From FishC Mobile | 显示全部楼层
人造人 发表于 2020-3-7 18:20
你需要的是非阻塞输入,可以试试ncurses库



ok谢谢大佬虽然看完一脸懵逼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 00:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表