laocaiye 发表于 2025-6-6 21:45:46

游戏界面不能正常显示问题

目前,我正在学习“奇牛编程”rock老师的“羊了羊第二关”编程设计,刚听一部分,代码也是完全仿写。视频中介绍该游戏可以在vs2022运行。视频中运行正常,但是我的代码在VS2022
运行时出现两个问题:一是游戏界面稍作停顿就自动退出,二是中间要渲染的图片不能正常渲染。因为游戏界面不能正常显示,导致也没法向后学习。先把当前已形成的代码发布出来,
请帮忙查找上面两个问题原因。

#include <stdio.h>
#include <graphics.h>
#include <time.h>
#include "tools.h"

#define WIN_WIDTH504
#define WIN_HEIGHT 1000
#define MAX_LAYER54
#define BLOCK_KIND 15
#define BLOCK_W    61
#define BLOCK_H    68

IMAGE imgBg;
IMAGE imgBlocks;

typedef struct Block
{
        int layer; //方块所在层
        int type; //方块类型(物品)>=1,如果为0,则代表被消除
        int row, col; // 方块在这一层的位置
        int x, y; //
        bool isTop; //方块是否顶层方块,只有顶层方块才能消除
        int offset_x, offset_y; //这一层第一个方块的偏移

}Block;

Block** maps;

//初始化每一层map
void initLayer(int layer, int rows, int cols, int left, int top)
{
        maps =(Block**) malloc(sizeof(Block*) * (rows * cols+1));
        for (int row = 0; row < rows; row++)
        {
                for (int col = 0; col < cols; col++)
                {
                        maps = (Block*)malloc(sizeof(Block));
                        maps->row = row;
                        maps->col = col;
                        maps->offset_x = left;
                        maps->offset_x = top;
                        maps->type =1 + rand() % BLOCK_KIND;
                        maps->isTop = true;
                        maps->x = left + col * BLOCK_W;
                        maps->y = top + row * BLOCK_H;
                        maps->layer = layer;
                }
        }
        maps = NULL;
}

//初始化map
void initMap()
{
        int layer = 0;
        for (; layer < 12; layer++) initLayer(layer, 1, 1, 30, 440 + layer * 10);
        for (; layer < 24; layer++) initLayer(layer, 1, 1, 414, 440 + (layer-12) * 10);
        for (; layer < 30; layer++) initLayer(layer, 1, 1, 94, 583 + (layer-24) * 10);
        for (; layer < 36; layer++) initLayer(layer, 1, 1, 346, 583 + (layer-30) * 10);
        for (; layer < 42; layer++) initLayer(layer, 1, 1, 30+(layer-36)*10, 130);
        for (; layer < 48; layer++) initLayer(layer, 1, 1, 413-(layer-42)*10,130);

        initLayer(layer++, 4, 3, 159, 309);
        initLayer(layer++, 5, 3, 159, 228);
        initLayer(layer++, 5, 4, 129, 204);
        initLayer(layer++, 5, 5, 99, 180);
        initLayer(layer++, 3, 6, 70, 209);
        initLayer(layer++, 5, 3, 159, 228);
}

//游戏初始化
void initGame()
{
        //初始化游戏窗口
        initgraph(WIN_WIDTH, WIN_HEIGHT);
        //把背景图片装入数组
        loadimage(&imgBg, "res/bg1.png");
        loadimage(&imgBg, "res/bg2.png");
        //初始化随机种子
        srand((unsigned int)time(NULL));
        //初始化map
        initMap();
        //初始化图片组
        char fileName;
        for (int i = 0; i<BLOCK_KIND; i++)
        {
                for (int j = 0; j < 2; j++)
                {
                        sprintf_s(fileName, sizeof(fileName), "res/%d_%d.png", i + 1, j);
                        loadimage(&imgBlocks, fileName);
                }
               
        }
}

