0
C++ 控制台伪 3D MC 新增怪物 AI 版本
保留全部旧功能:重力、跳跃、方块碰撞、明暗渲染、放置 / 拆除方块 ✅ 新增怪物:自动在世界游荡,**近玩家会追逐 ✅ 怪物碰到玩家扣血,简单生命值** ✅ 怪物被方块阻挡,不能穿墙 ✅ 怪物会随机改变移动方向
#include <iostream>
#include <vector>
#include <cmath>
#include <windows.h>
#include <conio.h>
using namespace std;
const int SCREEN_WIDTH = 80;
const int SCREEN_HEIGHT = 24;
const int WORLD_SIZE = 16;
//方块:0空气,1石头,2草地
int world[WORLD_SIZE][WORLD_SIZE][WORLD_SIZE] = { 0 };
//玩家
float px = 8.0f, py = 2.0f, pz = 8.0f;
float rot = 0.0f;
float vy = 0.0f;
const float gravity = -0.008f;
const float jumpPower = 0.12f;
bool onGround = false;
int playerHp = 5;
//怪物结构体
struct Monster
{
float x, y, z;
float dir;
bool alive;
Monster() : x(3), y(1), z(3), dir(0), alive(true) {}
};
vector<Monster> monsters;
void cls()
{
COORD coord = { 0,0 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
bool IsBlockSolid(int x, int y, int z)
{
if (x < 0 || x >= WORLD_SIZE || y < 0 || y >= WORLD_SIZE || z < 0 || z >= WORLD_SIZE)
return true;
return world[x][y][z] != 0;
}
bool TryMove(float &x, float &y, float &z, float dx, float dy, float dz)
{
float nx = x + dx;
float ny = y + dy;
float nz = z + dz;
float half = 0.25f;
if (IsBlockSolid((int)(nx - half), (int)ny, (int)(nz - half))) return false;
if (IsBlockSolid((int)(nx + half), (int)ny, (int)(nz - half))) return false;
if (IsBlockSolid((int)(nx - half), (int)ny, (int)(nz + half))) return false;
if (IsBlockSolid((int)(nx + half), (int)ny, (int)(nz + half))) return false;
x = nx;
y = ny;
z = nz;
return true;
}
void InitWorld()
{
for (int x = 0; x < WORLD_SIZE; x++)
{
for (int z = 0; z < WORLD_SIZE; z++)
{
world[x][0][z] = 1;
world[x][1][z] = 2;
}
}
//生成2只怪物
monsters.emplace_back();
monsters.emplace_back();
monsters[1].x = 12;
monsters[1].z = 12;
}
void Render(char screen[SCREEN_HEIGHT][SCREEN_WIDTH])
{
for (int y = 0; y < SCREEN_HEIGHT; y++)
for (int x = 0; x < SCREEN_WIDTH; x++)
screen[y][x] = ' ';
float fov = 3.14159f / 4.0f;
for (int x = 0; x < SCREEN_WIDTH; x++)
{
float rayAngle = rot - fov / 2 + ((float)x / SCREEN_WIDTH) * fov;
float dx = cos(rayAngle);
float dz = sin(rayAngle);
float dist = 0;
bool hit = false;
int hitX, hitY, hitZ;
while (!hit && dist < 20)
{
dist += 0.05f;
int rx = (int)(px + dx * dist);
int rz = (int)(pz + dz * dist);
int ry = (int)(py);
if (rx < 0 || rx >= WORLD_SIZE || rz < 0 || rz >= WORLD_SIZE || ry < 0 || ry >= WORLD_SIZE)
{
hit = true;
dist = 20;
}
else if (world[rx][ry][rz] != 0)
{
hit = true;
hitX = rx; hitY = ry; hitZ = rz;
}
}
float wallHeight = 1.0f / dist * 6;
int startY = SCREEN_HEIGHT / 2 - wallHeight / 2;
int endY = SCREEN_HEIGHT / 2 + wallHeight / 2;
char ch;
if (dist < 3)
ch = '#';
else if (dist < 7)
ch = '%';
else if (dist < 12)
ch = '.';
else
ch = ' ';
for (int y = startY; y < endY; y++)
{
if (y >= 0 && y < SCREEN_HEIGHT)
screen[y][x] = ch;
}
}
}
//更新怪物AI
void UpdateMonster()
{
for (auto& m : monsters)
{
if (!m.alive) continue;
float dx = px - m.x;
float dz = pz - m.z;
float distPlayer = sqrt(dx*dx + dz*dz);
float speed = 0.04f;
//怪物离玩家近就追逐,远就随机游荡
if (distPlayer < 6.0f)
{
m.dir = atan2(dz, dx);
}
else
{
if(rand()%100 < 2)
m.dir += (rand()%2 == 0 ? 0.5f : -0.5f);
}
float mx = cos(m.dir) * speed;
float mz = sin(m.dir) * speed;
TryMove(m.x, m.y, m.z, mx, 0, mz);
//怪物碰到玩家扣血
if(distPlayer < 0.8f)
{
playerHp--;
//击退怪物
m.x -= dx * 0.3f;
m.z -= dz * 0.3f;
}
}
}
int main()
{
InitWorld();
char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
cout << "==== 伪3D体素世界【怪物AI版】 ====\n";
cout << "W向前 S向后 A左转 D右转\n";
cout << "空格:地面跳跃,空中放置方块\n";
cout << "X**方块 | ESC退出 | 小心怪物!\n";
Sleep(3000);
while (true)
{
if(playerHp <=0)
{
cls();
cout << "游戏结束!你被怪物击杀了!" << endl;
Sleep(3000);
break;
}
//重力更新
vy += gravity;
if (TryMove(px, py, pz, 0, vy, 0))
{
onGround = false;
}
else
{
if (vy < 0) onGround = true;
vy = 0;
}
UpdateMonster();
Render(screen);
cls();
for (int y = 0; y < SCREEN_HEIGHT; y++)
{
for (int x = 0; x < SCREEN_WIDTH; x++)
cout << screen[y][x];
cout << endl;
}
printf("X:%.2f Y:%.2f Z:%.2f HP:%d 地面:%d\n", px, py, pz, playerHp, onGround);
if (_kbhit())
{
char k = _getch();
float speed = 0.15f;
switch (k)
{
case 'w': TryMove(px, py, pz, cos(rot)*speed, 0, sin(rot)*speed); break;
case 's': TryMove(px, py, pz, -cos(rot)*speed, 0, -sin(rot)*speed); break;
case 'a': rot -= speed; break;
case 'd': rot += speed; break;
case ' ':
if (onGround)
{
vy = jumpPower;
}
else
{
int bx = (int)(px + cos(rot)*2);
int bz = (int)(pz + sin(rot)*2);
int by = (int)py;
if (bx >= 0 && bx < WORLD_SIZE && by >= 0 && by < WORLD_SIZE && bz >= 0 && bz < WORLD_SIZE)
world[bx][by][bz] = 2;
}
break;
case 'x':
{
int bx = (int)(px + cos(rot)*2);
int bz = (int)(pz + sin(rot)*2);
int by = (int)py;
if (bx >= 0 && bx < WORLD_SIZE && by >= 0 && by < WORLD_SIZE && bz >= 0 && bz < WORLD_SIZE)
world[bx][by][bz] = 0;
break;
}
case 27: return 0;
}
}
Sleep(30);
}
return 0;
}
🎮 新增内容
- 怪物 AI **
- 怪物距离玩家小于 6 格:主动追逐玩家
- 距离较远:随机游荡,时不时换方向
- 怪物同样有碰撞检测,不能穿墙
- 生命值:玩家初始 5 点 HP,怪物碰到就扣血,HP=0 游戏结束
- 怪物撞击玩家后会被击退,不会持续贴脸掉血
按键
- W:前进 S:后退
- A:左转 D:右转
- 空格:地面跳跃 / 空中放置草方块
- X:**面前方块
- ESC:退出
