xxxxxxxxxx
284
// numbers factory: "can you make N?"
// grid size
const KX = 40;
const KY = 40;
class Block{
static counter = 0;
constructor(x,y,label=''){
this.x = x;
this.y = y;
this.label = label;
this.isNumber = label.startsWith('#');
this.special = false;
this.id = Block.counter;
Block.counter+=1;
}
draw(){
this.drawAt(this.x,this.y);
}
drawAt(xx,yy){
if (this.special){
stroke("yellow");
fill("beige");
} else {
stroke("black");
fill("white");
if (this.label=='1'){
stroke("black");
fill("lightgreen");
}
}
if (this.isNumber){
stroke("#4CAF50");
fill(`rgb(${200+(27*this.id)%40},${200+(13*this.id)%50},191)`);
ellipse(xx,yy,KX,KY);
} else if (this.label.startsWith('=')){ // question blocks
push();
stroke("gold");
fill("yellow");
triangle(xx,yy-.25*KY,
xx+KX/2,yy+.25*KY,
xx+KX,yy-.25*KY);
pop();
push();
stroke("lightgreen");
fill("rgb(166,216,166)");
triangle(xx,yy+KY,
xx+KX/2,yy+1.25*KY,
xx+KX,yy+KY);
pop();
drawingContext.setLineDash([5,5]);
rect(xx,yy,KX,KY);
drawingContext.setLineDash([]); // reset line
} else {
if (this.label!='1'){
push();
stroke("gold");
fill("yellow");
triangle(xx,yy-.25*KY,
xx+KX/2,yy+.25*KY,
xx+KX,yy-.25*KY);
pop();
push();
stroke("lightgreen");
fill("rgb(166,216,166)");
triangle(xx,yy+KY,
xx+KX/2,yy+1.25*KY,
xx+KX,yy+KY);
pop();
rect(xx,yy,KX,KY);
} else { // default [1] block
push();
stroke("lightgreen");
fill("rgb(166,216,166)");
triangle(xx,yy+KY,
xx+KX/2,yy+1.25*KY,
xx+KX,yy+KY);
pop();
rect(xx,yy,KX,KY);
}
}
noStroke();
fill("black");
text(this.label,xx+KX/4,yy+KY*2/3);
}
isSelected(xx,yy){
return ((xx>=this.x) && (xx<=this.x+KX)) &&
((yy>=this.y) && (yy<=this.y+KY));
}
setSelected(yesOrNo){
this.special = yesOrNo;
}
getSelected(){
return this.special;
}
toggleSelected(){
this.special = !this.special;
}
act(){
if ((this.label=='1') && (this.special)){
if (isFree(blocks,this.x,this.y+KY)){
blocks.push( new Block(this.x,this.y+KY,'#1') );
} else {
showTextFor("Cannot create a '1', free the area",2);
}
this.toggleSelected();
}
if ((this.label=='+2') && (this.special)){
let b = getBlockAt(blocks,this.x,this.y-KY);
if (b!=null){
b.y = this.y+KY;
b.label = '#'+ (int(b.label.substring(1))+2);
}
this.toggleSelected();
}
if ((this.label=='x3') && (this.special)){
let b = getBlockAt(blocks,this.x,this.y-KY);
if (b!=null){
b.y = this.y+KY;
b.label = '#'+ (int(b.label.substring(1))*3);
}
this.toggleSelected();
}
if ((this.label.startsWith('=')) && (this.special)){
let equalTo = int(this.label.substring(1));
let b = getBlockAt(blocks,this.x,this.y-KY);
if (b!=null) {
b.y = this.y+KY;
if (int(b.label.substring(1))==equalTo){
showTextFor("Well done!",4);
} else {
showTextFor("Nop, try again...",2);
}
}
this.toggleSelected();
}
}
}
function isFree(blocks,xx,yy){
let existingBlock = getBlockAt(blocks,xx,yy);
return (existingBlock==null);
}
function getBlockAt(blocks,xx,yy){
let existingBlock = null;
for (let b of blocks){
if ((b.x==xx) && (b.y==yy)){
existingBlock = b;
break;
}
}
return existingBlock;
}
let showingText = {t:'',s:-1};
let blocks = [];
function setup() {
createCanvas(400, 400);
textSize(KX/3);
ellipseMode(CORNER);
rectMode(CORNER);
blocks.push( new Block(2*KX,1*KY,'1') );
blocks.push( new Block(2*KX,3*KY,'x3') );
blocks.push( new Block(5*KX,3*KY,'+2') );
blocks.push( new Block(1*KX,6*KY,'=9') );
blocks.push( new Block(4*KX,6*KY,'=11') );
blocks.push( new Block(7*KX,6*KY,'=15') );
}
function draw() {
background("#CBF7FC");
noFill();
stroke('black');
for (let i=0;i<width/KX;i++){
for (let j=0;j<height/KY;j++){
point((.5+i)*KX,(.5+j)*KY);
}
}
for (let b of blocks){
if (frameCount%30==0){
b.act();
}
if (b!=draggingBlock)
b.draw();
}
if (dragged){
draggingBlock.drawAt(mouseX-KX/2,mouseY-KY/2);
}
if (showingText.s>0){
showingText.s -= 1;
noStroke();
fill('black');
text(showingText.t,10,20);
}
}
function showTextFor(txt,secs){
showingText.t = txt;
showingText.s = ~~(secs * frameRate());
}
let draggingBlock;
let dragged = false;
function touchStarted(){
mousePressed();
}
function touchEnded(){
mouseReleased();
}
function mousePressed(){
//console.log(blocks);
let selectedBlock = null;
for (let b of blocks){
if (b.isSelected(mouseX,mouseY)){
selectedBlock = b;
break;
}
}
if ((selectedBlock!=null) && (!selectedBlock.isNumber)){
selectedBlock.toggleSelected();
}
draggingBlock = null;
if ((selectedBlock) && (selectedBlock.isNumber))
draggingBlock = selectedBlock; // eventually null
if (draggingBlock)
dragged = true;
}
function mouseReleased(){
if (dragged){
let newX = ~~(mouseX/KX)*KX;
let newY = ~~(mouseY/KY)*KY;
if (isFree(blocks,newX,newY)){
draggingBlock.x = newX;
draggingBlock.y = newY;
}
draggingBlock = null;
dragged = false;
//console.log("dragging done");
}
}