c++打地鼠程序运行黑屏

程序编译不报错气,但是运行时黑屏。运行环境是VS2022,所用编程语言是c++。
相关代码


```c++
#include <graphics.h>
#include <conio.h>
#include <mmsystem.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib,"Winmm.lib")
#include <time.h>
#include "Hamster.h"
#include "Hammer.h"

#define _CRT_SECURE_NO_DEPRECATEd
#define _CRT_SECURE_NO_WARNINGS

#define TEST 1
#define SPEED 20//地鼠移动间隔时间 ms

#define WINDOW_WIDTH        640 //窗口宽
#define WINDOW_HEITH        478 //窗口高

#define RULE_WIDTH            800//规则窗口宽
#define RULE_HEITH            601//规则窗口高

#define TOP_HEITH            192 //背景图top高
#define MID_UP_HEITH        120 //背景图mid_up高
#define MID_DOWN_HEITH        167 //背景图mid_down高
#define BOTTOM_HEITH        116 //背景图bottom高

#define MID_UP_BEGIN_Y        164 //背景图mid_up起始y坐标
#define MID_DOWN_BEGIN_Y    247 //背景图mid_down起始y坐标
#define BOTTOM_BEGIN_Y        364 //背景图bottom起始y坐标

#define LITTLE_Hamster_WIDTH    90 //小地鼠宽
#define LITTLE_Hamster_HEITH    74 //小地鼠高
#define MID_Hamster_WIDTH        102 //中地鼠宽
#define MID_Hamster_HEITH        86 //中地鼠高
#define BIG_Hamster_WIDTH        122 //大地鼠宽
#define BIG_Hamster_HEITH        106 //大地鼠高

#define LITTLE_Hamster_BEGIN_X    135 //小地鼠起始位置
#define LITTLE_Hamster_BEGIN_Y    191
#define LITTLE_Hamster_SPACE    137 //小地鼠间距

#define MID_Hamster_BEGIN_X        106 //中地鼠起始位置
#define MID_Hamster_BEGIN_Y        283
#define MID_Hamster_SPACE        156 //中地鼠间距

#define BIG_Hamster_BEGIN_X        65 //大地鼠起始位置
#define BIG_Hamster_BEGIN_Y        410
#define BIG_Hamster_SPACE        185 //大地鼠间距

#define UP                      1 //地鼠运动方向向上
#define DOWN                    0 //地鼠运动方向向下

#define HAMMER_BEGIN_X    320 //锤子初始位置
#define HAMMER_BEGIN_Y    220

#define SCORE_WORDS_X    10 //"得分"文字描述与数字的位置
#define SCORE_NUMBER_X    90
#define SCORE_Y            30

#define TARGET_WORDS_X    5  //"目标"文字描述与数字的位置
#define TARGET_NUMBER_X    90
#define TARGET_Y        10

#define MISSED_WORDS_X    520 //"错过的"文字描述与数字的位置
#define MISSED_NUMBER_X 610
#define MISSED_Y        10

#define MAX_MISSED_WORDS_X    525//"生命值"文字描述与数字的位置
#define MAX_MISSED_NUMBER_X 610
#define MAX_MISSED_Y        30

#define EFFECTIVE_ZONE_X 36
#define EFFECTIVE_ZONE_Y 101
#define EFFECTIVE_ZONE_HEIGHT 33
#define EFFECTIVE_ZONE_WIDTH 64

#define FRAME 20    //锤子砸下状态转换持起状态的间隔帧

#define time_internal 100//从地鼠被打倒后,到再次刷新地鼠的时间间隔

#define SIMPLE_TARGET    20//简单模式下需要锤的个数
#define MIDDLE_TARGET    30//中等模式下需要锤的个数
#define HARD_TARGET        45//困难模式下需要锤的个数
#define HEEL_TARGET        70//地狱模式下需要锤的个数

#define SIMPLE_MAXMISS    20//简单模式下最大可以错过地鼠的个数
#define MIDDLE_MAXMISS    15//中等模式下最大可以错过地鼠的个数
#define HARD_MAXMISS    10//困难模式下最大可以错过地鼠的个数
#define HEEL_MAXMISS    5//地狱模式下最大可以错过地鼠的个数

#define SIMPLE_SPEED    3//简单模式下地鼠的速度
#define MIDDLE_SPEED    5//中等模式下地鼠的速度
#define HARD_SPEED        9//困难模式下地鼠的速度
#define HEEL_SPEED        11//地狱模式下地鼠的速度

//图片数据

IMAGE top, mid_up, mid_down, bottom;//四张背景图原图
IMAGE top_y, mid_up_y, mid_down_y, bottom_y;//遮罩图

IMAGE little_Hamster, mid_Hamster, big_Hamster;//老鼠原图
IMAGE little_Hamster_y, mid_Hamster_y, big_Hamster_y;//遮罩图

IMAGE img_Hammer, img_Hammer_down;//锤子原图
IMAGE img_Hammer_mask, img_Hammer_down_mask;//锤子遮罩图

IMAGE img_hitted, img_hitted_mask;//击中图与遮罩图

IMAGE img_win; IMAGE img_lose;//获胜或者失败的图片

HWND hWnd;//窗口句柄

//全局变量
bool isOver;/* = false*///判断是否结束
bool isWin = false;//是否获胜
bool isLose = false;//是否失败
bool menu_exit = false;//是否在菜单页面退出
int score;//初始分数
int target;//设置目标
int missed;//成功逃离的地鼠d
int max_miss;//最多可miss的地鼠数量
int life;//剩余生命
int m;//记录当前是哪个地鼠动
int speed;//地鼠的速度,不同难度下不同
int tops[10];//排名前三位的分数
int top_life[10];//排名前三位的分数

void set() {//全局变量初始化函数
    isOver = false;//是否结束赋值为false
    isWin = false;//是否获胜赋值为否
    isLose = false;//是否失败赋值为否
    score = 0;//初始分数设置为0
    //target = SIMPLE;//设置目标为简单
    //max_miss = SIMPLE;
    missed = 0;
    //speed = HARD_SPEED;
    life = max_miss;
    srand(time(0));//播种
    m = rand() % 9;    //0-8
}


Hamster ds[9];//地鼠数组初始化

Hammer hammer;//锤子结构体初始化

void initGame() //游戏框架初始化
{
    //1 设置窗口

    hWnd = initgraph(WINDOW_WIDTH, WINDOW_HEITH);
    //2 图片资源引入,背景音乐资源引入
    loadimage(&top, _T("picture\\top.bmp"));
    loadimage(&mid_up, _T("picture\\mid_up.bmp"));
    loadimage(&mid_down, _T("picture\\mid_down.bmp"));
    loadimage(&bottom, _T("picture\\bottom.bmp"));

    loadimage(&top_y, _T("picture\\top_y.bmp"));
    loadimage(&mid_up_y, _T("picture\\mid_up_y.bmp"));
    loadimage(&mid_down_y, _T("picture\\mid_down_y.bmp"));
    loadimage(&bottom_y, _T("picture\\bottom_y.bmp"));

    loadimage(&little_Hamster, _T("picture\\little_mouse.bmp"));
    loadimage(&mid_Hamster, _T("picture\\mid_mouse.bmp"));
    loadimage(&big_Hamster, _T("picture\\big_mouse.bmp"));

    loadimage(&little_Hamster_y, _T("picture\\little_mouse_y.bmp"));
    loadimage(&mid_Hamster_y, _T("picture\\mid_mouse_y.bmp"));
    loadimage(&big_Hamster_y, _T("picture\\big_mouse_y.bmp"));

    loadimage(&little_Hamster_y, _T("picture\\little_mouse_y.bmp"));
    loadimage(&mid_Hamster_y, _T("picture\\mid_mouse_y.bmp"));
    loadimage(&big_Hamster_y, _T("picture\\big_mouse_y.bmp"));

    loadimage(&img_Hammer, _T("picture\\hammer.bmp"));
    loadimage(&img_Hammer_mask, _T("picture\\hammer_y.bmp"));

    loadimage(&img_Hammer_down, _T("picture\\hammer_down.bmp"));
    loadimage(&img_Hammer_down_mask, _T("picture\\hammer_down_y.bmp"));

    loadimage(&img_hitted, _T("picture\\died.png"));
    loadimage(&img_hitted_mask, _T("picture\\died_mask.png"));


    loadimage(&img_win, _T("picture\\win.png"));
    loadimage(&img_lose, _T("picture\\lose.png"));

    mciSendString(_T("open music\\bkmusic.mp3 alias bkmusic"), NULL, 0, NULL);
    mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);

    mciSendString(_T("open music\\hammerDown.wav alias hitmusic"), NULL, 0, NULL);//重新打开读取音乐文件

    //3 结构体数据初始化
    for (int i = 0; i < 9; i++)
    {
        if (i >= 0 && i < 3)
        {
            ds[i].img = little_Hamster;
            ds[i].img_y = little_Hamster_y;

            ds[i].x = LITTLE_Hamster_BEGIN_X + i * LITTLE_Hamster_SPACE;
            ds[i].y = LITTLE_Hamster_BEGIN_Y;
        }
        if (i >= 3 && i < 6)
        {
            ds[i].img = mid_Hamster;
            ds[i].img_y = mid_Hamster_y;

            ds[i].x = MID_Hamster_BEGIN_X + (i - 3) * MID_Hamster_SPACE;
            ds[i].y = MID_Hamster_BEGIN_Y;
        }
        if (i >= 6 && i < 9)
        {
            ds[i].img = big_Hamster;
            ds[i].img_y = big_Hamster_y;

            ds[i].x = BIG_Hamster_BEGIN_X + (i - 6) * BIG_Hamster_SPACE;
            ds[i].y = BIG_Hamster_BEGIN_Y;
        }

        ds[i].dir = 1;//1-up   0down
        ds[i].hitted = false;//地鼠是否被击过中赋值为否
    }

    hammer.img = img_Hammer;
    hammer.img_y = img_Hammer_mask;
    hammer.img_hit = img_Hammer_down;
    hammer.img_hit_y = img_Hammer_down_mask;
    hammer.img_thitted_mask = img_hitted_mask;
    hammer.img_thitted = img_hitted;
    hammer.x = HAMMER_BEGIN_X;
    hammer.y = HAMMER_BEGIN_Y;
    hammer.hit = false;

}


//画面显示
void drawGame() {
    BeginBatchDraw();
    putimage(0, 0, &top_y, SRCAND);//显示上部分背景图
    putimage(0, 0, &top, SRCPAINT);

    for (int i = 0; i < 3; i++)//显示小地鼠
    {
        ds[i].draw();
    }
    putimage(0, MID_UP_BEGIN_Y, &mid_up_y, SRCAND);//显示上半部分背景
    putimage(0, MID_UP_BEGIN_Y, &mid_up, SRCPAINT);
    for (int i = 3; i < 6; i++)//显示中地鼠
    {
        ds[i].draw();
    }
    putimage(0, MID_DOWN_BEGIN_Y, &mid_down_y, SRCAND);//显示中间部分背景
    putimage(0, MID_DOWN_BEGIN_Y, &mid_down, SRCPAINT);
    for (int i = 6; i < 9; i++)//显示大地鼠
    {
        ds[i].draw();
    }
    putimage(0, BOTTOM_BEGIN_Y, &bottom_y, SRCAND);//显示下部分背景
    putimage(0, BOTTOM_BEGIN_Y, &bottom, SRCPAINT);

    hammer.draw(ds[m].hitted, FRAME);//显示锤子

    //绘制当前得分与目标
    settextcolor(GREEN);
    TCHAR s1[] = _T("当前得分:");
    outtextxy(SCORE_WORDS_X, SCORE_Y, s1);
    TCHAR s_12[5];
    _stprintf_s(s_12, _T("%d"), score);
    outtextxy(SCORE_NUMBER_X, SCORE_Y, s_12);

    settextcolor(YELLOW);
    TCHAR s2[] = _T(" 目标得分:");
    outtextxy(TARGET_WORDS_X, TARGET_Y, s2);
    _stprintf_s(s_12, _T("%d"), target);
    outtextxy(TARGET_NUMBER_X, TARGET_Y, s_12);

    settextcolor(RED);
    TCHAR s3[] = _T("剩余生命:");
    outtextxy(MAX_MISSED_WORDS_X, MAX_MISSED_Y, s3);
    _stprintf_s(s_12, _T("%d"), life);
    outtextxy(MAX_MISSED_NUMBER_X, MAX_MISSED_Y, s_12);

    settextcolor(YELLOW);
    TCHAR s4[] = _T(" 初始血量:");
    outtextxy(MISSED_WORDS_X, MISSED_Y, s4);
    _stprintf_s(s_12, _T("%d"), max_miss);
    outtextxy(MAX_MISSED_NUMBER_X, MISSED_Y, s_12);

    EndBatchDraw();
}

bool canNotMoveUp()//检查是否往上走到顶了
{
    if (m >= 0 && m < 3) {
        if (ds[m].y <= LITTLE_Hamster_BEGIN_Y - LITTLE_Hamster_HEITH)
            return true;
    }
    if (m >= 3 && m < 6) {
        if (ds[m].y <= MID_Hamster_BEGIN_Y - MID_Hamster_HEITH)
            return true;
    }
    if (m >= 6 && m < 9) {
        if (ds[m].y <= BIG_Hamster_BEGIN_Y - BIG_Hamster_HEITH)
            return true;
    }
    return false;
}

bool canNotMoveDown()//检查是否往下走到底了
{
    if (m >= 0 && m < 3) {
        if (ds[m].y >= LITTLE_Hamster_BEGIN_Y)
            return true;
    }
    if (m >= 3 && m < 6) {
        if (ds[m].y >= MID_Hamster_BEGIN_Y)
            return true;
    }
    if (m >= 6 && m < 9) {
        if (ds[m].y >= BIG_Hamster_BEGIN_Y)
            return true;
    }
    return false;
}

void ctolGame()//控制 
{
    if (ds[m].dir == UP) {
        ds[m].moveUp(speed);
        if (canNotMoveUp())
            ds[m].dir = DOWN;
    }
    else {
        ds[m].moveDown(speed);
        if (canNotMoveDown()) {
            ds[m].dir = UP;
            if (ds[m].hitted == false) {
                missed++;
                life--;
            }
            else {
                ds[m].hitted = false;
            }
            int tmp = m;
            while (tmp == m)
                m = rand() % 9;//刷新地鼠
        }
    }
}

void refreshDiShu() {
    if (m >= 0 && m < 3)
        ds[m].y = LITTLE_Hamster_BEGIN_Y + 1;
    else if (m >= 3 && m < 6)
        ds[m].y = MID_Hamster_BEGIN_Y + 1;
    else if (m >= 6 && m < 9)
        ds[m].y = BIG_Hamster_BEGIN_Y + 1;
}

void control() {
    ExMessage m;//新版写法
    while (peekmessage(&m, EM_MOUSE, PM_NOREMOVE))
    {
        m = getmessage();
        if (m.message == WM_MOUSEMOVE)//更新锤子坐标
        {
            hammer.x = m.x - (img_Hammer.getwidth() / 2);
            hammer.y = m.y - (img_Hammer.getheight() / 2);
        }
        if (m.message == WM_LBUTTONDOWN && hammer.hit == false)//左键垂下去
        {
            hammer.hit = true;
        }
    }
}

void logic() {
    int effectiveZoneX, effectiveZoneY, effectiveZoneHeight, effectiveZoneWidth;//锤子的有效击中区域
    effectiveZoneX = hammer.x + EFFECTIVE_ZONE_X;
    effectiveZoneY = hammer.y + EFFECTIVE_ZONE_Y;
    effectiveZoneHeight = EFFECTIVE_ZONE_HEIGHT;
    effectiveZoneWidth = EFFECTIVE_ZONE_WIDTH;

    if (hammer.hit == true && ds[m].hitted == false) {
        if (abs(effectiveZoneX - ds[m].x) < effectiveZoneWidth / 2 + ds[m].img.getwidth() / 2 &&
            abs(effectiveZoneY - ds[m].y) < effectiveZoneHeight / 2 + ds[m].img.getheight() / 2) {
            score++;
            ds[m].hitted = true;
            ds[m].dir = DOWN;
            refreshDiShu();
        }
    }

    if (score == target) {
        isWin = true;
    }
    if (life == 0) {
        isLose = true;
    }
    if (isWin == true || isLose == true) {
        isOver = true;
    }

}
void readRecordFile()
{//读取存档
    FILE* fp;
    int temp;
    fp = fopen(".\\record.dat", "r");
    fscanf_s(fp, "%d %d %d %d %d %d", &tops[0], &top_life[0], &tops[1], &top_life[1], &tops[2], &top_life[2]);
    fclose(fp);

}
void WriteRecordFile()
{//保存存档
    FILE* fp;
    int temp;
    fp = fopen(".\\record.dat", "w");
    tops[3] = score;
    top_life[3] = life;
    int i = 0, j = 0;
    for (i = 0; i < 4; i++) {
        if (score == tops[i] && life > top_life[i]) {
            top_life[i] = life;
            break;
        }
    }
    for (int i = 0; i < 4 - 1; i++) {
        for (int j = 0; j < 4 - 1 - i; j++) {
            if (tops[j] < tops[j + 1]) {
                int temp = tops[j];
                int temp2 = top_life[i];
                tops[j] = tops[j + 1];
                top_life[j] = top_life[j + 1];
                tops[j + 1] = temp;
                top_life[j + 1] = temp2;
            }
        }
    }
    fprintf(fp, "%d %d %d %d %d %d", tops[0], top_life[0], tops[1], top_life[1], tops[2], top_life[2]);
    fclose(fp);
}
void draw_rank() {
    readRecordFile();
    WriteRecordFile();
    readRecordFile();

    settextcolor(YELLOW);
    TCHAR s0[] = _T("Rank!!!");
    outtextxy(SCORE_WORDS_X, SCORE_Y - 30, s0);
    TCHAR s_12[5];

    //initgraph(WIDTH,HEIGHT);
    settextcolor(GREEN);
    TCHAR s1[] = _T("Top1 score:      life:");
    outtextxy(SCORE_WORDS_X, SCORE_Y, s1);

    settextcolor(RED);
    _stprintf_s(s_12, _T("%d"), tops[0]);
    outtextxy(SCORE_NUMBER_X, SCORE_Y, s_12);
    _stprintf_s(s_12, _T("%d"), top_life[0]);
    outtextxy(SCORE_NUMBER_X + 43, SCORE_Y, s_12);

    settextcolor(GREEN);
    TCHAR s2[] = _T("Top2 score:      life:");
    outtextxy(SCORE_WORDS_X, SCORE_Y + 50, s2);
    settextcolor(RED);
    _stprintf_s(s_12, _T("%d"), tops[1]);
    outtextxy(SCORE_NUMBER_X, SCORE_Y + 50, s_12);
    _stprintf_s(s_12, _T("%d"), top_life[1]);
    outtextxy(SCORE_NUMBER_X + 43, SCORE_Y + 50, s_12);

    settextcolor(GREEN);
    TCHAR s3[] = _T("Top3 score:      life:");
    outtextxy(SCORE_WORDS_X, SCORE_Y + 100, s3);
    settextcolor(RED);
    _stprintf_s(s_12, _T("%d"), tops[2]);
    outtextxy(SCORE_NUMBER_X, SCORE_Y + 100, s_12);
    _stprintf_s(s_12, _T("%d"), top_life[2]);
    outtextxy(SCORE_NUMBER_X + 43, SCORE_Y + 100, s_12);

    Sleep(5000);
    closegraph();

}
void drawRules() {//显示规则
    ExMessage em;
    IMAGE img_rules;
    initgraph(RULE_WIDTH, RULE_HEITH);
    loadimage(&img_rules, _T("picture\\rules.jpg"));
    putimage(0, 0, &img_rules);

    bool exit = false;
    while (true) {
        while (peekmessage(&em, EM_MOUSE)) {
            em = getmessage();
            if (em.message == WM_KEYDOWN || em.message == WM_LBUTTONDOWN || em.message == WM_RBUTTONDOWN) { //按下键盘任意键,鼠标左右键时,退出规则,开始游戏。
                exit = true;
                closegraph();
                while (_kbhit())
                    _getch();//清空缓冲区,防止键盘跳过规则的情况下键盘缓冲区中存留一个字符导致选择难度出错的问题。
                break;
            }
        }
        if (exit == true) {
            break;
        }
    }
}
void choose() {//选择难度
    IMAGE img_choose;
    initgraph(RULE_WIDTH, RULE_HEITH);
    loadimage(&img_choose, _T("picture\\choose.png"));
    putimage(0, 0, &img_choose);
    while (true) {
        if (_kbhit())
        {
            char input = _getch();
            switch (input)
            {
            case '1': target = SIMPLE_TARGET; max_miss = SIMPLE_MAXMISS; speed = SIMPLE_SPEED; break;
                //case '2': target = MIDDLE_TARGET; max_miss = MIDDLE_MAXMISS; speed = MIDDLE_SPEED; break;
            case '2': target = HARD_TARGET; max_miss = HARD_MAXMISS; speed = HARD_SPEED; break;
            case '3': target = HARD_TARGET; max_miss = HEEL_MAXMISS; speed = HEEL_SPEED; break;
            case '4': closegraph(); menu_exit = true; break;
            default:continue;
            }
            break;
        }
    }
    closegraph();
}

void showResult() {
    closegraph();
    initgraph(RULE_WIDTH, RULE_HEITH);
    if (isWin == true)
        putimage(0, 0, &img_win);
    else
        putimage(0, 0, &img_lose);

    Sleep(1000);
    cleardevice();//关闭画面
}
int main()
{
    drawRules();//规则
    choose();//选择难度
    if (menu_exit == true) return 0;
    set();//全局变量初始化
    initGame();//游戏框架初始化
    SetTimer(hWnd, 2333, SPEED, (TIMERPROC)ctolGame);//生成计时器
    while (!isOver)//未结束则循环
    {
        logic();//逻辑部分
        drawGame();//画面显示
        control();//控制部分
    }
    showResult();//展示结果(win/lose)
    draw_rank();//展示排行榜
    return 0;
}







```

