๐ŸŽ‡ Geometric Tiles

BamgasiJMยท2025๋…„ 12์›” 21์ผ

p5.js Art

๋ชฉ๋ก ๋ณด๊ธฐ
38/65
post-thumbnail

๐Ÿ“ p5.js

// ============================
// Configuration
// ============================
const CANVAS_SIZE = 800;
const TILE_SIZE = 50;
const GRID_NOISE_SCALE = 0.01;
const TIME_NOISE_SCALE = 0.01;
const TIME_STEP = 0.2;

// ============================
// State
// ============================
let tiles = [];
let time = 0;

// ============================
// p5 Lifecycle
// ============================
function setup() {
  createCanvas(CANVAS_SIZE, CANVAS_SIZE);
  colorMode(HSB, 360, 100, 100, 100);
  angleMode(DEGREES);

  tiles = createTiles();
}

function draw() {
  background(5, 5, 5, 100);
  time += TIME_STEP;

  for (const tile of tiles) {
    updateTile(tile);
    renderTile(tile);
  }
}

// ============================
// Tile Creation
// ============================
function createTiles() {
  const result = [];

  for (let x = 0; x < width; x += TILE_SIZE) {
    for (let y = 0; y < height; y += TILE_SIZE) {
      result.push({
        position: createVector(x, y),
        rotation: random(270),
        rotationSpeed: random(-4, 4),
        hueBase: random(360),
        shapeType: floor(random(4)),
        noiseOffset: random(1000),
      });
    }
  }
  return result;
}

// ============================
// Tile Update
// ============================
function updateTile(tile) {
  const { x, y } = tile.position;

  tile.noiseValue = noise(
    x * GRID_NOISE_SCALE,
    y * GRID_NOISE_SCALE,
    time * TIME_NOISE_SCALE + tile.noiseOffset
  );

  tile.rotation += tile.rotationSpeed * tile.noiseValue;
}

// ============================
// Tile Rendering
// ============================
function renderTile(tile) {
  const { x, y } = tile.position;
  const centerX = x + TILE_SIZE * 0.5;
  const centerY = y + TILE_SIZE * 0.5;
  const n = tile.noiseValue;

  const hue = (tile.hueBase + time * 0.5 + n * 100) % 360;
  const saturation = 40 + sin(time * 6 + x * 0.01) * 20;
  const brightness = 50 + cos(time * 3 + y * 0.1) * 50;
  const size = TILE_SIZE * 0.5 * (0.8 + n * 0.4);

  push();
  translate(centerX, centerY);
  rotate(tile.rotation + n * 20);

  noStroke();
  fill(hue, saturation, brightness, 100);

  SHAPE_RENDERERS[tile.shapeType](size);

  drawInnerDot(size);
  pop();
}

// ============================
// Shape Renderers
// ============================
const SHAPE_RENDERERS = [
  drawSquare,
  drawCircle,
  drawTriangle,
  drawCross,
];

function drawSquare(size) {
  rect(-size / 2, -size / 2, size, size);
}

function drawCircle(size) {
  ellipse(0, 0, size, size);
}

function drawTriangle(size) {
  beginShape();
  for (let i = 0; i < 3; i++) {
    const angle = 120 * i - 90;
    vertex(cos(angle) * size * 0.5, sin(angle) * size * 0.5);
  }
  endShape(CLOSE);
}

function drawCross(size) {
  rect(-size / 2, -size / 6, size, size / 3);
  rect(-size / 6, -size / 2, size / 3, size);
}

function drawInnerDot(size) {
  fill(0, 0, 100, 100);
  ellipse(10, 0, size * 0.2);
}

// ============================
// Interaction
// ============================
function keyPressed() {
  if (key === " ") {
    for (const tile of tiles) {
      tile.rotationSpeed = random(-3, 3);
      tile.hueBase = random(360);
      tile.shapeType = floor(random(4));
    }
  }
}

๐Ÿ“ Class ์‚ฌ์šฉ + ์ฃผ์„

