Today I am starting my first pixelart challenge.
Tree!
Just trying recursive branching
var times = 0,
tree = function(layer, x, y, direction){
if(layer <= 0)
return;
var wind = cos(times/10*layer)/3,
i = 0,
cs = cos(direction),
sn = sin(direction);
point(x,y, 0xff0000);
for(; i< 5; i++){
point(x + cs*i,y+ sn*i, 0xff0000);
}
tree(layer - 1, x + cs*i,y + sn*i, direction - 0.5+wind);
tree(layer - 1, x + cs*i,y + sn*i, direction + 0.5+wind);
},
update = function(dt, t) {
clear();
times = t*10;
tree(5, w/2, h-3, Math.PI/2*3);
};
Dithering!
Let's make a simple dither algorithm. It would be useful for drawing lots of things in pixelart style.
First approach was too naive. It worked, but looks artificial.
var sum = 0,
dither = function(amount, filledColor, notEnoughColor) {
sum += amount;
// if colour storage is filled — return filled color
if(sum >= 1){
sum %= 1;
return filledColor;
}
return notEnoughColor;
}, x, y;
for(x = 0; x < w; x++){
for(y = 0; y < h; y++){
point( x, y, dither(x/w, 0xFF0000, 0x000000) );
}
}
Mouse
Previous dither function is not so bad when it is used with custom angles.
Added move
function that calls each time when mouse is moved over canvas.
var sum = 0,
dither = function(amount, filledColor, notEnoughColor) {
sum += amount;
// if colour storage is filled — return filled color
if(sum >= 1){
sum %= 1;
return filledColor;
}
return notEnoughColor;
}, x, y;
move = function() {
var angle = new Point(w/2, h/2).sub(mouse).getAngle(),
si = sin(angle), cs = cos(angle);
for(x = 0; x < w; x++){
for(y = 0; y < h; y++){
point( x, y, dither(
bound( (cs*(x-w/2)+si*(y-h/2)+h/2)/h ),
0xFF0000, 0x000000) );
}
}
}
Dither 2.0
Would use a simple hashing approach. Added another collector, so it would feel more randomized.
var sum = 0, kc = 0,
dither = function(amount, filledColor, notEnoughColor) {
kc = ((kc+1)*1.4 + 1) % 17;
sum += amount;
if(kc%3<1)sum+=amount
if(sum >= 1){
sum %= 1;
return filledColor;
}
return notEnoughColor;
}, x, y;
for(x = 0; x < w; x++){
for(y = 0; y < h; y++){
point( x, y, dither(x/w, 0xFF0000, 0x000000) );
}
}
With mouse move
var sum = 0, kc = 0,
dither = function(amount, filledColor, notEnoughColor) {
kc = ((kc+1)*1.4 + 1) % 17;
sum += amount;
if(kc%3<1)sum+=amount
if(sum >= 1){
sum %= 1;
return filledColor;
}
return notEnoughColor;
}, x, y;
// reset collectors
dither.reset = function() {
kc = 0;
return sum = 0;
};
move = function() {
dither.reset();
var angle = new Point(w/2, h/2).sub(mouse).getAngle(),
si = sin(angle), cs = cos(angle);
for(x = 0; x < w; x++){
for(y = 0; y < h; y++){
point( x, y, dither(
bound( (cs*(x-w/2)+si*(y-h/2)+h/2)/h ),
0xFF0000, 0x000000) );
}
}
}
Sky!
Now I am ready to draw the sky
var sky = px.createLayer(1),
center = new Point(w/2,h),
x, y;
for(x = 0; x < w; x++)
for(y = 0; y < h; y++)
sky.point(
x,
y,
dither(
center.distance(new Point(x,y))/200,
0x000000,
0x201050
));
var stars = [];
for(x = 0; x < 30; x++){
var star = new Point(rand(w), rand(h));
star.animation = rand(300);
star.color =[0x75F3FF,0xFEFFB7,0xACFF7C][rand(3)]
stars.push(star);
}
var starsLayer = px.createLayer(2);
var tick = 0;
var randomMeteor = function() {
var angle = rand(720)/720*Math.PI*2;
var meteor = new Point(0, w).rotate(angle);
meteor.mass = rand(1000)/1500+0.1;
meteor.direction = angle + Math.PI+ rand(1000)/200;
meteor.speed = rand(100)+500;
meteor.color =[0xFFFC07,0xFFFFFF,0xFFA8BB][rand(3)]
return meteor;
}
var meteors = [];
for(x = 0; x < 1; x++){
meteors.push(randomMeteor());
}
update = function(dt, t){
tick++;
starsLayer.clear();
dither.reset();
stars.forEach(function(star) {
var animate = sin(star.animation + t/20)+1;
starsLayer.point(star.x, star.y, dither(animate, star.color, alpha ));
});
meteors.forEach(function(meteor, i) {
var normal = new Point(0,1).rotate(meteor.direction);
meteor.mass-=dt;
if(meteor.mass<0){
meteors[i] = randomMeteor();
}else{
for(var k = 0, _k = meteor.speed*dt; k < _k; k++){
meteor.add(normal);
starsLayer.point(meteor.x+w/2, meteor.y+h/2, meteor.color);
}
}
})
}
This is it. It is a simple sky, but tools are working and I am ready to begin my challenge!