# A new era of 3d r-casting?

**URL:** <https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127>\
**Category:** Arcade\
**Tags:** game, graphics-and-math\
**Created:** [May 22, 2023, 2:38am UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127 "2023-05-22T02:38:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jackal](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/jackal/32/19506_2.png) [@jackal](https://forum.makecode.com/u/jackal)\
**Post date:** [May 22, 2023, 2:38am UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/1 "2023-05-22T02:38:34Z")

</div>

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)

```auto
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.

---

<div class="post-metadata">

**Author:** ![randomuser](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/randomuser/32/32505_2.png) [@randomuser](https://forum.makecode.com/u/randomuser)\
**Post date:** [May 22, 2023, 4:46pm UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/2 "2023-05-22T16:46:53Z")

</div>

Hmm… maybe!

---

<div class="post-metadata">

**Author:** ![ChimbroDaPro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/chimbrodapro/32/15852_2.png) [@ChimbroDaPro](https://forum.makecode.com/u/ChimbroDaPro)\
**Post date:** [May 22, 2023, 4:47pm UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/3 "2023-05-22T16:47:44Z")

</div>

WOAH… 😲

---

<div class="post-metadata">

**Author:** ![labfox29](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/labfox29/32/9252_2.png) [@labfox29](https://forum.makecode.com/u/labfox29)\
**Post date:** [May 22, 2023, 9:04pm UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/4 "2023-05-22T21:04:50Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![AqeeAqee](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/aqeeaqee/32/5424_2.png) [@AqeeAqee](https://forum.makecode.com/u/AqeeAqee)\
**Post date:** [May 23, 2023, 4:11pm UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/5 "2023-05-23T16:11:35Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![a012](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/a012/32/24099_2.png) [@a012](https://forum.makecode.com/u/a012)\
**Post date:** [August 27, 2025, 4:48pm UTC](https://forum.makecode.com/t/a-new-era-of-3d-r-casting/20127/6 "2025-08-27T16:48:07Z")

</div>

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.