// ======================================================
// 1. ์ „์—ญ ์„ค์ •๊ฐ’ (Configuration Constants)
// ======================================================

const CANVAS_SIZE = 800;        // ์บ”๋ฒ„์Šค์˜ ๊ฐ€๋กœยท์„ธ๋กœ ํฌ๊ธฐ
const TILE_SIZE = 50;           // ํ•˜๋‚˜์˜ ํƒ€์ผ์ด ์ฐจ์ง€ํ•˜๋Š” ์ •์‚ฌ๊ฐํ˜• ํฌ๊ธฐ
const GRID_NOISE_SCALE = 0.01;  // ๊ณต๊ฐ„ ๋…ธ์ด์ฆˆ์˜ ์„ธ๋ฐ€ํ•จ
const TIME_NOISE_SCALE = 0.01;  // ์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ๋…ธ์ด์ฆˆ ๋ณ€ํ™” ์†๋„
const TIME_STEP = 0.2;          // ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค time ๋ณ€์ˆ˜์— ๋”ํ•ด์ง€๋Š” ๊ฐ’ (์†๋„ ์กฐ์ ˆ)

// ======================================================
// 2. ์ „์—ญ ์ƒํƒœ ๋ณ€์ˆ˜ (Global State)
// ======================================================
// p5.js์˜ draw ๋ฃจํ”„ ์ „์ฒด์—์„œ ๊ณต์œ ๋˜๋Š” ์ƒํƒœ๊ฐ’

let tiles = []; // ๋ชจ๋“  ํƒ€์ผ ๊ฐ์ฒด(Tile ์ธ์Šคํ„ด์Šค)๋ฅผ ๋‹ด๋Š” ๋ฐฐ์—ด
let time = 0;   // ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ์‹œ๊ฐ„ ์ถ• ์—ญํ• ์„ ํ•˜๋Š” ๋ณ€์ˆ˜. ์ ์  ์ฆ๊ฐ€ํ•˜๋ฉฐ ๋ณ€ํ™”์˜ ๊ธฐ์ค€์ด ๋จ

// ======================================================
// 3. p5.js ๋ผ์ดํ”„์‚ฌ์ดํด ํ•จ์ˆ˜
// ======================================================

// p5.js ์ดˆ๊ธฐ ์„ค์ • ํ•จ์ˆ˜ (ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰)
function setup() {
  // ์บ”๋ฒ„์Šค ์ƒ์„ฑ
  createCanvas(CANVAS_SIZE, CANVAS_SIZE);

  // ์ƒ‰์ƒ ๋ชจ๋“œ๋ฅผ HSB๋กœ ์„ค์ •
  // hue: 0~360, saturation/brightness/alpha: 0~100
  colorMode(HSB, 360, 100, 100, 100);

  // ๊ฐ๋„ ๋‹จ์œ„๋ฅผ ๋ผ๋””์•ˆ์ด ์•„๋‹Œ ๋„(degree)๋กœ ์„ค์ •
  angleMode(DEGREES);

  // ํ™”๋ฉด ์ „์ฒด๋ฅผ TILE_SIZE ๊ฐ„๊ฒฉ์œผ๋กœ ๋‚˜๋ˆ„์–ด ํƒ€์ผ ๊ฐ์ฒด๋“ค์„ ์ƒ์„ฑํ•˜๊ณ  ๋ฐฐ์—ด์— ์ €์žฅ
  tiles = createTileGrid();
}

