西宁知名网站制作公司,前沿设计公司网站,怎么把一个网站的关键词,企业网站模板官网devc 5.11编译环境
dll编译环境设置参考
Dev c C语言实现第一个 dll 动态链接库 创建与调用-CSDN博客 插件 DLL代码和主程序代码如下
注意 dll 代码中的class 类名需要 和主程序 相同
其中使用了函数指针和强制类型转换
函数指针教程参考
以动态库链接库 .dll 探索结构体…devc 5.11编译环境
dll编译环境设置参考
Dev c C语言实现第一个 dll 动态链接库 创建与调用-CSDN博客 插件 DLL代码和主程序代码如下
注意 dll 代码中的class 类名需要 和主程序 相同
其中使用了函数指针和强制类型转换
函数指针教程参考
以动态库链接库 .dll 探索结构体参数-CSDN博客 注意退出游戏后需等30-50秒让dll自行销毁然后重开时才能正常运行。否则进入后不显示地图。
有dll时 无DLL插件读取到时即dll不在同程序目录下 dll.h
#ifndef _DLL_H_
#define _DLL_H_
#include iostream
using namespace std;
// 游戏背景操作板可以通过坐标直接改
class Bkmap
{public:Bkmap(int height,int wide){this-widewide;this-heightheight;this-bkmapnew char*[this-height];for(int i0; iheight; i){this-bkmap[i]new char[this-wide];for(int j0; jwide; j){this-bkmap[i][j]\0;}}}public:char** bkmap;int wide;int height;};// 玩家类移动攻击地图修改
class Player
{public:Player(int x,int y,int limitx,int limity){this-playerxx;this-playeryy;is_atk0;is_buff0;flag_x0;flag_y0;this-limitxlimitx;this-limitylimity;}~Player();public:char player1;int playerx;int playery;int flag_x;int flag_y;int limitx;int limity;int is_atk;int is_buff;public:
};// 攻击类这里直线攻击做测试
class Aking
{public:Aking(int height,int wide,int atk_time,int number){this-heightheight;this-widewide;this-numbernumber;this-atk_timeatk_time;atk_count0;}public:int height; // 攻击范围长宽int wide;int number; // 攻击序号因为有多个攻击技能所以编号可以查找攻击int atk_time; // 攻击时长int atk_count; // 当前攻击持续时间public:// 攻击中void atking(Bkmap* bkmap,Player* player){if (atk_count ! atk_time) // 攻击{atk_count;coutDLLatk_countendl; coutDLL:playerx player y:player-playerx,player-playeryendl;coutDLL: player is_atk:player-is_atkendl;for(int j0; j10; j){bkmap-bkmap[player-playery][player-playerx1j]P;}}else{atk_count0;player-is_atk0; // 玩家状态复位}}
};static Aking* akv3new Aking(20,50,20,3); // 静态类在调用时保存被调用的值调用结束后数值不清空 extern C{void mainDll(Bkmap* bkmap,Player* player);
}#endif
插件 dll.cpp
/* Replace dll.h with the name of your header */
#include dll.h
#include windows.hvoid mainDll(Bkmap* bkmap,Player* player)
{
// coutDLL: atking class startendl;akv3-atking(bkmap,player);
} 主程序注意和dll放在同一个目录下
#include iostream
#include string.h
#include windows.h#define KEY_DOWN(vKey) ((GetAsyncKeyState(vKey) 0x8000) ? 1:0) // 判断是否按下按键按下之后最高位变成 1所以需要位运算去除其他位只检测最高位
#define KEY_DOWN_FOREGROUND(hWnd, vk) (KEY_DOWN(vk) GetForegroundWindow() hWnd) // 前景窗口判断
#pragma warning(disable : 4996)
using namespace std;// 加入的游戏背景数据通常不修改放到 Bkmap 进行修改
class Gamemap
{public:Gamemap(int height,int wide){this-widewide;this-heightheight;this-gamemapnew int*[this-height];for(int i0; iheight; i){this-gamemap[i]new int[this-wide];for(int j0; jthis-wide; j){this-gamemap[i][j]0;}}}~Gamemap();public:int** gamemap;int wide;int height;
};
// 游戏背景操作板可以通过坐标直接改
class Bkmap
{public:Bkmap(int height,int wide){this-widewide;this-heightheight;this-bkmapnew char*[this-height];for(int i0; iheight; i){this-bkmap[i]new char[this-wide];for(int j0; jwide; j){this-bkmap[i][j]\0;}}}public:char** bkmap;int wide;int height;public:void adddata(){for(int i0; ithis-height; i) // 地图数据写入{for(int j0; jthis-wide-1; j){this-bkmap[i][j]*;}this-bkmap[i][this-wide-1]\0;coutthis-bkmap[i]okendl;}}void fresh(Gamemap* gamemap){for(int i0; igamemap-height; i) // 地图复印到选区{for(int j0; jgamemap-wide; j){if(gamemap-gamemap[i][j]0)this-bkmap[i][j] ; // 这里决定地图打印在屏幕的样子}}}};
// 字符串缓冲类
class Showmap
{public:Showmap(int height,int wide){this-showmapnew char[wide*height1000];strcpy(showmap,);
// showmap{}; // 不能这样写否则报错指针重新变空}public:char* showmap;public:void adddata(Bkmap* bkmap){couttestendl;if(showmapNULL){coutNULL;cout函数因空指针结束endl;return;}strcpy(showmap,);for(int i0; ibkmap-height; i) // 选区加入到打印缓冲区{strcat(showmap,bkmap-bkmap[i]);strcat(this-showmap,\n);}}void show(){coutthis-showmap;}
};// 玩家类移动攻击地图修改
class Player
{public:Player(int x,int y,int limitx,int limity){this-playerxx;this-playeryy;is_atk0;is_buff0;flag_x0;flag_y0;this-limitxlimitx;this-limitylimity;}~Player();public:char player1;int playerx;int playery;int flag_x;int flag_y;int limitx;int limity;int is_atk;int is_buff;public://玩家移动检测void checkmove(HWND hwnd){flag_x0;flag_y0;if (KEY_DOWN_FOREGROUND(hwnd, 0x41)) // A{flag_x - 1;}if (KEY_DOWN_FOREGROUND(hwnd, 0x57)) // W{flag_y - 1;}if (KEY_DOWN_FOREGROUND(hwnd, 0x44)) // D{flag_x 1;}if (KEY_DOWN_FOREGROUND(hwnd, 0x53)) // S{flag_y 1;}}// 打包速度检测void checkspeed(){if (flag_x 1) // 速度限制flag_x 1;else if (flag_x -1)flag_x -1;if (flag_y 1)flag_y 1;else if (flag_y -1)flag_y -1;}// 改变玩家位置void move(){if (flag_x) // 位移改变playerx flag_x;if (flag_y)playery flag_y;}
// 边界检测void checkboundary(){if (playerx limitx) // 角色位置限制playerx limitx - 1;else if (playerx 0)playerx 0;if (playery limity)playery limity - 1;else if (playery 0)playery 0;}void putinmap(Bkmap* bkmap){bkmap-bkmap[playery][playerx]player;}
// 检测攻击void checkatk(HWND hwnd){if (is_atk 0 KEY_DOWN_FOREGROUND(hwnd, 0x4A)) // j 键攻击{is_atk 1;}}
// 检测buffvoid checkbuff(HWND hwnd){if (is_buff 0 KEY_DOWN_FOREGROUND(hwnd, 0x4B)) // k 键增加范围 buff{is_buff 1;}}// 绘制地图void drawmap(HWND hwnd,Gamemap* gamemap){if (KEY_DOWN_FOREGROUND(hwnd, 0x30)) // 0 键绘制地图gamemap-gamemap[playery][playerx] 0;if (KEY_DOWN_FOREGROUND(hwnd, 0x36)) // 6 键绘制地图gamemap-gamemap[playery][playerx] 6;if (KEY_DOWN_FOREGROUND(hwnd, 0x37)) // 7 键绘制地图gamemap-gamemap[playery][playerx] 7;if (KEY_DOWN_FOREGROUND(hwnd, 0x38)) // 8 键绘制地图gamemap-gamemap[playery][playerx] 8;if (KEY_DOWN_FOREGROUND(hwnd, 0x39)) // 9 键绘制地图gamemap-gamemap[playery][playerx] 9;}
};class Dlling
{typedef void(*Menu)(Bkmap* bkmap,Player* player); // 定义函数指针函数返回值是 void, 指针类型名是 Menu, 参数是Bkmap*public:Dlling(char* name,int number){mainDllmainDll;HINSTANCE hDLL LoadLibrary(name); // 加载dll库if(hDLLNULL){cout没有在本目录里找到 dllv3.dllendl;atkNULL;Sleep(300);}else{void(*atkv2)(Bkmap* bkmap,Player*) (void (*)(Bkmap*,Player*))GetProcAddress(hDLL,mainDll); // 加载dll 的入口主函数 强制类型转换后加载的dll主函数成为atkv2的替身if(atkv2NULL){coutdllv3 插件没有读取endl;atkNULL;Sleep(300);}else{coutdllv3 读取成功endl;Sleep(300);atk atkv2;}}count0;}public:char* mainDll;Menu atk;int count; // 成员是一个指针目前没有函数替身所以没有编译报错public:void aking(Bkmap* bkmap,Player* player){coutclass_atkv3endl;if(player-is_atkatk!NULL){coutclass_atkv3 is goingendl;atk(bkmap,player); // 函数指针在初始化过程在有了替身函数所以可以加入变量}else if(player-is_atkatkNULL){coutdll是空的跳过执行函数endl;count;if(count10){player-is_atk0;count0;}}}
};int main()
{Gamemap* gamemap new Gamemap(20,50);Bkmap* bkmapnew Bkmap(20,50);Showmap* showmap new Showmap(20,80);Dlling* dll new Dlling(dllv3.dll,3);bkmap-fresh(gamemap);
// bkmap-adddata();showmap-adddata(bkmap);showmap-show();HWND hwnd GetForegroundWindow(); // 获取前端窗口句柄由于程序刚运行时是在前端所以这就是本程序的窗口句柄Player* player new Player(0,0,50,20);while(1){if (KEY_DOWN_FOREGROUND(hwnd, VK_ESCAPE)){printf(游戏退出\n);break;}if(KEY_DOWN_FOREGROUND(hwnd,0x31)){player-is_atk1;}player-checkmove(hwnd);player-checkspeed();player-move();player-checkboundary();bkmap-fresh(gamemap);dll-aking(bkmap,player);player-putinmap(bkmap);showmap-adddata(bkmap);cout玩家位置player-playerx,player-playeryendl;showmap-show();Sleep(100);system(cls);}return 0;}