///|
fn clamp_color_channel(channel : Int) -> Int {
if channel < 0 {
0
} else if channel > 255 {
255
} else {
channel
}
}
///|
fn color_from_rgb(r : Int, g : Int, b : Int) -> @srender.Color {
{
r: clamp_color_channel(r).reinterpret_as_uint(),
g: clamp_color_channel(g).reinterpret_as_uint(),
b: clamp_color_channel(b).reinterpret_as_uint(),
a: 1.0,
}
}
///|
fn color_from_hex(hex : String) -> @srender.Color {
let r = try! @strconv.parse_int(hex[1:3].to_string(), base=16)
let g = try! @strconv.parse_int(hex[3:5].to_string(), base=16)
let b = try! @strconv.parse_int(hex[5:7].to_string(), base=16)
color_from_rgb(r, g, b)
}
///|
fn make_rect(x : Double, y : Double, width : Double, height : Double) -> @smath.Rect {
{
position: @smath.Vec2D(x, y),
size: @smath.Vec2D(width, height),
}
}
///|
fn draw_filled_rect(
x : Double,
y : Double,
width : Double,
height : Double,
color : @srender.Color
) -> Unit {
@backend.draw_rect({
rect: make_rect(x, y, width, height),
fill_color: color,
stroke_color: None,
})
}
///|
fn draw_text_line(
text : String,
x : Double,
y : Double,
size : Double,
color : @srender.Color
) -> Unit {
@backend.draw_text({
text,
position: @smath.Vec2D(x, y),
style: {
family: "Arial",
size,
color,
align: @smath.HAlign::Left,
baseline: @smath.VAlign::Top,
},
})
}
///|
fn render_3d_system(_delta : Double) -> Unit {
let rays = cast_all_rays()
let wall_height = 64.0
let distance_scale = 1000.0
@backend.draw_gradient_rect({
rect: make_rect(0.0, 0.0, CANVAS_WIDTH, CANVAS_HEIGHT / 2.0),
color_start: color_from_hex("#2A2A2A"),
color_end: color_from_hex("#1E1E1E"),
})
@backend.draw_gradient_rect({
rect: make_rect(0.0, CANVAS_HEIGHT / 2.0, CANVAS_WIDTH, CANVAS_HEIGHT / 2.0),
color_start: color_from_hex("#2F4F2F"),
color_end: color_from_hex("#1A3A1A"),
})
let strip_width = CANVAS_WIDTH / rays.length().to_double()
for i, ray in rays {
let wall_height = wall_height * distance_scale / ray.distance
let wall_top = (CANVAS_HEIGHT - wall_height) / 2
let strip_x = i.to_double() * strip_width
// Get texture for this wall (assuming all walls are type 1 for now)
let texture = get_wall_texture(1)
// Calculate texture X coordinate - use a fixed value to remove horizontal variation
let texture_x = 32 // Fixed X coordinate - no horizontal texture movement
// Sample just a few points and draw larger blocks for performance
let num_segments = 16 // Only 16 texture samples per wall strip
let segment_height = wall_height / num_segments.to_double()
// Calculate world Y position for texture mapping
let wall_world_height = 64.0 // Standard wall height in world units
let texture_y_scale = texture.height.to_double() / wall_world_height
for segment in 0.. Unit {
let scale = 6.0
let offset_x = 10.0
let offset_y = 10.0
let map = get_map()
// Draw map tiles
for y in 0.. Unit {
// Draw level display in top right corner
let level_text = "Level: \{current_level.val + 1}"
draw_text_line(
level_text,
CANVAS_WIDTH - 140.0,
40.0,
36.0,
color_from_hex("#FFFFFF"),
)
// Draw congratulations message when all levels completed
if completed_all_levels.val {
draw_text_line(
"CONGRATULATIONS!",
CANVAS_WIDTH / 2.0 - 170.0,
30.0,
32.0,
color_from_hex("#00FF00"), // Gold color
)
draw_text_line(
"You completed all levels!",
CANVAS_WIDTH / 2.0 - 120.0,
70.0,
20.0,
color_from_hex("#00FF00"), // Green color
)
}
}