~sircmpwn/cells

2816bf27a73cbf6bcfc22f1df83e626abfba0345 — Drew DeVault 3 months ago 7a0641f
Implement local drawing operations
2 files changed, 85 insertions(+), 12 deletions(-)

M index.js
M messages.go
M index.js => index.js +81 -10
@@ 12,8 12,10 @@ const MAX_DIST = CELL_SIZE * 8;
const FADE_DIST = PLAYER_SIZE * 2;
const PLAYER_SPEED = CELL_SIZE * 24;
const MAX_SPEED = CELL_SIZE * 32;
const CHUNK_SIZE = 32;

let mouse = { x: 0, y: 0 };
let painting = false;
let player = { x: 0, y: 0 };
let velocity = { x: 0, y: 0 };
let player_color = [ 255, 0, 0 ];


@@ 21,6 23,7 @@ let peers = [];
let pings = [];
let last_ts = 0;
let keys = [];
let map = { };

const proto = window.location.protocol === "http:" ? "ws:" : "wss:";
const ws = new WebSocket(`${proto}//${window.location.host}/socket`);


@@ 58,6 61,48 @@ function to_display(coords) {
  return { x, y };
}

function lookup_cell({ x, y }) {
  const chunk_x = Math.floor(x / CHUNK_SIZE),
    chunk_y = Math.floor(y / CHUNK_SIZE);
  const chunk = map[`${chunk_x},${chunk_y}`];
  if (typeof chunk === "undefined") {
    return [255, 255, 255];
  }
  let local_x = x % CHUNK_SIZE, local_y = y % CHUNK_SIZE;
  if (local_x < 0) {
    local_x = CHUNK_SIZE + local_x;
  }
  if (local_y < 0) {
    local_y = CHUNK_SIZE + local_y;
  }
  return chunk[local_y * CHUNK_SIZE + local_x];
}

function set_cell({ x, y }, color) {
  const chunk_x = Math.floor(x / CHUNK_SIZE),
    chunk_y = Math.floor(y / CHUNK_SIZE);
  const key = `${chunk_x},${chunk_y}`;
  if (typeof map[key] === "undefined") {
    let chunk = [];
    for (let n = 0; n < CHUNK_SIZE * CHUNK_SIZE; ++n) {
      chunk[n] = [255, 255, 255];
    }
    map[key] = chunk;
  }
  let local_x = x % CHUNK_SIZE, local_y = y % CHUNK_SIZE;
  if (local_x < 0) {
    local_x = CHUNK_SIZE + local_x;
  }
  if (local_y < 0) {
    local_y = CHUNK_SIZE + local_y;
  }
  if (typeof color === "undefined") {
    // TODO: Send change to server
    color = player_color;
  }
  map[key][local_y * CHUNK_SIZE + local_x] = color;
}

function draw_grid(width, height) {
  ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
  ctx.lineWidth = 1;


@@ 71,12 116,9 @@ function draw_grid(width, height) {
    for (let x = -1; (x - 1) * CELL_SIZE < width; ++x) {
      let display_x = x * CELL_SIZE - offs_x, display_y = y * CELL_SIZE - offs_y;
      let grid_x = x + x_addr, grid_y = y + y_addr;
      let filled = grid_x < 10 && grid_y < 10
        && grid_x >= 5 && grid_y >= 5;
      if (filled) {
        ctx.fillStyle = to_rgba(player_color);
        ctx.fillRect(display_x, display_y, CELL_SIZE, CELL_SIZE);
      }
      let color = lookup_cell({ x: grid_x, y: grid_y });
      ctx.fillStyle = to_rgba(color);
      ctx.fillRect(display_x, display_y, CELL_SIZE, CELL_SIZE);
      ctx.strokeRect(display_x, display_y, CELL_SIZE, CELL_SIZE);
    }
  }


@@ 128,7 170,8 @@ function draw_pings(ts) {
  });
}

function cursor_position(width, height) {
function cursor_position() {
  const width = window.innerWidth, height = window.innerHeight;
  const player_x = width / 2, player_y = height / 2;
  const a = mouse.x - player_x, o = mouse.y - player_y;
  const h = Math.sqrt(a * a + o * o);


@@ 143,7 186,7 @@ function cursor_position(width, height) {
}

function draw_cursor(width, height) {
  const cursor = cursor_position(width, height);
  const cursor = cursor_position();
  const player_x = width / 2, player_y = height / 2;

  let alpha = 1.0;


@@ 270,18 313,46 @@ function frame(ts) {
canvas.addEventListener('mousemove', e => {
  mouse.x = e.clientX;
  mouse.y = e.clientY;
  if (painting) {
    const cursor = cursor_position();
    if (cursor.x === mouse.x && cursor.y === mouse.y) {
      const coords = to_grid(cursor);
      const cell = lookup_cell(coords);
      if (cell[0] !== player_color[0]
          && cell[1] !== player_color[1]
          && cell[2] !== player_color[2]) {
        set_cell(coords);
      }
    }
    set_cell(to_grid(cursor));
  }
});

canvas.addEventListener('mousedown', e => {
  mouse.x = e.clientX;
  mouse.y = e.clientY;
  if (e.button === 2) {
    const coords = to_grid(mouse);
  const coords = to_grid(mouse);
  const cursor = cursor_position();
  switch (e.button) {
  case 0:
    if (cursor.x === mouse.x && cursor.y === mouse.y) {
      set_cell(to_grid(cursor));
      painting = true;
    }
    break;
  case 2:
    ping(coords, player_color);
    ws.send(JSON.stringify({
      "type": "ping",
      "coords": { "x": coords.x, "y": coords.y },
    }));
    break;
  }
});

canvas.addEventListener('mouseup', e => {
  if (e.button === 0) {
    painting = false;
  }
});


M messages.go => messages.go +4 -2
@@ 1,5 1,7 @@
package main

const CHUNK_SIZE = 32

type Color [3]int

type Position struct {


@@ 39,8 41,8 @@ type DespawnPeerMessage struct {

type CellMapMessage struct {
	Message
	Coords Coordinates    `json:"coords"`
	Cells  [32 * 32]Color `json:"cells"`
	Coords Coordinates                    `json:"coords"`
	Cells  [CHUNK_SIZE * CHUNK_SIZE]Color `json:"cells"`
}

type PingMessage struct {