c++编写植物大战僵尸

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

源代码

#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.csdn.net/download/m0_72703340/86268275

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
编写植物大战僵尸的游戏需要一定的游戏开发经验和C++编程知识。以下是一个简单的示例,展示了如何使用C++编写植物大战僵尸的基本功能: ```cpp #include <iostream> #include <cstdlib> #include <ctime> // 植物类 class Plant { public: int health; // 植物的生命值 Plant() { health = 100; } virtual void attack() = 0; // 抽象攻击方法 }; // 僵尸类 class Zombie { public: int health; // 僵尸的生命值 Zombie() { health = 100; } virtual void attack() = 0; // 抽象攻击方法 }; // 向日葵类 class Sunflower : public Plant { public: void attack() override { std::cout << "向日葵发射阳光攻击!" << std::endl; // 具体的攻击逻辑 } }; // 豌豆射手类 class Peashooter : public Plant { public: void attack() override { std::cout << "豌豆射手发射豌豆攻击!" << std::endl; // 具体的攻击逻辑 } }; // 普通僵尸类 class NormalZombie : public Zombie { public: void attack() override { std::cout << "普通僵尸发起普通攻击!" << std::endl; // 具体的攻击逻辑 } }; // 高级僵尸类 class AdvancedZombie : public Zombie { public: void attack() override { std::cout << "高级僵尸发起高级攻击!" << std::endl; // 具体的攻击逻辑 } }; int main() { srand(time(nullptr)); // 初始化随机数种子 Plant* plant = nullptr; Zombie* zombie = nullptr; // 创建一个向日葵和一个普通僵尸 plant = new Sunflower(); zombie = new NormalZombie(); plant->attack(); zombie->attack(); delete plant; delete zombie; return 0; } ``` 这只是一个简单的示例,实际上,开发完整的植物大战僵尸游戏需要更多的功能和逻辑。你可以根据自己的需求和创意进行扩展和修改。希望对你有所帮助!
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

luciferau

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值