【发布时间】:2021-12-22 16:47:38
【问题描述】:
[已解决] 这是我的全部代码都完成了一个工作:
#include <ncurses.h>
#include <random>
#include <ctime>
using namespace std;
//VARIABLES
///////////
int tick_count = 0;
char key;
int width = 10, height = 10;
class Entity {
public:
class Common {
public:
char icon;
int x, y;
char collide;
int power = 0, speed = 0, defense = 0, health = 0;
int hp;
virtual void move(int dir) {
switch (dir) {
case 1:
y--;
break;
case 2:
y++;
break;
case 3:
x--;
break;
case 4:
x++;
break;
}
}
virtual ~Common() {}
};
class Player: public Common {
public:
int target, room;
Player() {
icon = '@';
x = 1, y = 1;
collide = 'n';
power = 1, speed = 1, defense = 1, health = 10;
hp = health;
}
};
class Kobold: public Common {
public:
Kobold() {
icon = 'K';
collide = 'n';
power = 1, speed = 0, defense = 1, health = 2;
hp = health;
}
};
class Spider: public Common {
public:
Spider() {
icon = 'S';
collide = 'n';
power = 4, speed = 2, defense = 0, health = 3;
hp = health;
}
};
};
class Room {
public:
int width, height, difficulty, enemies;
};
Room room[1];
Entity::Player player;
Entity::Common * enemy[2];
int enemy_ID, enemy_count = 2;
///////////
void INIT() {
room[0].width = 10, room[0].height = 10, room[0].enemies = 0;
player.x = player.y = 1, player.collide = 'n', player.room = 0;
enemy[0] = new Entity::Kobold();
enemy[1] = new Entity::Spider();
enemy[0]->x = enemy[0]->y = 5;
enemy[1]->x = enemy[1]->y = 8;
}
void DRAW() {
clear();
printw("ATK: %d, DEF: %d, HP: %d \n", player.power, player.defense, player.hp);
printw("#");
for (int i = 0; i < room[player.room].width - 1; i++) {
printw("--");
}
printw("-#\n");
for (int j = 0; j < room[player.room].height; j++) {
printw("|");
for (int i = 0; i < room[player.room].width; i++) {
if (i == room[player.room].width - 1) {
if (i == player.x and j == player.y) {
printw("%c", player.icon);
}
else if (i == enemy[enemy_ID]->x and j == enemy[enemy_ID]->y) {
printw("%c", enemy[enemy_ID]->icon);
}
else {
printw(" ");
}
}
else {
if (i == player.x and j == player.y) {
printw("%c ", player.icon);
}
else if (i == enemy[enemy_ID]->x and j == enemy[enemy_ID]->y) {
printw("%c ", enemy[enemy_ID]->icon);
}
else {
printw(" ");
}
}
}
printw("|\n");
}
printw("#");
for (int i = 0; i < width - 1; i++) {
printw("--");
}
printw("-#\n");
//Debug
mvprintw(1, 30, "%d %s %c %c", tick_count, typeid(enemy[0]).name(), player.collide, enemy[0]->collide);
}
void LOGIC() {
//GAME LOGIC
////////////
tick_count += 1;
srand(time(NULL));
////////////
//BATTLE LOGIC
//////////////
if (player.collide == 'e' or enemy[enemy_ID]->collide == 'p') {
for (int i; i < enemy_count; i++) {
if (enemy[enemy_ID]->collide == 'p')
player.target = i;
}
if (player.speed > enemy[player.target]->speed) {
}
else if (player.speed < enemy[player.target]->speed) {
}
else if (player.speed == enemy[player.target]->speed) {
if (player.collide = 'e') {
if (rand() % 2) {
enemy[player.target]->hp -= player.power - enemy[player.target]->defense;
mvprintw(14, 0, "You hit %s with %d damage", enemy[player.target], player.power - enemy[player.target]->defense);
clrtoeol();
}
else {
}
}
else if (player.collide = 'n') {
player.hp -= enemy[player.target]->power - player.defense;
mvprintw(14, 0, "%s hit you with %d damage", enemy[player.target], enemy[player.target]->power - player.defense);
getch();
clrtoeol();
}
}
}
//////////////
//PLAYER LOGIC
//////////////
if (player.x - 1 == enemy[enemy_ID]->x and player.y == enemy[enemy_ID]->y and key == 'a'
or player.x + 1 == enemy[enemy_ID]->x and player.y == enemy[enemy_ID]->y and key == 'd'
or player.y - 1 == enemy[enemy_ID]->y and player.x == enemy[enemy_ID]->x and key == 'w'
or player.y + 1 == enemy[enemy_ID]->y and player.x == enemy[enemy_ID]->x and key == 's'
)
player.collide = 'e';
else
player.collide = 'n';
if (player.x < 0)
player.x = 0;
else if (player.x == width)
player.x = width - 1;
else if (player.y < 0)
player.y = 0;
else if (player.y == height)
player.y = height - 1;
//////////////
//ENEMY LOGIC
/////////////
for (enemy_ID = 0; enemy_ID < enemy_count - 1; enemy_ID++)
enemy_ID++;
if (enemy[enemy_ID]->x == player.x and enemy[enemy_ID]->y > player.y and enemy[enemy_ID]->y - 1 != player.y)
enemy[enemy_ID]->move(1);
else if (enemy[enemy_ID]->x == player.x and enemy[enemy_ID]->y < player.y and enemy[enemy_ID]->y + 1 != player.y)
enemy[enemy_ID]->move(2);
else if (enemy[enemy_ID]->y == player.y and enemy[enemy_ID]->x > player.x and enemy[enemy_ID]->x - 1 != player.x)
enemy[enemy_ID]->move(3);
else if (enemy[enemy_ID]->y == player.y and enemy[enemy_ID]->x < player.x and enemy[enemy_ID]->x + 1 != player.x)
enemy[enemy_ID]->move(4);
if (enemy[enemy_ID]->x - 1 == player.x and player.y == enemy[enemy_ID]->y
or enemy[enemy_ID]->x + 1 == player.x and player.y == enemy[enemy_ID]->y
or enemy[enemy_ID]->y - 1 == player.y and player.x == enemy[enemy_ID]->x
or enemy[enemy_ID]->y + 1 == player.y and player.x == enemy[enemy_ID]->x
)
enemy[enemy_ID]->collide = 'p';
else
enemy[enemy_ID]->collide = 'n';
/////////////
}
void INPUT() {
key = getch();
switch (key) {
case 'w':
player.move(1);
break;
case 's':
player.move(2);
break;
case 'a':
player.move(3);
break;
case 'd':
player.move(4);
break;
}
}
int main() {
initscr();
cbreak();
noecho();
INIT();
DRAW();
while (key != '\n') {
//Main Loop
///////////////////////
INPUT();
LOGIC();
DRAW();
///////////////////////
refresh();
}
endwin();
return 0;
}
[问题] (抱歉标题可能令人困惑)我正在制作一个老式的基于 ascii 的流氓类。这是一些代码:
class Entity {
public:
class Player {
public:
int x, y, target;
char collide;
int power = 1, speed = 1, defense = 1, health = 10;
int hp = health;
void move(int dir);
};
class Kobold {
public:
int x, y;
char collide;
const int power = 2, speed = 1, defense = 1, health = 3;
int hp = health;
void move(int dir);
};
我的目标是创建一个名为 enemy 的数组,并让每个数组值(或任何它的名称)具有不同的类作为其类型。例如:enemy[0] 可以是Kobold 的对象,它是Entity 的成员,并且enemy[5] 是Spider 的对象,它是Entity 的成员等等。这样更容易在for 循环中拥有更容易声明和引用的敌人。我要问的是如何以这种方式声明数组enemy。拥有并回答我的问题会很好,但我不确定这是否可能以简单的方式实现,所以如果有人有更简单或更简单的方法来实现我的目标,我也希望看到它。提前致谢。
编辑:示例代码(忽略它不是真实的):
//Declaring an array with 8 values with no type
void enemy[8];
//Assigning the Kobold class to the first enemy as it's type
enemy[0] = Entity::Kobold;
//Assigning the Spider class to the 3rd enemy as it's type
enemy[2] = Entity::Spider;
//Player attacks 3rd enemy (spider) and inflicts damage
enemy[2].hp -= player.power;
//Checks if any enemy is dead, and if so then delete it
for (int i = 0; i < 8; i++) {
if (enemy[i].hp <= 0) {
//Removing enemy from it's class, therefore deleting it
void enemy[i];
}
}
//First enemy (Kobold) attacks player, inflicting damage
player.hp -= enemy[0].power;
//Player isn't dead, and attacks first enemy (Kobold) and kills it
enemy[0].hp -= player.power;
//Checks if any enemy is dead, and if so then delete it (again)
for (int i = 0; i < 8; i++) {
if (enemy[i].hp <= 0) {
//Removing enemy from it's class, therefore deleting it
void enemy[i];
}
}
printw("You Win!");
我知道它没有效果并且可能有一些错误,但它只是用来帮助可视化我正在尝试做的事情。
编辑:
这与我要问的类似: Is it possible to have an array of different objects that come from the same base class?
我正在尝试将数组作为Entity 的对象,但我想让任何数组值成为Entity 的任何子类的对象。所以是这样的:
Entity enemy[5];
enemy[0] = new Kobold;
enemy[4] = new Spider;
然后我可以像这样引用更简单的:
for (int i = 0; i < 5; i++) {
if (array[i].x == player.x and array[i].y == player.y) {
printw("player and an enemy are in the same spot");
}
}
所以重点是一次(虚拟地)轻松访问每个敌人的变量。
另一个例子(检查任何敌人是否有 0 hp):
for (int i = 0; i < amount_of_enemies; i++) {
if (enemy[i].hp <= 0) {
//some code to delete the enemy and give player XP etc.
}
}
【问题讨论】:
-
您可能希望在您最喜欢的 C++ 教科书中阅读多态和虚函数。
-
“这样更容易有敌人[...]”——再读一遍。您对问题的描述表明“敌人”是您代码中的一个概念。实现这个概念的
enemy类在哪里? -
您确定
Player和Kobold是Entity类的成员吗?它们不应该是Entity的子类吗? -
@SergeBallesta 也不是子类,它们是内部类。但是,是的,可能不是提问者想要做的。
-
@SergeBallesta 是的,我就是这个意思,我的错。