鱼C论坛

 找回密码
 立即注册
查看: 606|回复: 8

[已解决]c变量问题求助

[复制链接]
发表于 2023-6-30 11:04:56 | 显示全部楼层 |阅读模式

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

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

x
请问下面的代码中有什么问题,level的值应该随循环而增加,但打印调试信息时level值一直为2.
#include "ExBall.h"
#include <stdlib.h>

void initBall(struct ExBall* pBall, int level)
{
    pBall->x = 200+rand() % 401; // 在 0 - 400 范围内生成随机 x 坐标
    pBall->y = rand() % 20 + 300; // 在 300 - 320 范围内生成随机 y 坐标
    pBall->r = 15 - 2.5 * level; // 根据关卡等级调整球的大小
    pBall->dx = 5 + 2 * level; // 根据关卡等级调整球的速度
    pBall->dy = -5 - 2 * level; // 根据关卡等级调整球的速度
    static int levelValue = 1;
    pBall->level = levelValue; // 设置球的关卡等级
    pBall->color = WHITE;
    levelValue = level; // 更新静态变量的值
}

void drawBall(const struct ExBall* pBall)
{
    setfillcolor(pBall->color);
    fillcircle(pBall->x, pBall->y, pBall->r);
}

#include "ExGame.h"
#include "ExTimer.h"
#include <graphics.h>
#include "ExBall.h"

static void keyDown(struct ExGame* exgame, HWND hwnd);
static int hitBricks(struct ExGame* exgame);
static int hitBoard(struct ExGame* exgame);
static void moveBall(struct ExGame* exgame);
static int gameOver(struct ExGame* exgame);
static int gameWin(struct ExGame* exgame, HWND hwnd);
int ExGame::initialLevel = 1;
void gameInit(struct ExGame* exgame)
{
    initMap(&exgame->map);
    initBoard(&exgame->board);
    exgame->score = 0;
    exgame->level = ExGame::initialLevel; // 将初始关卡等级赋值给 level
    initBall(&exgame->ball, exgame->level);
}
int gameLoop(struct ExGame* exgame)
{
    HWND hwnd = initgraph(WIDTH, HEIGHT);
    IMAGE bk;
    loadimage(&bk, "./w.jpg", WIDTH, HEIGHT);
    BeginBatchDraw();

    while (1)
    {
        putimage(0, 0, &bk);
        drawMap(exgame->map);
        drawBoard(exgame->board);
        drawBall(&exgame->ball);
        char scoreStr[20];
        sprintf_s(scoreStr, "Score: %d", exgame->score);
        outtextxy(10, HEIGHT - 30, scoreStr);

        keyDown(exgame, hwnd); // 添加hwnd参数
        moveBall(exgame);

        if (gameOver(exgame))
        {
            int choice = MessageBoxA(hwnd, "你输了 再玩一遍吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION);
            if (choice == IDNO) // Exit
            {
                closegraph();
                return 0;
            }
            else if (choice == IDYES) // Play Again
            {
                gameInit(exgame);
            }
        }
        else if (gameWin(exgame, hwnd))
        {
            char levelStr[20];
            sprintf_s(levelStr, "Level: %d", exgame->level);
            outtextxy(10, HEIGHT - 60, levelStr);
            MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
            exgame->level++; // 进入下一关,更新关卡等级
            printf("Current level: %d\n", exgame->level);
            initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球
            gameInit(exgame);
        }

        FlushBatchDraw();
        Sleep(20);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}

static void keyDown(struct ExGame* exgame, HWND hwnd) // 添加hwnd参数
{
    if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && exgame->board.x > 0)
    {
        exgame->board.x -= exgame->board.speed;
    }
    if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && exgame->board.x + exgame->board.w < WIDTH)
    {
        exgame->board.x += exgame->board.speed;
    }
    if (GetAsyncKeyState('9')) // 后门,按下数字9进入下一关
    {
        exgame->level++; // 更新关卡等级
        printf("Current level: %d\n", exgame->level);
        initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球
        gameInit(exgame);
    }
}

static int hitBricks(struct ExGame* exgame)
{
    int j = exgame->ball.x / BRICKS_W;
    int i = (exgame->ball.y - exgame->ball.r) / BRICKS_H;
    if (i < ROW && j < COLS && exgame->map.arr[i][j] != 0)
    {
        exgame->map.arr[i][j] = 0;
        exgame->score += 10;
        return 1;
    }
    return 0;
}

