2301_81201339 2024-01-18 17:27 采纳率: 100%
浏览 5
已结题

VisualStudio使用<thread>多线程

我在Visual Studio 2022中编译C++坦克大战使用的多线程
结果报错
报错为

img

报错时不提示错误在哪
我在添加这行前

std::thread a(getoperate);

一切正常
求解决方法或另一种可行的方法


#include<easyx.h>
#include<conio.h>
#include<thread>

//自定更改区
#pragma region change area

#define TANK_COUNT 2//坦克种数
#define TANK_WIDTH 3//坦克宽(单数)
#define TANK_HEIGHT 3//坦克高(单数)

#define KEY_UP  72//上
#define KEY_LEFT 75//左
#define KEY_RIGHT 77//右
#define KEY_DOWN 80//下
#define KEY_SPACE 32//空格
#define KEY_Q 113//q
#define KEY_E 101//e

#define UNIT_SIZE 20//方块大小

#define WIDTH 20//活动区宽
#define HEIGHT 30//活动区高(更改时需>15)



bool enemyandme[TANK_COUNT * 4][TANK_HEIGHT][TANK_WIDTH] =
{
    //我
    {0,1,0,1,1,1,1,1,1},//上
    {1,1,0,1,1,1,1,1,0},//左
    {1,1,1,1,1,1,0,1,0},//下
    {0,1,1,1,1,1,0,1,1},//右
    //敌人1
    {0,1,0,1,1,1,1,0,1},//上
    {1,1,0,0,1,1,1,1,0},//左
    {1,0,1,1,1,1,0,1,0},//下
    {0,1,1,1,1,0,0,1,1}//右
};//坦克图案(1有)(0无)

#pragma endregion

//主体(请谨慎修改)
struct coordinate
{
    int x;
    int y;
    int to;
    bool exist = false;
    void operator=(coordinate a) {
        x = a.x;
        y = a.y;
        to = a.to;
        exist = a.exist;
    }
}tank[HEIGHT / TANK_HEIGHT * WIDTH / TANK_WIDTH], bullet[HEIGHT * WIDTH];//实体
                                          
int Fraction=0, Level=1, tanktop=0, bullettop=0;

int main();//主函数(带初始化)
void getoperate();//获取用户操作
void drawhint();//画提示框
void drawtank(int No,coordinate object);//画坦克
void drawblock(int x, int y);//画方块
void sleep();//暂停
void drawbullet();//画子弹
void a();
#pragma endregion

//函数定义(请谨慎修改)
int main() {
    Fraction = 0;
    Level = 1;
    tanktop = 1;
    bullettop = 0;
    tank[0] = { 9,9,0,true };
    initgraph(UNIT_SIZE * (WIDTH + 10), UNIT_SIZE * HEIGHT);
    cleardevice();
    line(UNIT_SIZE * WIDTH + 1, 0, UNIT_SIZE * WIDTH + 1, UNIT_SIZE * HEIGHT);
    outtextxy(UNIT_SIZE* WIDTH +10, 20, _T("分数:"));
    outtextxy(UNIT_SIZE * WIDTH +10, 60, _T("生命:"));
    outtextxy(UNIT_SIZE * WIDTH +10, 100, _T("等级:"));
    outtextxy(UNIT_SIZE * WIDTH +10, 140, _T("提示:"));
    outtextxy(UNIT_SIZE * WIDTH +50, 180, _T("按↑↓←→键操控"));
    outtextxy(UNIT_SIZE * WIDTH +50, 220, _T("按e键发射子弹"));
    outtextxy(UNIT_SIZE * WIDTH +50, 260, _T("按空格键暂停"));
    for (int i = 0; i < 4;i++)drawblock(23+i, 3);
    drawhint();
    drawtank(0, tank[0]);
    //初始界面
    std::thread a(getoperate);
}
#pragma region My
/*
* 名字:getoperate
* 功能:获取用户操作
* 参数:无
*/
void getoperate()
{
    char key;
    while (true) {
        if (_kbhit()) {
            clearrectangle(tank[0].x * UNIT_SIZE, tank[0].y * UNIT_SIZE, (tank[0].x + TANK_WIDTH) * UNIT_SIZE, (tank[0].y + TANK_HEIGHT) * UNIT_SIZE);
            key = _getch();
            switch (key)
            {
            case KEY_UP:
                if (tank[0].y - 1 >= 0) {
                    tank[0].y--;
                    tank[0].to = 0;
                }

                break;
            case KEY_DOWN:
                if (tank[0].y + 4 <= HEIGHT)
                {
                    tank[0].y++;
                    tank[0].to = 2;
                }
                break;
            case KEY_RIGHT:
                if (tank[0].x + 4 <= WIDTH)
                {
                    tank[0].x++;
                    tank[0].to = 1;
                }
                break;
            case KEY_LEFT:
                if (tank[0].x - 1 >= 0) {
                    tank[0].x--;
                    tank[0].to = 3;
                }
                break;
            case KEY_SPACE:
                drawtank(0, tank[0]);
                sleep();
                break;
            case KEY_E:
                if (bullettop == HEIGHT * WIDTH)bullettop = 0; 
                bullet[bullettop].exist = true;
                bullet[bullettop].to = tank[0].to;
                switch (tank[0].to)
                {
                case 0:
                    bullet[bullettop].x = tank[0].x + TANK_WIDTH / 2;
                    bullet[bullettop].y = tank[0].y - 1;
                    break;
                case 1:
                    bullet[bullettop].x = tank[0].x + TANK_WIDTH;
                    bullet[bullettop].y = tank[0].y + TANK_HEIGHT / 2;
                    break;
                case 2:
                    bullet[bullettop].x = tank[0].x + TANK_WIDTH / 2;
                    bullet[bullettop].y = tank[0].y + TANK_HEIGHT;
                    break;
                case 3:
                    bullet[bullettop].x = tank[0].x - 1;
                    bullet[bullettop].y = tank[0].y + TANK_HEIGHT / 2;
                }
                bullettop++;
                break;
            }
            drawtank(0, tank[0]);
        }
        drawbullet();
        Sleep(50);
    }
}