void updateWindow()
{
        //BeginBatchDraw();
        //绘制背景
        putimage(0, 0, &imgBg);
        //渲染图片
        for (int i = 0; i < MAX_LAYER; i++)
        {
                for (int j = 0; maps; i++)
                {
                        Block* p = maps;
                        IMAGE* imgTmp = &imgBlocks;
                        putimagePNG(p->x, p->y, imgTmp);
                }
        }
        //EndBatchDraw();
}

int main()
{
        initGame();

        updateWindow();
        system("pause");
        return 0;
}

小甲鱼的二师兄 发表于 2025-6-6 21:53:19

你的 main 函数逻辑,updateWindow 只绘制一次,然后 system("pause") 等你按任意键,程序随即退出。

没有消息循环,窗口停留时间极短(除非你马上切换到窗口并操作),大部分情况下窗口一闪而过。

应该在 main 中添加一个主循环,持续刷新界面并响应窗口关闭事件。

小甲鱼的二师兄 发表于 2025-6-6 21:53:51

图片无法渲染可能是图片路径问题:图片必须放在可执行文件同目录下的res文件夹里,且文件名及扩展名大小写完全一致。否则 loadimage 加载失败,渲染时只是空白。

爬虫121 发表于 2025-6-6 23:32:40

小甲鱼的二师兄 发表于 2025-6-6 21:53
图片无法渲染可能是图片路径问题:图片必须放在可执行文件同目录下的res文件夹里,且文件名及扩展名大小写 ...

专业

laocaiye 发表于 2025-6-7 18:09:44

本帖最后由 laocaiye 于 2025-6-7 18:13 编辑

小甲鱼的二师兄 发表于 2025-6-6 21:53
图片无法渲染可能是图片路径问题:图片必须放在可执行文件同目录下的res文件夹里,且文件名及扩展名大小写 ...

因为是对现有代码进行测试,就是绘制一次看效果。在暂停状态下,界面应该一直存在啊。并且视频中老师也是这么写的,教学视频中运行界面是稳定的,也是按应有的效果出现的。但是我的怎么就是不行?也没有提示编译或运行错误。前阶段也是仿照这个老师讲的游戏“五子棋人机对战”,单独编译或运行都不提示错误,但是运行起来后,人刚下一个黑子,界面就崩了。我下断点调试时,一直是下载各种链接库文件界面。感觉五子棋羊了个羊游戏相比较扫雷游戏,也只是复杂点啊,我仿写的扫雷游戏在 VS2022上运行还是很完美的。但是羊了个羊和五子棋不清楚怎么运行不起来。

laocaiye 发表于 2025-6-7 18:10:40

图片资源放置位置也是正确的,并没有放错。

小甲鱼的二师兄 发表于 2025-6-7 21:06:16

laocaiye 发表于 2025-6-7 18:09
因为是对现有代码进行测试,就是绘制一次看效果。在暂停状态下,界面应该一直存在啊。并且视频中老师也 ...

但是EasyX(你用的<graphics.h>就是EasyX库)创建的是独立的图形窗口,system("pause")并不会让图形窗口保持。

EasyX窗口本身在主函数结束时就会关闭。如果你想让窗口保持打开状态,应该有一个消息循环或等待窗口关闭,比如:

while (!_kbhit()) {
    Sleep(10);
}

小甲鱼的二师兄 发表于 2025-6-7 21:07:22

图片不能正常渲染可能原因:

1. 图片路径错误:你说路径没问题,但建议绝对路径或用_access()测试图片是否存在。

2. 图片加载失败:loadimage()没有返回值,不报错,但图片未加载会导致putimage()不显示。

3. 图片格式问题:确保res/bg1.png和其它图片都是真正的PNG图片。

4. putimagePNG问题:你用的是putimagePNG(),不是EasyX自带的putimage()。如果putimagePNG是自己写的,要确认实现没问题!EasyX本身没有putimagePNG,只有putimage。

laocaiye 发表于 2025-6-11 19:27:18

我现在学习植物大战僵尸游戏,回头我再对前面提到的两个游戏视频教程细细观看,估计还是有什么语句处理位置有问题。
页: [1]
查看完整版本: 游戏界面不能正常显示问题