程序设计大赛答辩演讲稿.doc
《程序设计大赛答辩演讲稿.doc》由会员分享,可在线阅读,更多相关《程序设计大赛答辩演讲稿.doc(16页珍藏版)》请在冰豆网上搜索。
![程序设计大赛答辩演讲稿.doc](https://file1.bdocx.com/fileroot1/2022-10/16/90ed23cd-fd07-45ca-8bb1-9cfe31fdc37a/90ed23cd-fd07-45ca-8bb1-9cfe31fdc37a1.gif)
尊敬的各位评委,各位老师:
你们好,我叫,来自140406班的LZ组合。
我们组的题目是《连连看辅助工具》。
在作品演讲之前,请允许我代表我们小组感谢黑马IT学院和计算机学院能够提供给我这样一个展示自我的平台,谢谢(行礼)
下面,开始我们组的品演示,首先,打开我们的连连看辅助工具,因为在制作之前,我们小组考虑到不同系统的用户需求,所以制作了三个版本的“连连看辅助工具”,并分别对应W732位操作系统,W764位操作系统和W864位操作系统,由于我的电脑是W864位操作系统,所以就只演示W864位版本的。
接下来,让我们进入游戏,考虑到时间问题,所以只用练习模式来演示,首先尝试“单消”功能,所谓单消,顾名思义,便是只消除一对棋子的意思,它是本游戏的基础,接下来的一些中重要的功能都是围绕着它展开;然后,让我们尝试一下“秒杀”功能,“秒杀”就是全屏清除,我们可以多尝试几个图(演示);接下来,让我们尝试一下“自动挂机”功能,勾选“自动挂机”我们会发现游戏开始自动以一个一个的消除,同时我们也可以通过移动下面的滑块来调节自动挂机的速度,这就是我们的“挂机速度调节”功能(演示);至于“去游戏倒计时”功能,是取消游戏倒计时,让游戏无比流畅;而“无限道具”功能,则是让游戏的道具增加,下面我给大家试一下(演示)
接下来“自动开局”功能为了让游戏自动开始;“窗口置顶”功能是将游戏页面放在桌面最上方,便于对游戏的操作,并使游戏辅助工具更加稳定再加上先前“去游戏倒计时”功能都是为了给游戏的自动挂机做铺垫,让挂机变得流畅,下面让我们来试一下这两个功能(演示)
讲解完了本工具的大体功能,让我们来和别人正式的玩一局。
(游戏时间需自由发挥带上所有的功能并突出功能特色)这真是完美的一次胜利,那它到底是怎样实现的哪?
下面开始进行PPT的讲解。
这个辅助工具是由我们计算机科学与工程学院140406班的LZ组合制作,我们的口号是“理智成就自我”(全组齐声),“LZ”是“理智”的缩写,所以我们会用我们的理性和智慧去处理每一件事,这虽然是我们小组第一次参加比赛,但我相信这绝不会是最后一次。
OK,下面让我们进入正题。
我们的连连看辅助工具共有8项功能,包括:
单消、秒杀、无限道具、自动开局、自动挂机、挂机速度调节、去游戏倒计时、游戏窗口置顶(翻页)
下面开始“单消”功能的详细介绍
首先让我们看看程序的流程图
首先,我们读取棋盘的内存数据
然后判断是否有相同的棋子
接下来模拟鼠标点击
判断棋子的数量是否减少如果减少了
就更新棋盘数据
最后
结束单消
现在让我们来看看具体的代码
这是一段用来打开进程读取进程并将棋盘的内存数据存放到数组中的程序
首先,我们定义一个字节型的数组因为棋盘是11行19列,所以定义为chessdata【11】*【19】
然后定义一个hWndgameh用来表示窗口句柄
FindWindow,是用来寻找窗口ID的函数/FindWindow,
LPCTSTRlpClassName,//pointertoclassname
LPCTSTRlpWindowName//pointertowindowname);
这个函数拥有两个参数
其中lpClassName参数指向类名,lpWindowName指向窗口名
在本程序中不需要指向类名的参数,所以第一个参数为空,而第二个参数指向窗口名,也就是之前定义过的gameCaption
然后下一步我们需要定义一个DoubleWord类型的变量processid由于每个word为2个字节的长度,所以processid双字节为4个字节
接下来我们要使用GetWindowThreadProcessId这个函数来找到窗口的进程,这个函数同样拥有两个参数
DWORDGetWindowThreadProcessId(HWNDhWnd,LPDWORDlpdwProcessId);其中第一个参数指向被查找的句柄也就是Findwindow的返回值gameh
第二个参数是进程号的存放地址,我们可以指向刚刚定义的processid
hWnd[in](向函数提供的)被查找窗口的句柄.lpdwProcessId[out]进程号的存放地址(变量地址)
接下来我们需要用OpenProcess这个函数获取进程的句柄并且将句柄保存在processH中
OpenProcess函数用来打开一个已存在的进程对象,并返回进程的句柄。
HANDLEOpenProcess(DWORDdwDesiredAccess,//渴望得到的访问权限(标志)BOOLbInheritHandle,//是否继承句柄DWORDdwProcessId//进程标示符
这个函数拥有三个参数,第一个参数是访问权限,我们定义为PROCESS_ALL_ACCESS也就是对进程内存的全部操作权限第二个是是否继承句柄,我们选择否,也就是false第三个进程标示符,也就是进程号,我们已经通过GetWindowThreadProcessId得到了,也就是processid
因此我们得到了进程的句柄processH
然后我们需要定义一个同样是DoubleWord类型的变量byread,
再定义一个没有类型的指针LPCVOIDpbase(基础)这个指针存放的是棋盘数据的首地址其中这个C代表不能修改变量的意思
这个首地址是通过CE(CheatEngine61_cn)这个工具找到的这个基址是一个十六进制数字0x00189F74
然后再次定义一个没有类型的指针LPVOIDnbuffer(缓冲)用来存放棋盘的数据
最后我们使用ReadProcessMemory这个函数,这个函数拥有5个参数,第一个是参数是进程的句柄,也就是processH;第二个参数是要读取内存的首地址,也就是我们之前定义的pbase;第三个参数是我们存入内存数据的地址,我们将其存在nuffer中;
第四个参数是要传送的字节数,因为棋盘是11*19,所以我们就传送11*19个数据;第五个参数是实际传送的字节数.函数返回时报告实际写入多少,我们将其存在byread之中
BOOLReadProcessMemory(HANDLEhProcess,PVOIDpvAddressRemote,PVOIDpvBufferLocal,DWORDdwSize,PDWORDpdwNumBytesRead);
实际应用
hProcess[in]远程进程句柄。
被读取者
pvAddressRemote[in]远程进程中内存地址。
从具体何处读取
pvBufferLocal[out]本地进程中内存地址.函数将读取的内容写入此处
dwSize[in]要传送的字节数。
要写入多少
pdwNumBytesRead[out]实际传送的字节数.函数返回时报告实际写入多少
这样我们就完成读取棋盘数据的功能了
然后我们开始寻找棋盘中相同的棋子,通过查找内存中相同的数据我们找出相同的棋子
程序中的for循环是用来不断改变棋子的位子,其中x1,y1是棋子1的位子,x2,y2是棋子二的位子
x1=1,y1=1代表第一行第一列的棋子,x1=2,y1=2代表第二行,第二列的棋子,以此类推
如果棋子1与棋子2的内存数据相等,那么我们就模拟鼠标点击,然后通过鼠标的模拟点击和棋子数量是否减少来决定单消的程序是否结束。
下面我们开始介绍模拟鼠标点击的程序,首先我们通过之前的ReadProcessMemory函数,将棋盘中剩余棋子的数量保存在chessnum中
然后将它的值赋给l,通过Findwindow获得窗口句柄,并且将其保存在hwnd中
然后定义一个整型变量lparam
根据棋子1与棋子2的位子来给lparam赋值,因为第一行第一列的鼠标坐标为(192.21)相邻棋子之间的间隔为35
并且由于我们要用到的是32位的鼠标地址,我们我们将x左移16位,所以给lparam赋值为lparam=((p1.y*35+192)<<16)+(p1.x*31+21);
接下来我们开始使用这个SendMassage函数,该函数将指定的消息发送到一个或多个窗口。
此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回
而我们就需要这个函数发送一个鼠标消息,这个函数拥有四个参数,第一个是我们通过Findwindow找到的窗口的句柄hwnd;第二个是消息的标识(志)符,我们模拟的是鼠标点击
所以就是WM_LBUTTONDOWN和WM_LBUTTONUP,对应的是鼠标的按下和抬起;第三个和第四个参数都是32位的特定附加信息,我们使用第四个,也就是将第三个参数设为零,第四个参数设为鼠标地址也就是我们之前定义的lparam
sendmessage
hWnd是接收消息的窗口的句柄
Msg是消息标识符
wParam是32位的特定附加信息。
lParam是32位特定附加信息
这样我们就可以模拟点击棋子1了,然后我们再次按照上面的方法点击棋子二,通过下面if语句,判断如果棋子减少了,就返回大于一的数;终止循环。
如果棋子不变,就返回0,让上面的循环继续,知道棋子数发生变化为止
这样,我们的单消功能就完成了
下面我们开始讲解秒杀的程序
先看看流程图,首先我们需要执行单消这个程序,然后我们需要判断棋子数是否为零,如果为零就退出循环结束程序,如果不为零,就继续执行单消程序
下面开始讲解代码的实现
我们先将单消的函数进行封装,定义成clearpair()函数
然后我们经行while循环,直到棋子数为零,才终止循环;此时,我们也就完成了秒杀功能
下面我们开始介绍无限道具的程序
对于无限道具,我们只需要找到游戏道具的内存地址,并且将其改写就OK了
下面开始讲解程序
程序前面我们已经讲解过,定义窗口名,获取窗口句柄,获取进程句柄,唯一不同的是我们要用到writeprocessmemory函数来写入进程
WriteProcessMemory
此函数能写入某一进程的内存区域(直接写入会出AccessViolation错误,故需此函数)。
VC++声明
BOOLWriteProcessMemory(HANDLEhProcess,LPVOIDlpBaseAddress,LPVOIDlpBuffer,DWORDnSize,LPDWORDlpNumberOfBytesWritten);
参数:
hProcess
由OpenProcess返回的进程句柄。
如参数传数据为INVALID_HANDLE_VALUE【即-1】目标进程为自身进程
lpBaseAddress
要写的内存首地址
再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。
lpBuffer
指向要写的数据的指针。
nSize
要写入的字节数。
返回值
非零值代表成功。
该函数一共拥有5个参数,第一个参数是由openprocess返回的进程句柄;第二个是要写入的首地址,也就是我们游戏道具的首地址;要写入数据的指针,也就是我在上面定义的数组a,b,c,d,e,;
第四个是要写入的字节数,我们都定义为1个字节;第五个是返回值,我们把上面定义的bywritesize放到这里,存储返回值;
由于道具是有两个内存地址控制,一个地址控制道具种类,一个地址控制道具数量,例如第一个函数控制的是道具的数量,第二个控制的就是“重列”这个道具是否出现
这样我们就完成游戏道具内存的写入了
下面开始讲解自动挂机的功能
这个功能很简单,只需要在单消的基础上加入一个定时器函数就行了,流程图也很简单,就是更新数据,然