static int hitBoard(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y && exgame->ball.y - exgame->ball.r <= exgame->board.y + exgame->board.h)
    {
        if (exgame->ball.x + exgame->ball.r >= exgame->board.x && exgame->ball.x - exgame->ball.r <= exgame->board.x + exgame->board.w)
        {
            return 1;
        }
    }
    return 0;
}

static void moveBall(struct ExGame* exgame)
{
    if (exgame->ball.x - exgame->ball.r <= 0 || exgame->ball.x + exgame->ball.r >= WIDTH)
    {
        exgame->ball.dx = -exgame->ball.dx;
    }
    if (exgame->ball.y - exgame->ball.r <= 0 || hitBoard(exgame) || hitBricks(exgame))
    {
        exgame->ball.dy = -exgame->ball.dy;
    }
    exgame->ball.x += exgame->ball.dx;
    exgame->ball.y += exgame->ball.dy;
}

static int gameOver(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y + exgame->board.h)
    {
        return 1;
    }
    return 0;
}

static int gameWin(struct ExGame* exgame, HWND hwnd)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLS; j++)
        {
            if (exgame->map.arr[i][j] != 0)
            {
                return 0;
            }
        }
    }

    char levelStr[20];
    sprintf_s(levelStr, "Level: %d", exgame->level);
    outtextxy(10, HEIGHT - 60, levelStr);
    MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);

    exgame->level++; // 进入下一关,更新关卡等级
    printf("Current level: %d\n", exgame->level);
    initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球的位置、大小和速度
    gameInit(exgame);

    return 1;
}
最佳答案
2023-6-30 14:52:39

根据代码的片段分析,以下是可能存在的问题:

  • 缺少头文件引用:代码中使用了graphics.h等头文件,但没有看到相应的头文件引用语句。请确保在运行代码之前正确引用所需的头文件。
  • main函数缺失:这是一个代码片段,缺少main函数的定义。请确保在该文件或其他文件中包含适当的main函数。
  • 使用了未定义的结构体和函数:在代码中引用了ExGame、ExTimer、ExBall等结构体和相关函数,但是没有提供相应的定义。请确保这些结构体和函数的定义在代码中的其他位置或其他相关文件中。
  • 初始化图形库错误:在gameLoop函数中调用了initgraph函数初始化图形库,但是没有检查初始化是否成功。请确保调用成功后再进行图形绘制操作。
  • 图形绘制顺序有误:在gameLoop函数中,先绘制背景图像,然后在其上绘制地图、挡板和球等元素,最后执行FlushBatchDraw函数刷新绘图缓冲区。正确的绘制顺序应该是先绘制地图、挡板和球等元素,然后再绘制背景图像,最后刷新绘图缓冲区。


请注意,以上只是根据代码片段进行的初步分析,可能存在其他问题。

根据代码片段的问题,以下是修改后的代码建议:
#include "ExGame.h"
#include "ExTimer.h"
#include <graphics.h>
#include "ExBall.h"

static void keyDown(struct ExGame* exgame, HWND hwnd);
static int hitBricks(struct ExGame* exgame);
static int hitBoard(struct ExGame* exgame);
static void moveBall(struct ExGame* exgame);
static int gameOver(struct ExGame* exgame);
static int gameWin(struct ExGame* exgame, HWND hwnd);

void gameInit(struct ExGame* exgame)
{
    initMap(&exgame->map);
    initBoard(&exgame->board);
    exgame->score = 0;
    exgame->level = ExGame::initialLevel;
    initBall(&exgame->ball, exgame->level);
}

int gameLoop(struct ExGame* exgame)
{
    HWND hwnd = initgraph(WIDTH, HEIGHT);
    if (hwnd == NULL) {
        printf("图形库初始化失败\n");
        return -1;
    }
    
    IMAGE bk;
    loadimage(&bk, "./w.jpg", WIDTH, HEIGHT);
    BeginBatchDraw();

    while (1)
    {
        putimage(0, 0, &bk);
        drawMap(exgame->map);
        drawBoard(exgame->board);
        drawBall(&exgame->ball);
        char scoreStr[20];
        sprintf_s(scoreStr, "Score: %d", exgame->score);
        outtextxy(10, HEIGHT - 30, scoreStr);

        keyDown(exgame, hwnd);
        moveBall(exgame);

        if (gameOver(exgame))
        {
            int choice = MessageBoxA(hwnd, "你输了 再玩一遍吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION);
            if (choice == IDNO)
            {
                closegraph();
                return 0;
            }
            else if (choice == IDYES)
            {
                gameInit(exgame);
            }
        }
        else if (gameWin(exgame, hwnd))
        {
            char levelStr[20];
            sprintf_s(levelStr, "Level: %d", exgame->level);
            outtextxy(10, HEIGHT - 60, levelStr);
            MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
            exgame->level++;
            printf("Current level: %d\n", exgame->level);
            initBall(&exgame->ball, exgame->level);
            gameInit(exgame);
        }

        FlushBatchDraw();
        Sleep(20);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}

static void keyDown(struct ExGame* exgame, HWND hwnd)
{
    if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && exgame->board.x > 0)
    {
        exgame->board.x -= exgame->board.speed;
    }
    if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && exgame->board.x + exgame->board.w < WIDTH)
    {
        exgame->board.x += exgame->board.speed;
    }
    if (GetAsyncKeyState('9'))
    {
        exgame->level++;
        printf("Current level: %d\n", exgame->level);
        initBall(&exgame->ball, exgame->level);
        gameInit(exgame);
    }
}

static int hitBricks(struct ExGame* exgame)
{
    int j = exgame->ball.x / BRICKS_W;
    int i = (exgame->ball.y - exgame->ball.r) / BRICKS_H;
    if (i < ROW && j < COLS && exgame->map.arr[i][j] != 0)
    {
        exgame->map.arr[i][j] = 0;
        exgame->score += 10;
        return 1;
    }
    return 0;
}

static int hitBoard(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y && exgame->ball.y - exgame->ball.r <= exgame->board.y + exgame->board.h)
    {
        if (exgame->ball.x + exgame->ball.r >= exgame->board.x && exgame->ball.x - exgame->ball.r <= exgame->board.x + exgame->board.w)
        {
            return 1;
        }
    }
    return 0;
}

static void moveBall(struct ExGame* exgame)
{
    if (exgame->ball.x - exgame->ball.r <= 0 || exgame->ball.x + exgame->ball.r >= WIDTH)
    {
        exgame->ball.dx = -exgame->ball.dx;
    }
    if (exgame->ball.y - exgame->ball.r <= 0 || hitBoard(exgame) || hitBricks(exgame))
    {
        exgame->ball.dy = -exgame->ball.dy;
    }
    exgame->ball.x += exgame->ball.dx;
    exgame->ball.y += exgame->ball.dy;
}

static int gameOver(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y + exgame->board.h)
    {
        return 1;
    }
    return 0;
}

static int gameWin(struct ExGame* exgame, HWND hwnd)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLS; j++)
        {
            if (exgame->map.arr[i][j] != 0)
            {
                return 0;
            }
        }
    }
    char levelStr[20];
    sprintf_s(levelStr, "Level: %d", exgame->level);
    outtextxy(10, HEIGHT - 60, levelStr);
    MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
    exgame->level++;
    printf("Current level: %d\n", exgame->level);
    gameInit(exgame);

    return 1;
}

void initBall(struct ExBall* pBall, int level)
{
    pBall->x = 200 + rand() % 401;
    pBall->y = rand() % 20 + 300;
    pBall->r = 15 - 2.5 * level;
    pBall->dx = 5 + 2 * level;
    pBall->dy = -5 - 2 * level;
    pBall->level = level;
    pBall->color = WHITE;
}

void drawBall(const struct ExBall* pBall)
{
    setfillcolor(pBall->color);
    fillcircle(pBall->x, pBall->y, pBall->r);
}
这是根据代码片段进行的修改建议,但仍然需要确保整个代码的完整性和正确性。如果问题仍然存在,请尽可能提供完整的代码,以便进行更准确的分析和修复。
1d958a38c42bc4033426dfdf51d0b0a.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-30 11:16:25 | 显示全部楼层
我注意到 initBall 函数中关于 levelValue 的使用可能导致了这个问题。
static int levelValue = 1;
pBall->level = levelValue; // 设置球的关卡等级
levelValue = level; // 更新静态变量的值

