在 Processing 中创建随机像素化线条
Creating random pixeled lines in Proccesing
我正在尝试制作游戏,但我被随机关卡设计困住了。基本上,我试图创建一条从一个 edge/corner 到另一个 edge/corner 的线,同时具有一些随机性。
参见下图 1 [link 损坏] 和 2 的示例。我在 processing 中这样做,但我尝试过的每一次尝试都没有产生正确的结果。我可以让它们随机填充,但不是排成一行或从边到边。顺便说一句,我正在尝试在 16 x 16 网格上执行此操作。任何想法或帮助将不胜感激谢谢!
图 2:
根据您的描述,挑战在于从上到下连接一条线,并带有一点随机性驱动 left/right 方向。
有多种选择。
这是我想到的一个基本想法:
- 选择一个开始的 x 位置:左边说右边在中间
- 对于从 0 到 15 的每一行(对于 16 像素级别)
- 在 3 个数字之间随机选择一个:
- 如果是第一个向左走(x 递减)
- 如果是第二个向右走(x 增量)
- 如果是第 3 次:忽略:这意味着该线将直线向下进行此迭代
这是一个基本草图,使用 PImage
可视化数据来说明这一点:
void setup(){
size(160, 160);
noSmooth();
int levelSize = 16;
PImage level = createImage(levelSize, levelSize, RGB);
level.loadPixels();
java.util.Arrays.fill(level.pixels, color(255));
int x = levelSize / 2;
for(int y = 0 ; y < levelSize; y++){
int randomDirection = (int)random(3);
if(randomDirection == 1) x--;
if(randomDirection == 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level.pixels[x + y * levelSize] = color(0);
}
level.updatePixels();
// render result;
image(level, 0, 0, width, height);
fill(127);
text("click to reset", 10, 15);
}
// hacky reset
void draw(){}
void mousePressed(){
setup();
}
上面的逻辑很简单,但可以自由地用其他选项替换 random(3)
(也许 throwing dice to determine direction or exploring other psuedo-random number generators (PRNGs) such as randomGaussian()
, noise()
(和相关函数)等)
这是上面的 p5.js 版本:
let levelSize = 16;
let numBlocks = levelSize * levelSize;
let level = new Array(numBlocks);
function setup() {
createCanvas(320, 320);
level.fill(0);
let x = floor(levelSize / 2);
for(let y = 0 ; y < levelSize; y++){
let randomDirection = floor(random(3));
if(randomDirection === 1) x--;
if(randomDirection === 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level[x + y * levelSize] = 1;
}
// optional: print to console
// prettyPrintLevel(level, levelSize, numBlocks);
}
function draw() {
background(255);
// visualise
for(let i = 0 ; i < numBlocks; i++){
let x = i % levelSize;
let y = floor(i / levelSize);
fill(level[i] == 1 ? color(0) : color(255));
rect(x * 20, y * 20, 20, 20);
}
}
function prettyPrintLevel(level, levelSize, numBlocks){
for(let i = 0; i < numBlocks; i+= levelSize){
print(level.slice(i, i + levelSize));
}
}
function mousePressed(){
setup();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
在这两个示例中,数据都是结构化的一维数组,但是,如果它更容易,它可以很容易地成为二维数组。在这个开发阶段,最简单、最易读的选项就是要走的路。
我正在尝试制作游戏,但我被随机关卡设计困住了。基本上,我试图创建一条从一个 edge/corner 到另一个 edge/corner 的线,同时具有一些随机性。
参见下图 1 [link 损坏] 和 2 的示例。我在 processing 中这样做,但我尝试过的每一次尝试都没有产生正确的结果。我可以让它们随机填充,但不是排成一行或从边到边。顺便说一句,我正在尝试在 16 x 16 网格上执行此操作。任何想法或帮助将不胜感激谢谢!
图 2:
根据您的描述,挑战在于从上到下连接一条线,并带有一点随机性驱动 left/right 方向。
有多种选择。
这是我想到的一个基本想法:
- 选择一个开始的 x 位置:左边说右边在中间
- 对于从 0 到 15 的每一行(对于 16 像素级别)
- 在 3 个数字之间随机选择一个:
- 如果是第一个向左走(x 递减)
- 如果是第二个向右走(x 增量)
- 如果是第 3 次:忽略:这意味着该线将直线向下进行此迭代
- 在 3 个数字之间随机选择一个:
这是一个基本草图,使用 PImage
可视化数据来说明这一点:
void setup(){
size(160, 160);
noSmooth();
int levelSize = 16;
PImage level = createImage(levelSize, levelSize, RGB);
level.loadPixels();
java.util.Arrays.fill(level.pixels, color(255));
int x = levelSize / 2;
for(int y = 0 ; y < levelSize; y++){
int randomDirection = (int)random(3);
if(randomDirection == 1) x--;
if(randomDirection == 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level.pixels[x + y * levelSize] = color(0);
}
level.updatePixels();
// render result;
image(level, 0, 0, width, height);
fill(127);
text("click to reset", 10, 15);
}
// hacky reset
void draw(){}
void mousePressed(){
setup();
}
上面的逻辑很简单,但可以自由地用其他选项替换 random(3)
(也许 throwing dice to determine direction or exploring other psuedo-random number generators (PRNGs) such as randomGaussian()
, noise()
(和相关函数)等)
这是上面的 p5.js 版本:
let levelSize = 16;
let numBlocks = levelSize * levelSize;
let level = new Array(numBlocks);
function setup() {
createCanvas(320, 320);
level.fill(0);
let x = floor(levelSize / 2);
for(let y = 0 ; y < levelSize; y++){
let randomDirection = floor(random(3));
if(randomDirection === 1) x--;
if(randomDirection === 2) x++;
// if randomDirection is 0 ignore as we don't change x -> just go down
// constrain to valid pixel
x = constrain(x, 0, levelSize - 1);
// render dot
level[x + y * levelSize] = 1;
}
// optional: print to console
// prettyPrintLevel(level, levelSize, numBlocks);
}
function draw() {
background(255);
// visualise
for(let i = 0 ; i < numBlocks; i++){
let x = i % levelSize;
let y = floor(i / levelSize);
fill(level[i] == 1 ? color(0) : color(255));
rect(x * 20, y * 20, 20, 20);
}
}
function prettyPrintLevel(level, levelSize, numBlocks){
for(let i = 0; i < numBlocks; i+= levelSize){
print(level.slice(i, i + levelSize));
}
}
function mousePressed(){
setup();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
在这两个示例中,数据都是结构化的一维数组,但是,如果它更容易,它可以很容易地成为二维数组。在这个开发阶段,最简单、最易读的选项就是要走的路。