193 lines
4.3 KiB
Plaintext
193 lines
4.3 KiB
Plaintext
// Forest example (Diablo-style camera) for lance3d
|
|
// Fixed 3/4 camera, WASD movement
|
|
// Press ESC to exit.
|
|
|
|
var time_mod = use('time')
|
|
var lance3d = use('core')
|
|
var math = use('math/radians')
|
|
|
|
// Meshes
|
|
var ground_mesh = null
|
|
var trunk_mesh = null
|
|
var canopy_mesh = null
|
|
var player_mesh = null
|
|
|
|
// Materials
|
|
var ground_mat = null
|
|
var trunk_mat = null
|
|
var canopy_mat_a = null
|
|
var canopy_mat_b = null
|
|
var player_mat = null
|
|
|
|
// Player state
|
|
var player = {
|
|
x: 0,
|
|
y: 0.5,
|
|
z: 0,
|
|
yaw: 0,
|
|
speed: 6.0
|
|
}
|
|
|
|
// Trees: array of {x, z, trunk_h, trunk_r, canopy_s, canopy_mat}
|
|
var trees = []
|
|
var num_trees = 80
|
|
|
|
var cam_offset = { x: 10, y: 12, z: 10 }
|
|
|
|
var last_time = 0
|
|
|
|
function _init() {
|
|
log.console("lance3d Forest (Diablo camera) Example")
|
|
log.console("WASD move, ESC exit")
|
|
|
|
lance3d.set_style("ps1")
|
|
|
|
lance3d.seed(1337)
|
|
|
|
lance3d.set_lighting({
|
|
sun_dir: [0.4, 1.0, 0.2],
|
|
sun_color: [1.0, 0.95, 0.9],
|
|
ambient: [0.35, 0.35, 0.40]
|
|
})
|
|
|
|
lance3d.set_fog({
|
|
enabled: true,
|
|
color: [0.55, 0.70, 0.90],
|
|
near: 40,
|
|
far: 160
|
|
})
|
|
|
|
// Create meshes
|
|
ground_mesh = lance3d.make_plane(220, 220)
|
|
trunk_mesh = lance3d.make_cube(1, 1, 1)
|
|
canopy_mesh = lance3d.make_cube(1, 1, 1)
|
|
player_mesh = lance3d.make_cube(1, 1, 1)
|
|
|
|
// Create materials
|
|
ground_mat = { paint: [0.12, 0.22, 0.10, 1.0], coverage: "opaque", face: "single", lamp: "lit" }
|
|
trunk_mat = { paint: [0.35, 0.23, 0.14, 1.0], coverage: "opaque", face: "single", lamp: "lit" }
|
|
canopy_mat_a = { paint: [0.11, 0.40, 0.18, 1.0], coverage: "opaque", face: "single", lamp: "lit" }
|
|
canopy_mat_b = { paint: [0.09, 0.33, 0.14, 1.0], coverage: "opaque", face: "single", lamp: "lit" }
|
|
player_mat = { paint: [0.85, 0.25, 0.20, 1.0], coverage: "opaque", face: "single", lamp: "lit" }
|
|
|
|
// Generate trees
|
|
for (var i = 0; i < num_trees; i++) {
|
|
var x = (lance3d.rand() - 0.5) * 90
|
|
var z = (lance3d.rand() - 0.5) * 90
|
|
|
|
trees.push({
|
|
x: x,
|
|
z: z,
|
|
trunk_h: lance3d.rand() * 3 + 2,
|
|
trunk_r: lance3d.rand() * 0.25 + 0.25,
|
|
canopy_s: lance3d.rand() * 1.0 + 1.5,
|
|
canopy_mat: lance3d.rand() < 0.5 ? canopy_mat_a : canopy_mat_b
|
|
})
|
|
}
|
|
|
|
last_time = time_mod.number()
|
|
frame()
|
|
}
|
|
|
|
function _update(dt) {
|
|
if (lance3d.key('escape')) {
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
// Movement input
|
|
var forward = 0
|
|
var right = 0
|
|
if (lance3d.key('w')) forward += 1
|
|
if (lance3d.key('s')) forward -= 1
|
|
if (lance3d.key('d')) right -= 1
|
|
if (lance3d.key('a')) right += 1
|
|
|
|
if (forward != 0 || right != 0) {
|
|
// Update yaw based on movement direction
|
|
player.yaw = math.arc_tangent(forward, -right)
|
|
|
|
var fx = math.sine(player.yaw)
|
|
var fz = math.cosine(player.yaw)
|
|
|
|
var len = math.sqrt(fx * fx + fz * fz)
|
|
if (len > 0) {
|
|
fx /= len
|
|
fz /= len
|
|
}
|
|
|
|
player.x += fx * player.speed * dt
|
|
player.z += fz * player.speed * dt
|
|
}
|
|
}
|
|
|
|
function _draw() {
|
|
lance3d.clear(0.55, 0.70, 0.90, 1.0)
|
|
|
|
// Set up camera following player
|
|
lance3d.camera_perspective(55, 0.1, 300)
|
|
lance3d.camera_look_at(
|
|
player.x + cam_offset.x,
|
|
cam_offset.y,
|
|
player.z + cam_offset.z,
|
|
player.x, 0, player.z
|
|
)
|
|
|
|
// Draw ground
|
|
lance3d.draw_mesh(ground_mesh, null, ground_mat)
|
|
|
|
// Draw tree trunks
|
|
for (var i = 0; i < trees.length; i++) {
|
|
var tree = trees[i]
|
|
var trunk_transform = lance3d.trs_matrix(
|
|
tree.x, tree.trunk_h / 2, tree.z,
|
|
0, 0, 0, 1,
|
|
tree.trunk_r, tree.trunk_h, tree.trunk_r
|
|
)
|
|
lance3d.draw_mesh(trunk_mesh, trunk_transform, trunk_mat)
|
|
}
|
|
|
|
// Draw tree canopies
|
|
for (var i = 0; i < trees.length; i++) {
|
|
var tree = trees[i]
|
|
var canopy_transform = lance3d.trs_matrix(
|
|
tree.x, tree.trunk_h + tree.canopy_s / 2, tree.z,
|
|
0, 0, 0, 1,
|
|
tree.canopy_s, tree.canopy_s, tree.canopy_s
|
|
)
|
|
lance3d.draw_mesh(canopy_mesh, canopy_transform, tree.canopy_mat)
|
|
}
|
|
|
|
// Draw player
|
|
var q = lance3d.euler_to_quat(0, player.yaw, 0)
|
|
var player_transform = lance3d.trs_matrix(
|
|
player.x, player.y, player.z,
|
|
q.x, q.y, q.z, q.w,
|
|
0.7, 1.0, 0.7
|
|
)
|
|
lance3d.draw_mesh(player_mesh, player_transform, player_mat)
|
|
}
|
|
|
|
function frame() {
|
|
lance3d._begin_frame()
|
|
|
|
if (!lance3d._process_events()) {
|
|
log.console("Exiting...")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var now = time_mod.number()
|
|
var dt = now - last_time
|
|
last_time = now
|
|
|
|
_update(dt)
|
|
_draw()
|
|
|
|
lance3d._end_frame()
|
|
|
|
$delay(frame, 1/60)
|
|
}
|
|
|
|
_init()
|