Как правильно рисовать ящики при пиропроцессинге?
Я пытаюсь написать очень простую программу для рисования блоков, используя pyprocessing, но условие проверки, находится ли мышь внутри блока, не выполняется, когда логика выглядит хорошо:
#!/usr/bin/env python
from pyprocessing import *
S = 20
W = 5
H = 5
data = [[0] * W] * H
def setup():
size(W*(S+5),H*(S+5))
def draw():
background(0)
for y in xrange(H):
for x in xrange(W):
fill(data[x][y] * 255)
rect(x*S,y*S,S,S)
def mouseDragged():
for y in xrange(H):
for x in xrange(W):
xs = x * S
ys = y * S
# this doesn't behave as expected: it should draw a single box if the condition is met, not the whole row
if (mouse.x >= xs) and (mouse.x <= (xs+S)) and (mouse.y >= ys and mouse.y <= (ys+S)):
if key.pressed:
data[x][y] = 0
else:
data[x][y] = 1
run()
Я попробовал тот же подход с использованием Java-версии Processing, и он работает, как и ожидалось:
int S = 20;
int W = 5;
int H = 5;
int[][] data = new int[W][H];
void setup(){
size(100,100);
noStroke();
}
void draw(){
background(0);
for (int y = 0 ; y < H; y++){
for (int x = 0 ; x < W; x++){
fill(data[x][y] * 255);
rect(x*S,y*S,S,S);
}
}
}
void mouseDragged(){
for (int y = 0 ; y < H; y++){
for (int x = 0 ; x < W; x++){
int xs = x * S;
int ys = y * S;
if ((mouseX > xs) && (mouseX < (xs+S)) && (mouseY >= ys && mouseY <= (ys+S))){
data[x][y] = 1;
}
}
}
}
Подобное поведение в JS:
var S = 20;
var W = 5;
var H = 5;
var data = new Array(W);
function setup(){
createCanvas(100,100);
noStroke();
for (var i = 0 ; i < H; i++) data[i] = [0,0,0,0,0];
}
function draw(){
background(0);
for (var y = 0 ; y < H; y++){
for (var x = 0 ; x < W; x++){
fill(data[x][y] * 255);
rect(x*S,y*S,S,S);
}
}
}
function mouseDragged(){
for (var y = 0 ; y < H; y++){
for (var x = 0 ; x < W; x++){
var xs = x * S;
var ys = y * S;
if ((mouseX > xs) && (mouseX < (xs+S)) && (mouseY >= ys && mouseY <= (ys+S))){
data[x][y] = 1;
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.23/p5.min.js"></script>
Правильно ли я пишу условие границ коробки в Python? Если это так, есть ли ошибка с pyprocessing? Как я могу пройти это?
я использую pyprocessing.version '0.1.3.22'
1 ответ
Проблема в том, чтобы быть ленивым:
data = [[0] * W] * H
Это не просто создает вложенный массив, он копирует ссылки первого массива ([0]
), поэтому, когда я изменяю одно значение в одной строке, изменяется вся строка.
Так как у меня большой опыт работы с python, я инициализировал массив, вероятно, не pythonic:
data = []
for y in xrange(H):
data.append([])
for x in xrange(W):
data[y].append(0)
Итак, полный рабочий код:
#!/usr/bin/env python
from pyprocessing import *
S = 20
W = 5
H = 5
# data = [[0] * W] * H #trouble
data = []
for y in xrange(H):
data.append([])
for x in xrange(W):
data[y].append(0)
def setup():
size(W*(S),H*(S))
def draw():
background(0)
for y in xrange(H):
for x in xrange(W):
fill(data[x][y] * 255)
rect(x*S,y*S,S,S)
def mouseDragged():
for y in xrange(H):
for x in xrange(W):
xs = x * S
ys = y * S
if (mouse.x >= xs) and (mouse.x <= (xs+S)) and (mouse.y >= ys and mouse.y <= (ys+S)):
if key.pressed:
data[x][y] = 0
else:
data[x][y] = 1
run()