Skip to content

Instantly share code, notes, and snippets.

@kleimkuhler
Created March 6, 2019 18:38
Show Gist options
  • Save kleimkuhler/5bc412e9a511ada829996ca8613db1c7 to your computer and use it in GitHub Desktop.
Save kleimkuhler/5bc412e9a511ada829996ca8613db1c7 to your computer and use it in GitHub Desktop.
This is an incomplete example of an asteroids game made in ReasonML using Reprocessing.
/*
Replace the `index.re` of [reprocessing-example] for an almost asteroids
game. This was made at the [ReasonML Dojo] by Ben, Ian, and me. I highly
recommend attending a meeting if you able to!
[reprocessing-example]: https://github.com/bsansouci/reprocessing-example
[ReasonML Dojo]: https://www.meetup.com/sv-ocaml/events/258916644/
*/
open Reprocessing;
type pos = (float, float);
type proj = {
position: pos,
rotation: float,
};
type state = {
position: pos,
rotation: float,
projectiles: list(proj),
asteroids: list(proj),
};
let get_direction = rot => (cos(rot), sin(rot));
let setup = env => {
Env.size(~width=600, ~height=600, env);
{position: (150., 150.), rotation: 0., projectiles: [], asteroids: []};
};
let vel = 5.;
let bullet_ratio = 2.;
let asteroid_ratio = 0.5;
let draw = (state, env) => {
Draw.background(Utils.color(~r=255, ~g=217, ~b=229, ~a=255), env);
Draw.fill(Utils.color(~r=41, ~g=166, ~b=244, ~a=255), env);
Draw.noStroke(env);
Draw.rectf(~pos=state.position, ~width=10., ~height=10., env);
Draw.text(
~pos=(125, 25),
~body=
Printf.sprintf(
"Projectiles: %d - Asteroids: %d",
List.length(state.projectiles),
List.length(state.asteroids),
),
env,
);
let (x, y) = state.position;
let (dx, dy) = get_direction(state.rotation);
Draw.linef(~p1=state.position, ~p2=(x +. dx *. 20., y +. dy *. 20.), env);
List.iter(
(p: proj) => {
Draw.noStroke(env);
Draw.ellipsef(p.position, 5., 5., env);
},
state.projectiles,
);
List.iter(
(p: proj) => {
Draw.fill(Utils.color(~r=255, ~g=217, ~b=229, ~a=255), env);
Draw.stroke(Constants.black, env);
Draw.ellipsef(p.position, 5., 5., env);
},
state.asteroids,
);
let gc = (ratio: float, new_projs, p: proj) => {
let (x, y) = p.position;
if (x > float_of_int(Env.width(env))
|| y > float_of_int(Env.height(env))
|| x < 0.
|| y < 0.) {
new_projs;
} else {
let (dx, dy) = get_direction(p.rotation);
[
{...p, position: (x +. dx *. vel *. ratio, y +. dy *. vel *. ratio)},
...new_projs,
];
};
};
let state = {
...state,
projectiles: List.fold_left(gc(bullet_ratio), [], state.projectiles),
asteroids: List.fold_left(gc(asteroid_ratio), [], state.asteroids),
};
let state =
if (Env.key(Up, env)) {
let (x, y) = state.position;
let (dx, dy) = get_direction(state.rotation);
{...state, position: (x +. dx *. vel, y +. dy *. vel)};
} else {
state;
};
let state =
if (Env.key(Down, env)) {
let (x, y) = state.position;
let (dx, dy) = get_direction(state.rotation);
{...state, position: (x -. dx *. vel, y -. dy *. vel)};
} else {
state;
};
let state =
if (Env.key(Right, env)) {
let rot = state.rotation;
{...state, rotation: rot +. 0.1};
} else {
state;
};
let state =
if (Env.key(Left, env)) {
let rot = state.rotation;
{...state, rotation: rot -. 0.1};
} else {
state;
};
let state =
if (Env.key(Space, env)) {
let projectile = {position: state.position, rotation: state.rotation};
{...state, projectiles: [projectile, ...state.projectiles]};
} else {
state;
};
let state =
if (Utils.random(0, 100) < 5) {
let x = Utils.randomf(0., float_of_int(Env.width(env)));
let rot = Utils.randomf(0., Constants.pi);
let asteroid = {position: (x, 0.), rotation: rot};
{...state, asteroids: [asteroid, ...state.asteroids]};
} else {
state;
};
state;
};
run(~setup, ~draw, ());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment