c++编写植物大战僵尸

该程序用于查找并修改植物大战僵尸游戏中阳光和金币的数值,通过读取内存地址实现。首先检查游戏是否运行,然后获取进程句柄和内存地址,读取阳光和金币的初始值,并进行二级偏移地址读取。用户可以输入修改后的阳光值,程序通过WriteProcessMemory函数写入新的值。同时,程序还实现了一个数字雨的图形效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <graphics.h>//图形库头文件
#include <Windows.h>
#define WIDTH 960
#define HEIGTH 640
#define STR_SIZE 20//数字雨素组最大村粗
#define STR_NUM 128//数字雨串速
#define STR_WIDTH 15//数字雨宽度
struct Rain//数字雨结构
{
	int x;//数字雨横向位置
	int y;//Y坐标
	int  speed;//下降速度
	char str[STR_SIZE];//数字雨数组
}rain[STR_NUM];
char CreateCh()
{
	char temp = 0;
	int flag = rand() % 3;//0,1,2
	if (flag == 0)
	{
		temp = rand() % 26 + 'a';
	}
	else if (flag == 1)
	{
		temp = rand() % 26 + 'A';
	}
	else
	{
		temp = rand() % 10 + '0';
	}
	return temp;
}
void GameInit()
{
	for (int i = 0; i < STR_NUM; i++)//坐标速度初始化
	{
		rain[i].x = i * STR_WIDTH;//循环乘以字符的宽度
		rain[i].y = rand() % HEIGTH;//Y随机
		rain[i].speed = rand() % 5 + 5;//5 6 7 8 9 10
	}
	for (int i = 0; i < STR_NUM; i++)
	{
		for (int j = 0; j < STR_SIZE; j++)
		{
			rain[i].str[j] = CreateCh();
		}
	}
}
void GameDraw()
{
	cleardevice();
	for (int i = 0; i < STR_NUM; i++)
	{
		for (int j = 0; j < STR_SIZE; j++)
		{
			outtextxy(rain[i].x, rain[i].y - STR_WIDTH * j, rain[i].str[j]);
			settextcolor(RGB(0, 70 - 13 * j, 0));
		}
	}
}
void GamePlay()
{
	for (int i = 0; i < STR_NUM; i++)
	{
		rain[i].y += rain[i].speed;
		if (rain[i].y - STR_SIZE * STR_WIDTH > HEIGTH)
		{
			rain[i].y = 0;
		}
	}
}
void ChangeCh()
{
	for (int i = 0; i < STR_NUM; i++)
	{
		rain[rand() % STR_NUM].str[rand() % STR_SIZE] = CreateCh();
	}

}
int main()
{
	//1,步骤查找植物大战僵尸Plants vs. Zombies GOTY  
	HWND hGameWnd = FindWindow(L"MainWindow", L"Plants vs. Zombies GOTY ");
	//没有运行游戏5
	if (hGameWnd == NULL)
	{
		printf("没有运行这个游戏\n");
		return 0;
	}
	//2根据窗口句柄获取进程的PID,Process ID
	DWORD dwPID = 0;
	GetWindowThreadProcessId(hGameWnd, &dwPID);
	if (dwPID == 0)
	{
		printf("获取进程PID失败:%d\n", GetLastError());
		return 0;
	}
	//3.根据PID获取进程句柄
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);//打开哪个进程,PID的进程
	if (hProcess == NULL)
	{
		printf("打开进程失败,错误代码:%d\n", GetLastError());
		return 0;
	}
	//4从指定位置进程内存区去读取数据
	DWORD dwSunshineBase = 0x007794f8;
	DWORD dwSunshineAddressValue = 0;
	SIZE_T dwSize = 0;
	if (FALSE == ReadProcessMemory(
		hProcess,//读取哪一个进程
		(LPVOID)dwSunshineBase,//要读取的基地址       
		&dwSunshineAddressValue,//接受进程地址数据
		sizeof(DWORD),//DWORD=unsigned long 要读取的4个字节数
		&dwSize))
	{
		printf("获取阳光静态地址失败错误代码.\n", GetLastError());
		return 0;
	}
	DWORD dwMoneyBase = 0x007794f8;
	DWORD dwMoneyAddressValue = 0;
	SIZE_T dwMent = 0;
	if (FALSE == ReadProcessMemory(
		hProcess,//读取哪一个进程
		(LPVOID)dwMoneyBase,//要读取的基地址       
		&dwMoneyAddressValue,//接受进程地址数据
		sizeof(DWORD),//DWORD=unsigned long 要读取的4个字节数
		&dwMent))
	{
		printf("获取金币静态地址失败错误代码.\n", GetLastError());
		return 0;
	}
	//5,获取一级阳光便宜地址;
	DWORD dwSunshineOffsetFirst = 0X868;
	DWORD dwSunshineOffsetValue = 0;//读 取出来的地址值保留到这个变量来
	if (FALSE == ReadProcessMemory(hProcess,
		(LPVOID)(dwSunshineAddressValue + dwSunshineOffsetFirst),
		&dwSunshineOffsetValue,
		sizeof(DWORD),
		&dwSize))
	{
		printf("获取一级阳光偏移地址失败,错误代码%d\n", GetLastError());
		return 0;
	}
	//5,获取一级金币偏移地址
	DWORD dwMoneyOffsetFirst = 0X950;
	DWORD dwMoneyOffsetValue = 0;//读 取出来的地址值保留到这个变量来
	if (FALSE == ReadProcessMemory(hProcess,
		(LPVOID)(dwMoneyAddressValue + dwMoneyOffsetFirst),
		&dwMoneyOffsetValue,
		sizeof(DWORD),
		&dwMent))
	{
		printf("获取一级金币偏移地址失败,错误代码%d\n", GetLastError());
		return 0;
	}

	//6,二级便宜
	DWORD dwSunshineOffsetSecond = 0x5578;//2级便宜的地址
	DWORD dwSunshine = 0;//2级便宜后直接的到我们的阳光值
	if (FALSE == ReadProcessMemory(
		hProcess,
		(LPVOID)(dwSunshineOffsetValue + dwSunshineOffsetSecond),
		&dwSunshine,
		sizeof(DWORD),
		&dwSize
	))
	{
		printf("2级偏移阳光地址失败,错误代码%d\n", GetLastError());
		return 0;
	}
	DWORD dwMoneyOffsetSecond = 0x50;//2级便宜的地址
	DWORD dwMoney = 0;//2级便宜后直接的到我们的阳光值
	if (FALSE == ReadProcessMemory(
		hProcess,
		(LPVOID)(dwMoneyOffsetValue + dwMoneyOffsetSecond),
		&dwMoney,
		sizeof(DWORD),
		&dwMent
	))
	{
		printf("2级偏移金币地址失败,错误代码%d\n", GetLastError());
		return 0;
	}
	printf("阳光值是%d\n", dwSunshine);
	printf("请输入你要修改的阳光值:\n");
	int nModifySunshine;
	scanf("%d", &nModifySunshine);
	WriteProcessMemory(
		hProcess,
		(LPVOID)(dwSunshineOffsetValue + dwSunshineOffsetSecond),
		&nModifySunshine,
		sizeof(DWORD),
		&dwSize);
	printf("金币值是%d\n", dwMoney);
	//printf("请属入你要修改的金币值:\n");
	//int nModeMoney;
	//scanf("%d", &nModeMoney);
	//WriteProcessMemory(
	//	hProcess,
	//	(LPVOID)(dwMoneyOffsetValue + dwMoneyOffsetSecond),
	//	&nModeMoney,
	//	sizeof(DWORD),
	//	&dwMent);*/
	initgraph(WIDTH, HEIGTH);
	srand(GetTickCount());
	GameInit();
	DWORD t1, t2;
	t1 = t2 = GetTickCount();//获取电脑开机到现在所获取的毫秒数
	while (1)
	{
		ChangeCh();
		BeginBatchDraw();//双缓冲
		if (t2 - t1 > 10)
		{
			GamePlay();
			t1 = t2;
		}
		t2 = GetTickCount();
		GameDraw();
		EndBatchDraw();
	}
	CloseHandle(hProcess);
	return 0;
}

下载链接

https://download.youkuaiyun.com/download/m0_72703340/86268275

### 使用Dev-C++编写C语言程序 #### 安装Dev-C++ 为了使用Dev-C++编写C语言程序,首先需要下载并安装该软件。作为一个免费开源的集成开发环境(IDE),Dev-C++支持Windows操作系统下的C和C++编程[^3]。 #### 创建新项目 启动Dev-C++之后,在菜单栏选择`File -> New -> Project...`选项来新建一个项目。对于C语言程序来说,应该选择控制台应用程序(Console Application)类别中的C语言模板,并按照向导逐步设置项目的保存路径和其他配置项。 #### 设置源文件名及后缀 当创建新的源代码文件时,请确保将文件扩展名指定为`.c`而不是默认情况下可能给出的`.cpp`。这是因为尽管C++兼容所有的C特性,但某些特定于C的标准库函数或行为可能会有所不同;因此保持正确的文件类型有助于避免潜在的问题[^4]。 #### 编写简单比较大小的C语言程序 下面展示了一个简单的例子——两个整数之间的最大值计算: ```c #include <stdio.h> int main() { int num1, num2; printf("请输入第一个数字:"); scanf("%d", &num1); printf("请输入第二个数字:"); scanf("%d", &num2); if (num1 > num2){ printf("较大的数值是 %d\n", num1); } else if(num1 < num2){ printf("较大的数值是 %d\n", num2); }else{ printf("两数相等。\n"); } return 0; } ``` 这段代码实现了基本输入输出操作以及条件判断语句的应用,适合初学者练习理解变量声明、用户交互逻辑等方面的知识点[^1]。 #### 调试与运行 完成编码工作后,可以通过点击工具栏上的绿色播放按钮或者按F9键来进行编译链接过程。如果一切顺利,则可以直接执行生成好的可执行文件查看结果;如果有错误发生,则可以根据报错信息修正相应的地方再重新尝试构建直至成功为止。 #### 利用辅助功能提升效率 除了上述核心流程外,利用好Dev-C++内置的一些实用特性也能极大地方便日常学习实践。比如启用自动补全可以帮助快速定位标准库内的各种API接口定义;而语法着色则让阅读复杂表达式变得更加直观容易。这些都属于提高生产力的有效手段之一[^2]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesphoros

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值