Files
retro3d/examples/billboard_test.ce

157 lines
3.7 KiB
Plaintext

// Billboard Test for retro3d
// Usage: cell run examples/billboard_test.ce <sprite_path>
// sprite_path should be without extension, e.g. "assets/goblin"
// Creates two rows of billboards going off into the distance like alongside a road
// Colors shift through hues as they get further away
var time_mod = use('time')
var retro3d = use('core')
var sprite_path = args[0]
if (!sprite_path) {
log.console("Usage: cell run examples/billboard_test.ce <sprite_path>")
log.console(" sprite_path: path without extension (e.g. 'assets/goblin')")
$_.stop()
}
var sprite = null
var last_time = 0
var cam_angle = 0
function hsv_to_rgb(h, s, v) {
var c = v * s
var x = c * (1 - Math.abs((h / 60) % 2 - 1))
var m = v - c
var r = 0, g = 0, b = 0
if (h < 60) { r = c; g = x; b = 0 }
else if (h < 120) { r = x; g = c; b = 0 }
else if (h < 180) { r = 0; g = c; b = x }
else if (h < 240) { r = 0; g = x; b = c }
else if (h < 300) { r = x; g = 0; b = c }
else { r = c; g = 0; b = x }
return [r + m, g + m, b + m, 1]
}
function _init() {
log.console("retro3d Billboard Test")
log.console("Loading sprite: " + sprite_path)
retro3d.set_style("ps1")
sprite = retro3d.load_sprite(sprite_path)
if (!sprite) {
log.console("Error: Could not load sprite: " + sprite_path)
$_.stop()
return
}
log.console("Sprite loaded: " + text(sprite.width) + "x" + text(sprite.height))
log.console("Controls:")
log.console(" A/D - Rotate camera")
log.console(" ESC - Exit")
retro3d.set_ambient(0.4, 0.4, 0.5)
retro3d.set_light_dir(0.5, 1.0, 0.3, 1.0, 0.95, 0.9, 1.0)
last_time = time_mod.number()
frame()
}
function _update(dt) {
if (retro3d._state.keys_held['escape']) {
$_.stop()
}
if (retro3d._state.keys_held['a']) {
cam_angle = cam_angle - 1.5 * dt
}
if (retro3d._state.keys_held['d']) {
cam_angle = cam_angle + 1.5 * dt
}
}
function _draw() {
retro3d.clear(0.2, 0.3, 0.4, 1.0)
if (!sprite) return
// Set up perspective camera
retro3d.camera_perspective(60, 0.1, 100)
// Camera orbits around origin
var cam_dist = 8
var cam_x = Math.sin(cam_angle) * cam_dist
var cam_z = Math.cos(cam_angle) * cam_dist
var cam_y = 2
retro3d.camera_look_at(cam_x, cam_y, cam_z, 0, 1, 0)
// Draw ground plane
retro3d.push_state()
var ground_mat = retro3d.make_material("lit", {
color: [0.3, 0.4, 0.3, 1]
})
retro3d.set_material(ground_mat)
var ground = retro3d.make_plane(20, 20)
var ground_transform = retro3d.make_transform()
retro3d.draw_model(ground, ground_transform)
retro3d.pop_state()
// Draw two rows of billboards going into the distance
// Left row at x = -2, right row at x = 2
var num_billboards = 10
var spacing = 2.0
var start_z = -2
for (var i = 0; i < num_billboards; i++) {
var z = start_z - i * spacing
var distance_norm = i / (num_billboards - 1) // 0 to 1
// Hue shifts from 0 (red) to 270 (purple) as distance increases
var hue = distance_norm * 270
var color = hsv_to_rgb(hue, 0.9, 1.0)
// Left row
retro3d.draw_billboard(sprite, -2, 0, z, {
color: color,
mode: "cutout",
face: "y"
})
// Right row (slightly different hue offset)
var hue_right = (hue + 30) % 360
var color_right = hsv_to_rgb(hue_right, 0.9, 1.0)
retro3d.draw_billboard(sprite, 2, 0, z, {
color: color_right,
mode: "cutout",
face: "y"
})
}
}
function frame() {
retro3d._begin_frame()
if (!retro3d._process_events()) {
log.console("Exiting...")
$_.stop()
return
}
var now = time_mod.number()
var dt = now - last_time
last_time = now
_update(dt)
_draw()
retro3d._end_frame()
$_.delay(frame, 1/60)
}
_init()