Skip to content
This repository has been archived by the owner on Aug 24, 2024. It is now read-only.

Commit

Permalink
Configurable brush settings
Browse files Browse the repository at this point in the history
  • Loading branch information
nint8835 committed Apr 27, 2024
1 parent 28279d2 commit 741af71
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 36 deletions.
18 changes: 11 additions & 7 deletions frontend/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import Controls from './components/Controls.svelte';
import Framerate from './components/Framerate.svelte';
import { init } from './game';
Expand All @@ -8,11 +9,14 @@
});
</script>

<canvas
class="scale h-[480px] w-[640px] bg-black bg-opacity-25"
style="image-rendering: pixelated"
id="canvas"
width="640"
height="480"
></canvas>
<div class="w-[640px]">
<canvas
class="scale h-[480px] w-full bg-black bg-opacity-25"
style="image-rendering: pixelated"
id="canvas"
width="640"
height="480"
></canvas>
<Controls />
</div>
<Framerate />
25 changes: 25 additions & 0 deletions frontend/src/components/Controls.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import { settingsStore } from '../game';
</script>

<div class="grid grid-cols-2 gap-2 rounded-b-lg bg-slate-950 p-4">
<label class="flex flex-row items-center justify-between">
Brush size:
<input
class="rounded-md bg-slate-900 p-2 outline-none ring-teal-600 transition-all focus:ring-2"
type="number"
min="0"
max="50"
step="1"
bind:value={$settingsStore.brushSize}
/>
</label>
<label class="flex flex-row items-center justify-between">
Brush colour:
<input
class="rounded-md bg-slate-900 p-2 outline-none ring-teal-600 transition-all focus:ring-2"
type="color"
bind:value={$settingsStore.brushColour}
/>
</label>
</div>
2 changes: 1 addition & 1 deletion frontend/src/components/Framerate.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
}
</script>

<div>FPS: {frameRate}</div>
<div class="absolute bottom-2 right-2 text-slate-500">FPS: {frameRate}</div>
18 changes: 15 additions & 3 deletions frontend/src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@ import { draw_frame } from '@/conjam.mjs';
import { writable } from 'svelte/store';

const scaleFactor = 1;

const state = {
frameNumber: 0,
lastFrameTime: performance.now(),
currentFrameTime: performance.now(),

mouseDown: false,
mouseX: 0,
mouseY: 0,
};
export const store = writable(state);

const settings = {
brushSize: 10,
brushColour: '#ff0000',
};
export const settingsStore = writable(settings);

function tickFrame() {
draw_frame(state.frameNumber, state.mouseDown, state.mouseX, state.mouseY);
draw_frame(
state.mouseDown,
state.mouseX,
state.mouseY,
settings.brushSize,
(parseInt(settings.brushColour.substring(1), 16) << 8) | 0xff,
);
state.currentFrameTime = performance.now();
state.frameNumber++;
store.update(() => ({ ...state }));
state.lastFrameTime = state.currentFrameTime;
requestAnimationFrame(tickFrame);
Expand Down
13 changes: 11 additions & 2 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { svelte } from '@sveltejs/vite-plugin-svelte';
import type { UserConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default {
base: '/conjam/',
plugins: [tsconfigPaths(), svelte()],
plugins: [
tsconfigPaths(),
svelte(),
{
name: 'Reload Fix',
handleHotUpdate({ server }) {
server.hot.send({ type: 'full-reload' });
},
},
],
} satisfies UserConfig;
32 changes: 9 additions & 23 deletions src/conjam.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ const max_x = 639

const max_y = 479

fn random_colour() -> canvas.Pixel {
let colours = [0xff0000ff, 0x00ff00ff, 0x0000ffff]

colours
|> list.shuffle()
|> list.first()
|> result.unwrap(0x00000000)
}

fn apply_gravity(frame_data: canvas.ImageData, index: Int) -> canvas.ImageData {
let x = index % canvas.canvas_width
let y = index / canvas.canvas_width
Expand Down Expand Up @@ -89,11 +80,7 @@ fn collapse_like(frame_data: canvas.ImageData, index: Int) -> canvas.ImageData {
}
}

fn iter_pixels(
frame_data: canvas.ImageData,
frame_number: Int,
index: Int,
) -> canvas.ImageData {
fn iter_pixels(frame_data: canvas.ImageData, index: Int) -> canvas.ImageData {
case index {
-1 -> frame_data
_ -> {
Expand All @@ -102,20 +89,18 @@ fn iter_pixels(
|> apply_gravity(index)
|> collapse_like(index)

iter_pixels(new_frame_data, frame_number, index - 1)
iter_pixels(new_frame_data, index - 1)
}
}
}

const brush_size = 20

fn apply_brush(
frame_data: canvas.ImageData,
mouse_x: Int,
mouse_y: Int,
brush_size: Int,
brush_colour: canvas.Pixel,
) -> canvas.ImageData {
let colour = random_colour()

list.range(-1 * brush_size, brush_size)
|> list.fold(frame_data, fn(row_data, y) {
list.range(-1 * brush_size, brush_size)
Expand All @@ -138,29 +123,30 @@ fn apply_brush(
True -> pixel_data
False -> {
pixel_data
|> canvas.set_pixel(mouse_x + x, mouse_y + y, colour)
|> canvas.set_pixel(mouse_x + x, mouse_y + y, brush_colour)
}
}
})
})
}

pub fn draw_frame(
frame_number: Int,
mouse_down: Bool,
mouse_x: Int,
mouse_y: Int,
brush_size: Int,
brush_colour: canvas.Pixel,
) {
use data <- canvas.mutate_frame()

let initial_data = case mouse_down {
True -> {
data
|> apply_brush(mouse_x, mouse_y)
|> apply_brush(mouse_x, mouse_y, brush_size, brush_colour)
}
False -> data
}

initial_data
|> iter_pixels(frame_number, canvas.canvas_height * canvas.canvas_width)
|> iter_pixels(canvas.canvas_height * canvas.canvas_width)
}

0 comments on commit 741af71

Please sign in to comment.