问题标题: MC

0
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;
}

🎮 新增内容

  1. 怪物 AI **
    • 怪物距离玩家小于 6 格:主动追逐玩家
    • 距离较远:随机游荡,时不时换方向
    • 怪物同样有碰撞检测,不能穿墙
  2. 生命值:玩家初始 5 点 HP,怪物碰到就扣血,HP=0 游戏结束
  3. 怪物撞击玩家后会被击退,不会持续贴脸掉血

按键

  • W:前进 S:后退
  • A:左转 D:右转
  • 空格:地面跳跃 / 空中放置草方块
  • X:**面前方块
  • ESC:退出

0
0
0
张天泽
张天泽
新手守护
新手守护

@于逸杋,别**我,再**把你举报了

不好可以慢慢讲,别拿你的发言权开玩笑

我要回答