在这段代码中,您首先将 levelValue 的值赋给了 pBall->level ,然后才更新 levelValue 的值。因此,在第一次调用 initBall 时,无论参数 level 的值是多少, pBall->level 始终被设置为1,因为这是 levelValue 的初始值。随后的调用则总是使用上一次调用时的 level 值。

要解决这个问题,你应该首先更新 levelValue 的值,然后再将其赋给 pBall->level 。更改后的代码应如下所示:
static int levelValue = 1;
levelValue = level; // 更新静态变量的值
pBall->level = levelValue; // 设置球的关卡等级

然而,这个修正前提是 levelValue 这个静态变量的存在有必要。从代码来看, levelValue 和参数 level 始终保持一致,这使得我不明白为什么要使用这个静态变量。如果 levelValue 并无特殊用途,建议直接使用 level 参数,将 pBall->level 设置为 level :
pBall->level = level; // 设置球的关卡等级

此外,您在游戏胜利后调用了 initBall ,然后又调用了 gameInit ,注意到 gameInit 函数中也有调用 initBall ,所以实际上在游戏胜利后您连续两次初始化了球。这可能不是您想要的,您可能需要删除 gameWin 函数中的 initBall 调用,只在 gameInit 中调用它。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-30 11:29:13 | 显示全部楼层
isdkz 发表于 2023-6-30 11:16
我注意到 initBall 函数中关于 levelValue 的使用可能导致了这个问题。

你好,我根据您的建议修改了代码,取消了levelvalue。gameWin 函数中的 initBall 调用已被删除,只在 gameInit 函数中调用它,static int gameWin(struct ExGame* exgame, HWND hwnd)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLS; j++)
        {
            if (exgame->map.arr[i][j] != 0)
            {
                return 0;
            }
        }
    }
    char levelStr[20];
    sprintf_s(levelStr, "Level: %d", exgame->level);
    outtextxy(10, HEIGHT - 60, levelStr);
    MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
    exgame->level++; // 进入下一关,更新关卡等级
    printf("Current level: %d\n", exgame->level);
    gameInit(exgame);

    return 1;
}void gameInit(struct ExGame* exgame)
{
    initMap(&exgame->map);
    initBoard(&exgame->board);
    exgame->score = 0;
    exgame->level = ExGame::initialLevel; // 将初始关卡等级赋值给 level
    initBall(&exgame->ball, exgame->level);
}

