more examples
12
clay.cm
@@ -87,16 +87,17 @@ function annotate_tree(node, root_height, parent_node) {
|
||||
}
|
||||
|
||||
clay.layout = function(fn, size) {
|
||||
var sz = is_array(size) ? {width: size[0], height: size[1]} : size
|
||||
lay_ctx.reset()
|
||||
_next_id = 0
|
||||
var root_id = lay_ctx.item()
|
||||
|
||||
lay_ctx.set_size(root_id, size)
|
||||
lay_ctx.set_size(root_id, sz)
|
||||
lay_ctx.set_contain(root_id, layout.contain.row)
|
||||
|
||||
var root_node = {
|
||||
id: root_id,
|
||||
config: meme(base_config, {size: size}),
|
||||
config: meme(base_config, {size: sz}),
|
||||
children: []
|
||||
}
|
||||
|
||||
@@ -107,10 +108,10 @@ clay.layout = function(fn, size) {
|
||||
lay_ctx.run()
|
||||
|
||||
// Annotate tree for clay_input (boundingbox, CHILDREN, PARENT)
|
||||
annotate_tree(root_node, size.height, null)
|
||||
annotate_tree(root_node, sz.height, null)
|
||||
|
||||
// Build flat drawable list and attach to tree root
|
||||
root_node.drawables = build_drawables(root_node, size.height)
|
||||
root_node.drawables = build_drawables(root_node, sz.height)
|
||||
return root_node
|
||||
}
|
||||
|
||||
@@ -384,9 +385,10 @@ clay.button = function(str, action, configs) {
|
||||
}]
|
||||
|
||||
var _configs = is_array(configs) ? configs : [configs]
|
||||
var merged = process_configs(_configs)
|
||||
|
||||
clay.zstack(array(btn_config, _configs), function() {
|
||||
clay.text(str, {color: {r:1,g:1,b:1,a:1}})
|
||||
clay.text(str, {color: {r:1,g:1,b:1,a:1}, font_path: merged.font_path})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
45
examples/bisect.ce
Normal file
@@ -0,0 +1,45 @@
|
||||
log.console("bisect: start")
|
||||
var sprite = use('sprite')
|
||||
var clay = use('clay')
|
||||
var core = use('core')
|
||||
var fx_graph = use('fx_graph')
|
||||
var sdl_gpu = use('sdl_gpu')
|
||||
log.console("bisect: modules loaded")
|
||||
|
||||
core.start({
|
||||
width: 640,
|
||||
height: 480,
|
||||
title: "Paladin Simple",
|
||||
framerate: 60,
|
||||
update: function(dt) {},
|
||||
render: function() {
|
||||
var win_size = core.window_size()
|
||||
var graph = fx_graph.create()
|
||||
|
||||
var ui_scene = clay.layout(function() {
|
||||
clay.container({padding: 20, contain: clay.contain.content}, function() {
|
||||
clay.vstack({
|
||||
padding: 20,
|
||||
spacing: 10,
|
||||
width: 200
|
||||
}, function() {
|
||||
clay.text("PALADIN UI", {font_size: 24, color: {r:1, g:0.8, b:0.2, a:1}})
|
||||
clay.text("Item 1")
|
||||
clay.text("Item 2")
|
||||
})
|
||||
})
|
||||
}, [win_size.width, win_size.height])
|
||||
|
||||
graph.add_node('render_view', {
|
||||
root: ui_scene,
|
||||
camera: {pos: [0, 0], width: win_size.width, height: win_size.height, anchor: [0, 0], ortho: true},
|
||||
target: 'screen',
|
||||
clear_color: {r:0,g:0,b:0,a:0}
|
||||
})
|
||||
|
||||
return graph
|
||||
},
|
||||
input: function(ev) {
|
||||
if (ev.type == 'quit') $stop()
|
||||
}
|
||||
})
|
||||
BIN
examples/bunny.png
Normal file
|
After Width: | Height: | Size: 449 B |
BIN
examples/enemies/barnacle_attack_a.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/enemies/barnacle_attack_b.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/enemies/barnacle_attack_rest.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/enemies/bee_a.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/bee_b.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/enemies/bee_rest.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/block_fall.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/enemies/block_idle.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/block_rest.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/fish_blue_rest.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/enemies/fish_blue_swim_a.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/fish_blue_swim_b.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/fish_purple_down.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/fish_purple_rest.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/fish_purple_up.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/fish_yellow_rest.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/fish_yellow_swim_a.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/fish_yellow_swim_b.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/enemies/fly_a.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/enemies/fly_b.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/fly_rest.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/enemies/frog_idle.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/enemies/frog_jump.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/enemies/frog_rest.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/enemies/ladybug_fly.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/enemies/ladybug_rest.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/ladybug_walk_a.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/ladybug_walk_b.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/mouse_rest.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/enemies/mouse_walk_a.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/mouse_walk_b.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/saw_a.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
examples/enemies/saw_b.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/enemies/saw_rest.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
examples/enemies/slime_block_jump.png
Normal file
|
After Width: | Height: | Size: 764 B |
BIN
examples/enemies/slime_block_rest.png
Normal file
|
After Width: | Height: | Size: 685 B |
BIN
examples/enemies/slime_block_walk_a.png
Normal file
|
After Width: | Height: | Size: 767 B |
BIN
examples/enemies/slime_block_walk_b.png
Normal file
|
After Width: | Height: | Size: 760 B |
BIN
examples/enemies/slime_fire_flat.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/enemies/slime_fire_rest.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/slime_fire_walk_a.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/slime_fire_walk_b.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/slime_normal_flat.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
examples/enemies/slime_normal_rest.png
Normal file
|
After Width: | Height: | Size: 905 B |
BIN
examples/enemies/slime_normal_walk_a.png
Normal file
|
After Width: | Height: | Size: 972 B |
BIN
examples/enemies/slime_normal_walk_b.png
Normal file
|
After Width: | Height: | Size: 920 B |
BIN
examples/enemies/slime_spike_flat.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
examples/enemies/slime_spike_rest.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/slime_spike_walk_a.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/slime_spike_walk_b.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/enemies/snail_rest.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/snail_shell.png
Normal file
|
After Width: | Height: | Size: 939 B |
BIN
examples/enemies/snail_walk_a.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/snail_walk_b.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/enemies/worm_normal_move_a.png
Normal file
|
After Width: | Height: | Size: 1007 B |
BIN
examples/enemies/worm_normal_move_b.png
Normal file
|
After Width: | Height: | Size: 989 B |
BIN
examples/enemies/worm_normal_rest.png
Normal file
|
After Width: | Height: | Size: 690 B |
BIN
examples/enemies/worm_ring_move_a.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
examples/enemies/worm_ring_move_b.png
Normal file
|
After Width: | Height: | Size: 1012 B |
BIN
examples/enemies/worm_ring_rest.png
Normal file
|
After Width: | Height: | Size: 840 B |
BIN
examples/fonts/c64.ttf
Normal file
BIN
examples/fonts/dos.ttf
Normal file
BIN
examples/fonts/teenytinypixels.ttf
Normal file
303
examples/paladin.ce
Normal file
@@ -0,0 +1,303 @@
|
||||
log.console("paladin game starting")
|
||||
|
||||
var time = use('time')
|
||||
var random = use('random').random
|
||||
|
||||
var core = use('core')
|
||||
var sprite = use('sprite')
|
||||
var text2d = use('text2d')
|
||||
var particles2d = use('particles2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var tilemap2d = use('tilemap2d')
|
||||
var clay = use('clay')
|
||||
|
||||
var sprites = [] // Keep references for cleanup
|
||||
var emitters = [] // Particle emitters
|
||||
var bunnies = [] // Bouncing bunnies for Y-sort test
|
||||
|
||||
// Cameras
|
||||
var world_camera = {
|
||||
pos: {x: 2.5, y: 2.5},
|
||||
width: 5,
|
||||
height: 5,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var hud_camera = {
|
||||
pos: {x: 0, y: 0},
|
||||
width: 640,
|
||||
height: 360,
|
||||
anchor: {x: 0, y: 0}
|
||||
}
|
||||
|
||||
// Group effects definition - THIS IS THE KEY PART
|
||||
var group_effects = {
|
||||
'bloom': {
|
||||
effects: [{type: 'bloom', threshold: 0.1, intensity: 5, blur_passes: 1}]
|
||||
},
|
||||
'masked_fire': {
|
||||
effects: [
|
||||
{type: 'bloom', threshold: 0.1, intensity: 5, blur_passes: 0},
|
||||
{type: 'mask', channel: 'alpha', mask_group: 'mask_text'}
|
||||
]
|
||||
},
|
||||
'corner_fire': {
|
||||
effects: [{type: 'mask', channel: 'alpha', mask_group: 'corner_mask'}]
|
||||
}
|
||||
}
|
||||
|
||||
// Compositor config - pure data
|
||||
var compositor_config = {
|
||||
clear: {r: 0, g: 0, b: 0, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'world',
|
||||
plane: 'world',
|
||||
camera: world_camera,
|
||||
resolution: {width: 500, height: 500},
|
||||
presentation: 'letterbox',
|
||||
clear: {r: 0.1, g: 0.1, b: 0.9, a: 1}
|
||||
},
|
||||
{
|
||||
name: 'hud',
|
||||
plane: 'hud',
|
||||
camera: hud_camera,
|
||||
resolution: {width: 640, height: 360},
|
||||
presentation: 'integer_scale',
|
||||
clear: {r: 0, g: 0, b: 0, a: 0},
|
||||
layer_sort: {
|
||||
'100': 'y' // Bunny layer uses Y-sort
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ui',
|
||||
plane: 'ui',
|
||||
camera: hud_camera,
|
||||
resolution: {width: 640, height: 360},
|
||||
presentation: 'integer_scale',
|
||||
clear: null
|
||||
}
|
||||
],
|
||||
group_effects
|
||||
}
|
||||
|
||||
function init_game() {
|
||||
// Cleanup old sprites
|
||||
var i = 0
|
||||
for (i = 0; i < length(sprites); i++)
|
||||
sprites[i].destroy()
|
||||
sprites = []
|
||||
emitters = []
|
||||
bunnies = []
|
||||
|
||||
// World sprites
|
||||
|
||||
// Background Tilemap
|
||||
var tiles = []
|
||||
var x = 0
|
||||
var y = 0
|
||||
for (x = 0; x < 5; x++) {
|
||||
tiles[x] = []
|
||||
for (y = 0; y < 5; y++) {
|
||||
tiles[x][y] = 'examples/tiles/terrain_dirt_cloud'
|
||||
}
|
||||
}
|
||||
|
||||
sprites[] = tilemap2d({
|
||||
plane: 'world',
|
||||
layer: 0,
|
||||
tiles: tiles,
|
||||
tile_width: 1,
|
||||
tile_height: 1,
|
||||
offset_x: 0,
|
||||
offset_y: 0
|
||||
})
|
||||
|
||||
sprites[] = sprite({
|
||||
plane: 'world',
|
||||
layer: 10,
|
||||
image: 'examples/enemies/saw_a',
|
||||
pos: {x: 1, y: 1},
|
||||
anchor_x: 0.5,
|
||||
})
|
||||
|
||||
// HUD sprites
|
||||
sprites[] = text2d({
|
||||
plane: 'hud',
|
||||
groups: ['mask_text'], // Effect routing only
|
||||
layer: 50,
|
||||
text: 'PALADIN',
|
||||
pos: {x: 640/2 - 270, y: 360/2},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 150
|
||||
})
|
||||
|
||||
var masked_fire = particles2d.create({
|
||||
plane: 'hud',
|
||||
groups: ['masked_fire'], // Effect routing only
|
||||
layer: 40,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 40,
|
||||
height: 40
|
||||
})
|
||||
sprites[] = masked_fire
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 320, y: 180},
|
||||
spawn_area: {width: 500, height: 200},
|
||||
velocity: {x: 0, y: 50},
|
||||
velocity_var: {x: 30, y: 30},
|
||||
life: 2,
|
||||
rate: 60,
|
||||
scale: 3,
|
||||
scale_var: 0.3,
|
||||
color: {r: 1, g: 0.6, b: 0.2},
|
||||
handle: masked_fire
|
||||
})
|
||||
|
||||
sprites[] = sprite({
|
||||
plane: 'hud',
|
||||
groups: ['corner_mask'], // Effect routing only
|
||||
layer: 60,
|
||||
image: 'examples/tiles/fireball',
|
||||
pos: {x: 600, y: 40},
|
||||
width: 50,
|
||||
height: 50,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5
|
||||
})
|
||||
|
||||
var corner_fire = particles2d.create({
|
||||
plane: 'hud',
|
||||
groups: ['corner_fire'], // Effect routing only
|
||||
layer: 70,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 25,
|
||||
height: 25
|
||||
})
|
||||
sprites[] = corner_fire
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 600, y: 40},
|
||||
spawn_area: {width: 30, height: 30},
|
||||
velocity: {x: 0, y: 30},
|
||||
velocity_var: {x: 20, y: 20},
|
||||
life: 1.5,
|
||||
rate: 10,
|
||||
scale: 1,
|
||||
scale_var: 0.2,
|
||||
color: {r: 1, g: 0.5, b: 0.1},
|
||||
handle: corner_fire
|
||||
})
|
||||
|
||||
var bloom_fire = particles2d.create({
|
||||
plane: 'hud',
|
||||
groups: ['bloom'], // Effect routing only
|
||||
layer: 80,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 48,
|
||||
height: 48
|
||||
})
|
||||
sprites[] = bloom_fire
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 100, y: 100},
|
||||
spawn_area: {width: 50, height: 50},
|
||||
velocity: {x: 100, y: 0},
|
||||
velocity_var: {x: 40, y: 40},
|
||||
life: 2.5,
|
||||
rate: 12,
|
||||
scale: 1.2,
|
||||
scale_var: 0.4,
|
||||
color: {r: 1, g: 0.8, b: 0.3},
|
||||
handle: bloom_fire
|
||||
})
|
||||
|
||||
// Bouncing bunnies - exactly two, big, bottom of screen, Y-sort layer 100
|
||||
var bunny = null
|
||||
for (i = 0; i < 2; i++) {
|
||||
bunny = sprite({
|
||||
plane: 'hud',
|
||||
layer: 100, // This layer has Y-sort enabled
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 320 + (i == 0 ? -20 : 20), y: 340},
|
||||
width: 96,
|
||||
height: 96,
|
||||
anchor_x: 0.5,
|
||||
})
|
||||
|
||||
bunny._base_y = 340
|
||||
bunny._t = i * 0.7 // phase offset so they don’t match
|
||||
bunny._amp = 240 // bounce height in pixels
|
||||
bunny._speed = 1 * random() // bounce speed
|
||||
sprites[] = bunny
|
||||
bunnies[] = bunny
|
||||
}
|
||||
|
||||
|
||||
log.console("World initialized - " + text(length(film2d.query({}))) + " drawables")
|
||||
}
|
||||
var json = use('json')
|
||||
var last_time = 0
|
||||
|
||||
function update(dt) {
|
||||
// Update all particle emitters
|
||||
var i = 0
|
||||
for (i = 0; i < length(emitters); i++)
|
||||
particles2d.emitters.update(emitters[i], dt)
|
||||
|
||||
// Update bouncing bunnies
|
||||
// Update bouncing bunnies (vertical bob only)
|
||||
var b = null
|
||||
var cycle = null
|
||||
var u = null
|
||||
for (i = 0; i < length(bunnies); i++) {
|
||||
b = bunnies[i]
|
||||
b._t += dt
|
||||
|
||||
// Bob between base_y and base_y - amp using triangle wave
|
||||
cycle = (b._t * b._speed) % 2
|
||||
u = cycle < 1 ? cycle : 2 - cycle
|
||||
b.pos.y = b._base_y - u * b._amp
|
||||
|
||||
// Optional: if your Y-sort uses an explicit key, keep it in sync
|
||||
// b.y_sort_key = b.pos.y
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
// 1. Build Clay UI
|
||||
var clay_tree = clay.layout(function() {
|
||||
clay.vstack({gap: 10, padding: 20, align: 'center'}, function() {
|
||||
clay.text("Clay UI Sample", {font_size: 24, color: {r:1,g:1,b:0}})
|
||||
clay.image('examples/tiles/key_blue', {size:{width:32,height:32}, color: {r:1,g:0,b:0}})
|
||||
clay.container({size: [200, 100], background_color: {r:0.2, g:0.2, b:0.2, a:0.8}, padding: 10}, function() {
|
||||
clay.vstack(function() {
|
||||
clay.text("List Item 1")
|
||||
clay.text("List Item 2")
|
||||
clay.text("List Item 3")
|
||||
})
|
||||
})
|
||||
})
|
||||
}, {width: 640, height: 360})
|
||||
|
||||
// Assign clay drawables to UI plane
|
||||
compositor_config.planes[2].drawables = clay_tree.drawables
|
||||
compositor_config.planes[2].clear = {r: 0, g: 0, b: 0, a: 0}
|
||||
|
||||
var plan = compositor.compile(compositor_config)
|
||||
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init_game()
|
||||
|
||||
core.start({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
title: "Paladin - Data Oriented",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render,
|
||||
editor: function(ui) {
|
||||
}
|
||||
})
|
||||
99
examples/paladin_simple.ce
Normal file
@@ -0,0 +1,99 @@
|
||||
// paladin_simple.ce - Simple test for prosperon rendering
|
||||
|
||||
log.console("paladin simple test starting")
|
||||
|
||||
var sprite = use('sprite')
|
||||
var clay = use('clay')
|
||||
var core = use('core')
|
||||
var fx_graph = use('fx_graph')
|
||||
var sdl_gpu = use('sdl_gpu')
|
||||
|
||||
var fcfg = {font_path: 'examples/fonts/dos'}
|
||||
|
||||
core.start({
|
||||
width: 640,
|
||||
height: 480,
|
||||
title: "Paladin Simple",
|
||||
framerate: 60,
|
||||
update: function(dt) {},
|
||||
render: build_render_graph,
|
||||
input: function(ev) {
|
||||
if (ev.type == 'quit') $stop()
|
||||
}
|
||||
})
|
||||
|
||||
function build_render_graph() {
|
||||
var win_size = core.window_size()
|
||||
var graph = fx_graph.create()
|
||||
|
||||
// Simple sprite scene
|
||||
var scene = {
|
||||
type: 'group',
|
||||
children: [{
|
||||
type: 'sprite',
|
||||
image: 'examples/tiles/fireball',
|
||||
pos: {x: win_size.width / 2, y: win_size.height / 2},
|
||||
width: win_size.height / 2, // Half screen height
|
||||
height: win_size.height / 2,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
}]
|
||||
}
|
||||
|
||||
var camera = {
|
||||
pos: [0, 0],
|
||||
width: win_size.width,
|
||||
height: win_size.height,
|
||||
anchor: [0, 0],
|
||||
ortho: true,
|
||||
background: {r: 0.2, g: 0.2, b: 0.3, a: 1}
|
||||
}
|
||||
|
||||
// Render to screen
|
||||
|
||||
var ui_scene = clay.layout(function() {
|
||||
clay.container({padding: 20, contain: clay.contain.content}, function() {
|
||||
// Top-left HUD panel
|
||||
clay.vstack({
|
||||
background_image: 'examples/tiles/brick_brown',
|
||||
slice: 0.33,
|
||||
padding: 20,
|
||||
spacing: 10,
|
||||
width: 200
|
||||
}, function() {
|
||||
clay.text("PALADIN UI", [{font_size: 24, color: {r:1, g:0.8, b:0.2, a:1}}, fcfg])
|
||||
|
||||
clay.hstack({spacing: 10}, function() {
|
||||
clay.image('examples/tiles/hud_heart', {width: 24, height: 24})
|
||||
clay.text("x 3", [{font_size: 20}, fcfg])
|
||||
})
|
||||
|
||||
clay.button("PAUSE", function() { log.console("Pause clicked") }, fcfg)
|
||||
|
||||
// Scissored scroll area test
|
||||
clay.container({
|
||||
width: 160, height: 60,
|
||||
background_color: {r:0, g:0, b:0, a:0.5},
|
||||
clipped: true
|
||||
}, function() {
|
||||
clay.vstack({offset: {x:0, y: -10}}, function() {
|
||||
clay.text("Item 1", fcfg)
|
||||
clay.text("Item 2", fcfg)
|
||||
clay.text("Item 3", fcfg)
|
||||
clay.text("Item 4", fcfg)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}, {width: win_size.width, height: win_size.height})
|
||||
|
||||
graph.add_node('render_view', {
|
||||
root: ui_scene,
|
||||
camera: {pos: [0, 0], width: win_size.width, height: win_size.height, anchor: [0, 0], ortho: true},
|
||||
target: 'screen',
|
||||
clear_color: {r:0,g:0,b:0,a:0} // Cleared transparent
|
||||
})
|
||||
|
||||
return graph
|
||||
}
|
||||
BIN
examples/rope.jpg
Normal file
|
After Width: | Height: | Size: 256 KiB |
315
examples/test_line2d.ce
Normal file
@@ -0,0 +1,315 @@
|
||||
log.console("test_line2d starting")
|
||||
|
||||
var time = use('time')
|
||||
|
||||
var core = use('core')
|
||||
var line2d = use('line2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var lines = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 400, y: 300},
|
||||
width: 800,
|
||||
height: 600,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 800, height: 600},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Row 1: Basic lines with different widths
|
||||
|
||||
// Thin line
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 50, y: 550}, {x: 150, y: 520}, {x: 200, y: 560}],
|
||||
width: 4,
|
||||
tint: {r: 1, g: 0.3, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
// Medium line
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 250, y: 550}, {x: 350, y: 520}, {x: 400, y: 560}],
|
||||
width: 12,
|
||||
tint: {r: 0.3, g: 1, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
// Thick line
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 450, y: 550}, {x: 550, y: 520}, {x: 600, y: 560}],
|
||||
width: 24,
|
||||
tint: {r: 0.3, g: 0.3, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Variable width line
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 650, y: 560}, {x: 700, y: 520}, {x: 750, y: 560}],
|
||||
widths: [8, 24, 8],
|
||||
tint: {r: 1, g: 1, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
// Row 2: Textured ropes with different UV modes
|
||||
|
||||
// Rope with repeat UV (default for ropes)
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 50, y: 450}, {x: 120, y: 420}, {x: 200, y: 440}, {x: 280, y: 400}],
|
||||
width: 20,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'repeat',
|
||||
u_per_unit: 1 / 32
|
||||
}
|
||||
})
|
||||
|
||||
// Rope with stretch UV
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 320, y: 450}, {x: 400, y: 420}, {x: 480, y: 440}, {x: 560, y: 400}],
|
||||
width: 20,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'stretch'
|
||||
}
|
||||
})
|
||||
|
||||
// Rope with per-segment UV
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 600, y: 450}, {x: 660, y: 420}, {x: 720, y: 440}, {x: 780, y: 400}],
|
||||
width: 20,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'per_segment'
|
||||
}
|
||||
})
|
||||
|
||||
// Row 3: Cap styles
|
||||
|
||||
// Butt cap (default)
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 80, y: 320}, {x: 180, y: 320}],
|
||||
width: 20,
|
||||
cap: 'butt',
|
||||
tint: {r: 0.8, g: 0.5, b: 0.2, a: 1}
|
||||
})
|
||||
|
||||
// Square cap
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 250, y: 320}, {x: 350, y: 320}],
|
||||
width: 20,
|
||||
cap: 'square',
|
||||
tint: {r: 0.5, g: 0.8, b: 0.2, a: 1}
|
||||
})
|
||||
|
||||
// Round cap
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 420, y: 320}, {x: 520, y: 320}],
|
||||
width: 20,
|
||||
cap: 'round',
|
||||
tint: {r: 0.2, g: 0.5, b: 0.8, a: 1}
|
||||
})
|
||||
|
||||
// Round cap with texture
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 590, y: 320}, {x: 750, y: 320}],
|
||||
width: 24,
|
||||
cap: 'round',
|
||||
image: 'examples/rope'
|
||||
})
|
||||
|
||||
// Row 4: Complex paths
|
||||
|
||||
// Wavy line (will be animated)
|
||||
var wave_points = []
|
||||
var i = 0
|
||||
for (i = 0; i < 12; i++) {
|
||||
wave_points[] = {
|
||||
x: 50 + i * 30,
|
||||
y: 220 + math.sine(i * 0.8) * 30
|
||||
}
|
||||
}
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: wave_points,
|
||||
width: 14,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'repeat',
|
||||
u_per_unit: 1 / 24
|
||||
}
|
||||
})
|
||||
|
||||
// Spiral/coil
|
||||
var spiral_points = []
|
||||
var angle = null
|
||||
var radius = null
|
||||
for (i = 0; i < 20; i++) {
|
||||
angle = i * 0.5
|
||||
radius = 20 + i * 3
|
||||
spiral_points[] = {
|
||||
x: 550 + math.cosine(angle) * radius,
|
||||
y: 200 + math.sine(angle) * radius
|
||||
}
|
||||
}
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: spiral_points,
|
||||
width: 10,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'repeat',
|
||||
u_per_unit: 1 / 20
|
||||
}
|
||||
})
|
||||
|
||||
// Row 5: Closed shapes and special cases
|
||||
|
||||
// Closed triangle
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 80, y: 80}, {x: 140, y: 140}, {x: 20, y: 140}],
|
||||
width: 8,
|
||||
closed: true,
|
||||
tint: {r: 1, g: 0.5, b: 0.8, a: 1}
|
||||
})
|
||||
|
||||
// Closed pentagon
|
||||
var pent_points = []
|
||||
for (i = 0; i < 5; i++) {
|
||||
angle = i * (2 * 3.14159 / 5) - 3.14159 / 2
|
||||
pent_points[] = {
|
||||
x: 220 + math.cosine(angle) * 50,
|
||||
y: 110 + math.sine(angle) * 50
|
||||
}
|
||||
}
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: pent_points,
|
||||
width: 10,
|
||||
closed: true,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'repeat',
|
||||
u_per_unit: 1 / 30
|
||||
}
|
||||
})
|
||||
|
||||
// Animated rope (will swing)
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 1,
|
||||
points: [{x: 400, y: 50}, {x: 400, y: 100}, {x: 400, y: 150}],
|
||||
width: 16,
|
||||
image: 'examples/rope',
|
||||
uv: {
|
||||
mode: 'repeat',
|
||||
u_per_unit: 1 / 20
|
||||
}
|
||||
})
|
||||
|
||||
// Fuse/wire with opacity gradient (simulated via tint)
|
||||
lines[] = line2d.polyline({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
points: [{x: 500, y: 80}, {x: 580, y: 60}, {x: 660, y: 100}, {x: 740, y: 70}],
|
||||
width: 8,
|
||||
image: 'examples/rope',
|
||||
opacity: 0.7,
|
||||
tint: {r: 1, g: 0.8, b: 0.4, a: 1}
|
||||
})
|
||||
|
||||
log.console("test_line2d initialized with " + text(length(lines)) + " lines")
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Animate the wavy line (index 11)
|
||||
var pts = null
|
||||
var i = 0
|
||||
if (lines[11]) {
|
||||
pts = lines[11].points
|
||||
for (i = 0; i < length(pts); i++) {
|
||||
pts[i].y = 220 + math.sine(i * 0.8 + t * 2) * 30
|
||||
}
|
||||
lines[11].set_points(pts)
|
||||
}
|
||||
|
||||
// Animate the hanging rope (index 15) - swing like a pendulum
|
||||
var swing = null
|
||||
if (lines[15]) {
|
||||
swing = math.sine(t * 1.5) * 40
|
||||
pts = [
|
||||
{x: 400, y: 50},
|
||||
{x: 400 + swing * 0.5, y: 100},
|
||||
{x: 400 + swing, y: 150}
|
||||
]
|
||||
lines[15].set_points(pts)
|
||||
}
|
||||
|
||||
// Animate UV offset on the spiral (index 12) for scrolling texture effect
|
||||
if (lines[12]) {
|
||||
lines[12].uv.u_offset = t * 0.5
|
||||
lines[12]._rebuild()
|
||||
}
|
||||
|
||||
// Pulse opacity on the fuse (index 16)
|
||||
if (lines[16]) {
|
||||
lines[16].opacity = 0.5 + 0.5 * math.sine(t * 3)
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 800,
|
||||
height: 600,
|
||||
title: "Test Line2D - Ropes and Lines",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
301
examples/test_particles.ce
Normal file
@@ -0,0 +1,301 @@
|
||||
log.console("test_particles starting")
|
||||
|
||||
var time = use('time')
|
||||
var random = use('random').random
|
||||
|
||||
var core = use('core')
|
||||
var particles2d = use('particles2d')
|
||||
var text2d = use('text2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var particle_handles = []
|
||||
var emitters = []
|
||||
var labels = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 250, y: 250},
|
||||
width: 500,
|
||||
height: 500,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.05, g: 0.05, b: 0.1, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 500, height: 500},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.05, g: 0.05, b: 0.1, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Emitter 1: Normal particles (top-left)
|
||||
var handle1 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 20,
|
||||
height: 20
|
||||
})
|
||||
particle_handles[] = handle1
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 100, y: 400},
|
||||
spawn_area: {width: 30, height: 10},
|
||||
velocity: {x: 0, y: 50},
|
||||
velocity_var: {x: 20, y: 10},
|
||||
life: 2,
|
||||
rate: 15,
|
||||
scale: 1,
|
||||
scale_var: 0.2,
|
||||
color: {r: 1, g: 0.8, b: 0.3},
|
||||
handle: handle1
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Normal",
|
||||
pos: {x: 70, y: 480},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 2: Half opacity (top-center)
|
||||
var handle2 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 20,
|
||||
height: 20,
|
||||
opacity: 0.5
|
||||
})
|
||||
particle_handles[] = handle2
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 250, y: 400},
|
||||
spawn_area: {width: 30, height: 10},
|
||||
velocity: {x: 0, y: 50},
|
||||
velocity_var: {x: 20, y: 10},
|
||||
life: 2,
|
||||
rate: 15,
|
||||
scale: 1,
|
||||
scale_var: 0.2,
|
||||
color: {r: 1, g: 0.8, b: 0.3},
|
||||
handle: handle2
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Opacity 0.5",
|
||||
pos: {x: 210, y: 480},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 3: Red tint (top-right)
|
||||
var handle3 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 20,
|
||||
height: 20,
|
||||
tint: {r: 1, g: 0.2, b: 0.2, a: 1}
|
||||
})
|
||||
particle_handles[] = handle3
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 400, y: 400},
|
||||
spawn_area: {width: 30, height: 10},
|
||||
velocity: {x: 0, y: 50},
|
||||
velocity_var: {x: 20, y: 10},
|
||||
life: 2,
|
||||
rate: 15,
|
||||
scale: 1,
|
||||
scale_var: 0.2,
|
||||
color: {r: 1, g: 0.8, b: 0.3},
|
||||
handle: handle3
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Red Tint",
|
||||
pos: {x: 370, y: 480},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 4: Blue tint (bottom-left)
|
||||
var handle4 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 24,
|
||||
height: 24,
|
||||
tint: {r: 0.3, g: 0.5, b: 1, a: 1}
|
||||
})
|
||||
particle_handles[] = handle4
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 100, y: 200},
|
||||
spawn_area: {width: 40, height: 10},
|
||||
velocity: {x: 0, y: 60},
|
||||
velocity_var: {x: 30, y: 15},
|
||||
life: 2.5,
|
||||
rate: 20,
|
||||
scale: 1.2,
|
||||
scale_var: 0.3,
|
||||
color: {r: 1, g: 1, b: 1},
|
||||
handle: handle4
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Blue Tint",
|
||||
pos: {x: 70, y: 280},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 5: Green tint + opacity (bottom-center)
|
||||
var handle5 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 24,
|
||||
height: 24,
|
||||
tint: {r: 0.3, g: 1, b: 0.3, a: 1},
|
||||
opacity: 0.7
|
||||
})
|
||||
particle_handles[] = handle5
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 250, y: 200},
|
||||
spawn_area: {width: 40, height: 10},
|
||||
velocity: {x: 0, y: 60},
|
||||
velocity_var: {x: 30, y: 15},
|
||||
life: 2.5,
|
||||
rate: 20,
|
||||
scale: 1.2,
|
||||
scale_var: 0.3,
|
||||
color: {r: 1, g: 1, b: 1},
|
||||
handle: handle5
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Green + 70%",
|
||||
pos: {x: 210, y: 280},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 6: Animated tint (bottom-right)
|
||||
var handle6 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 24,
|
||||
height: 24,
|
||||
tint: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
particle_handles[] = handle6
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 400, y: 200},
|
||||
spawn_area: {width: 40, height: 10},
|
||||
velocity: {x: 0, y: 60},
|
||||
velocity_var: {x: 30, y: 15},
|
||||
life: 2.5,
|
||||
rate: 20,
|
||||
scale: 1.2,
|
||||
scale_var: 0.3,
|
||||
color: {r: 1, g: 1, b: 1},
|
||||
handle: handle6
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Rainbow",
|
||||
pos: {x: 370, y: 280},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Emitter 7: Animated opacity (center)
|
||||
var handle7 = particles2d.create({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/tiles/fireball',
|
||||
width: 32,
|
||||
height: 32,
|
||||
opacity: 1
|
||||
})
|
||||
particle_handles[] = handle7
|
||||
emitters[] = particles2d.emitters.create({
|
||||
pos: {x: 250, y: 80},
|
||||
spawn_area: {width: 60, height: 20},
|
||||
velocity: {x: 0, y: 40},
|
||||
velocity_var: {x: 40, y: 20},
|
||||
life: 3,
|
||||
rate: 25,
|
||||
scale: 1.5,
|
||||
scale_var: 0.4,
|
||||
color: {r: 1, g: 0.6, b: 0.2},
|
||||
handle: handle7
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Pulsing Opacity",
|
||||
pos: {x: 180, y: 20},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 0, a: 1}
|
||||
})
|
||||
|
||||
log.console("test_particles initialized with " + text(length(emitters)) + " emitters")
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Update all emitters
|
||||
var i = 0
|
||||
for (i = 0; i < length(emitters); i++) {
|
||||
particles2d.emitters.update(emitters[i], dt)
|
||||
}
|
||||
|
||||
// Animate rainbow tint on emitter 6
|
||||
var rainbow_handle = particle_handles[5]
|
||||
rainbow_handle.tint.r = 0.5 + 0.5 * math.sine(t * 2)
|
||||
rainbow_handle.tint.g = 0.5 + 0.5 * math.sine(t * 2 + 2.094)
|
||||
rainbow_handle.tint.b = 0.5 + 0.5 * math.sine(t * 2 + 4.188)
|
||||
|
||||
// Animate pulsing opacity on emitter 7
|
||||
var pulsing_handle = particle_handles[6]
|
||||
pulsing_handle.opacity = 0.3 + 0.7 * abs(math.sine(t * 1.5))
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 500,
|
||||
height: 500,
|
||||
title: "Test Particles Features",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
352
examples/test_shape2d.ce
Normal file
@@ -0,0 +1,352 @@
|
||||
log.console("test_shape2d starting")
|
||||
|
||||
var time = use('time')
|
||||
|
||||
var core = use('core')
|
||||
var shape2d = use('shape2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var shapes = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 400, y: 300},
|
||||
width: 800,
|
||||
height: 600,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 800, height: 600},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Row 1: Basic shapes - rect, circle, ellipse, pill
|
||||
|
||||
// Rectangle with rounded corners
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 100, y: 500},
|
||||
width: 120,
|
||||
height: 80,
|
||||
radius: 10,
|
||||
fill: {r: 0.2, g: 0.6, b: 0.9, a: 1}
|
||||
})
|
||||
|
||||
// Circle
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 250, y: 500},
|
||||
radius: 50,
|
||||
fill: {r: 0.9, g: 0.3, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
// Ellipse
|
||||
shapes[] = shape2d.ellipse({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 400, y: 500},
|
||||
width: 140,
|
||||
height: 80,
|
||||
fill: {r: 0.3, g: 0.9, b: 0.4, a: 1}
|
||||
})
|
||||
|
||||
// Pill (stadium)
|
||||
shapes[] = shape2d.pill({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 550, y: 500},
|
||||
width: 140,
|
||||
height: 60,
|
||||
fill: {r: 0.9, g: 0.7, b: 0.2, a: 1}
|
||||
})
|
||||
|
||||
// Row 2: Stroke variations
|
||||
|
||||
// Rect with stroke only
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 100, y: 380},
|
||||
width: 100,
|
||||
height: 80,
|
||||
radius: 5,
|
||||
fill: {r: 0, g: 0, b: 0, a: 0},
|
||||
stroke: {r: 1, g: 1, b: 1, a: 1},
|
||||
stroke_thickness: 3,
|
||||
stroke_align: 'center',
|
||||
dash_len: 14,
|
||||
gap_len: 6
|
||||
})
|
||||
|
||||
// Circle with thick stroke
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 250, y: 380},
|
||||
radius: 45,
|
||||
fill: {r: 0.2, g: 0.2, b: 0.3, a: 1},
|
||||
stroke: {r: 0.5, g: 0.8, b: 1, a: 1},
|
||||
stroke_thickness: 6,
|
||||
stroke_align: 'outside',
|
||||
dash_len: 14,
|
||||
gap_len: 6
|
||||
})
|
||||
|
||||
// Ellipse with inside stroke
|
||||
shapes[] = shape2d.ellipse({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 400, y: 380},
|
||||
width: 120,
|
||||
height: 70,
|
||||
fill: {r: 0.4, g: 0.2, b: 0.5, a: 1},
|
||||
stroke: {r: 1, g: 0.5, b: 0.8, a: 1},
|
||||
stroke_thickness: 4,
|
||||
stroke_align: 'inside',
|
||||
dash_len: 14,
|
||||
gap_len: 6
|
||||
})
|
||||
|
||||
// Pill with dashed stroke
|
||||
shapes[] = shape2d.pill({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 550, y: 380},
|
||||
width: 130,
|
||||
height: 50,
|
||||
fill: {r: 0.1, g: 0.3, b: 0.2, a: 1},
|
||||
stroke: {r: 0.3, g: 1, b: 0.5, a: 1},
|
||||
stroke_thickness: 3,
|
||||
dash_len: 15,
|
||||
gap_len: 8
|
||||
})
|
||||
|
||||
// Row 3: Feather / soft edges
|
||||
|
||||
// Soft rect
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 100, y: 260},
|
||||
width: 100,
|
||||
height: 80,
|
||||
radius: 20,
|
||||
fill: {r: 0.8, g: 0.4, b: 0.1, a: 1},
|
||||
feather: 10
|
||||
})
|
||||
|
||||
// Soft circle (glow effect)
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 250, y: 260},
|
||||
radius: 40,
|
||||
fill: {r: 1, g: 0.9, b: 0.3, a: 1},
|
||||
feather: 20
|
||||
})
|
||||
|
||||
// Soft ellipse
|
||||
shapes[] = shape2d.ellipse({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 400, y: 260},
|
||||
width: 120,
|
||||
height: 60,
|
||||
fill: {r: 0.3, g: 0.5, b: 1, a: 0.8},
|
||||
feather: 15
|
||||
})
|
||||
|
||||
// Sharp vs soft comparison
|
||||
shapes[] = shape2d.pill({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 550, y: 260},
|
||||
width: 120,
|
||||
height: 50,
|
||||
fill: {r: 1, g: 0.2, b: 0.6, a: 1},
|
||||
feather: 5
|
||||
})
|
||||
|
||||
// Row 4: Opacity and blending
|
||||
|
||||
// Semi-transparent overlapping shapes
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 80, y: 130},
|
||||
width: 100,
|
||||
height: 80,
|
||||
fill: {r: 1, g: 0, b: 0, a: 0.6},
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 1,
|
||||
pos: {x: 120, y: 130},
|
||||
width: 100,
|
||||
height: 80,
|
||||
fill: {r: 0, g: 1, b: 0, a: 0.6},
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 2,
|
||||
pos: {x: 100, y: 150},
|
||||
width: 100,
|
||||
height: 80,
|
||||
fill: {r: 0, g: 0, b: 1, a: 0.6},
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
// Animated opacity circle
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 280, y: 130},
|
||||
radius: 50,
|
||||
fill: {r: 1, g: 1, b: 1, a: 1},
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
// Different corner radii
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 420, y: 130},
|
||||
width: 100,
|
||||
height: 80,
|
||||
radius: 0,
|
||||
fill: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
})
|
||||
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 540, y: 130},
|
||||
width: 100,
|
||||
height: 80,
|
||||
radius: 20,
|
||||
fill: {r: 0.6, g: 0.6, b: 0.6, a: 1}
|
||||
})
|
||||
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 660, y: 130},
|
||||
width: 100,
|
||||
height: 80,
|
||||
radius: 40,
|
||||
fill: {r: 0.7, g: 0.7, b: 0.7, a: 1}
|
||||
})
|
||||
|
||||
// Row 5: Large decorative shapes
|
||||
|
||||
// Background panel
|
||||
shapes[] = shape2d.rect({
|
||||
plane: 'main',
|
||||
layer: -1,
|
||||
pos: {x: 700, y: 400},
|
||||
width: 160,
|
||||
height: 350,
|
||||
radius: 15,
|
||||
fill: {r: 0.15, g: 0.15, b: 0.2, a: 1},
|
||||
stroke: {r: 0.3, g: 0.3, b: 0.4, a: 1},
|
||||
stroke_thickness: 2
|
||||
})
|
||||
|
||||
// Decorative circles inside panel
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 700, y: 500},
|
||||
radius: 30,
|
||||
fill: {r: 0.8, g: 0.2, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 700, y: 420},
|
||||
radius: 25,
|
||||
fill: {r: 0.2, g: 0.8, b: 0.3, a: 1}
|
||||
})
|
||||
|
||||
shapes[] = shape2d.circle({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
pos: {x: 700, y: 350},
|
||||
radius: 20,
|
||||
fill: {r: 0.2, g: 0.3, b: 0.8, a: 1}
|
||||
})
|
||||
|
||||
log.console("test_shape2d initialized with " + text(length(shapes)) + " shapes")
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Animate opacity on the white circle (index 16)
|
||||
if (shapes[16]) {
|
||||
shapes[16].opacity = 0.3 + 0.7 * (0.5 + 0.5 * math.sine(t * 2))
|
||||
}
|
||||
|
||||
// Animate the glow circle size (index 10)
|
||||
var scale = null
|
||||
if (shapes[10]) {
|
||||
scale = 1 + 0.2 * math.sine(t * 3)
|
||||
shapes[10].width = 80 * scale
|
||||
shapes[10].height = 80 * scale
|
||||
}
|
||||
|
||||
// Rotate the dashed pill stroke (index 7)
|
||||
if (shapes[7]) {
|
||||
shapes[4].dash_offset = t * 30
|
||||
shapes[5].dash_offset = t * 30
|
||||
shapes[6].dash_offset = t * 30
|
||||
shapes[7].dash_offset = t * 30
|
||||
}
|
||||
|
||||
// Pulse the decorative circles
|
||||
if (shapes[21]) {
|
||||
shapes[21].fill.r = 0.5 + 0.5 * math.sine(t * 1.5)
|
||||
}
|
||||
if (shapes[22]) {
|
||||
shapes[22].fill.g = 0.5 + 0.5 * math.sine(t * 1.5 + 2.094)
|
||||
}
|
||||
if (shapes[23]) {
|
||||
shapes[23].fill.b = 0.5 + 0.5 * math.sine(t * 1.5 + 4.188)
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 800,
|
||||
height: 600,
|
||||
title: "Test Shape2D - SDF Shapes",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
206
examples/test_sprite.ce
Normal file
@@ -0,0 +1,206 @@
|
||||
log.console("test_sprite starting")
|
||||
|
||||
var time = use('time')
|
||||
|
||||
var core = use('core')
|
||||
var sprite = use('sprite')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var sprites = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 250, y: 250},
|
||||
width: 500,
|
||||
height: 500,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 500, height: 500},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Row 1: Opacity test - 0, 0.25, 0.5, 0.75, 1.0
|
||||
var i = 0
|
||||
for (i = 0; i < 5; i++) {
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 50 + i * 100, y: 450},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
opacity: i * 0.25
|
||||
})
|
||||
}
|
||||
|
||||
// Row 2: Tint test - red, green, blue, yellow, magenta
|
||||
var tints = [
|
||||
{r: 1, g: 0, b: 0, a: 1},
|
||||
{r: 0, g: 1, b: 0, a: 1},
|
||||
{r: 0, g: 0, b: 1, a: 1},
|
||||
{r: 1, g: 1, b: 0, a: 1},
|
||||
{r: 1, g: 0, b: 1, a: 1}
|
||||
]
|
||||
for (i = 0; i < 5; i++) {
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 50 + i * 100, y: 350},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
tint: tints[i]
|
||||
})
|
||||
}
|
||||
|
||||
// Row 3: Filter test - nearest (small scaled up) vs linear (small scaled up)
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 125, y: 250},
|
||||
width: 150,
|
||||
height: 150,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
filter: 'nearest'
|
||||
})
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 375, y: 250},
|
||||
width: 150,
|
||||
height: 150,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
filter: 'linear'
|
||||
})
|
||||
|
||||
// Row 4: Flip test - normal, flip_x, flip_y, flip_both
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 75, y: 125},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
flip: {x: false, y: false}
|
||||
})
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 175, y: 125},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
flip: {x: true, y: false}
|
||||
})
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 275, y: 125},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
flip: {x: false, y: true}
|
||||
})
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 375, y: 125},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
flip: {x: true, y: true}
|
||||
})
|
||||
|
||||
// Row 5: UV scroll test - animated texture offset
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 450, y: 125},
|
||||
width: 64,
|
||||
height: 64,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
uv: {offset: {x: 0, y: 0}, scale: {x: 1, y: 1}, rotate: 0}
|
||||
})
|
||||
|
||||
// Animated opacity sprite
|
||||
sprites[] = sprite({
|
||||
plane: 'main',
|
||||
layer: 1,
|
||||
image: 'examples/bunny',
|
||||
pos: {x: 250, y: 50},
|
||||
width: 80,
|
||||
height: 80,
|
||||
anchor_x: 0.5,
|
||||
anchor_y: 0.5,
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
log.console("test_sprite initialized with " + text(length(sprites)) + " sprites")
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Animate opacity on the last sprite (pulsing)
|
||||
var animated_opacity_sprite = sprites[length(sprites) - 1]
|
||||
animated_opacity_sprite.opacity = 0.5 + 0.5 * math.sine(t * 2)
|
||||
|
||||
// Animate UV scroll on the UV test sprite
|
||||
var uv_sprite = sprites[length(sprites) - 2]
|
||||
uv_sprite.uv.offset.x = (t * 0.5) % 1
|
||||
uv_sprite.uv.offset.y = (t * 0.3) % 1
|
||||
|
||||
// Animate tint on first tint sprite (cycling hue)
|
||||
var tint_sprite = sprites[5]
|
||||
tint_sprite.tint.r = 0.5 + 0.5 * math.sine(t * 1.5)
|
||||
tint_sprite.tint.g = 0.5 + 0.5 * math.sine(t * 1.5 + 2.094)
|
||||
tint_sprite.tint.b = 0.5 + 0.5 * math.sine(t * 1.5 + 4.188)
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 500,
|
||||
height: 500,
|
||||
title: "Test Sprite Features",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
256
examples/test_text.ce
Normal file
@@ -0,0 +1,256 @@
|
||||
log.console("test_text starting")
|
||||
|
||||
var time = use('time')
|
||||
|
||||
var core = use('core')
|
||||
var text2d = use('text2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var texts = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 250, y: 250},
|
||||
width: 500,
|
||||
height: 500,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 500, height: 500},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.1, g: 0.1, b: 0.15, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Row 1: Normal text
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Normal Text",
|
||||
pos: {x: 20, y: 470},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 24,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Row 2: Opacity variations
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Opacity 0.25",
|
||||
pos: {x: 20, y: 420},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
opacity: 0.25
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Opacity 0.5",
|
||||
pos: {x: 200, y: 420},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
opacity: 0.5
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Opacity 0.75",
|
||||
pos: {x: 360, y: 420},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
opacity: 0.75
|
||||
})
|
||||
|
||||
// Row 3: Tint colors
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Red Tint",
|
||||
pos: {x: 20, y: 360},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 24,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 1, g: 0.2, b: 0.2, a: 1}
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Green Tint",
|
||||
pos: {x: 180, y: 360},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 24,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 0.2, g: 1, b: 0.2, a: 1}
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Blue Tint",
|
||||
pos: {x: 360, y: 360},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 24,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 0.2, g: 0.2, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Row 4: Combined tint + opacity
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Yellow + 50% Opacity",
|
||||
pos: {x: 20, y: 300},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 1, g: 1, b: 0, a: 1},
|
||||
opacity: 0.5
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Cyan + 75% Opacity",
|
||||
pos: {x: 280, y: 300},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 0, g: 1, b: 1, a: 1},
|
||||
opacity: 0.75
|
||||
})
|
||||
|
||||
// Row 5: Different sizes
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Small",
|
||||
pos: {x: 20, y: 240},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 12,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Medium",
|
||||
pos: {x: 100, y: 240},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Large",
|
||||
pos: {x: 220, y: 240},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 32,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "XL",
|
||||
pos: {x: 360, y: 240},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 48,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Row 6: Animated text (pulsing opacity)
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Pulsing Opacity",
|
||||
pos: {x: 150, y: 150},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 28,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
opacity: 1
|
||||
})
|
||||
|
||||
// Row 7: Animated tint (rainbow cycle)
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "Rainbow Tint",
|
||||
pos: {x: 150, y: 100},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 28,
|
||||
color: {r: 1, g: 1, b: 1, a: 1},
|
||||
tint: {r: 1, g: 0, b: 0, a: 1}
|
||||
})
|
||||
|
||||
// Row 8: Typewriter effect simulation
|
||||
texts[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
text: "",
|
||||
pos: {x: 20, y: 50},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 20,
|
||||
color: {r: 0.8, g: 1, b: 0.8, a: 1}
|
||||
})
|
||||
|
||||
log.console("test_text initialized with " + text(length(texts)) + " text elements")
|
||||
}
|
||||
|
||||
var typewriter_text = "Hello, this is a typewriter effect demo..."
|
||||
var typewriter_index = 0
|
||||
var typewriter_timer = 0
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Animate pulsing opacity
|
||||
var pulsing_text = texts[length(texts) - 3]
|
||||
pulsing_text.opacity = 0.3 + 0.7 * abs(math.sine(t * 2))
|
||||
|
||||
// Animate rainbow tint
|
||||
var rainbow_text = texts[length(texts) - 2]
|
||||
rainbow_text.tint.r = 0.5 + 0.5 * math.sine(t * 2)
|
||||
rainbow_text.tint.g = 0.5 + 0.5 * math.sine(t * 2 + 2.094)
|
||||
rainbow_text.tint.b = 0.5 + 0.5 * math.sine(t * 2 + 4.188)
|
||||
|
||||
// Typewriter effect
|
||||
typewriter_timer += dt
|
||||
var typewriter = null
|
||||
if (typewriter_timer > 0.08) {
|
||||
typewriter_timer = 0
|
||||
typewriter_index++
|
||||
if (typewriter_index > length(typewriter_text)) {
|
||||
typewriter_index = 0
|
||||
}
|
||||
typewriter = texts[length(texts) - 1]
|
||||
typewriter.text = text(typewriter_text, 0, typewriter_index)
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 500,
|
||||
height: 500,
|
||||
title: "Test Text Features",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
187
examples/test_tilemap.ce
Normal file
@@ -0,0 +1,187 @@
|
||||
log.console("test_tilemap starting")
|
||||
|
||||
var time = use('time')
|
||||
|
||||
var core = use('core')
|
||||
var tilemap2d = use('tilemap2d')
|
||||
var text2d = use('text2d')
|
||||
var compositor = use('compositor')
|
||||
var film2d = use('film2d')
|
||||
var math = use('math/radians')
|
||||
|
||||
var tilemaps = []
|
||||
var labels = []
|
||||
var t = 0
|
||||
|
||||
var camera = {
|
||||
pos: {x: 250, y: 250},
|
||||
width: 500,
|
||||
height: 500,
|
||||
anchor: {x: 0.5, y: 0.5}
|
||||
}
|
||||
|
||||
var compositor_config = {
|
||||
clear: {r: 0.05, g: 0.05, b: 0.1, a: 1},
|
||||
planes: [
|
||||
{
|
||||
name: 'main',
|
||||
plane: 'main',
|
||||
camera: camera,
|
||||
resolution: {width: 500, height: 500},
|
||||
presentation: 'stretch',
|
||||
clear: {r: 0.05, g: 0.05, b: 0.1, a: 1}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function make_grid(w, h, img) {
|
||||
var tiles = []
|
||||
var x = 0
|
||||
var y = 0
|
||||
for (x = 0; x < w; x++) {
|
||||
tiles[x] = []
|
||||
for (y = 0; y < h; y++) {
|
||||
tiles[x][y] = img
|
||||
}
|
||||
}
|
||||
return tiles
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Tilemap 1: Normal (top-left)
|
||||
tilemaps[] = tilemap2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
tiles: make_grid(4, 4, 'examples/tiles/terrain_dirt_cloud'),
|
||||
tile_width: 25,
|
||||
tile_height: 25,
|
||||
offset_x: 0,
|
||||
offset_y: 14
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Normal",
|
||||
pos: {x: 50, y: 480},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Tilemap 2: Opacity 0.5 (top-right)
|
||||
tilemaps[] = tilemap2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
tiles: make_grid(4, 4, 'examples/tiles/terrain_dirt_cloud'),
|
||||
tile_width: 25,
|
||||
tile_height: 25,
|
||||
offset_x: 10,
|
||||
offset_y: 14,
|
||||
opacity: 0.5
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Opacity 0.5",
|
||||
pos: {x: 280, y: 480},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Tilemap 3: Red tint (bottom-left)
|
||||
tilemaps[] = tilemap2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
tiles: make_grid(4, 4, 'examples/tiles/terrain_dirt_cloud'),
|
||||
tile_width: 25,
|
||||
tile_height: 25,
|
||||
offset_x: 0,
|
||||
offset_y: 4,
|
||||
tint: {r: 1, g: 0.3, b: 0.3, a: 1}
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Red Tint",
|
||||
pos: {x: 50, y: 230},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Tilemap 4: Green tint (bottom-right)
|
||||
tilemaps[] = tilemap2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
tiles: make_grid(4, 4, 'examples/tiles/terrain_dirt_cloud'),
|
||||
tile_width: 25,
|
||||
tile_height: 25,
|
||||
offset_x: 10,
|
||||
offset_y: 4,
|
||||
tint: {r: 0.3, g: 1, b: 0.3, a: 1}
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Green Tint",
|
||||
pos: {x: 280, y: 230},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 1, a: 1}
|
||||
})
|
||||
|
||||
// Tilemap 5: Animated opacity (center bottom)
|
||||
tilemaps[] = tilemap2d({
|
||||
plane: 'main',
|
||||
layer: 0,
|
||||
tiles: make_grid(3, 3, 'examples/tiles/terrain_dirt_cloud'),
|
||||
tile_width: 30,
|
||||
tile_height: 30,
|
||||
offset_x: 6,
|
||||
offset_y: 0,
|
||||
opacity: 1
|
||||
})
|
||||
labels[] = text2d({
|
||||
plane: 'main',
|
||||
layer: 10,
|
||||
text: "Animated Opacity",
|
||||
pos: {x: 180, y: 20},
|
||||
font: 'examples/fonts/dos',
|
||||
size: 14,
|
||||
color: {r: 1, g: 1, b: 0, a: 1}
|
||||
})
|
||||
|
||||
log.console("test_tilemap initialized with " + text(length(tilemaps)) + " tilemaps")
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
t += dt
|
||||
|
||||
// Animate opacity on the center tilemap
|
||||
var animated_tilemap = tilemaps[4]
|
||||
animated_tilemap.opacity = 0.3 + 0.7 * abs(math.sine(t * 1.5))
|
||||
|
||||
// Animate tint on the red tilemap (pulse)
|
||||
var red_tilemap = tilemaps[2]
|
||||
var pulse = 0.5 + 0.5 * math.sine(t * 2)
|
||||
red_tilemap.tint.r = 0.5 + 0.5 * pulse
|
||||
red_tilemap.tint.g = 0.2 * pulse
|
||||
red_tilemap.tint.b = 0.2 * pulse
|
||||
}
|
||||
|
||||
function render() {
|
||||
var plan = compositor.compile(compositor_config)
|
||||
return compositor.execute(plan)
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
core.start({
|
||||
width: 500,
|
||||
height: 500,
|
||||
title: "Test Tilemap Features",
|
||||
framerate: 60,
|
||||
update: update,
|
||||
render: render
|
||||
})
|
||||
BIN
examples/tiles/block_blue.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
examples/tiles/block_coin.png
Normal file
|
After Width: | Height: | Size: 849 B |
BIN
examples/tiles/block_coin_active.png
Normal file
|
After Width: | Height: | Size: 851 B |
BIN
examples/tiles/block_empty.png
Normal file
|
After Width: | Height: | Size: 431 B |
BIN
examples/tiles/block_empty_warning.png
Normal file
|
After Width: | Height: | Size: 676 B |
BIN
examples/tiles/block_exclamation.png
Normal file
|
After Width: | Height: | Size: 808 B |
BIN
examples/tiles/block_exclamation_active.png
Normal file
|
After Width: | Height: | Size: 809 B |
BIN
examples/tiles/block_green.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
examples/tiles/block_plank.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tiles/block_planks.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tiles/block_red.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
examples/tiles/block_spikes.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tiles/block_strong_coin.png
Normal file
|
After Width: | Height: | Size: 773 B |
BIN
examples/tiles/block_strong_coin_active.png
Normal file
|
After Width: | Height: | Size: 756 B |
BIN
examples/tiles/block_strong_danger.png
Normal file
|
After Width: | Height: | Size: 765 B |
BIN
examples/tiles/block_strong_danger_active.png
Normal file
|
After Width: | Height: | Size: 747 B |
BIN
examples/tiles/block_strong_empty.png
Normal file
|
After Width: | Height: | Size: 442 B |
BIN
examples/tiles/block_strong_empty_active.png
Normal file
|
After Width: | Height: | Size: 417 B |
BIN
examples/tiles/block_strong_exclamation.png
Normal file
|
After Width: | Height: | Size: 735 B |
BIN
examples/tiles/block_strong_exclamation_active.png
Normal file
|
After Width: | Height: | Size: 718 B |
BIN
examples/tiles/block_yellow.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
examples/tiles/bomb.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tiles/bomb_active.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tiles/brick_brown.png
Normal file
|
After Width: | Height: | Size: 367 B |
BIN
examples/tiles/brick_brown_diagonal.png
Normal file
|
After Width: | Height: | Size: 563 B |