more examples

This commit is contained in:
2026-02-26 15:54:11 -06:00
parent ce6b0ddb3a
commit 9147db6fdc
393 changed files with 2091 additions and 24 deletions

12
clay.cm
View File

@@ -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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
examples/enemies/bee_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
examples/enemies/bee_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
examples/enemies/fly_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
examples/enemies/fly_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
examples/enemies/saw_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
examples/enemies/saw_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 B

BIN
examples/fonts/c64.ttf Normal file

Binary file not shown.

BIN
examples/fonts/dos.ttf Normal file

Binary file not shown.

Binary file not shown.

303
examples/paladin.ce Normal file
View 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 dont 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) {
}
})

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

315
examples/test_line2d.ce Normal file
View 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
View 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
View 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
View 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
View 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
View 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
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

BIN
examples/tiles/bomb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

Some files were not shown because too many files have changed in this diff Show More