int gameLoop(struct ExGame* exgame)
{
    HWND hwnd = initgraph(WIDTH, HEIGHT);
    IMAGE bk;
    loadimage(&bk, "./w.jpg", WIDTH, HEIGHT);
    BeginBatchDraw();

    while (1)
    {
        putimage(0, 0, &bk);
        drawMap(exgame->map);
        drawBoard(exgame->board);
        drawBall(&exgame->ball);
        char scoreStr[20];
        sprintf_s(scoreStr, "Score: %d", exgame->score);
        outtextxy(10, HEIGHT - 30, scoreStr);

        keyDown(exgame, hwnd); // 添加hwnd参数
        moveBall(exgame);

        if (gameOver(exgame))
        {
            int choice = MessageBoxA(hwnd, "你输了 再玩一遍吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION);
            if (choice == IDNO) // Exit
            {
                closegraph();
                return 0;
            }
            else if (choice == IDYES) // Play Again
            {
                gameInit(exgame);
            }
        }
        else if (gameWin(exgame, hwnd))
        {
            char levelStr[20];
            sprintf_s(levelStr, "Level: %d", exgame->level);
            outtextxy(10, HEIGHT - 60, levelStr);
            MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
            exgame->level++; // 进入下一关,更新关卡等级
            printf("Current level: %d\n", exgame->level);
            initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球
            gameInit(exgame);
        }

        FlushBatchDraw();
        Sleep(20);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}但是level的打印值还是恒为2
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-30 11:30:18 | 显示全部楼层
1493916656 发表于 2023-6-30 11:29
你好,我根据您的建议修改了代码,取消了levelvalue。gameWin 函数中的 initBall 调用已被删除,只在 gam ...

放在代码标签里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-30 11:40:34 | 显示全部楼层

抱歉 能给出更详细的指导吗?我对这个不是很熟悉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-30 11:41:35 | 显示全部楼层
1493916656 发表于 2023-6-30 11:40
抱歉 能给出更详细的指导吗?我对这个不是很熟悉

https://fishc.com.cn/thread-128631-1-1.html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-30 14:37:33 | 显示全部楼层
歌者文明清理员 发表于 2023-6-30 11:41
https://fishc.com.cn/thread-128631-1-1.html
#include "ExGame.h"
#include "ExTimer.h"
#include <graphics.h>
#include "ExBall.h"

static void keyDown(struct ExGame* exgame, HWND hwnd); 
static int hitBricks(struct ExGame* exgame);
static int hitBoard(struct ExGame* exgame);
static void moveBall(struct ExGame* exgame);
static int gameOver(struct ExGame* exgame);
static int gameWin(struct ExGame* exgame, HWND hwnd); 
int ExGame::initialLevel = 1;
void gameInit(struct ExGame* exgame)
{
    initMap(&exgame->map);
    initBoard(&exgame->board);
    exgame->score = 0;
    exgame->level = ExGame::initialLevel; // 将初始关卡等级赋值给 level
    initBall(&exgame->ball, exgame->level);
}

int gameLoop(struct ExGame* exgame)
{
    HWND hwnd = initgraph(WIDTH, HEIGHT);
    IMAGE bk;
    loadimage(&bk, "./w.jpg", WIDTH, HEIGHT);
    BeginBatchDraw();

    while (1)
    {
        putimage(0, 0, &bk);
        drawMap(exgame->map);
        drawBoard(exgame->board);
        drawBall(&exgame->ball);
        char scoreStr[20];
        sprintf_s(scoreStr, "Score: %d", exgame->score);
        outtextxy(10, HEIGHT - 30, scoreStr);

        keyDown(exgame, hwnd); // 添加hwnd参数
        moveBall(exgame);

        if (gameOver(exgame))
        {
            int choice = MessageBoxA(hwnd, "你输了 再玩一遍吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION);
            if (choice == IDNO) // Exit
            {
                closegraph();
                return 0;
            }
            else if (choice == IDYES) // Play Again
            {
                gameInit(exgame);
            }
        }
        else if (gameWin(exgame, hwnd)) 
        {
            char levelStr[20];
            sprintf_s(levelStr, "Level: %d", exgame->level);
            outtextxy(10, HEIGHT - 60, levelStr);
            MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
            exgame->level++; // 进入下一关,更新关卡等级
            printf("Current level: %d\n", exgame->level);
            initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球
            gameInit(exgame);
        }

        FlushBatchDraw();
        Sleep(20);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}

static void keyDown(struct ExGame* exgame, HWND hwnd) // 添加hwnd参数
{
    if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && exgame->board.x > 0)
    {
        exgame->board.x -= exgame->board.speed;
    }
    if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && exgame->board.x + exgame->board.w < WIDTH)
    {
        exgame->board.x += exgame->board.speed;
    }
    if (GetAsyncKeyState('9')) // 后门,按下数字9进入下一关
    {
        exgame->level++; // 更新关卡等级
        printf("Current level: %d\n", exgame->level);
        initBall(&exgame->ball, exgame->level); // 根据新关卡等级重新初始化球
        gameInit(exgame);
    }
}

static int hitBricks(struct ExGame* exgame)
{
    int j = exgame->ball.x / BRICKS_W;
    int i = (exgame->ball.y - exgame->ball.r) / BRICKS_H;
    if (i < ROW && j < COLS && exgame->map.arr[i][j] != 0)
    {
        exgame->map.arr[i][j] = 0;
        exgame->score += 10;
        return 1;
    }
    return 0;
}

static int hitBoard(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y && exgame->ball.y - exgame->ball.r <= exgame->board.y + exgame->board.h)
    {
        if (exgame->ball.x + exgame->ball.r >= exgame->board.x && exgame->ball.x - exgame->ball.r <= exgame->board.x + exgame->board.w)
        {
            return 1;
        }
    }
    return 0;
}

static void moveBall(struct ExGame* exgame)
{
    if (exgame->ball.x - exgame->ball.r <= 0 || exgame->ball.x + exgame->ball.r >= WIDTH)
    {
        exgame->ball.dx = -exgame->ball.dx;
    }
    if (exgame->ball.y - exgame->ball.r <= 0 || hitBoard(exgame) || hitBricks(exgame))
    {
        exgame->ball.dy = -exgame->ball.dy;
    }
    exgame->ball.x += exgame->ball.dx;
    exgame->ball.y += exgame->ball.dy;
}

static int gameOver(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y + exgame->board.h)
    {
        return 1;
    }
    return 0;
}