/*
* 名字:drawhint
* 功能:画分数、等级
* 参数:无
*/
void drawhint() 
{
    TCHAR s[9];
    _stprintf_s(s, _T("%d"), Fraction);
    outtextxy(UNIT_SIZE * 20+50, 20, s);
    _stprintf_s(s, _T("%d"), Level);
    outtextxy(UNIT_SIZE * 20+50, 100, s);
}

/*
* 名字:drawtank
* 功能:画坦克
* 参数:
*    a - 坦克 0第一种 1第二种......
*    b - 朝向 
*    x - x坐标
*    y - y坐标
*/
void drawtank(int No,coordinate object)
{
    for (int a = 0; a < TANK_HEIGHT; a++)
    {
        for (int b = 0; b < TANK_WIDTH; b++) {
            if (enemyandme[No * 4 + object.to][a][b]) {
                drawblock(object.x + b, object.y + a);
            }
        }
    }
    
}

/*
* 名字:drawblock
* 功能:画方块
* 参数:
*    x - x坐标
*    y - y坐标
*/
void drawblock(int x, int y)
{
    x *= UNIT_SIZE;
    y *= UNIT_SIZE;
    rectangle(x + 1, y + 1, x + UNIT_SIZE - 1, y + UNIT_SIZE - 1);
    solidrectangle(x + 5, y + 5, x + UNIT_SIZE - 5, y + UNIT_SIZE - 5);
}

/*
* 名字:sleep
* 功能:暂停
* 参数:无
*/
void sleep()
{
    while (!_kbhit);
}

/*
* 名字:emission
* 功能:发射子弹
* 参数:无
*/
void drawbullet()
{
    BeginBatchDraw();
    for (int i = 0; i < bullettop; i++)
    {
        if (bullet[i].exist == true) {
            clearrectangle(bullet[i].x * UNIT_SIZE, bullet[i].y * UNIT_SIZE, bullet[i].x * UNIT_SIZE + UNIT_SIZE, bullet[i].y * UNIT_SIZE + UNIT_SIZE);
            switch (bullet[i].to) {
            case 0:
                if (bullet[i].y-1 > 0)bullet[i].y--;
                else bullet[i].exist = false;
                break;
            case 1:
                if (bullet[i].x+1 < WIDTH)bullet[i].x++;
                else bullet[i].exist = false;
                break;
            case 2:
                if (bullet[i].y+1 < HEIGHT)bullet[i].y++;
                else bullet[i].exist = false;
                break;
            case 3:
                if (bullet[i].x-1 > 0)bullet[i].x--;
                else bullet[i].exist = false;
            }
            if(bullet[i].exist == true)drawblock(bullet[i].x, bullet[i].y);
        }
    }
    EndBatchDraw();
}
#pragma endregion
  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2024-01-18 20:11
    关注

    【以下回答由 GPT 生成】

    针对以上问题,我将逐一回答并给出解决方案:

    1. 确保std::thread初始化代码的正确性:
    2. 首先,确保在代码文件的开头包含了正确的头文件,如 。
    3. 确保使用了正确的命名空间,使用 namespace std; 或者直接在 std::thread 前添加 std:: 作为前缀。
    4. 确保在创建 std::thread 对象时传递了正确的参数,即目标函数名和参数(如果有的话)。
    5. 确保在使用 std::thread 对象前调用了 join() 或者 detach(),以确保线程的正确结束。

    6. 确保添加了正确的头文件:

    7. 根据需要使用的功能,确保添加了正确的头文件。如 std::thread 需要添加 ,std::mutex 需要添加 等等。
    8. 可以通过检查编译器报错信息中缺少的头文件来判断是否添加了正确的头文件。

    9. 更新编码以实现多线程:

    10. 首先,将需要在独立线程中运行的代码封装成一个函数,并确保函数的参数列表和返回类型正确。
    11. 使用 std::thread 类创建一个新的线程对象,并将刚刚封装的函数作为目标函数传递给它。可以在创建线程对象时同时传递需要的参数。
    12. 调用线程对象的 join() 或者 detach() 方法以确保线程的正确结束。
    13. 在主线程中可以继续执行其他操作,也可以等待子线程的结果。

    14. 提供更多报错信息:

    15. 在编译器报错时,请仔细阅读错误信息并尝试理解其中的含义。
    16. 可以将报错信息复制粘贴到搜索引擎中,并尝试查找相关资料来解决问题。
    17. 如果错误信息不够清晰,可以尝试在编译选项中启用更详细的错误信息(如 -Wall 或 -Wextra)。

    请提供更多关于错误的详细信息,我将尽力帮助您解决问题。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月19日
  • 已采纳回答 1月19日
  • 创建了问题 1月18日

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。