// p5.js ๋ฌดํ•œ ๋ฐ˜๋ณต ํ•จ์ˆ˜ (๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์‹คํ–‰๋จ)
function draw() {
  // ์„ค์ •ํ•œ ๋ฐฐ๊ฒฝ ์ƒ‰์™€ ์•ŒํŒŒ๊ฐ’์„ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๋ฎ์–ด์”Œ์›€
  background(5, 5, 5, 100);

  // ์‹œ๊ฐ„ ๊ฐ’ ์ฆ๊ฐ€. ์ด๊ฐ’์€ ๋…ธ์ด์ฆˆ, ์ƒ‰์ƒ ๋ณ€ํ™”, ํšŒ์ „์— ์‚ฌ์šฉ๋จ.
  time += TIME_STEP;

  // ๋ชจ๋“  ํƒ€์ผ์— ๋Œ€ํ•ด
  // 1) ํ˜„์žฌ ์‹œ๊ฐ„ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ฉฐ ํƒ€์ผ์˜ ๋…ธ์ด์ฆˆ์™€ ํšŒ์ „ ์ƒํƒœ ๊ฐฑ์‹ 
  // 2) ๊ฐฑ์‹ ๋œ ์ƒํƒœ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํƒ€์ผ์„ ํ™”๋ฉด์— ๊ทธ๋ฆผ
  for (const tile of tiles) {
    tile.update(time);
    tile.render();
  }
}

// ======================================================
// 4. ํƒ€์ผ ๊ทธ๋ฆฌ๋“œ ์ƒ์„ฑ ํ•จ์ˆ˜
// ======================================================

// ํ™”๋ฉด์„ TILE_SIZE ๋‹จ์œ„์˜ ๊ฒฉ์ž๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ์œ„์น˜์— Tile ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
function createTileGrid() {
  // ์ƒ์„ฑ๋œ ํƒ€์ผ๋“ค์„ ์ €์žฅํ•  ๋ฐฐ์—ด
  const result = [];

  // ๊ฐ€๋กœ ์„ธ๋กœ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ๊ฐ TILE_SIZE ๊ฐ„๊ฒฉ๋งŒํผ ์ด๋™ํ•˜๋ฉฐ ๋ฐ˜๋ณต
  for (let x = 0; x < width; x += TILE_SIZE) {
    for (let y = 0; y < height; y += TILE_SIZE) {
      // ํ˜„์žฌ ๊ฒฉ์ž ์œ„์น˜(x, y)์— ์ƒˆ๋กœ์šด Tile ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐฐ์—ด์— ์ถ”๊ฐ€
      result.push(new Tile(x, y, TILE_SIZE));
    }
  }

  // ์™„์„ฑ๋œ ํƒ€์ผ ๋ฐฐ์—ด ๋ฐ˜ํ™˜
  return result;
}

// ======================================================
// 5. Tile ํด๋ž˜์Šค ์ •์˜
// ======================================================
// Tile ํด๋ž˜์Šค๋Š” "ํƒ€์ผ ํ•˜๋‚˜"๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋‹จ์œ„ ๊ฐ์ฒด
// ์œ„์น˜, ์ƒ‰, ํšŒ์ „, ํ˜•ํƒœ, ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋กœ์ง์„ ์ •์˜ํ•จ

class Tile {
  // --------------------------------------------------
  // 5-1. ์ƒ์„ฑ์ž (constructor)
  // --------------------------------------------------
  // new Tile(x, y, size) ํ˜•ํƒœ๋กœ ํ˜ธ์ถœ๋จ
  // ํƒ€์ผ์ด ์ฒ˜์Œ ๋งŒ๋“ค์–ด์งˆ ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋จ

  constructor(x, y, size) {
    // ํƒ€์ผ์˜ ์ขŒ์ƒ๋‹จ ์œ„์น˜
    // p5.Vector๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ดํ›„ ๋ฒกํ„ฐ ์—ฐ์‚ฐ ํ™•์žฅ์ด ์šฉ์ดํ•จ
    this.position = createVector(x, y);

    // ํƒ€์ผ์˜ ๊ธฐ๋ณธ ํฌ๊ธฐ ์ €์žฅ
    this.size = size;

    // ์ดˆ๊ธฐ ํšŒ์ „ ๊ฐ๋„๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ์„ค์ • (0~270๋„ ์‚ฌ์ด)
    this.rotation = random(270);

    // ํšŒ์ „ ์†๋„๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ์„ค์ • (-4 ~ +4๋„/ํ”„๋ ˆ์ž„)
    this.rotationSpeed = random(-4, 4);

    // ํƒ€์ผ์˜ ๊ธฐ๋ณธ ์ƒ‰์กฐ(hue)๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ์„ค์ • (0~30์œผ๋กœ ์œ ์‚ฌ์ƒ‰ ๋ถ„ํฌ)
    this.hueBase = random(30);

    // ์–ด๋–ค ํ˜•ํƒœ๋ฅผ ๊ทธ๋ฆด์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์ธ๋ฑ์Šค
    // 0: ์‚ฌ๊ฐํ˜•, 1: ์›, 2: ์‚ผ๊ฐํ˜•, 3: ์‹ญ์ž
    this.shapeType = floor(random(4));

    // ๊ฐ ํƒ€์ผ๋งˆ๋‹ค ๋‹ค๋ฅธ ๋…ธ์ด์ฆˆ ํŒจํ„ด์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋žœ๋ค ์˜คํ”„์…‹
    this.noiseOffset = random(1000);

    // ํ˜„์žฌ ํ”„๋ ˆ์ž„์—์„œ ๊ณ„์‚ฐ๋œ ๋…ธ์ด์ฆˆ ๊ฐ’ ์ €์žฅ์šฉ ๋ณ€์ˆ˜ (์ดˆ๊ธฐ๊ฐ’ 0)
    this.noiseValue = 0;
  }

  // --------------------------------------------------
  // 5-2. update ๋ฉ”์„œ๋“œ
  // --------------------------------------------------
  // ์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ํƒ€์ผ์˜ "์ƒํƒœ ๋ณ€ํ™”"๋ฅผ ๋‹ด๋‹น
  // ์œ„์น˜๋Š” ๊ณ ์ •๋˜์–ด ์žˆ๊ณ , ํšŒ์ „๊ณผ ๋…ธ์ด์ฆˆ ๊ฐ’๋งŒ ๋ณ€ํ•จ

  update(t) {
    // ํƒ€์ผ ์œ„์น˜์˜ x, y ์ขŒํ‘œ๋ฅผ ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ ์ถ”์ถœ
    const { x, y } = this.position;

    // 3์ฐจ์› Perlin ๋…ธ์ด์ฆˆ ๊ฐ’์„ ๊ณ„์‚ฐ (๊ณต๊ฐ„ x, ๊ณต๊ฐ„ y, ์‹œ๊ฐ„ t + ์˜คํ”„์…‹)
    this.noiseValue = noise(
      x * GRID_NOISE_SCALE,
      y * GRID_NOISE_SCALE,
      t * TIME_NOISE_SCALE + this.noiseOffset
    );

    // ๋…ธ์ด์ฆˆ ๊ฐ’์— ๋น„๋ก€ํ•˜์—ฌ ํšŒ์ „ ์†๋„ ์ ์šฉ (๋…ธ์ด์ฆˆ๊ฐ€ ํด์ˆ˜๋ก ๋” ๋น ๋ฅด๊ฒŒ ํšŒ์ „)
    this.rotation += this.rotationSpeed * this.noiseValue;
  }

  // --------------------------------------------------
  // 5-3. render ๋ฉ”์„œ๋“œ
  // --------------------------------------------------
  // ํƒ€์ผ์„ ์‹ค์ œ๋กœ ํ™”๋ฉด์— ๊ทธ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  // ๊ณ„์‚ฐ๋œ ์ƒํƒœ๊ฐ’์„ ์‹œ๊ฐ์  ์š”์†Œ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

  render() {
    // ํƒ€์ผ ์œ„์น˜์˜ x, y ์ขŒํ‘œ ์ถ”์ถœ
    const { x, y } = this.position;

    // ํƒ€์ผ์˜ ์ค‘์‹ฌ ์ขŒํ‘œ ๊ณ„์‚ฐ
    const centerX = x + this.size * 0.5;
    const centerY = y + this.size * 0.5;

    // ํ˜„์žฌ ๊ณ„์‚ฐ๋œ ๋…ธ์ด์ฆˆ ๊ฐ’์„ n์œผ๋กœ ์‚ฌ์šฉ
    const n = this.noiseValue;

    // ์ƒ‰์กฐ(hue): ๊ธฐ๋ณธ hue + ์‹œ๊ฐ„์— ๋”ฐ๋ฅธ ๋ณ€ํ™” + ๋…ธ์ด์ฆˆ ์˜ํ–ฅ
    const hue = (this.hueBase + time * 0.5 + n * 100) % 360;

    // ์ฑ„๋„(saturation): ์‹œ๊ฐ„๊ณผ x ์œ„์น˜์— ๋”ฐ๋ฅธ ์‚ฌ์ธํŒŒ๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ง„๋™
    const saturation = 40 + sin(time * 6 + x * 0.01) * 20;

    // ๋ช…๋„(brightness): ์‹œ๊ฐ„๊ณผ y ์œ„์น˜์— ๋”ฐ๋ฅธ ์ฝ”์‚ฌ์ธํŒŒ๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ง„๋™
    const brightness = 50 + cos(time * 3 + y * 0.1) * 50;

    // ๋„ํ˜•์˜ ์‹ค์ œ ๊ทธ๋ ค์งˆ ํฌ๊ธฐ: ๋…ธ์ด์ฆˆ์— ๋”ฐ๋ผ 0.8~1.2๋ฐฐ ์‚ฌ์ด์—์„œ ๋ณ€๋™
    const drawSize = this.size * 0.5 * (0.8 + n * 0.4);

    push(); // ํ˜„์žฌ ์ขŒํ‘œ๊ณ„์™€ ์Šคํƒ€์ผ ์ €์žฅ

    // ํƒ€์ผ ์ค‘์‹ฌ์œผ๋กœ ์ขŒํ‘œ๊ณ„๋ฅผ ์ด๋™
    translate(centerX, centerY);

    // ๊ณ„์‚ฐ๋œ ํšŒ์ „ ๊ฐ๋„ ์ ์šฉ (๊ธฐ๋ณธ ํšŒ์ „ + ๋…ธ์ด์ฆˆ์— ๋”ฐ๋ฅธ ์ถ”๊ฐ€ ํšŒ์ „)
    rotate(this.rotation + n * 20);

    // ํ…Œ๋‘๋ฆฌ ์—†์Œ
    noStroke();

    // ๊ณ„์‚ฐ๋œ HSB ์ƒ‰์ƒ๊ณผ ๋ถˆํˆฌ๋ช…๋„ 100์œผ๋กœ ์ฑ„์šฐ๊ธฐ
    fill(hue, saturation, brightness, 100);

    // shapeType์— ๋”ฐ๋ผ ๋„ํ˜• ๊ทธ๋ฆฌ๊ธฐ
    this.drawShape(drawSize);

    // ๋„ํ˜• ์ค‘์•™์— ์ž‘์€ ํฐ ์  ์ถ”๊ฐ€
    this.drawInnerDot(drawSize);

    pop(); // ์ขŒํ‘œ๊ณ„์™€ ์Šคํƒ€์ผ ๋ณต์›
  }

  // --------------------------------------------------
  // 5-4. ๋„ํ˜• ์„ ํƒ ๋ฉ”์„œ๋“œ
  // --------------------------------------------------
  // shapeType ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ
  // ๋ฏธ๋ฆฌ ์ •์˜๋œ ํ•จ์ˆ˜ ๋ฐฐ์—ด์—์„œ ๋„ํ˜•์„ ํ˜ธ์ถœ

  drawShape(size) {
    SHAPE_RENDERERS[this.shapeType](size);
  }

  // --------------------------------------------------
  // 5-5. ๋‚ด๋ถ€ ์  ์žฅ์‹
  // --------------------------------------------------
  // ํƒ€์ผ ์ค‘์•™์— ์ž‘์€ ํฐ์ƒ‰ ์› ๊ทธ๋ฆผ

  drawInnerDot(size) {
    fill(0, 0, 100, 100); // HSB Mode๋กœ ์ฑ„์šฐ๊ธฐ
    ellipse(10, 0, size * 0.2); // ์ค‘์‹ฌ์—์„œ ์•ฝ๊ฐ„ ์˜ค๋ฅธ์ชฝ(10,0)
  }