static int gameWin(struct ExGame* exgame, HWND hwnd)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLS; j++)
        {
            if (exgame->map.arr[i][j] != 0)
            {
                return 0;
            }
        }
    }
    char levelStr[20];
    sprintf_s(levelStr, "Level: %d", exgame->level);
    outtextxy(10, HEIGHT - 60, levelStr);
    MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
    exgame->level++; // 进入下一关,更新关卡等级
    printf("Current level: %d\n", exgame->level);
    gameInit(exgame);

    return 1;
}

#include "ExBall.h"
#include <stdlib.h> 

void initBall(struct ExBall* pBall, int level)
{
    pBall->x = 200 + rand() % 401; // 在 0 - 400 范围内生成随机 x 坐标
    pBall->y = rand() % 20 + 300; // 在 300 - 320 范围内生成随机 y 坐标
    pBall->r = 15 - 2.5 * level; // 根据关卡等级调整球的大小
    pBall->dx = 5 + 2 * level; // 根据关卡等级调整球的速度
    pBall->dy = -5 - 2 * level; // 根据关卡等级调整球的速度
    pBall->level = level; // 设置球的关卡等级
    pBall->color = WHITE;
}

void drawBall(const struct ExBall* pBall)
{
    setfillcolor(pBall->color);
    fillcircle(pBall->x, pBall->y, pBall->r);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-30 14:52:39 | 显示全部楼层    本楼为最佳答案   

根据代码的片段分析,以下是可能存在的问题:

  • 缺少头文件引用:代码中使用了graphics.h等头文件,但没有看到相应的头文件引用语句。请确保在运行代码之前正确引用所需的头文件。
  • main函数缺失:这是一个代码片段,缺少main函数的定义。请确保在该文件或其他文件中包含适当的main函数。
  • 使用了未定义的结构体和函数:在代码中引用了ExGame、ExTimer、ExBall等结构体和相关函数,但是没有提供相应的定义。请确保这些结构体和函数的定义在代码中的其他位置或其他相关文件中。
  • 初始化图形库错误:在gameLoop函数中调用了initgraph函数初始化图形库,但是没有检查初始化是否成功。请确保调用成功后再进行图形绘制操作。
  • 图形绘制顺序有误:在gameLoop函数中,先绘制背景图像,然后在其上绘制地图、挡板和球等元素,最后执行FlushBatchDraw函数刷新绘图缓冲区。正确的绘制顺序应该是先绘制地图、挡板和球等元素,然后再绘制背景图像,最后刷新绘图缓冲区。


请注意,以上只是根据代码片段进行的初步分析,可能存在其他问题。

根据代码片段的问题,以下是修改后的代码建议:
#include "ExGame.h"
#include "ExTimer.h"
#include <graphics.h>
#include "ExBall.h"

static void keyDown(struct ExGame* exgame, HWND hwnd);
static int hitBricks(struct ExGame* exgame);
static int hitBoard(struct ExGame* exgame);
static void moveBall(struct ExGame* exgame);
static int gameOver(struct ExGame* exgame);
static int gameWin(struct ExGame* exgame, HWND hwnd);

void gameInit(struct ExGame* exgame)
{
    initMap(&exgame->map);
    initBoard(&exgame->board);
    exgame->score = 0;
    exgame->level = ExGame::initialLevel;
    initBall(&exgame->ball, exgame->level);
}

int gameLoop(struct ExGame* exgame)
{
    HWND hwnd = initgraph(WIDTH, HEIGHT);
    if (hwnd == NULL) {
        printf("图形库初始化失败\n");
        return -1;
    }
    
    IMAGE bk;
    loadimage(&bk, "./w.jpg", WIDTH, HEIGHT);
    BeginBatchDraw();

    while (1)
    {
        putimage(0, 0, &bk);
        drawMap(exgame->map);
        drawBoard(exgame->board);
        drawBall(&exgame->ball);
        char scoreStr[20];
        sprintf_s(scoreStr, "Score: %d", exgame->score);
        outtextxy(10, HEIGHT - 30, scoreStr);

        keyDown(exgame, hwnd);
        moveBall(exgame);

        if (gameOver(exgame))
        {
            int choice = MessageBoxA(hwnd, "你输了 再玩一遍吗?", "游戏结束", MB_YESNO | MB_ICONQUESTION);
            if (choice == IDNO)
            {
                closegraph();
                return 0;
            }
            else if (choice == IDYES)
            {
                gameInit(exgame);
            }
        }
        else if (gameWin(exgame, hwnd))
        {
            char levelStr[20];
            sprintf_s(levelStr, "Level: %d", exgame->level);
            outtextxy(10, HEIGHT - 60, levelStr);
            MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
            exgame->level++;
            printf("Current level: %d\n", exgame->level);
            initBall(&exgame->ball, exgame->level);
            gameInit(exgame);
        }

        FlushBatchDraw();
        Sleep(20);
    }

    EndBatchDraw();
    closegraph();
    return 0;
}

static void keyDown(struct ExGame* exgame, HWND hwnd)
{
    if ((GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)) && exgame->board.x > 0)
    {
        exgame->board.x -= exgame->board.speed;
    }
    if ((GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)) && exgame->board.x + exgame->board.w < WIDTH)
    {
        exgame->board.x += exgame->board.speed;
    }
    if (GetAsyncKeyState('9'))
    {
        exgame->level++;
        printf("Current level: %d\n", exgame->level);
        initBall(&exgame->ball, exgame->level);
        gameInit(exgame);
    }
}

