【问题标题】:C++ ASCII game console screen flickeringC++ ASCII 游戏机屏幕闪烁
【发布时间】:2015-10-02 19:01:19
【问题描述】:

我正在使用 C++ 制作一个简单的游戏 这只是一个带有 ASCII 地图的瓷砖游戏。 游戏本身运行良好,但是当我移动播放器时控制台屏幕(地图)闪烁,我不知道如何解决这个问题。有任何帮助,谢谢!

代码:

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <vector>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;

vector<string> map;
int playerX = 10;
int playerY = 10;
int oldPlayerX;
int oldPlayerY;
bool done = false;

void loadMap();
void printMap();
void setPosition(int y, int x);
void eventHandling();

int main()
{
    loadMap();
    map[playerY][playerX] = '@';
    printMap();
    while(!done){
        eventHandling();
        printMap();
    }
    exit(1);
    return 0;
}

void eventHandling(){
    char command;
    command = _getch();
    system("cls");
    oldPlayerX = playerX;
    oldPlayerY = playerY;

    if(command == 'w'){
        playerY--;
    }else if(command == 'a'){
        playerX--;
    }else if(command == 'd'){
        playerX++;
    }else if(command == 's'){
        playerY++;
    }

    if(map[playerY][playerX] == '#'){
        playerX = oldPlayerX;
        playerY = oldPlayerY;
    }

    setPosition(playerY,playerX);

}

void setPosition(int y, int x){
    map[oldPlayerY][oldPlayerX] = '.';
    map[y][x] = '@';
}

void  printMap(){
    for(int i = 0 ; i < map.size() ; i++){
        cout << map[i] << endl;
    }
}

void loadMap(){
    ifstream file;
    file.open("level.txt");

    string line;
    while(getline(file, line)){
        map.push_back(line);
    }
}

【问题讨论】:

  • 这一切都是因为system("cls");而发生的。使用另一种方法,例如自己打印整个页面或通过到处打印空格字符手动清除它,然后打印您的地图数据。
  • 你最好不要打电话给system("cls");。我知道当你第一次开始制作命令行游戏时感觉“更干净”,但大多数程序不这样做,而且人们通常不喜欢在他们没有尝试这样做时清除屏幕。此外,它不是可移植的,而您的其余代码可能是。
  • using namespace std; 是一种不好的做法,所以不要养成这样做的习惯。只需写出std::mapstd::ifstreamstd::coutstd::getline 等。如果你不这样做,它最终会咬你的(你不知道std 中的所有内容,如果你使用相同的呢?命名为什么?)
  • 你们认为清除控制台屏幕的正确方法是什么?
  • @HugoCornel 不要清除它。没有一些第三方库(这也将受到限制),就没有可移植的方式。你的程序不知道它正在写入屏幕,它只知道它正在写入stdout,它可能是一个文件、一个管道、一个套接字、一个打印机,谁知道呢?

标签: c++ ascii tile


【解决方案1】:

std::cout 不打算以这种方式使用。

您应该参考目标操作系统和环境的系统特定 API。例如,对于 Windows,您应该使用 Console API functions 来达到您的目的。这些函数在Wincon.h包含文件中定义。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
【解决方案2】:

如果您使用双缓冲系统也有帮助,这样只有每帧需要覆盖的内容才会被更改。 IO 操作非常昂贵,因此应尽量减少。

Cameron Gives a Very Thorough Description of How to Do this Here

但本质上,您会使用两个数组,一个包含地图的当前状态,一个包含之前的状态,并且只写入已更改的特定位置。

【讨论】:

  • 对于真正的双缓冲,请在同一线程中查看我的reply。本质上,与其拥有两个数组,不如创建两个本机控制台缓冲区并像在 OpenGL 或 Direct3D 中通常所做的那样切换它们。完整示例源代码请查看回复。
【解决方案3】:

在许多系统上都可以清除屏幕的一种方法是打印换页符\f。 Linux 控制台支持这一点,如果你加载了ansi.sys,MS-DOS 也支持。 Unix 有ncursesterminfo 来抽象这些函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    相关资源
    最近更新 更多