C++ OOP 设计决策

标签 c++

我为一款名为 Assault Cube 的开源射击游戏编写了一个瞄准机器人。以下是部分源代码:

Main.h:

/*
    Control + 0 = enable aimbot
    Control + 9 = enable vacuum hack
*/

#include "stdafx.h"
#ifndef MAIN_H
#define MAIN_H
#include "Player.h"
#include "Constants.h"
#include "Calculations.h"
#include <math.h>

Player players[32]; // need to give access to this to Calculations

int main() {
    bool aimbotEnabled = false;
    bool vacEnabled = false;
    Player* closestTargetPointer = nullptr;
    // [Base + DF73C] = Player 1 base
    players[0] = Player(reinterpret_cast<char**>(Constants::baseAddress + 0xDF73C));
    char** extraPlayersBase = *(reinterpret_cast<char***>(Constants::baseAddress + 0xE5F00));

    // [Base + E5F00] = A
    // [A + 0,4,8...] = Player 2/3/4... base
    for (int i = 0; i < Calculations::getNumberOfPlayers() - 1; i++) {
        players[i + 1] = Player(extraPlayersBase + i * 4);
    }

    while (true) {
        if (GetAsyncKeyState(VK_CONTROL)) {
            if (GetAsyncKeyState('0')) {
                aimbotEnabled = !aimbotEnabled;
                Sleep(500);
            } else if (GetAsyncKeyState('9')) {
                vacEnabled = !vacEnabled;
                Sleep(500);
            }
        }

        if (aimbotEnabled) {
            closestTargetPointer = Calculations::getClosestTarget();

            if (closestTargetPointer != nullptr) {
                players[0].setCrosshairX(Calculations::getCrosshairHorizontalAngle(players[0], *closestTargetPointer));
                players[0].setCrosshairY(Calculations::getCrosshairVerticalAngle(players[0], *closestTargetPointer));
            }
        }

        if (vacEnabled) {
            for (int i = 1; i < Calculations::getNumberOfPlayers(); i++) {
                players[i].setX(players[0].getX() + 10);
                players[i].setY(players[0].getY());
                players[i].setZ(players[0].getZ());
            }
        }

        Sleep(10);
    }
}
#endif

计算.h:

#include "stdafx.h"
#ifndef CALCULATIONS_H
#define CALCULATIONS_H
#include "Player.h"
#include "Constants.h"

namespace Calculations {
    /* Pythagorean's theorem applied twice for getting distance between two players in 3D space */
    float getDistanceBetween(Player one, Player two) {
        return sqrt(
                   (one.getX() - two.getX()) * (one.getX() - two.getX())
                   + (one.getY() - two.getY()) * (one.getY() - two.getY())
                   + (one.getZ() - two.getZ()) * (one.getZ() - two.getZ())
               );
    }

    int getNumberOfPlayers() {
        return *(reinterpret_cast<int*>(Constants::baseAddress + 0xE4E10));
    }

    Player* getClosestTarget() {
        float smallestDistance;
        int index = -1;

        for (int i = 1; i < getNumberOfPlayers(); i++) {
            if (players[i].getHP() > 0 && players[i].isVisible()) { // this is an error, because Calculations does not have access to the players array in Main
                float tempDistance = getDistanceBetween(players[0], players[i]);

                if (index == -1 || tempDistance < smallestDistance) {
                    smallestDistance = tempDistance;
                    index = i;
                }
            }
        }

        if (index == -1) {
            return nullptr;
        } else {
            return &players[index];
        }
    }

    float getCrosshairHorizontalAngle(Player me, Player target) {
        float deltaX = target.getX() - me.getX();
        float deltaY = me.getY() - target.getY();

        if (target.getX() > me.getX() && target.getY() < me.getY()) {
            return atanf(deltaX / deltaY) * 180.0f / Constants::pi;
        } else if (target.getX() > me.getX() && target.getY() > me.getY()) {
            return atanf(deltaX / deltaY) * 180.0f / Constants::pi + 180.0f;
        } else if (target.getX() < me.getX() && target.getY() > me.getY()) {
            return atanf(deltaX / deltaY) * 180.0f / Constants::pi - 180.0f;
        } else {
            return atanf(deltaX / deltaY) * 180.0f / Constants::pi + 360.0f;
        }
    }

    float getCrosshairVerticalAngle(Player me, Player target) {
        float deltaZ = target.getZ() - me.getZ();
        float dist = getDistanceBetween(me, target);
        return asinf(deltaZ / dist) * 180.0f / Constants::pi;
    }
}
#endif

错误:

1>  Calculations.h
1>Calculations.h(26): error C2065: 'players' : undeclared identifier
1>Calculations.h(26): error C2228: left of '.getHP' must have class/struct/union
1>Calculations.h(26): error C2228: left of '.isVisible' must have class/struct/union
1>Calculations.h(27): error C2065: 'players' : undeclared identifier
1>Calculations.h(39): error C2065: 'players' : undeclared identifier

所有这些错误都是因为 Calculations 无法访问 Main 中的players 数组。有什么方法可以让计算访问玩家数组吗?

另外,请告诉我我将计算作为命名空间的决定是否正确。

最佳答案

添加在Calculations.h的开头

extern Player players[32];

告诉编译器在另一个位置/文件中获取players的定义。

extern 关键字相当于声明而不定义。这是一种显式声明变量的方法,或者在没有定义的情况下强制声明的方法...

The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it's defined). When modifying a variable, extern specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends). The variable or function may be defined in another source file, or later in the same file. Declarations of variables and functions at file scope are external by default.

来源here (+示例)和 here .

最后注意:extern 对于函数和变量的行为不同。 more .

关于C++ OOP 设计决策,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17119603/

相关文章:

c++ - 将 vector 传递给 C++ 中的函数时出现类型问题

c++ - 为什么不能在 C++ 类中重新定义类型名称?

c++ - 从专有格式到 C++ 类

c++ - __u8 和 uint8_t 之间的区别

c++ - 为什么 gcc 会立即销毁我的对象,尽管它的范围? (我如何让它不那样做?)

c++ - 键盘布局方向

c++ - 没有运算符 "<<"匹配

c++ - 了解 vtu 文件大小

python - 如何在 Visual Code 中设置 launch.json 来调试 C

c++ - 不知道如何从冒泡排序函数返回值