【发布时间】:2021-04-05 09:48:00
【问题描述】:
早上好。 我正在学习一些关于继承和控制台操作的概念。 如您所见,我是初学者。
所以我试图在控制台上绘制一个字符,我希望更新它的位置。 现在请注意,我知道我的代码可能在多种方面都非常糟糕,并且可能有数百种更好的完全替代方法可以做到这一点,但我想首先了解一些继承概念以及为什么它不能按原样工作。
所以,我在控制台上绘制了我的玩家角色“X”,然后我通过调用特定的成员方法来更新它的位置来移动它。 现在,因为我让 Player 类扩展了 DrawConsole 类,所以我想在 Player 实例上调用 drawConsole。
当我这样做时,我让 playerA 实例的位置坐标实际更新,但对播放器实例的引用现在有两个名为“位置”的成员,如您在图像上看到的那样。 我怎么能说选择 playerA 而不完全重新编写代码或使用完全不同的方法? 或者也许只是我不能,我实际上已经完全改变了方法? 希望我能够表达我的疑问。
这里是代码
#include <ctime>
#include <cstdlib>
#include "windows.h"
#define width 100
#define height 15
class StaticBuffer
{
public:
StaticBuffer() { srand(time(0)); }
void loadBackGround(CHAR_INFO *backGround, int swidth, int sheight)
{
for (int y = 0; y < sheight; y++)
{
int rnd = rand() % 100 + 1;
for (int x = 0; x < swidth; x++)
if (y == 0 || y == sheight - 1)
{
backGround[y * swidth + x].Char.AsciiChar = (unsigned char)127;
backGround[y * swidth + x].Attributes = (unsigned char)23;
}
else if (x > 4 * rnd && x < (4 * rnd) + 5 || x > 4 * rnd / 2 && x < (4 * rnd / 2) + 5)
{
backGround[y * swidth + x].Char.AsciiChar = (unsigned char)178;
backGround[y * swidth + x].Attributes = (unsigned char)12;
}
else
{
backGround[y * swidth + x].Char.AsciiChar = 32;
backGround[y * swidth + x].Attributes = (unsigned char)3;
}
}
}
private:
};
class DrawConsole
{
public:
DrawConsole()
{
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
rConsole = GetStdHandle(STD_INPUT_HANDLE);
windowSizeInit = {0, 0, 30, 10};
windowSize = {0, 0, bufferSize.X - 1, bufferSize.Y - 1};
backGround = new CHAR_INFO[bufferSize.X * bufferSize.Y];
obstacle = new CHAR_INFO[bufferSize.X * bufferSize.Y];
inputBuffer = new INPUT_RECORD[4];
drawBackGround.loadBackGround(backGround, bufferSize.X, bufferSize.Y);
nInputWritten = 0;
nOutputWritten = 0;
playerString[0] = L'X';
charLenght = 1;
position = {10,13};
}
void drawConsole()
{
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
rConsole = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleWindowInfo(wConsole, TRUE, &windowSizeInit);
wConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleScreenBufferSize(wConsole, bufferSize);
SetConsoleWindowInfo(wConsole, TRUE, &windowSize);
WriteConsoleOutputA(wConsole, backGround, bufferSize, {0,0}, &windowSize);
WriteConsoleOutputCharacterW(wConsole, playerString, charLenght, position, &nOutputWritten);
}
void drawChar()
{
WriteConsoleOutputA(wConsole, backGround, bufferSize, {0,0}, &windowSize);
WriteConsoleOutputCharacterW(wConsole, playerString, charLenght, position, &nOutputWritten);
}
protected:
HANDLE wConsole;
HANDLE rConsole;
COORD bufferSize{width, height};
SMALL_RECT windowSizeInit;
SMALL_RECT windowSize;
CHAR_INFO *backGround;
CHAR_INFO *obstacle;
INPUT_RECORD *inputBuffer;
DWORD nInputWritten;
DWORD nOutputWritten;
DWORD charLenght;
StaticBuffer drawBackGround;
wchar_t playerString[2];
COORD position;
};
class Player :public DrawConsole
{
public:
Player()
{
position.X = 20;
position.Y = height - 2;
}
void movePlayerRight()
{
for (int i = 0; i < 3; i++)
position.X += 1;
}
COORD getPositionC() { return position; }
private:
COORD position;
};
Player *playerA = new Player;
DrawConsole *myConsole = new DrawConsole;
int main()
{
myConsole->drawConsole();
while (true)
{
//Sleep(5000);
playerA->movePlayerRight();
playerA->drawChar();
}
}
【问题讨论】:
-
只需从派生类中删除位置成员即可。
-
我需要它在 Player 实例上调用 movePlayerRight()。
-
"我需要它" 你需要一个职位或两个不同的职位。如果您需要一个职位,则需要一个名为“职位”的变量。删除另一个。如果您需要两个不同的位置,则需要两个变量,但是将它们都命名为“位置”是一个非常糟糕的主意。重命名另一个。如果你不能决定是想要一个职位还是两个不同的职位,那是设计问题,而不是 C++ 问题。
标签: c++ oop inheritance