需要easyx库和picture*.bmp

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7569530
  • 这篇博客也不错, 你可以看下C++学习之企业员工信息管理系统(vs2010上实现,部分实现思路以及代码示例)
  • 除此之外, 这篇博客: C++ 整数的质因数分解 VS2019中的 利用短除法原理进行整数的质因数分解,代码如下: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    #include<iostream>
    using namespace std;
    
    int main()
    {
    	cout << "请输入要进行质因数分解的整数" << endl;
    	unsigned long n;
    
    	cin >> n;
    	if (n == 0 || n == 1)
    		cout << n << "既不是质数也不是和数" << endl;
    	else
    	{
    		cout << n << "的质因数有:";
    		//应用短除法原理,进行质因数求解
    		int i = 2;		//从2开始短除,不能整除时除数i自增,直到除数i等于被除数
    		do
    		{
    			if (n % i == 0)	//当能够整除时进行循环
    			{
    				int temp = n / i;	//对被除数进行替换
    				n = temp;
    				cout << i << " ";	//每循环一次打印一次质因数
    			}
    			else
    			i++;	//不能整除时对除数i进行自增
    		} while (i != n);	//除数等于被除数时终止循环
    		cout << n << endl;	//打印最后一个质因数(短除法运算到最后的商)
    	}
    	return 0;
    }
    
  • 以下回答来自chatgpt:

    由于提供的参考资料没有与打地鼠程序出现黑屏的问题相关的内容,无法根据参考资料提供具体解决方案。建议检查代码逻辑和可能存在的错误,例如是否正确处理窗口初始化、绘制等相关函数。如果问题仍然存在,建议参考VS的调试工具和日志输出来分析和解决问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^