# Lesson 2: Moving ball

In this lesson, we will program a ball which bounces against the edges of a box, and which is duplicated on every emission of a signal split `split`. Here is an example of what we aim to achieve: lessons/lesson2/split.rml

We first define the data structure to represent the bounds of a box.

```type box =
{ left: float;
right: float;
top: float;
bot: float; }
```

We create a box.

```let box =
{ left = 0.; right = 400.;
bot = 0.; top = 400.; }
```

We display the box.

```let () =
let g =
" " ^
(string_of_int (int_of_float (box.right -. box.left))) ^
"x" ^
(string_of_int (int_of_float (box.top -. box.bot)))
in
Graphics.open_graph g
```

We now define the data structure to represent the state of a ball.

```type state =
{ pos: (float * float, float * float) event;
speed: (float * float, float * float) event;
color: Graphics.color; }
```

It is a record whose fields `pos`, `speed`, `radius` and `color` represent respectively the position, velocity, radius and color of a ball.

The type of the field `pos` is ```(float * float, float * float) event```. That is, it is an event on which we can emit and receive a tuple of floating numbers. It will represent the flow of positions.

To observe the balls, we use a global signal named `draw` on which each ball will emit its state. All the emitted states are collected into a list.

```signal draw default [] gather (fun x y -> x :: y) ;;
```

The behavior of a ball bouncing into the limit of the box can be programmed as follows.

```let process move state =
loop
(* emit the position *)
emit draw state;

(* compute the new position *)
let pre_vx, pre_vy = last ?state.speed in
let pre_x, pre_y = last ?state.pos in
let vx =
if box.left < pre_x && pre_x < box.right then pre_vx
else -. pre_vx
in
let vy =
if box.bot < pre_y && pre_y < box.top then pre_vy
else -. pre_vy
in
let x, y = (pre_x +. vx, pre_y +. vy) in

(* update the state *)
emit state.speed (vx, vy);
emit state.pos (x, y);
pause
end
```

The process is an infinite loop that first emits the current state, then computes the new position and then finally updates the state.

Let us now create a state. To do that, we have to define auxiliary functions. The first one associates a color to an integer.

```let color_of_int n =
match n mod 7 with
| 0 -> Graphics.rgb 220 20 60
| 1 -> Graphics.blue
| 2 -> Graphics.rgb 34 139 34
| 3 -> Graphics.red
| 4 -> Graphics.rgb 150 150 150
| 5 -> Graphics.black
| 6 -> Graphics.magenta
| _ -> Graphics.black
```

The second function creates a vector of norm `k`.

```let random_speed k =
let alpha = Random.float 7. in
(k *. cos alpha, k *. sin alpha)
```

Now, a function which creates a value of type `state` can be defined as follows.

```let new_state () =
signal pos
default ((box.right -. box.left) /. 2., (box.top -. box.bot) /. 2.)
gather (fun x _ -> x)
in
signal speed default random_speed 2. gather (fun x _ -> x) in
let color = color_of_int (Random.int 7) in
{ pos = pos; speed = speed; radius = 25.; color = color; }
```

The default value of the signal `pos` is the center of the box. The combination function only keeps one of the values emitted during an instant.

Let us create a ball:

```#run (move (new_state ())) ;;
```

To observe the position of the ball, we program a process which displays the value of the `draw` signal.

```let process window =
loop
await draw (all) in
Graphics.clear_graph();
List.iter
(fun state ->
let x, y = last ?state.pos in
Graphics.set_color state.color;
Graphics.fill_circle
(int_of_float x) (int_of_float y)
all
end
```

```#run window ;;
```

Now we want to create a ball which is duplicated each time a signal `split` is emitted.

```signal split default () gather (fun () () -> ()) ;;
```

We first define a function which creates a new state from an existing one.

```let new_state' state =
signal pos default last ?state.pos gather fun x _ -> x in
signal speed default random_speed 2. gather fun x _ -> x in
let color = color_of_int (Random.int 7) in
{ pos = pos; speed = speed; radius = radius; color = color; }
```

Dynamic creation is achieved by combining recursion and parallel composition.

```let rec process ball state =
do run (move state)
until split ->
run (ball (new_state' state))
||
run (ball (new_state' state))
done
```

```#run (ball (new_state ())) ;;
```

Finally, each time we emit the `split` event, the ball is duplicated.

```emit split ;;
```

```emit split ;;
```

Warning the JavaScript interpreter can stop if there is to many balls.