Xadrez - Experimentos em Programação Criativa - 10
Essa é mais uma tentativa de reproduzir uma imagem utilizando computação criativa. Como nas últimas vezes, o objetivo dessa tentativa é de utilizar uma inspiração para aprender técnicas e conceitos novos. Esses artigos são principalmente criados como uma forma de catalogar o processo de implementação para referencia futura quando eu estiver desenvolvendo novas coisas.
Inspiração
Desta vez, uma das imagens que eu tinha salvo como inspiração é a capa do album Wings da banda BTS:
Nessa imagem, quatro círculos são desenhados com diferentes estilos. A proposta não é desenvolver algo 100% fiel, mas que relembre essa capa.
O resultado foi o seguinte:
Implementação
Usarei novamento o editor do p5 para essa implementação.
Passo 1
Começando pelo grid, vamos criar uma matriz que guardará cada uma das células. Os valores serão 1 para células pretas e 0 para células brancas.
1 | const matrix = [] |
E pintamos eles na tela como um grid de quadrados
1 |
|
Com isso temos o seguinte resultado:
Passo 2
Para o próximo passo, vamos adicionar os pequenos círculos nas quatro pontas do tabuleiro. Basta verificarmos se o quadrado faz parte de uma das pontas, e adicionar um círculo na posição central
1 | ... |
Resultando no seguinte:
Passo 3
Neste último passo, vamos adicionar a ação do clique. O próprio p5.js já possui uma função interna que observa o método mouseClicked()
para facilitar o desenvolvimento, por isso podemos só implementar esse método e usar as variáveis mouseX
e mouseY
para detectar a posição do canvas que foi clicado.
1 | function mouseClicked() { |
E com uma lógica um pouco mais elaborada, podemos fazer o deslocamento das células para a direção desejada.
1 | function mouseClicked() { |
Produzindo nosso resultado final:
Próximos passos
Para um resultado mais fiel ao original, seria legal adicionar uma animação para visualizar as linhas e colunas movendo para a direção que estão sendo deslocadas, além de linhas delimitando quais direções podem ou não ser clicadas.
Código completo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72const matrix = []
const WIDTH = 60
const CHECKED_SIZE = 6
function setup() {
createCanvas(WIDTH * (CHECKED_SIZE + 2), WIDTH * (CHECKED_SIZE + 2))
new Array(CHECKED_SIZE).fill(0).map((_, i) => {
matrix.push([])
new Array(CHECKED_SIZE).fill(0).map((_, j) => {
const v = i % 2 === 0 ? (j % 2 === 0 ? 1 : 0) : (j % 2 === 0 ? 0 : 1)
matrix[i].push(v)
})
})
}
function draw() {
background(220)
stroke(0)
strokeWeight(2)
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
fill(matrix[i][j] === 1 ? 0 : 220)
const x = WIDTH * i + WIDTH
const y = WIDTH * j + WIDTH
square(x, y, WIDTH)
const isXWall = i === 0 || i === CHECKED_SIZE - 1
const isYWall = j === 0 || j === CHECKED_SIZE - 1
if (isXWall && isYWall) {
fill(matrix[i][j] === 1 ? 220 : 0)
circle(x + WIDTH/2, y + WIDTH/2, WIDTH / 2)
}
}
}
}
function mouseClicked() {
const isLeftWall = mouseX < WIDTH
const isRightWall = mouseX > WIDTH * 7
const isTopWall = mouseY < WIDTH
const isBottomWall = mouseY > WIDTH * 7
if (isLeftWall || isRightWall) {
const row = floor(mouseY * (CHECKED_SIZE + 2) / width)
rotateMatrix(row - 1, 'x', isLeftWall ? 'right' : 'left')
}
if (isTopWall || isBottomWall) {
const column = floor(mouseX * (CHECKED_SIZE + 2) / width)
rotateMatrix(column - 1, 'y', isTopWall ? 'bottom' : 'top')
}
}
function rotateMatrix(index, axis, direction) {
if (index < 0 || index >= CHECKED_SIZE) return
if(axis === 'y') {
if (direction === 'bottom') {
matrix[index].unshift(matrix[index].pop())
} else {
matrix[index].push(matrix[index].shift())
}
} else {
const cells = matrix.map(row => row[index])
if (direction === 'right') {
cells.unshift(cells.pop())
} else {
cells.push(cells.shift())
}
matrix.forEach((row, i) => row[index] = cells[i])
}
}