C++ ASCII 游戏控制台屏幕闪烁
C++ ASCII game console screen flickering
我正在使用 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);
}
}
std::cout
不应以这种方式使用。
对于目标 OS 和环境,您应该参考系统特定 API。例如,对于 Windows,您应该根据自己的目的使用 Console API functions。这些函数在 Wincon.h
包含文件中定义。
一种适用于许多系统的清除屏幕的方法是打印换页字符,\f
。 Linux 控制台支持此功能,如果您加载 ansi.sys
,MS-DOS 也支持此功能。 Unix有ncurses
和terminfo
来抽象这些函数。
如果您使用双缓冲系统也有帮助,这样只有每帧需要覆盖的内容才会被更改。 IO 操作非常昂贵,因此应该尽量减少。
但本质上,您会使用两个数组,一个包含地图的当前状态,一个包含之前的状态,并且只写入已更改的特定位置。
我正在使用 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);
}
}
std::cout
不应以这种方式使用。
对于目标 OS 和环境,您应该参考系统特定 API。例如,对于 Windows,您应该根据自己的目的使用 Console API functions。这些函数在 Wincon.h
包含文件中定义。
一种适用于许多系统的清除屏幕的方法是打印换页字符,\f
。 Linux 控制台支持此功能,如果您加载 ansi.sys
,MS-DOS 也支持此功能。 Unix有ncurses
和terminfo
来抽象这些函数。
如果您使用双缓冲系统也有帮助,这样只有每帧需要覆盖的内容才会被更改。 IO 操作非常昂贵,因此应该尽量减少。
但本质上,您会使用两个数组,一个包含地图的当前状态,一个包含之前的状态,并且只写入已更改的特定位置。