第一人称射击游戏 C++控制台版(未完成)

简介: 第一人称射击游戏 C++控制台版(未完成)

一、在控制台中显示画面

使用cout方式显示时刷新速度较慢,不能满足游戏需求。 游戏的显示借助windows函数。

#include<iostream>
using namespace std;
 
#include<Windows.h>
 
//定义屏幕宽度、高度
int nScreenWidth = 120;
int nScreenHeight = 40;
 
int main()
{
  // Create Screen Buffer 创建屏幕缓冲区
  wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight];
  HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
  SetConsoleActiveScreenBuffer(hConsole);
  DWORD dwBytesWritten = 0;
 
  //游戏循环
  while (1)
  {
    // Display Frame    显示
    screen[nScreenWidth * nScreenHeight - 1] = '\0';
    WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
 
  }
  
}

二、

地图

//地图
int nMapWidth = 16;       // World Dimensions
int nMapHeight = 16;
//玩家位置X、Y、角度
float fPlayerX = 0.0f;      // Player Start Position
float fPlayerY = 0.0f;
float fPlayerA = 0.0f;      // Player Start Rotation
 
 
// 创建地图   Create Map of world space # = wall block, . = space
  wstring map;
  map += L"################";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"#..............#";
  map += L"################";

地图与实际的对应

 

 

(玩家视角有限)          

(玩家视线)

通过视线与墙面的碰撞检测,生成玩家看到的画面。

for (int x = 0; x < nScreenWidth; x++)
    {
      // For each column, calculate the projected ray angle into world space
      float fRayAngle = (fPlayerA - fFOV / 2.0f) + ((float)x / (float)nScreenWidth) * fFOV;//从左半边到右半边
      float fDistanceToWall = 0.0f; //  
      bool bHitWall = false;
 
      float fEyeX = sinf(fRayAngle); //视线方向对应的单位分量 Unit vector for ray in player space
      float fEyeY = cosf(fRayAngle);
 
      //增量方式  判断视线撞墙
      while (!bHitWall && fDistanceToWall<fDepth) 
      {
        fDistanceToWall += 0.1f;
        int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall);
        int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall);
 
        // 检查视线达到边界  Test if ray is out of bounds
        if (nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight)
        {
          bHitWall = true;      // Just set distance to maximum depth
          fDistanceToWall = fDepth;
        }
        else
        {
          //检查视线是否遇到墙体
          if (map[nTestY*nMapWidth + nTestX] == '#')
          {
            bHitWall = true;
          }
        }
      }
      //计算到天花板和地板的距离
      int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight/((float)fDistanceToWall);
      int nFloor = nScreenHeight - nCeiling;
 
 
 
      for (int y = 0; y < nScreenHeight; y++)
      {
        // Each Row
        if (y < nCeiling) //天花板
          screen[y*nScreenWidth + x] = ' ';
        else if (y > nCeiling && y <= nFloor)
          screen[y*nScreenWidth + x] = '#';
        else // 地板 Floor
        {
          
          screen[y*nScreenWidth + x] = ' ';
        }
      }
    }

三、左右移动,其中用tp2-tp1来获得一帧花费的时间,使得运动看起来更流畅。

#include<chrono>          //时间相关  
    auto tp1 = chrono::system_clock::now();
  auto tp2 = chrono::system_clock::now();
 
  //游戏循环
  while (1)
  {
    //计算时间
    tp2 = chrono::system_clock::now();
    chrono::duration<float>elapsedTime = tp2 - tp1;
    tp1 = tp2;
    float fElapsedTime = elapsedTime.count(); //一帧的时间
 
    // Handle CCW Rotation
    if (GetAsyncKeyState((unsigned short)'A') & 0x8000)
      fPlayerA -= (0.1f)*fElapsedTime;
 
    if (GetAsyncKeyState((unsigned short)'D') & 0x8000)
      fPlayerA += (0.1f)*fElapsedTime;

做到这里(视频的19:06),当我继续往下做的时候发现图像显示的很奇怪,方块都串行显示,看起来像乱码。


但是参考之前的俄罗斯方块中的控制台设置方法,改变控制台之后还是没有改变。


没有找到解决方法,但猜测是和控制台相关的问题(使用作者代码运行也是乱码https://github.com/OneLoneCoder/videos/blob/master/OneLoneCoder_CommandLineFPS.cpp)。


相关文章
|
7月前
|
计算机视觉 索引
扫雷-包含空白展开,标记功能,游戏界面优化-控制台全力复刻
扫雷-包含空白展开,标记功能,游戏界面优化-控制台全力复刻
|
2月前
|
人工智能 算法 BI
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
|
2月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
3月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
245 0
|
6月前
|
C++
C++小练习:猜数游戏
C++小练习:猜数游戏
|
6月前
|
存储 人工智能 C++
【PTA】L1-093 猜帽子游戏(C++)
【PTA】L1-093 猜帽子游戏(C++)
112 1
|
6月前
|
存储
控制台版 赛车游戏
控制台版 赛车游戏
|
6月前
|
C++
俄罗斯方块 C++控制台版
俄罗斯方块 C++控制台版
|
7月前
|
测试技术
消除游戏(第十三届蓝桥杯省赛C++C组 , 第十三届蓝桥杯省赛PythonA/B/研究生组)
消除游戏(第十三届蓝桥杯省赛C++C组 , 第十三届蓝桥杯省赛PythonA/B/研究生组)
消除游戏(第十三届蓝桥杯省赛C++C组 , 第十三届蓝桥杯省赛PythonA/B/研究生组)
|
7月前
|
人工智能 BI 测试技术
三国游戏(第十四届蓝桥杯省赛C++C组)
三国游戏(第十四届蓝桥杯省赛C++C组)