CS_newby 2023-12-23 23:58 采纳率: 83.3%
浏览 8
已结题

学期报告C语言小游戏

这是我跟伙伴写的小游戏,现在遇到几个问题:
1.游戏画面闪烁很卡。
2.我认为在我的代码中应该是白底黑字,却相反。
3.若把speed调成帧率,会比较好吗(过于快但卡降低)
4.炸弹调低会比较有可玩性?本来考量的是运气因素,但好像有点太过了。
5.随着函式增多咋越来越卡

哦 还有 这是Windows写的 如果要在其他系统跑咋办啊。。
如果你们有什么其他部分的建议也欢迎提出,我会很谢谢你们。

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<stdbool.h>
#include <mmsystem.h>

#define RED     "\x1b[31m"
#define GREEN   "\x1b[32m"
#define YELLOW  "\x1b[33m"
#define BLUE    "\x1b[34m"
#define MAGENTA "\x1b[35m"
#define CYAN    "\x1b[36m"
#define RESET   "\x1b[0m"

typedef struct info
{
    int max;
    int speed;
    short int b1x,b1y,b2x,b2y,b3x,b3y;//bomb generate randomly every second
    short int score;
    short int x, y, fruitx, fruity;
    short int flag;
    short int width, height;
    // corner
    short int ulx, uly, urx, ury, dlx, dly, drx, dry;
    bool gameover, restart, ten, press, Bomb;
}Info;

void playSound(const char* soundFilePath) {
    PlaySound(soundFilePath, NULL, SND_FILENAME | SND_ASYNC);
}