  // --------------------------------------------------
  // 5-6. ์™ธํ˜• ๋žœ๋คํ™” ๋ฉ”์„œ๋“œ
  // --------------------------------------------------
  // ์™ธ๋ถ€์—์„œ ํ˜ธ์ถœ ์‹œ ํƒ€์ผ์˜ ํšŒ์ „ ์†๋„, ์ƒ‰์ƒ, ๋„ํ˜•์„ ๋‹ค์‹œ ๋žœ๋คํ™”

  randomizeAppearance() {
    this.rotationSpeed = random(-4, 4);
    this.hueBase = random(30);
    this.shapeType = floor(random(4));
  }
}

// ======================================================
// 6. ๋„ํ˜• ๋ Œ๋”๋ง ํ•จ์ˆ˜๋“ค
// ======================================================
// ๊ฐ ํ•จ์ˆ˜๋Š” "ํ˜„์žฌ ์ขŒํ‘œ๊ณ„ ๊ธฐ์ค€"์œผ๋กœ ๋„ํ˜•์„ ๊ทธ๋ฆผ
// Tile ํด๋ž˜์Šค์—์„œ๋Š” ์ขŒํ‘œ ๋ณ€ํ™˜๋งŒ ๋‹ด๋‹นํ•˜๊ณ 
// ์‹ค์ œ ๋„ํ˜• ์ •์˜๋Š” ์ด ์˜์—ญ์— ์œ„์ž„ํ•จ

// ๊ฐ ๋„ํ˜•์„ ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜๋“ค์„ ๋ฐฐ์—ด๋กœ ๋ฌถ์Œ (0,1,2,3 ์ธ๋ฑ์Šค๋กœ ์„ ํƒ)
const SHAPE_RENDERERS = [drawSquare, drawCircle, drawTriangle, drawCross];

// ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ (์ค‘์‹ฌ ๊ธฐ์ค€)
function drawSquare(size) {
  rect(-size / 2, -size / 2, size, size);
}

// ์› ๊ทธ๋ฆฌ๊ธฐ (์ค‘์‹ฌ ๊ธฐ์ค€)
function drawCircle(size) {
  ellipse(0, 0, size, size);
}

// ์ •์‚ผ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ (์ค‘์‹ฌ ๊ธฐ์ค€, ์œ„์ชฝ์ด ๋พฐ์กฑ)
function drawTriangle(size) {
  beginShape();
  for (let i = 0; i < 3; i++) {
    const angle = 120 * i - 90; // 120๋„ ๊ฐ„๊ฒฉ, -90๋„๋กœ ํšŒ์ „ํ•˜์—ฌ ์œ„์ชฝ ์ •์ 
    vertex(
      cos(angle) * size * 0.5, 
      sin(angle) * size * 0.5
    );
  }
  endShape(CLOSE);
}

// ์‹ญ์ž ๋ชจ์–‘ ๊ทธ๋ฆฌ๊ธฐ (๊ฐ€๋กœ ๋ง‰๋Œ€ + ์„ธ๋กœ ๋ง‰๋Œ€)
function drawCross(size) {
  rect(-size / 2, -size / 6, size, size / 3);  // ๊ฐ€๋กœ ๋ง‰๋Œ€
  rect(-size / 6, -size / 2, size / 3, size);  // ์„ธ๋กœ ๋ง‰๋Œ€
}

// ======================================================
// 7. ์ž…๋ ฅ ์ฒ˜๋ฆฌ
// ======================================================
// ์ŠคํŽ˜์ด์Šค๋ฐ”๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ชจ๋“  ํƒ€์ผ์˜ ์™ธํ˜•์ด ์ƒˆ๋กœ ๋žœ๋คํ™”

function keyPressed() {
  if (key === " ") {
    for (const tile of tiles) {
      tile.randomizeAppearance();
    }
  }
}

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0๊ฐœ์˜ ๋Œ“๊ธ€