Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,3 @@ jobs:

- name: Run tests
run: opam exec -- dune runtest

- name: Build docs
run: opam exec -- dune build @doc
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
# Claudius Examples

A library of examples of using Claudius, mostly from [Tiny Code Christmas](https://tcc.lovebyte.party) and [Genuary](https://genuary.art).
A library of examples of using [Claudius](https://github.com/claudiusFX/claudius), a simple retro-style graphics library for OCaml. Many originally created for [Tiny Code Christmas](https://tcc.lovebyte.party) and [Genuary](https://genuary.art).

To run these you will need to install Claudius via opam, and then you can `dune exec [example_name]`.

# Examples Directory

## Using primitives

These examples just show a single feature of Claudius, and are a good place to start if you're trying to understand how Claudius works.

* [Bounce](/bounce/) - example of a bouncing ball made from ellipses.
* [Polygons](/polygons/) - rotating filled polygons.
* [Red Hexagon](/red_hexagon/) - a different style of rotating polyons.
* [Screen saver](/screen_saver/) - a recreation of a classic screen saver effect from the early Macintosh era.
* [Shapes](/shapes/) - using simple shape outlines to create some animation effects.
* [TextGrid](/textgrid/) - drawing characters using the built in font for Claudius.
* [DSOTM](/dsotm/) - using a combination of primitive shapes to build up a familiar image.

## Algorithmic effects

These examples start to use Claudius to build up interesting effects based on some simple algorithms

* [Fern](/fern/) - drawing a [Bansley Fern fractal](https://en.wikipedia.org/wiki/Barnsley_fern).
* [Julia Set](/julia_set/) - an animated [Julia set fractal](https://en.wikipedia.org/wiki/Julia_set).
* [Koch Snowflake](/koch_snowflake/) - an example of using recursion to draw a [Koch snowflake fractal](https://en.wikipedia.org/wiki/Koch_snowflake).
* [Koch Snowflake Filled](/koch_snowflake_filled/) - a filled in version of the [Koch snowflake example](/koch_snowflake/).
* [Lorenz](/lorenz/) - an animated [Lorenz Attractor](https://en.wikipedia.org/wiki/Lorenz_system).
* [Murmuration](/murmuration/) - another Lorenz Attractor, but this time used to mimic a flock of swarming birds.
* [Plasma](/plasma/) - an example of a classic [plasma effect](https://en.wikipedia.org/wiki/Plasma_effect).
* [Tunnel](/tunnel/) - an example of how simple math functions can create complex looking scenes.

## Misc effects

Other more complex effects created using Claudius

* [Anni Albers](/anni_albers/) - a homage to leading textile artist [Anni Albers](https://en.wikipedia.org/wiki/Anni_Albers).
* [Anni Albers Also](/anni_albers_too/) - a second homage to leading textile artist [Anni Albers](https://en.wikipedia.org/wiki/Anni_Albers).
* [Islamic pattern](/islamic_pattern/) - an example playing with [Islamic geometric patterns](https://en.wikipedia.org/wiki/Islamic_geometric_patterns) and positive/negative space.
* [Islamic pattern filled](/islamic_pattern_filled/) - a solid verson of the [Islamic pattern example](/islamic_pattern/).
* [Particles](/particles/) - creating a pseudo-3D point cloud of a planet.
* [Landscape](/landscape/) - using the algorithm from the [Plasma example](/plasma/) to create a pseudo-3D landscape.
* [Lava lamp](/lava_lamp/) - yet another effect routed in the [Plasma example](/plasma/), this time with dithering added.
* [Physics](/physics/) - an example of using a simple [Hooke's law](https://en.wikipedia.org/wiki/Hooke%27s_law) library to add physics to the [Landscape](/landscape/) example.
* [Walking Mesh](/walking_mesh/) - an example of what looks like a stateful effect being implemented functionally.
* [Vera Molnár](/vera_molnar/) - a homage to pioneering digital artist [Vera Molnár](https://en.wikipedia.org/wiki/Vera_Molnár).

## Interactive programs

* [Paint](/paint/) - a simple painting program in a few lines of OCaml using Claudius.
* [Filedrop](/filedrop/) - a simple GIF image viewer that accepts files dropped on it.
* [keytest](/keytest/) - an example that shows what key was pressed.
1 change: 1 addition & 0 deletions anni_albers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A homage to the textile artist [Anni Albers](https://en.wikipedia.org/wiki/Anni_Albers), showing that inspiration for digital art can come from different domains.
4 changes: 4 additions & 0 deletions anni_albers/bin/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(executable
(public_name anni_albers)
(name main)
(libraries claudius))
5 changes: 2 additions & 3 deletions day11/bin/main.ml → anni_albers/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ let tick t s _p _i =
let fx = Float.of_int x and fy = Float.of_int y and ft = Float.of_int t in
let c = 1 + Int.of_float ((sin (sin (fx /. 8.))) *. (sin (sin (fy /. 8.))) *. (1. +. (5. *. sin (ft /. 500.)))) mod cols in
if c < 0 then c + cols else c
)
)

(* ----- *)

let () =
Screen.create 126 226 3 (Palette.load_tic80_palette havrekaka_palette) |>
Base.run "Genuary 11: Anni Albers" None tick

Base.run "Anni Albers" None tick
4 changes: 4 additions & 0 deletions anni_albers_too/bin/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(executable
(public_name anni_albers_too)
(name main)
(libraries claudius))
2 changes: 1 addition & 1 deletion day112/bin/main.ml → anni_albers_too/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ let tick t s _p _i =
let () =
Palette.load_tic80_palette havrekaka_palette |>
Screen.create 500 600 1 |>
Base.run "Genuary 11: Anni Albers" None tick
Base.run "Anni Albers Also" None tick
4 changes: 4 additions & 0 deletions bauhaus/bin/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(executable
(public_name bauhaus)
(name main)
(libraries claudius))
21 changes: 8 additions & 13 deletions day18/bin/main.ml → bauhaus/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ open Claudius
let outer_radius = 140.
let inner_radius = 100.

let prev = Framebuffer.init (480, 480) (fun _ _ -> 0)
let double_buffer = Framebuffer.init (480, 480) (fun _x _y -> 0)

let boot s =
let max_col = (Palette.size (Screen.palette s)) - 1 in
Expand All @@ -17,36 +17,31 @@ let boot s =
let y = Int.of_float ((outer_radius +. 1.) *. (sin angle)) in
Framebuffer.pixel_write (x + (w/2)) (y + (h/2)) (max_col - 1) fb
done;
Framebuffer.map2_inplace (fun _ p -> p) prev fb;
fb

let tick_d t s _fb _i =
let tick_d t s prev _i =
let w, h = Screen.dimensions s in
let cx = (w/2) and cy = (h/2) in
let delta = Framebuffer.init (w, h) (fun _x _y -> 0) in
Framebuffer.map_inplace (fun _ -> 0) double_buffer;
Framebuffer.mapi_inplace (fun x y ofb ->
let op = Framebuffer.pixel_read x y ofb in
match op with
| None -> 0
| Some (p) ->
match p with
| 0 -> 0
| 255 -> 255
| i -> (
| 254 -> (
let dx = Float.of_int(x - cx)
and dy = Float.of_int(y - cy) in
let wobble = 0.05 *. sin((Float.of_int t) /. 100.) in
let angle = (atan2 dy dx) +. ((Random.float wobble) -. (wobble /. 2.))
and radius = sqrt ((dy *. dy) +. (dx *. dx)) in
let nx = Int.of_float ((radius +. 2.) *. (cos angle)) in
let ny = Int.of_float ((radius +. 2.) *. (sin angle)) in
let col = i in
Framebuffer.pixel_write (nx + cx) (ny + cy) col delta;
col - 1
)
Framebuffer.pixel_write (nx + cx) (ny + cy) 254 double_buffer;
255)
| x -> x
) prev;
Framebuffer.map2_inplace (+) prev delta;
Framebuffer.map (fun p -> if p >= 0 && (p < 256) then p else 0) prev
Framebuffer.map2 (fun b a -> if a != 0 then a else b) prev double_buffer


let tick t s fb i =
Expand Down
16 changes: 8 additions & 8 deletions bounce/bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ let filled = ref true
(* Squash and stopping parameters :) Must stop after some time. This is to make sure that the whole infinitesimal bounce effect (Rolling) is avoided *)
let squash_factor = 0.25
let fps = 60.0
let stop_after_frames = int_of_float (2.0 *. fps)
let bounce_vis_vel_threshold = 2.0
let stop_after_frames = int_of_float (2.0 *. fps)
let bounce_vis_vel_threshold = 2.0
let last_bounce_t = ref 0

(* where the key states are being tracked *)
Expand Down Expand Up @@ -49,12 +49,12 @@ let tick t s _prev (inputs : Base.input_state) =
x_vel := if !x_pos > max_width /. 2.0 then -.2.0 else 2.0;
y_vel := 0.0;
last_bounce_t := t;
was_space_pressed := true
was_space_pressed := true
end;

if Base.KeyCodeSet.mem Key.X inputs.keys && not !was_x_pressed then begin
filled := not !filled;
was_x_pressed := true
was_x_pressed := true
end;

(* Update physics *)
Expand Down Expand Up @@ -103,14 +103,14 @@ let tick t s _prev (inputs : Base.input_state) =

(* Reset key states *)
if not (Base.KeyCodeSet.mem Key.Space inputs.keys) then
was_space_pressed := false;
was_space_pressed := false;
if not (Base.KeyCodeSet.mem Key.X inputs.keys) then
was_x_pressed := false;
was_x_pressed := false;

fb

let () =
Random.self_init ();
Palette.generate_plasma_palette 18
Palette.generate_plasma_palette 18
|> Screen.create (int_of_float max_width) (int_of_float max_height) 1
|> Base.run "Bounce Ball Mini Game" None tick
|> Base.run "Bounce Ball" None tick
4 changes: 0 additions & 4 deletions day10/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day10/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day10/lib/dune

This file was deleted.

4 changes: 0 additions & 4 deletions day11/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day11/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day11/lib/dune

This file was deleted.

4 changes: 0 additions & 4 deletions day112/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day112/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day112/lib/dune

This file was deleted.

4 changes: 0 additions & 4 deletions day12/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day12/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day12/lib/dune

This file was deleted.

4 changes: 0 additions & 4 deletions day17/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day17/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day17/lib/dune

This file was deleted.

4 changes: 0 additions & 4 deletions day17filled/bin/dune

This file was deleted.

24 changes: 0 additions & 24 deletions day17filled/dune-project

This file was deleted.

2 changes: 0 additions & 2 deletions day17filled/lib/dune

This file was deleted.

Loading