void hideCursor()
{
    CONSOLE_CURSOR_INFO cursorInfo;
    cursorInfo.dwSize = 1;
    cursorInfo.bVisible = FALSE;  // hide cursor
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

void genBomb(Info *ptr)
{
    ptr->b1x = rand() % ptr->width;
    ptr->b2x = rand() % ptr->width;
    ptr->b3x = rand() % ptr->width;
    ptr->b1y = rand() % ptr->height;
    ptr->b2y = rand() % ptr->height;
    ptr->b3y = rand() % ptr->height;
    return;
}

void genFruit(Info *ptr)
{
    ptr->fruitx = rand() % ptr->width;
    while(ptr->fruitx == 0 || ptr->fruitx == ptr->width - 1)
        ptr->fruitx = rand() % ptr->width;

    ptr->fruity = rand() % ptr->height;
    while(ptr->fruity == 0 || ptr->fruity == ptr->height - 1)
        ptr->fruity = rand() % ptr->height;

    while((ptr->fruitx == 1 && ptr->fruity == 1) || (ptr->fruitx == 1 && ptr->fruity == ptr->height - 2) || (ptr->fruitx == ptr->width - 2 && ptr->fruity == 1)
          || (ptr->fruitx == ptr->width - 2 && ptr->fruity == ptr->height - 2))
    {
        genFruit(ptr);
    }
    return;
}

void genpos(Info *ptr)
{
    ptr->urx = rand() % ptr->width;//Exit
    ptr->ury = rand() % ptr->height;
    ptr->dlx = rand() % ptr->width;//Score
    ptr->dly = rand() % ptr->height;
    ptr->drx = rand() % ptr->width;//Center
    ptr->dry = rand() % ptr->height;
}

void initial(Info *ptr)
{


    ptr->score = 0;
    ptr->flag = 0;
    ptr->speed = 200;

    ptr->width = 25;
    ptr->height = 20;

    ptr->restart = false;
    ptr-> gameover = false;
    ptr->ten = false;
    ptr->press = false;
    ptr->Bomb = false;

    ptr->x = ptr->width / 2;
    ptr->y = ptr->height / 2;

    ptr->ulx = 1;//+10
    ptr->uly = 1;

    genpos(ptr);
    genFruit(ptr);

    ptr->b1x = 0;
    ptr->b2x = 0;
    ptr->b3x = 0;
    ptr->b1y = 0;
    ptr->b2y = 0;
    ptr->b3y = 0;
    return;
}

void draw(Info *ptr)
{
    system("cls");
    printf("Get the Fruit!\n");
    printf("Moving:WASD  Don't touch '.', a bomb!\n E for exit, C for center, X gives you 10, Z backs to 0\n");
    if(ptr->press && !ptr->Bomb)
    {
        genBomb(ptr);
    }
    for (int i = 0; i < ptr->height; i++)
    {
        for (int j = 0; j < ptr->width; j++)
        {
            if (i == ptr->y && j == ptr->x)
                    printf(YELLOW"O"RESET);
            else if (i == 0 || i == ptr->height - 1 || j == 0 || j == ptr->width - 1)
                printf(MAGENTA"#"RESET);
            else if(i == ptr->uly && j == ptr->ulx && !ptr->ten)
                printf("X"); // +10
            else if(i == ptr->ury && j == ptr->urx)
                printf("E"); // Exit
            else if(i == ptr->dly && j == ptr->dlx)
                printf("Z"); // Score = 0
            else if(i == ptr->dry && j == ptr->drx)
                printf(BLUE"C"RESET); // Center
            else if((i == ptr->b1y && j == ptr->b1x) || (i == ptr->b2y && j == ptr->b2x) || (i == ptr->b3y && j == ptr->b3x))
                printf(RED"."RESET);//Bomb
            else
            {
                if (i == ptr->fruity && j == ptr->fruitx)
                    printf("*");
                else
                    printf(" ");
            }
        }
        printf("\n");
    }

    printf("score = %d\n", ptr->score);
    printf("Max score = %d\n", ptr->max);
    printf("press X to stop the game,press R to restart(in 10 sec)\nps:GOAL = 200\n");
}

void input(Info *ptr)
{
    if (kbhit())
    {
        ptr->press = true;

        switch (getch())
        {
            case 'a':
                ptr->flag = 1;
                break;
            case 's':
                ptr->flag = 2;
                break;
            case 'd':
                ptr->flag = 3;
                break;
            case 'w':
                ptr->flag = 4;
                break;
            case 'x':
                ptr->gameover = true;
                ptr->max = (ptr->score > ptr->max)? ptr->score : ptr->max;
                draw(ptr);
                break;
            case 'r':
                ptr->gameover = true;
                ptr->restart = true;
                ptr->max = (ptr->score > ptr->max)? ptr->score : ptr->max;
                break;
            default:
                break;
        }
    }
}

void detect(Info *ptr)//ms
{
    if(ptr->restart == true)
    {
        return;
    }
    int startTime = GetTickCount();
    while (GetTickCount() - startTime < 10000)
    {
        input(ptr);
        if(ptr->restart == true)
            return;
    }


    return;
}

void range(Info *ptr)
{
    ptr->width--;
    if(ptr->score % 20 == 0)
    {
        ptr->height-= 2;

        ptr->speed -= 10;
    }
    genpos(ptr);

    genFruit(ptr);


    ptr->x = rand() % ptr->width;
    while(ptr->x <= 1 || ptr->x >= ptr->width-2 || ptr->x == ptr->fruitx)
        ptr->x = rand() % ptr->width;

    ptr->y = rand() % ptr->height;
    while(ptr->y <= 1 || ptr->y >= ptr->height-2 || ptr->y == ptr->fruity)
        ptr->y = rand() % ptr->height;
}

void logic(Info *ptr)
{
    Sleep(ptr->speed);
    switch (ptr->flag)
    {
        case 1:
            ptr->x--;
            break;
        case 2:
            ptr->y++;
            break;
        case 3:
            ptr->x++;
            break;
        case 4:
            ptr->y--;
            break;
        default:
            break;
    }

    if (ptr->x <= 0 || ptr->x >= ptr->width-1 || ptr->y <= 0 || ptr->y >= ptr->height-1)
    {
        ptr->gameover = true;
        ptr->max = (ptr->score > ptr->max)? ptr->score : ptr->max;
        draw(ptr);
        printf("today is not your day;;");
    }
    else if((ptr->x == ptr->b1x && ptr->y == ptr->b1y)|| (ptr->x == ptr->b2x && ptr->y == ptr->b2y) || (ptr->x == ptr->b3x && ptr->y == ptr->b3y))
    {
        ptr->Bomb = true;
        ptr->gameover = true;
        ptr->max = (ptr->score > ptr->max)? ptr->score : ptr->max;
        draw(ptr);
        printf("Bomb! TAT");
    }
    else if (ptr->x == ptr->fruitx && ptr->y == ptr->fruity)
    {
        genFruit(ptr);
        ptr->score += 10;
        if(ptr->score == 200)
        {
            ptr->max = 200;
            draw(ptr);
            printf("you win\n");
            ptr->gameover = true;
        }
        else
            range(ptr);
    }
    else if(ptr->y == ptr->uly && ptr->x == ptr->ulx && !ptr->ten)
    {
        ptr->score += 10; // +10
        ptr->ten = true;
    }
    else if(ptr->y == ptr->ury && ptr->x == ptr->urx)
    {
        ptr->max = (ptr->score > ptr->max)? ptr->score : ptr->max;
        draw(ptr);
        printf("exit!");
        exit(0); // Exit
    }
    else if(ptr->y == ptr->dly && ptr->x == ptr->dlx)
            ptr->score = 0; // Score = 0
    else if(ptr->y == ptr->dry && ptr->x == ptr->drx)
    {
        ptr->x = ptr->width / 2;
        ptr->y = ptr->height / 2;
    } // Center
}

void run(Info *ptr)
{
    playSound("C:\\Users\\USER\\Downloads\\m_set_106.wav");
    initial(ptr);

    while(!ptr->gameover)
    {
        draw(ptr);
        input(ptr);
        logic(ptr);
    }

    detect(ptr);
    return;
}
void main()
{

    // Get handle to the console window
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);

    // Set the background color (e.g., bright blue on black)
    SetConsoleTextAttribute(consoleHandle, FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);

    ShowCursor(FALSE);
    hideCursor();
    Info *ptr;
    ptr = (Info *) malloc(sizeof(Info));
    ptr->max = 0;
    run(ptr);

    while(ptr->restart)
    {
        ptr->restart = false;
        run(ptr);
    }
    free(ptr);
}

  • 写回答

2条回答 默认 最新

  • 酷爱码 优质创作者: Java技术领域 2023-12-24 10:10
    关注

    1.游戏画面闪烁和卡顿可能是由于代码中的绘制方式不合理导致的。建议使用双缓冲技术来解决闪烁问题,并优化代码以提高游戏的性能。
    2.如果你想要白底黑字的效果,可以在绘制字符时使用相应的颜色控制序列。例如,将printf(YELLOW"O"RESET)修改为printf(RESET"O")。
    3.将速度调整为帧率可能会改善卡顿问题,但也可能导致游戏过快而难以操作。你可以尝试调整速度的数值来找到适合的平衡点。
    4.调低炸弹的生成频率可能会增加游戏的可玩性,但请注意不要降低到无法避免的程度,否则可能会让游戏变得过于困难。
    5.随着函数的增多,可能会增加程序的复杂度和运行负荷,从而导致卡顿。你可以尝试对代码进行优化,减少不必要的计算和重复操作,以提高性能。
    关于在其他系统上运行该游戏的问题,可以考虑使用跨平台的编程语言和库来重新实现游戏,以确保在不同的操作系统上都能正常运行。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月22日
  • 已采纳回答 1月14日
  • 创建了问题 12月23日