我正在写一个斗地主程序
现在想实现点牌上移,但是每次点牌时候只是瞬间上移,松开鼠标之后牌还是回原位
下面是部分代码(所有代码都在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你在哪里还调用过吗
不知道你这个问题是否已经解决, 如果还没有解决的话:问题解答:
针对斗地主程序中点击牌上移但松开鼠标回到原位的问题,我建议使用以下解决方案:
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作为成员变量,每个牌对象都有自己的状态,不会出现重新绘制场景后所有牌都还原的问题。
针对内存泄漏和指针越界等问题,建议使用以下方法:
使用智能指针:在C++中应该优先考虑使用智能指针,如std::unique_ptr、std::shared_ptr等,可以自动管理指针的内存,避免手动释放内存出现疏漏。
善于使用RAII技术:RAII(Resource Acquisition Is Initialization)指资源取得就是初始化,是一种C++的资源管理技术,即通过在对象构造时获取资源,对象析构时自动释放资源,从而保证资源的正确获取和释放。
使用工具检测内存:可以使用工具如Valgrind、AddressSanitizer等,对程序进行内存泄漏和指针越界等问题的检测,及时发现问题并进行修复。
开启编译器警告:可以在编译时开启警告,如gcc编译器使用-Wall选项,可以发现潜在的内存泄漏和指针越界等问题,加以解决。
编码规范和代码审查:制定编码规范,规范开发过程中的内存管理,同时加强代码审查,发现潜在问题及时修复。