static int hitBricks(struct ExGame* exgame)
{
    int j = exgame->ball.x / BRICKS_W;
    int i = (exgame->ball.y - exgame->ball.r) / BRICKS_H;
    if (i < ROW && j < COLS && exgame->map.arr[i][j] != 0)
    {
        exgame->map.arr[i][j] = 0;
        exgame->score += 10;
        return 1;
    }
    return 0;
}

static int hitBoard(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y && exgame->ball.y - exgame->ball.r <= exgame->board.y + exgame->board.h)
    {
        if (exgame->ball.x + exgame->ball.r >= exgame->board.x && exgame->ball.x - exgame->ball.r <= exgame->board.x + exgame->board.w)
        {
            return 1;
        }
    }
    return 0;
}

static void moveBall(struct ExGame* exgame)
{
    if (exgame->ball.x - exgame->ball.r <= 0 || exgame->ball.x + exgame->ball.r >= WIDTH)
    {
        exgame->ball.dx = -exgame->ball.dx;
    }
    if (exgame->ball.y - exgame->ball.r <= 0 || hitBoard(exgame) || hitBricks(exgame))
    {
        exgame->ball.dy = -exgame->ball.dy;
    }
    exgame->ball.x += exgame->ball.dx;
    exgame->ball.y += exgame->ball.dy;
}

static int gameOver(struct ExGame* exgame)
{
    if (exgame->ball.y + exgame->ball.r >= exgame->board.y + exgame->board.h)
    {
        return 1;
    }
    return 0;
}

static int gameWin(struct ExGame* exgame, HWND hwnd)
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLS; j++)
        {
            if (exgame->map.arr[i][j] != 0)
            {
                return 0;
            }
        }
    }
    char levelStr[20];
    sprintf_s(levelStr, "Level: %d", exgame->level);
    outtextxy(10, HEIGHT - 60, levelStr);
    MessageBox(hwnd, "你赢了", "游戏结束", MB_OK);
    exgame->level++;
    printf("Current level: %d\n", exgame->level);
    gameInit(exgame);

    return 1;
}

void initBall(struct ExBall* pBall, int level)
{
    pBall->x = 200 + rand() % 401;
    pBall->y = rand() % 20 + 300;
    pBall->r = 15 - 2.5 * level;
    pBall->dx = 5 + 2 * level;
    pBall->dy = -5 - 2 * level;
    pBall->level = level;
    pBall->color = WHITE;
}

void drawBall(const struct ExBall* pBall)
{
    setfillcolor(pBall->color);
    fillcircle(pBall->x, pBall->y, pBall->r);
}
这是根据代码片段进行的修改建议,但仍然需要确保整个代码的完整性和正确性。如果问题仍然存在,请尽可能提供完整的代码,以便进行更准确的分析和修复。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-30 15:58:57 | 显示全部楼层
小号。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 01:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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