我正在写一个斗地主程序 现在想实现点牌上移,但是每次点牌时候只是瞬间上移,松开鼠标之后牌还是回原位(语言-c++)

我正在写一个斗地主程序
现在想实现点牌上移,但是每次点牌时候只是瞬间上移,松开鼠标之后牌还是回原位
下面是部分代码(所有代码都在main.cpp的一个大循环中)

//gamingView.cpp
bool isClick[20] = { false };
int clicked[20];  // 点击了哪张牌
int clicked_count = 0;  // 当前处于点击状态的牌的数量
void moveImg(dealCards a, int x, int clicked[], int& clicked_count) {

    if (!isClick[x]) {
        cardPos[x][1] -= 40;
        isClick[x] = true;
        clicked[clicked_count++] = x;
    }
    else
    {
        cardPos[x][1] += 40;
        isClick[x] = false;

        // 把当前牌从 clicked 数组中移除
        for (int i = 0; i < clicked_count; i++) {
            if (clicked[i] == x) {
                clicked[i] = clicked[clicked_count - 1];
                clicked_count--;
                break;
            }
        }
    }

    for (int t = 0; t < 17; t++) {
        int j = a.player1[t].order;
        // 更新已经被点击过的牌的位置
        bool updated = false;
        for (int i = 0; i < clicked_count; i++) {
            if (clicked[i] == t) {
                putimage(cardPos[t][0], cardPos[t][1], &t_cards[j]);
                updated = true;
                break;
            }
        }
        if (!updated) {
            putimage(cardPos[t][0], cardPos[t][1], &t_cards[j]);
        }
    }



}

void gameingView::render() {
    if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
        curView = new menuView;
    }

    //发牌
    static dealCards a;
    putimage(0, 0, &img_bg[1]);
    if (!this->isRandom) {
        a.Initalize();
        a.send();
        this->isRandom = true;
    }
    a.show();

    //点牌上移
    ExMessage msg = getmessage(EX_MOUSE);

    //拆出来的按钮
    for (int i = 0; i < 20; i++)
    {
        if (msg.x >= cardPos[i][0] && msg.x <= cardPos[i][0] + 50 &&
            msg.y >= cardPos[i][1] && msg.y <= cardPos[i][1] + cards[0].getheight()) {
            switch (msg.message) {
            case WM_LBUTTONDOWN://鼠标按键动作    
                moveImg(a, i, clicked, clicked_count);
                break;
            }
        }
    }

    return;
}
//dealCard.cpp
void dealCards::show() {

    for (int i = 0; i < 17; i++) {
        int j = player1[i].order;
        int x = 178, y = 494;         
        cardPos[i][0] = x + 50 * i;//图片左上角x
        cardPos[i][1] = y; //图片左上角y
        transparentimage(NULL, cardPos[i][0], cardPos[i][1], &t_cards[j]);

        //三张可能的地主牌初始为零
        cardPos[17][0] = cardPos[18][1] = cardPos[18][0] = 
            cardPos[18][1] = cardPos[19][0] = cardPos[19][1] = 0;
    }

    //左右两个小牌代表两个bot的牌(不详细展示)
    IMAGE t;
    loadimage(&t, "img/card_bg.png", 68, 100);
    putimage(194, 292, &t);
    putimage(1019, 292, &t);
}
//dealCard.h
#pragma once
#include<iostream>
#include<string>
#include<easyx.h>
#include"img.h"
using namespace std;
#include"headInclude.h"
class dealCards
{
public:
    enum color {
            spade,
            heart,
            diamond,
            club,
            joker
        };//黑桃,红桃,方块,梅花,王

    struct poker
    {
        int num;//点数
        color colors;//花色
        int score;//分数(在斗地主中牌的大小,2最大3最小)
        int order;//牌的顺序,从黑桃a(0)开始到大王(53)
    };
    void send();
    void show();
    void Initalize();
    void rule(poker* card);
    poker pokers[54];
    poker player1[17];
    poker player2[17];
    poker player3[17];
    poker landlord[3];

    

};
//图片左上角的x和y
    extern int cardPos[20][2];

请尽量不要使用gpt

代码暂时没看出啥,moveImg你在哪里还调用过吗

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7769580
  • 以下回答来自chatgpt:

    问题解答:

    针对斗地主程序中点击牌上移但松开鼠标回到原位的问题,我建议使用以下解决方案:

    1.首先,在牌的类中增加一个bool类型的成员变量,用于标记牌是否被点击。

    class Card{
    private:
        int number;
        string suit;
        int xPos;
        int yPos;
        bool isClicked;
    public:
        //...
    };
    

    2.然后,在点击牌的事件处理函数中,添加相应的代码,来控制牌是否上移,并修改isClicked的值。

    void clickCard(Card& card, int clickX, int clickY){
        if(card.isClicked){ //牌已经被点击,还原位置
            card.setYPos(card.getYPos()+20);
            card.isClicked = false;
        }
        else{ //牌未被点击,上移20像素
            card.setYPos(card.getYPos()-20);
            card.isClicked = true;
        }
    }
    

    3.最后,在绘制牌的函数中,根据isClicked的值,来确定牌绘制的位置。

    void drawCard(Card& card){
        if(card.isClicked){ //点击了牌,绘制在上面
            drawImage(card.getImage(), card.getXPos(), card.getYPos()-20);
        }
        else{ //牌没有被点击,绘制在原位置
            drawImage(card.getImage(), card.getXPos(), card.getYPos());
        }
    }
    

    这样,每次点击牌,就会实现牌上移,并且保持上移状态,直到再次点击才还原位置。同时,由于isClicked作为成员变量,每个牌对象都有自己的状态,不会出现重新绘制场景后所有牌都还原的问题。

    针对内存泄漏和指针越界等问题,建议使用以下方法:

    1. 使用智能指针:在C++中应该优先考虑使用智能指针,如std::unique_ptr、std::shared_ptr等,可以自动管理指针的内存,避免手动释放内存出现疏漏。

    2. 善于使用RAII技术:RAII(Resource Acquisition Is Initialization)指资源取得就是初始化,是一种C++的资源管理技术,即通过在对象构造时获取资源,对象析构时自动释放资源,从而保证资源的正确获取和释放。

    3. 使用工具检测内存:可以使用工具如Valgrind、AddressSanitizer等,对程序进行内存泄漏和指针越界等问题的检测,及时发现问题并进行修复。

    4. 开启编译器警告:可以在编译时开启警告,如gcc编译器使用-Wall选项,可以发现潜在的内存泄漏和指针越界等问题,加以解决。

    5. 编码规范和代码审查:制定编码规范,规范开发过程中的内存管理,同时加强代码审查,发现潜在问题及时修复。


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