A new era of 3d r-casting?

So, OperaGX got an update, and C-GPT won’t say anything but errors to me, so I used the new ChatSonic to make a 3D game in scratch and wondered: “What would happen if I told it to make a raycasting system just like doom???”
And uh… Here’s what i said:
"Can you code a 3D raycasting script similar to the one that DOOM used in Microsoft Makecode Arcade?

Yes, I can help you with that. Raycasting is a technique used to create a 3D perspective in 2D games. Here’s an example code in MakeCode Arcade that implements raycasting for a 3D perspective:

(THIS IS ALL WRITTEN IN TYPESCRIPT BTW)

let screen: Image = null
let map = [
    [1,1,1,1,1],
    [1,0,0,0,1],
    [1,0,0,0,1],
    [1,0,0,0,1],
    [1,1,1,1,1]
]
let player = {
    x: 2.5,
    y: 2.5,
    dir: 0,
    fov: Math.PI / 4
}
function updateScreen() {
    screen.fill(1)
    for (let i = 0; i < screen.width(); i++) {
        let angle = player.dir - player.fov / 2 + player.fov * i / screen.width()
        let distance = 0
        let hit = false
        let x = player.x, y = player.y
        while (!hit && distance < 20) {
            let dx = Math.cos(angle) * distance
            let dy = Math.sin(angle) * distance
            let testX = Math.floor(x + dx)
            let testY = Math.floor(y + dy)
            if (testX >= 0 && testX < map[0].length && testY >= 0 && testY < map.length) {
                hit = map[testY][testX] === 1
            }
            distance += 0.1
        }
        let ceiling = (screen.height() - 2 * screen.height() / distance) / 2
        let floor = screen.height() - ceiling
        for (let j = 0; j < screen.height(); j++) {
            if (j < ceiling) {
                screen.setPixel(i, j, 2)
            } else if (j >= ceiling && j <= floor) {
                screen.setPixel(i, j, hit ? 0 : 3)
            } else {
                screen.setPixel(i, j, 4)
            }
        }
    }
    screen.setPixel(Math.floor(player.x), Math.floor(player.y), 5)
}
controller.A.onEvent(ControllerButtonEvent.Pressed, function() {
    player.dir += Math.PI / 4
    if (player.dir >= Math.PI * 2) {
        player.dir -= Math.PI * 2
    }
})
controller.B.onEvent(ControllerButtonEvent.Pressed, function() {
    player.dir -= Math.PI / 4
    if (player.dir < 0) {
        player.dir += Math.PI * 2
    }
})
controller.left.onEvent(ControllerButtonEvent.Pressed, function() {
    let dx = Math.cos(player.dir - Math.PI / 2) * 0.1
    let dy = Math.sin(player.dir - Math.PI / 2) * 0.1
    if (map[Math.floor(player.y)][Math.floor(player.x - dx)] === 0) {
        player.x -= dx
    }
    if (map[Math.floor(player.y - dy)][Math.floor(player.x)] === 0) {
        player.y -= dy
    }
})
controller.right.onEvent(ControllerButtonEvent.Pressed, function() {
    let dx = Math.cos(player.dir + Math.PI / 2) * 0.1
    let dy = Math.sin(player.dir + Math.PI / 2) * 0.1
    if (map[Math.floor(player.y)][Math.floor(player.x + dx)] === 0) {
        player.x += dx
    }
    if (map[Math.floor(player.y + dy)][Math.floor(player.x)] === 0) {
        player.y += dy
    }
})
controller.up.onEvent(ControllerButtonEvent.Pressed, function() {
    let dx = Math.cos(player.dir) * 0.1
    let dy = Math.sin(player.dir) * 0.1
    if (map[Math.floor(player.y - dy)][Math.floor(player.x)] === 0) {
        player.y -= dy
    }
    if (map[Math.floor(player.y)][Math.floor(player.x + dx)] === 0) {
        player.x += dx
    }
})
controller.down.onEvent(ControllerButtonEvent.Pressed, function() {
    let dx = Math.cos(player.dir + Math.PI) * 0.1
    let dy = Math.sin(player.dir + Math.PI) * 0.1
    if (map[Math.floor(player.y + dy)][Math.floor(player.x)] === 0) {
        player.y += dy
    }
    if (map[Math.floor(player.y)][Math.floor(player.x - dx)] === 0) {
        player.x -= dx
    }
})
game.onUpdate(function() {
    updateScreen()
    screen.show()
})

This could be a new era of raycasting, but I haven’t even tested it out, I just wanted to show all of you guys, especially @AqeeAqee . After this gets posted I’ve probably already tested it. But who ever is verifying this post or whatever: thanks.

5 Likes

Hmm… maybe!

WOAH… :astonished:

I copied it and I don’t know JavaScript that good, but the code had 8 errors, but it might work with some work.

Ah, interesting!
I haven’t run it, but just had a browse. This should be a classic r-casting algorithm, in other words, lots of optimization need be done before get a good FPS on Arcade device. And it will be more slow if add those Arcade features support, tilemap, sprite, saytext, sprite effect, etc.
But it would be a good implement for study at begin, if you want learn how r-casting works.

2 Likes

I like it but to be honest you accidentally duplicated the screen variable and also screen.show does not exist in screen. And also screen.width does not need to call because just write screen.width because it is already a number it is not a function somebody made that is the bug if you want to edit this go ahead please.

1 Like