You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

光线投射引擎运行结果不符合预期的问题排查求助

光线投射引擎渲染异常问题

我正在使用C#和MonoGame开发一个简单的光线投射引擎(目前暂不考虑纹理)。通过递增射线深度的方式检测射线是否击中墙体,再根据玩家与击中位置的距离渲染墙体。

玩家位于横向第3格、纵向第4格,朝向与正北方向呈30°。预期结果为黑色背景上渲染出倾斜的白色墙体,但实际运行结果不符合预期:
实际渲染效果

我创建了Canvas类用于在纹理上设置像素,通过SpriteBatch渲染:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Raycaster
{
    public class Canvas
    {
        Texture2D texture;
        Color[] pixels;

        bool changed = false;

        public Canvas(GraphicsDevice graphicsDevice, int width, int height)
        {
            texture = new Texture2D(graphicsDevice, width, height);
            pixels = new Color[width * height];
        }

        public void Draw(SpriteBatch _spriteBatch)
        {
            if (changed)
            {
                changed = false;
                texture.SetData(pixels);
            }
            
            _spriteBatch.Draw(texture, new Vector2(0, 0), Color.White);
        }

        public void SetPixel(int x, int y, Color color)
        {
            int position = x + (y * texture.Width);
            
            if (position >= 0 && position < pixels.Length)
            {
                pixels[position] = color;
                changed = true;
            }
        }

        public void Clear()
        {
            pixels = new Color[texture.Width * texture.Height];
        }
    }
}

以下是Game1.cs中定义的常量与变量:

const int Width = 1024;
const int Height = 700;

int[,] map = { 
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};

Vector2 playerPosition = new Vector2(192, 256);
double playerRotation = 30;

const double playerFOV = 60;
const double deltaAngle = playerFOV / Width;

const int unitsPerSquare = 64;

Canvas canvas;

Game1中的Draw方法代码:

GraphicsDevice.Clear(Color.Black);

canvas.Clear();

double angle = playerRotation - (playerFOV / 2);
for (int column = 0; column < Width; column++)
{
    int depth = 0;

    bool wallFound = false;
    Vector2 wallHit = new Vector2(0, 0);

    while (!wallFound)
    {
        if (depth > 1024) break;

        double x = playerPosition.X + depth * Math.Cos(angle);
        double y = playerPosition.Y + depth * Math.Sin(angle);

        if (x < 0 || y < 0 || x > Width || y > Height) break;

        for (int i = 0; i < map.GetLength(0); i++)
        {
            if (wallFound) break;

            for (int j = 0; j < map.GetLength(1); j++)
            {
                if (wallFound) break;

                int value = map[i, j];
                if (value == 0) continue;
                else if (value == 1)
                {
                    Vector2 currentPosition = new Vector2((float)x, (float)y);
                    Rectangle cubeRectangle = new Rectangle(i * unitsPerSquare, j * unitsPerSquare, unitsPerSquare, unitsPerSquare);
                    if (cubeRectangle.Contains(currentPosition))
                    {
                        wallFound = true;
                        wallHit = currentPosition;
                    }
                }
            }
        }

        depth++;
    }

    if (wallFound)
    {
        float distance = Vector2.Distance(playerPosition, wallHit);
        int wallRenderHeight = (int)Math.Round(Width * (1 / (distance / unitsPerSquare)));
        int wallRenderY = (Height / 2) - (wallRenderHeight / 2);
        for (int i = 0; i < wallRenderHeight; i++) canvas.SetPixel(column, i + wallRenderY, Color.White);
    }

    angle += deltaAngle;
}

_spriteBatch.Begin();
canvas.Draw(_spriteBatch);
_spriteBatch.End();

base.Draw(gameTime);

内容的提问来源于stack exchange,提问作者Atomic Peanut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:19:55