C++ 文字冒险游戏:2D阵列作为地图

C++ Text Adventure Game: 2D Array's as a map

本文关键字:地图 阵列 2D 文字 冒险游戏 C++      更新时间:2023-10-16

好的,所以我正在做一个非常简单的文本冒险游戏。现在我有一个功能正常的菜单,以及一个非常简单的"战斗模式",它将尽快转换为随机遭遇战。不过,我现在遇到的问题是地图。

这个想法是使用2D阵列系统作为地图,位置存储为坐标(如果有意义的话)。您可以输入4个方向,"北,东,南和西"四处走动,您可以去3种类型的地方。一片田野,一片森林和一座城堡。地图本身的大小为 5 x 6。

我想做的是让你从坐标 2、2 的中心开始,你可以四处移动,例如一个字段(由顶部的整数为 1 指定),它说"你在田野里",并做类似的事情来向城堡、森林、 等。我还希望它告诉玩家,如果他们试图移动到标有0的位置,他们不能去那里并阻止他们移动。

有人有什么建议吗?

编辑:好的,所以我再次运行了我的程序,我已经设法摆脱了一些错误,但我还有一堆(确切地说是 26 个,和 1 个警告。 有人愿意给我一些建议吗?

#pragma once
#include "Map.h"
#include <iostream>
using namespace std;
Map::Map()
{
}
void main()
{
// Declare variables & functions
int locationy;
int locationx;
char oper;
char location;
int pond = 0;
int field = 1;
int forest = 2;
int castle = 3;
int mapy;
int mapx;
int map;
//These two values declare the start location on the array map for the player
int mapy = 3;
int mapx = 3;
//These two variables track your current position on the map
mapy = 2;
mapx = 2;
map[locationy][locationx];
//Declares the amount of space within an array
int map[6][6] = 
{
{ 0, 0, 0, 0, 0, 0 },
{ 0, 2, 1, 2, 1, 0 },
{ 0, 1, 2, 1, 2, 0 },
{ 0, 1, 2, 2, 1, 0 },
{ 0, 1, 3, 1, 2, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
//Asks the player where they want to go around the map
cout << "Where to?" << endl;
//Request for user to enter an direction (I.e., North, East, South, West.)
cout << "Please choose  North, East, South or West" << endl;
//Displays the inputted values
cin >> oper;
//Pauses system so we can see what the program does
system("pause");
//Checks input from the player
if (cin == "North")
{
//Moves location upwards on the y axis
if (map[locationx][locationy + 1] != 0) { locationy += 1; };
else { cout << "That is water, dude. Swimming in platemail is NOT recommended.n";
}
//Checks input from the player
if (cin == "East")
{
//Moves location to the right on the x axis
if (map[locationx + 1][locationy] != 0) { locationy += 1; };
else { cout << "That is water, dude. Swimming in platemail is NOT recommended.n";
}
//Checks input from the player
if (cin == "South")
{
//Moves location downwards on the y axis
if (map[locationx][locationy - 1] != 0) { locationy += 1; }
else { cout << "That is water, dude. Swimming in platemail is NOT recommended.n";
}
//Checks input from the player
if (cin == "West")
{
//Moves location to the left on the x axis
if (map[locationx - 1][locationy] != 0) { locationy += 1; }
else { cout << "That is water, dude. Swimming in platemail is NOT recommended.n"
};
}
Map::~Map()
{
;
}

欢迎来到C++。现在,你犯了基本的初学者错误,即编写命令式代码。C++是面向对象的,这是使用它的关键。使您的代码更加有效。

在这种情况下,你应该从确定你的项目有哪些部分开始,哪些东西可以识别为类。你用 Map 这样做了,但你错过的是创建一个包装所有内容的类,比如 Game。

这是我的建议,到目前为止,许多部分尚未实施。

首先,代表某些地形的数字是丑陋的。让我们用枚举替换它们:

enum class Terrain: unsigned char {
pond = 0,
field = 1,
forest = 2,
castle = 3
}

从现在开始,只要提到池塘,您就可以写 Terrain::p ond。使代码更具可读性。

现在对于类布局(在 Game.h 中):

#include <vector>
using std::vector;
#include "Terrain.h"
//alternatively, define Terrain here instead of making it a separate header
class Game {
public:
Game();
Game(const string& file_name);
//Game(file_name) is something you might want to do later -
//create an instance of Game based on a file that contains a map,
//maybe more data, instead of hard-coding such things
void run();
private:
vector<vector<Terrain> > map;
//arrays are something you want to avoid. Use std::vector instead.
unsigned int location_x, location_y;
bool game_running;
//aka not has ended
void evaluate_step();
//this method is repeated and repeated until the game ends
//and contains the order in which every step is evaluated
void handle_input();
//Takes cin and does something with it
void evaluate_position();
//takes the position, gets the terrain from the position,
//does what happens on that terrain
void print();
//prints the whole map to the console
void set_default_map();
//sets map to the data you have in your code,
//to be used until reading from file is implemented
}

现在我们创建空构造函数来创建默认值(在 Game.cpp 中):

Game::Game(){
set_default_map();
location_x = ...;
location_y = ...;
game_running = true;
}

运行将简单地重复评估步骤:

void Game::run(){
while(game_running){
evaluate_step();
}
}
void Game::evaluate_step(){
handle_input();
print();
evaluate_terrain();
}

现在,我可以详细介绍,但我认为这应该让你了解这样的结构是什么样子的。基本思想是划分和划分,以获得清晰的概述,创造可读性。

如果您对这个提议的课程有疑问,我将编辑此答案。

在你的主语中,它会这样称呼:

#include "Game.h"
int main(){
Game game;
game.run();
return 0;
}

编辑:现在对于代码的错误:

  1. 你需要写 int main 而不是 void main。 void main 看起来像 Java 语法。
  2. Mapy和Mapx被声明了两次:int mapy;int mapy=3;。这是不允许的。要么删除第一个声明,要么使赋值不声明(int mapy;mapy=3;,尽管我更愿意删除第一个声明)。
  3. 不知道你想要什么map[locationy][locationx];.它在任何方面都不是有效的代码。
  4. map 也被声明了两次,有两种不同的类型(int 和 int[][])。删除第一个声明。
  5. 在你所有的cin病例中,你的条件格式很糟糕。if括号后不应有分号,if(..){..}else{..},而不是if(..){..};else{..}。此外,在每种情况下,都缺少一个括号。
  6. mapx 和 locationx 有什么区别?mapx 已设置,但使用了 locationx?我删除了 mapx 和 mapy,并将位置 x 和位置设置为 2。
  7. 不使用位置。这是干什么用的?
  8. 定义了池塘、田野等,但你不使用它。
  9. main 一次不需要杂注(也不需要防护装置)
  10. 不使用操作器。你可能想改变你的if条件,比如if(oper =="North")等等。为此,您需要更改操作器的类型。一个字符只能容纳一个字符。你可以使用 char*,但指针不好,所以最好使用字符串(你需要为此#include <string>)
  11. 读取和评估仅执行一次。执行一个步骤,程序结束。我猜不是你想要的 - 你可能想在它周围放一个循环,比如bool running = true; while(running){...}
  12. 对于任何方向,位置都以相同的方式更改。

更改了这些以使其运行(但您确实应该真正更改设计):

#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
void print_water_warning() {
cout << "That is water, dude. Swimming in platemail is NOT recommended.n";
}
int main() {
// Declare variables & functions
int locationy = 2;
int locationx = 2;
string oper;
//Declares the amount of space within an array
int map[6][6] = { {0, 0, 0, 0, 0, 0},
{0, 2, 1, 2, 1, 0},
{0, 1, 2, 1, 2, 0},
{0, 1, 2, 2, 1, 0}, 
{0, 1, 3, 1, 2, 0},
{0, 0, 0, 0, 0, 0} };
while (true) {
//Asks the player where they want to go around the map
cout << "Where to?" << endl;
//Request for user to enter an direction (I.e., North, East, South, West.)
cout << "Please choose  North, East, South or West" << endl;
//Displays the inputted values
cin >> oper;
//Checks input from the player
if (oper.compare("North") == 0) {
//Moves location upwards on the y axis
if (map[locationx][locationy + 1] != 0) {
locationy += 1;
} else {
print_water_warning();
}
}
//Checks input from the player
if (oper == "East") {
//Moves location to the right on the x axis
if (map[locationx + 1][locationy] != 0) {
locationx += 1;
} else {
print_water_warning();
}
}
//Checks input from the player
if (oper == "South") {
//Moves location downwards on the y axis
if (map[locationx][locationy - 1] != 0) {
locationy -= 1;
} else {
print_water_warning();
}
}
//Checks input from the player
if (oper == "West") {
//Moves location to the left on the x axis
if (map[locationx - 1][locationy] != 0) {
locationx -= 1;
} else {
print_water_warning();
}
}
} //end while
} //end main