xxxxxxxxxx
940
// Tiles:
// 0 - 19: "Individual" features (they don't need "corners" etc.). Rocks, trees, etc.
// 20 - 39: Water.
// 90 - 99: Experimental.
// Details:
// 0 - empty
// 1 - rock
// 2 - tree
// 20 - water center
// 21 - water top
// 22 - water TR
// 23 - water TL
// 24 - water BL
// 25 - water BR
// 26 - land w/ water TR
// 27 - land w/ water TL
// 28 - land w/ water BL
// 29 - land w/ water BR
// 30 - water center with vertical bridge
// 31 - water top with vertical bridge
// 32 - water center with horizontal bridge
// 33 - water center with 1 lily pad
// 34 - water center with 2 lily pads
// 35 - water center with rock
// 36 - water top with rock
// 90 - acacia
// 91 - normals test
// 92 - lit tree
let tileMap =
[
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,35,20,20,34,20,35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,29,20, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,20,33,20,20,20,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[21,21,31,36,21,22, 0,23,21,31,20,20, 0, 0, 0, 2, 2, 1, 2, 0, 0, 0,24,20,30,33,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1,24,30,35,35,25, 0,20,27, 0,26,20, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0,32, 0, 2, 0,32, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0,20,28, 0,29,20, 0, 0, 2, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0,24,20,31,20,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0,23,21,22, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,20,33,22, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,23,21,21,36,21,21,21,21,36],
[ 1,29,23,21,22, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1,24,35,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,34,33,20,20,20,35,20,20],
[21,20,20,33,34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,24,20,25,27, 0, 2,26,34,35],
[ 1,26,24,20,20,28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,20,20],
[ 1, 0, 0,26,20,20,22, 0, 0, 0, 0, 0, 0, 0,91,91,91,91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,29,20,20],
[ 1, 0, 0, 0,20,20,25, 0, 0, 0, 0, 0, 0, 0,91,91,91,91, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,23,21,21,21,21,31,20,20,20],
[ 1, 0, 0, 0,32,27, 0, 0, 0, 0, 0, 0, 0, 0,91,91,91,91, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0,33,27,26,24,20,30,25,27, 1],
[ 1, 0, 0, 0,20,28, 0, 0, 0, 0, 0, 0, 0, 0,91,91,91,91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,32,28, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0,24,20,31,21,21,21,21,21,22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,29,20,20,21,31,21,21,31,21,21],
[ 1, 0, 0, 0, 0, 0, 0, 0,26,20,34,20,20, 0, 0, 0, 0, 0,23,21,31,21,21,22, 0, 0,92, 0,23,21,20,34,20,27, 0,26,24,20,34,20],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0,24,20,33,20,28, 0, 0, 0,29,20,20,30,34,20,20, 0, 0, 0, 0,20,20,20,20,25, 0, 0,90, 0,26,24,33],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,26,24,20,21,21,21,20,20,20,34,20,20,20, 0, 2, 0, 0,32,32,27, 0, 0, 0, 0, 0, 0, 0,26,20],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,26,20,20,20,33,20,20,20,20, 0, 0, 0,29,20,20,28,29,23,22,28, 0, 0, 2,29,20],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,35,35,34,35,20,33,34,35, 1, 1,23,34,20,33,34,20,33,20,20,36,21,21,20,20],
];
let tileMapRows = tileMap.length;
let tileMapCols = tileMap[0].length;
let worldW = tileMapCols * M;
let worldH = tileMapRows * M;
function IsSolid(tile)
{
switch (tile)
{
default: // by default, all tiles are solid
return true;
case 0: // empty
case 26: // land w/ water TR
case 27: // land w/ water TL
case 28: // land w/ water BL
case 29: // land w/ water BR
case 30: // water center with vertical bridge
case 31: // water top with vertical bridge
case 32: // water center with horizontal bridge
return false;
}
}
function DrawTile(tile, x, y)
{
// No need to draw tiles that are far from the camera
let cameraDeltaX = abs(cameraX + canvasHalfW - x);
let cameraDeltaY = abs(cameraY + canvasHalfH - y);
if (cameraDeltaX > canvasHalfW + M ||
cameraDeltaY > canvasHalfH + M)
return;
switch (tile)
{
default: // empty ground
break;
case 1: // rock
DrawRock(x, y);
break;
case 2: // tree
DrawLitTree(x, y);
break;
case 20: // water center
DrawWaterCenter(x, y);
break;
case 21: // water top
DrawWaterCenter(x, y);
DrawWaterTopShadow(x, y);
break;
case 22: // water TR
DrawWaterTR(x, y);
break;
case 23: // water TL
DrawWaterTL(x, y);
break;
case 24: // water BL
DrawWaterBL(x, y);
break;
case 25: // water BR
DrawWaterBR(x, y);
break;
case 26: // land w/ water TR
DrawWaterCenter(x, y);
DrawLandTR(x, y);
break;
case 27: // land w/ water TL
DrawWaterCenter(x, y);
DrawLandTL(x, y);
break;
case 28: // land w/ water BL
DrawWaterCenter(x, y);
DrawLandBL(x, y);
break;
case 29: // land w/ water BR
DrawWaterCenter(x, y);
DrawLandBR(x, y);
break;
case 30: // water center with vertical bridge
DrawWaterCenter(x, y);
DrawVerticalBridge(x, y);
break;
case 31: // water top with vertical bridge
DrawWaterCenter(x, y);
DrawWaterTopShadow(x, y);
DrawVerticalBridge(x, y);
break;
case 32: // water center with horizontal bridge
DrawWaterCenter(x, y);
DrawHorizontalBridge(x, y);
break;
case 33: // water with one lily pad
DrawWaterCenter(x, y);
DrawOneLilyPad(x, y);
break;
case 34: // water with two lily pads
DrawWaterCenter(x, y);
DrawTwoLilyPads(x, y);
break;
case 35: // water with rock
DrawWaterCenter(x, y);
DrawRock(x, y);
break;
case 36: // water top with rock
DrawWaterCenter(x, y);
DrawWaterTopShadow(x, y);
DrawRock(x, y);
break;
case 90: // acacia
DrawAcacia(x, y);
break;
case 91: // normals test
DrawNormalsTest(x, y);
break;
case 92: // lit tree
DrawLitTree(x, y);
break;
}
}
function DrawRock(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.rectMode(CORNERS);
layer2.noStroke();
layer2.fill(shadowColor);
layer2.rect(x, y + M * 17/32, x + M * 34/32, y + M * 34/32, M * 9/32);
}
layer2.pop();
// Draw rock on layer4
layer4.push();
{
layer4.rectMode(CORNERS);
layer4.strokeWeight(strokeThickness);
layer4.stroke(strokeColor);
layer4.fill(rockColor0);
layer4.rect(x + M * 2/32, y - M * 0.2, x + M * 30/32, y + M * 31/32, M * 8/32);
layer4.fill(rockColor1);
layer4.noStroke();
layer4.rect(x + M * 5/32, y - M * 0.16, x + M * 27/32, y + M * 0.3, M * 6/32);
}
layer4.pop();
}
function DrawTree(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.noStroke();
layer2.fill(shadowColor);
layer2.ellipse(x + M * 17/32, y + M * 30/32, M * 34/32, M/2);
}
layer2.pop();
// Draw tree on layer4
layer4.push();
{
// Tree triangle layout:
//
// t4 t5 CCW winding on all triangles (and trunk quads):
// t2 t3 0 0
// t0 t1 /| |\
// trunk 1-2 1-2 etc.
let midX = x + M/2;
let t0x0 = midX;
let t0y0 = y + M * 8/32;
let t0x1 = x - M * 3/32;
let t0y1 = y + M * 24/32;
let t0x2 = midX;
let t0y2 = t0y1 + M * 4/32;
let t1x0 = midX;
let t1y0 = t0y0;
let t1x1 = midX;
let t1y1 = t0y2;
let t1x2 = x + M * 35/32;
let t1y2 = t0y1;
let t2x0 = midX;
let t2y0 = y;
let t2x1 = x + M * 1/32;
let t2y1 = y + M * 16/32;
let t2x2 = midX;
let t2y2 = t2y1 + M * 3/32;
let t3x0 = midX;
let t3y0 = t2y0;
let t3x1 = midX;
let t3y1 = t2y2;
let t3x2 = x + M * 31/32;
let t3y2 = t2y1;
let t4x0 = midX;
let t4y0 = y - M * 8/32;
let t4x1 = x + M * 5/32;
let t4y1 = y + M * 8/32;
let t4x2 = midX;
let t4y2 = t4y1 + M * 2/32;
let t5x0 = midX;
let t5y0 = t4y0;
let t5x1 = midX;
let t5y1 = t4y2;
let t5x2 = x + M * 27/32;
let t5y2 = t4y1;
let trunk0x0 = midX;
let trunk0y0 = t0y1;
let trunk0x1 = midX - M * 6/32;
let trunk0y1 = trunk0y0;
let trunk0x2 = trunk0x1;
let trunk0y2 = y + M * 29/32;
let trunk0x3 = trunk0x0;
let trunk0y3 = y + M * 31/32;
let trunk1x0 = trunk0x0;
let trunk1y0 = trunk0y0;
let trunk1x1 = trunk1x0;
let trunk1y1 = trunk0y3;
let trunk1x2 = midX + M * 6/32;
let trunk1y2 = trunk0y2;
let trunk1x3 = trunk1x2;
let trunk1y3 = trunk1y0;
layer4.strokeWeight(strokeThickness);
layer4.stroke(strokeColor);
layer4.fill(treeTrunkColor);
layer4.quad(trunk0x0, trunk0y0, trunk0x1, trunk0y1, trunk0x2, trunk0y2, trunk0x3, trunk0y3);
layer4.fill(treeTrunkColorD);
layer4.quad(trunk1x0, trunk1y0, trunk1x1, trunk1y1, trunk1x2, trunk1y2, trunk1x3, trunk1y3);
layer4.fill(treeMainColor0);
layer4.triangle(t0x0, t0y0, t0x1, t0y1, t0x2, t0y2);
layer4.fill(treeMainColor0D);
layer4.triangle(t1x0, t1y0, t1x1, t1y1, t1x2, t1y2);
layer4.fill(treeMainColor1);
layer4.triangle(t2x0, t2y0, t2x1, t2y1, t2x2, t2y2);
layer4.fill(treeMainColor1D);
layer4.triangle(t3x0, t3y0, t3x1, t3y1, t3x2, t3y2);
layer4.fill(treeMainColor2);
layer4.triangle(t4x0, t4y0, t4x1, t4y1, t4x2, t4y2);
layer4.fill(treeMainColor2D);
layer4.triangle(t5x0, t5y0, t5x1, t5y1, t5x2, t5y2);
}
layer4.pop();
}
function DrawWaterCenter(x, y)
{
// Water is drawn on the lowest layer
layer0.push();
{
layer0.noStroke();
layer0.fill(waterColor);
layer0.rect(x, y, M, M);
}
layer0.pop();
}
function DrawWaterTopShadow(x, y)
{
layer1.push();
{
// draw the top shadow
layer1.rectMode(CORNERS);
layer1.noStroke();
layer1.fill(groundColor);
layer1.rect(x, y, x + M, y + waterDepth);
layer1.fill(shadowColor);
layer1.rect(x, y, x + M, y + waterDepth);
}
layer1.pop();
}
function DrawWaterTR(x, y)
{
// We cheat here and draw the land's shadow together
// with the water in the same (bottom) layer
layer0.push();
{
// First, draw the top shadow
layer0.noStroke();
layer0.fill(shadowColor);
layer0.rect(x, y, M, M, 0, waterCornerRadius, 0, 0);
// layer0.arc(x, y + M, 2 * M, 2 * M, 270, 360);
// Then the water
layer0.fill(waterColor);
layer0.rect(x, y + waterDepth, M, M - waterDepth, 0, waterCornerRadius, 0, 0);
// layer0.arc(x, y + M + waterDepth, 2 * M, 2 * M, 270, 360);
}
layer0.pop();
}
function DrawWaterTL(x, y)
{
// We cheat here and draw the land's shadow together
// with the water in the same (bottom) layer
layer0.push();
{
// First, draw the top shadow
layer0.noStroke();
layer0.fill(shadowColor);
layer0.rect(x, y, M, M, waterCornerRadius, 0, 0, 0);
// Then the water
layer0.fill(waterColor);
layer0.rect(x, y + waterDepth, M, M, waterCornerRadius, 0, 0, 0);
}
layer0.pop();
}
function DrawWaterBL(x, y)
{
// Water is drawn on the lowest layer
layer0.push();
{
layer0.noStroke();
layer0.fill(waterColor);
layer0.rect(x, y, M, M, 0, 0, 0, waterCornerRadius);
}
layer0.pop();
}
function DrawWaterBR(x, y)
{
// Water is drawn on the lowest layer
layer0.push();
{
layer0.noStroke();
layer0.fill(waterColor);
layer0.rect(x, y, M, M, 0, 0, waterCornerRadius, 0);
}
layer0.pop();
}
function DrawLandTR(x, y)
{
// Ground is drawn on the second-lowest layer
layer1.push();
{
// We're just leaving the TR corner of water
layer1.noStroke();
layer1.fill(groundColor);
layer1.rect(x, y, M, M, 0, waterCornerRadius, 0, 0);
}
layer1.pop();
}
function DrawLandTL(x, y)
{
// Ground is drawn on the second-lowest layer
layer1.push();
{
// We're just leaving the TL corner of water
layer1.noStroke();
layer1.fill(groundColor);
layer1.rect(x, y, M, M, waterCornerRadius, 0, 0, 0);
}
layer1.pop();
}
function DrawLandBL(x, y)
{
// TODO:
// Come up with a way of doing this without triply drawing so many pixels
// Ground is drawn on the second-lowest layer
layer1.push();
{
// First we draw the land cover plus the extension that will
// be shadow-colored
layer1.noStroke();
layer1.fill(groundColor);
layer1.rect(x, y, M, M + waterDepth, 0, 0, 0, waterCornerRadius);
// Next we draw the shadow over that entire bit
layer1.fill(shadowColor);
layer1.rect(x, y, M, M + waterDepth, 0, 0, 0, waterCornerRadius);
// Finally we re-draw the land over the shadow minus the extension
layer1.fill(groundColor);
layer1.rect(x, y, M, M, 0, 0, 0, waterCornerRadius);
}
layer1.pop();
}
function DrawLandBR(x, y)
{
// Ground is drawn on the second-lowest layer
layer1.push();
{
layer1.noStroke();
layer1.fill(groundColor);
layer1.rect(x, y, M, M + waterDepth, 0, 0, waterCornerRadius, 0);
// Next we draw the shadow over that entire bit
layer1.fill(shadowColor);
layer1.rect(x, y, M, M + waterDepth, 0, 0, waterCornerRadius, 0);
// Finally we re-draw the land over the shadow minus the extension
layer1.fill(groundColor);
layer1.rect(x, y, M, M, 0, 0, waterCornerRadius, 0);
}
layer1.pop();
}
function DrawOneLilyPad(x, y)
{
// Lily pads are drawn on the ground layer
layer1.push();
{
layer1.strokeWeight(strokeThickness);
layer1.stroke(strokeColor);
layer1.fill(lilyPadColor); // We cheat and draw lily pads here too
layer1.arc(x + M * 0.4, y + M * 0.4, M * 0.6, M * 0.48, 350, 320, PIE);
}
layer1.pop();
}
function DrawTwoLilyPads(x, y)
{
// Lily pads are drawn on the ground layer
layer1.push();
{
layer1.strokeWeight(strokeThickness);
layer1.stroke(strokeColor);
layer1.fill(lilyPadColor);
layer1.arc(x + M * 0.65, y + M * 0.75, M * 0.4, M * 0.32, 135, 115, PIE);
layer1.arc(x + M * 0.3, y + M * 0.3, M * 0.3, M * 0.24, 40, 0, PIE);
}
layer1.pop();
}
function DrawVerticalBridge(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.rectMode(CORNERS);
layer2.noStroke();
layer2.fill(shadowColor);
layer2.rect(x + M * 2/32, y + M * 2/32, x + M * 34/32, y + M * 34/32, M * 2/32);
}
layer2.pop();
// Draw bridge on layer3
layer3.push();
{
layer3.rectMode(CORNERS);
layer3.strokeWeight(strokeThickness);
layer3.stroke(strokeColor);
layer3.fill(bridgeColor0);
layer3.rect(x + M * 3/32, y - M * 2/32, x + M * 10/32, y + M * 34/32);
layer3.rect(x + M * 29/32, y - M * 2/32, x + M * 22/32, y + M * 34/32);
layer3.fill(bridgeColor1);
layer3.rect(x + M * 3/32, y - M * 2/32, x + M * 30/32, y + M * 6/32);
layer3.rect(x + M * 2/32, y + M * 6/32, x + M * 29/32, y + M * 14/32);
layer3.rect(x + M * 3/32, y + M * 14/32, x + M * 30/32, y + M * 22/32);
layer3.rect(x + M * 2/32, y + M * 22/32, x + M * 29/32, y + M * 30/32);
// layer3.fill(bridgeColor0);
// layer3.rect(x + M * 3/32, y - M * 8/32, x + M * 8/32, y + M * 2/32);
// layer3.rect(x + M * 29/32, y - M * 8/32, x + M * 24/32, y + M * 2/32);
// layer3.rect(x + M * 3/32, y + M * 18/32, x + M * 8/32, y + M * 28/32);
// layer3.rect(x + M * 29/32, y + M * 18/32, x + M * 24/32, y + M * 28/32);
// layer3.fill(bridgeColor2);
// layer3.rect(x + M * 3/32, y - M * 8/32, x + M * 8/32, y - M * 5/32);
// layer3.rect(x + M * 29/32, y - M * 8/32, x + M * 24/32, y - M * 5/32);
// layer3.rect(x + M * 3/32, y + M * 18/32, x + M * 8/32, y + M * 21/32);
// layer3.rect(x + M * 29/32, y + M * 18/32, x + M * 24/32, y + M * 21/32);
}
layer3.pop();
}
function DrawHorizontalBridge(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.rectMode(CORNERS);
layer2.noStroke();
layer2.fill(shadowColor);
layer2.rect(x, y + M * 5/32, x + M * 32/32, y + M * 33/32, M * 2/32);
// We also draw the bottom slats on this same layer
layer2.strokeWeight(strokeThickness);
layer2.stroke(strokeColor);
layer2.fill(bridgeColor0);
layer2.rect(x - M * 2/32, y + M * 5/32, x + M * 34/32, y + M * 11/32);
layer2.rect(x - M * 2/32, y + M * 24/32, x + M * 34/32, y + M * 30/32);
}
layer2.pop();
// Draw bridge on layer3
layer3.push();
{
layer3.rectMode(CORNERS);
layer3.strokeWeight(strokeThickness);
layer3.stroke(strokeColor);
layer3.fill(bridgeColor1);
layer3.rect(x , y + M * 5/32, x + M * 8/32, y + M * 28/32);
layer3.rect(x + M * 8/32, y + M * 4/32, x + M * 16/32, y + M * 27/32);
layer3.rect(x + M * 16/32, y + M * 5/32, x + M * 24/32, y + M * 28/32);
layer3.rect(x + M * 24/32, y + M * 4/32, x + M * 32/32, y + M * 27/32);
// layer3.fill(bridgeColor0);
// layer3.rect(x + M * 1/32, y - M * 2/32, x + M * 6/32, y + M * 8/32);
// layer3.rect(x + M * 31/32, y - M * 2/32, x + M * 26/32, y + M * 8/32);
// layer3.rect(x + M * 1/32, y + M * 15/32, x + M * 6/32, y + M * 25/32);
// layer3.rect(x + M * 31/32, y + M * 15/32, x + M * 26/32, y + M * 25/32);
// layer3.fill(bridgeColor2);
// layer3.rect(x + M * 1/32, y - M * 2/32, x + M * 6/32, y + M * 1/32);
// layer3.rect(x + M * 31/32, y - M * 2/32, x + M * 26/32, y + M * 1/32);
// layer3.rect(x + M * 1/32, y + M * 15/32, x + M * 6/32, y + M * 18/32);
// layer3.rect(x + M * 31/32, y + M * 15/32, x + M * 26/32, y + M * 18/32);
}
layer3.pop();
}
function DrawAcacia(x, y)
{
let trunk = color(30, 50, 50);
let trunkD = color(70, 50, 20);
let canopyTop = color(70, 40, 65);
let canopyTopD = color(110, 40, 45);
let canopyBottom = color(80, 50, 25);
let canopyBottomD = color(120, 50, 15);
let b0x0 = x + M * 16/32;
let b0y0 = y - M * 8/32;
let b0x1 = b0x0 + M * 8/32;
let b0y1 = b0y0 + M * 24/32;
let b0x2 = b0x1;
let b0y2 = b0y1 - M * 8/32;
let b1x0 = x - M * 8/32;
let b1y0 = y;
let b1x1 = b1x0 + M * 17/32;
let b1y1 = b1y0 + M * 20/32;
let b1x2 = b1x1 - M * 2/32;
let b1y2 = b1y1 - M * 8/32;
let b2x0 = x + M * 48/32;
let b2y0 = y;
let b2x1 = b2x0 - M * 20/32;
let b2y1 = b2y0 + M * 10/32;
let b2x2 = b2x1 - M * 3/32;
let b2y2 = b2y1 + M * 8/32;
let t0x0 = x + M * 24/32;
let t0y0 = y;
let t0x1 = t0x0 - M * 16/32;
let t0y1 = t0y0 + M * 28/32;
let t0x2 = t0x1 + M * 8/32;
let t0y2 = t0y0 + M;
let t0x3 = t0x0 + M * 6/32;
let t0y3 = t0y0;
let t1x0 = t0x3;
let t1y0 = t0y3;
let t1x1 = t0x2;
let t1y1 = t0y2;
let t1x2 = t1x1 + M * 8/32;
let t1y2 = t1y1 - M * 4/32;
let t1x3 = x + M;
let t1y3 = t1y0 + M * 2/32;
let t2x0 = x;
let t2y0 = y + M * 2/32;
let t2x1 = t2x0 + M * 8/32;
let t2y1 = y + M * 28/32;
let t2x2 = t2x1 + M * 8/32;
let t2y2 = t2y1 + M * 4/32;
let t2x3 = t2x2 - M * 8/32;
let t2y3 = y;
let t3x0 = t2x3;
let t3y0 = t2y3;
let t3x1 = t2x2;
let t3y1 = t2y2;
let t3x2 = t3x1 + M * 8/32;
let t3y2 = t3y1 - M * 4/32;
let t3x3 = t3x0 + M * 4/32;
let t3y3 = t3y0 + M * 1/32;
let c0x0 = x - M;
let c0y0 = y;
let c0x1 = c0x0 + M * 24/32;
let c0y1 = c0y0 + M * 4/32;
let c0x2 = c0x1 - M * 8/32;
let c0y2 = c0y0 - M * 24/32;
let c1x0 = x + M * 12/32;
let c1y0 = y - M * 26/32;
let c1x1 = c1x0 + M * 4/32;
let c1y1 = c1y0 + M * 20/32;
let c1x2 = c1x1 + M * 24/32;
let c1y2 = c1y1;
let c1x3 = x + M;
let c1y3 = y - M;
let c2x0 = c0x2;
let c2y0 = c0y2;
let c2x1 = c0x1;
let c2y1 = c0y1;
let c2x2 = c1x1;
let c2y2 = c1y1;
let c2x3 = c1x0;
let c2y3 = c1y0;
let c3x0 = c1x3;
let c3y0 = c1y3;
let c3x1 = c1x2;
let c3y1 = c1y2;
let c3x2 = x + 2 * M;
let c3y2 = y;
let c3x3 = c3x2 - M * 8/32;
let c3y3 = c3y2 - M/2;
let c4x0 = c0x0;
let c4y0 = c0y0;
let c4x1 = c0x1;
let c4y1 = c4y0 + M * 8/32;
let c4x2 = c4x1;
let c4y2 = c0y1;
let c5x0 = c1x1;
let c5y0 = c1y1;
let c5x1 = c5x0 + M * 8/32;
let c5y1 = c5y0 + M * 6/32;
let c5x2 = c5x1 + M * 24/32;
let c5y2 = c5y1 + M * 8/32;
let c5x3 = c5x2 - M * 8/32;
let c5y3 = c5y2 - M/2;
let c6x0 = c4x2;
let c6y0 = c4y2;
let c6x1 = c4x1;
let c6y1 = c4y1;
let c6x2 = c5x1;
let c6y2 = c5y1;
let c6x3 = c5x0;
let c6y3 = c5y0;
let c7x0 = c5x3;
let c7y0 = c5y3;
let c7x1 = c5x2;
let c7y1 = c5y2;
let c7x2 = c3x2;
let c7y2 = c3y2;
layer2.push();
{
layer2.noStroke();
layer2.fill(shadowColor);
layer2.ellipse(x + M * 18/32, y + M * 30/32, M * 2.5, M);
}
layer2.pop();
layer4.push();
{
layer4.strokeWeight(strokeThickness);
layer4.stroke(strokeColor);
layer4.fill(trunkD);
layer4.triangle(b0x0, b0y0, b0x1, b0y1, b0x2, b0y2);
layer4.fill(trunk);
layer4.quad(t0x0, t0y0, t0x1, t0y1, t0x2, t0y2, t0x3, t0y3);
layer4.quad(t2x0, t2y0, t2x1, t2y1, t2x2, t2y2, t2x3, t2y3);
layer4.fill(trunkD);
layer4.quad(t1x0, t1y0, t1x1, t1y1, t1x2, t1y2, t1x3, t1y3);
layer4.quad(t3x0, t3y0, t3x1, t3y1, t3x2, t3y2, t3x3, t3y3);
layer4.fill(trunk);
layer4.triangle(b1x0, b1y0, b1x1, b1y1, b1x2, b1y2);
layer4.fill(trunkD);
layer4.triangle(b2x0, b2y0, b2x1, b2y1, b2x2, b2y2);
}
layer4.pop();
layer5.push();
{
layer5.strokeWeight(strokeThickness);
layer5.stroke(strokeColor);
layer5.fill(canopyBottom);
layer5.triangle(c4x0, c4y0, c4x1, c4y1, c4x2, c4y2);
layer5.quad(c5x0, c5y0, c5x1, c5y1, c5x2, c5y2, c5x3, c5y3);
layer5.fill(canopyBottomD);
layer5.quad(c6x0, c6y0, c6x1, c6y1, c6x2, c6y2, c6x3, c6y3);
layer5.triangle(c7x0, c7y0, c7x1, c7y1, c7x2, c7y2);
layer5.fill(canopyTop);
layer5.triangle(c0x0, c0y0, c0x1, c0y1, c0x2, c0y2);
layer5.quad(c1x0, c1y0, c1x1, c1y1, c1x2, c1y2, c1x3, c1y3);
layer5.fill(canopyTopD);
layer5.quad(c2x0, c2y0, c2x1, c2y1, c2x2, c2y2, c2x3, c2y3);
layer5.quad(c3x0, c3y0, c3x1, c3y1, c3x2, c3y2, c3x3, c3y3);
}
layer5.pop();
}
function DrawNormalsTest(x, y)
{
let halfM = M/2;
// right
let t0p0 = createVector(x + M, y);
let t0p1 = createVector(x + halfM, y + halfM);
let t0p2 = createVector(t0p0.x, y + M);
// top
let t1p0 = createVector(t0p1.x, t0p1.y);
let t1p1 = createVector(t0p0.x, t0p0.y);
let t1p2 = createVector(x, y);
// left
let t2p0 = createVector(t1p0.x, t1p0.y);
let t2p1 = createVector(t1p2.x, t1p2.y);
let t2p2 = createVector(t2p1.x, t0p2.y);
// bottom
let t3p0 = createVector(t2p0.x, t2p0.y);
let t3p1 = createVector(t2p2.x, t2p2.y);
let t3p2 = createVector(t0p2.x, t3p1.y);
// normals
let n0 = createVector(1, 0, 2).normalize();
let n1 = createVector(0, -1, 2).normalize();
let n2 = createVector(-1, 0, 2).normalize();
let n3 = createVector(0, 1, 2).normalize();
// positions
let t0Pos = createVector(x+3*M/4, y+M/2);
let t1Pos = createVector(x+M/2, y+M/4);
let t2Pos = createVector(x+M/4, y+M/2);
let t3Pos = createVector(x+M/2, y+3*M/4);
// drawing
layer1.push();
{
layer1.noStroke();
PushLighting();
SetEmission(0, 0, 0);
SetAmbient(0.05, 0.01, 0.2);
SetDiffuse(0, 1, 0.5);
SetSpecular(1, 0.9, 0.6);
SetKA(1);
SetKD(1);
SetKS(0.03);
SetShininess(0);
Tri(t0p0, t0p1, t0p2, t0Pos, n0, layer1);
Tri(t1p0, t1p1, t1p2, t1Pos, n1, layer1);
Tri(t2p0, t2p1, t2p2, t2Pos, n2, layer1);
Tri(t3p0, t3p1, t3p2, t3Pos, n3, layer1);
PopLighting();
}
layer1.pop();
}
function DrawLitTree(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.noStroke();
layer2.fill(shadowColor);
layer2.ellipse(x + M * 17/32, y + M * 30/32, M * 34/32, M/2);
}
layer2.pop();
// Draw tree on layer4
// Tree triangle layout:
//
// t4 t5 CCW winding on all triangles (and trunk quads):
// t2 t3 0 0
// t0 t1 /| |\
// trunk 1-2 1-2 etc.
let midX = x + M/2;
let t0p0 = createVector(midX, y + 8*M/32);
let t0p1 = createVector(x - 3*M/32, y + 24*M/32);
let t0p2 = createVector(t0p0.x, t0p1.y + 4*M/32);
let t1p0 = t0p0;
let t1p1 = createVector(t1p0.x, t0p2.y)
let t1p2 = createVector(x + 35*M/32, t0p1.y)
let t2p0 = createVector(midX, y);
let t2p1 = createVector(x + M/32, y + M/2);
let t2p2 = createVector(t2p0.x, t2p1.y + 3*M/32);
let t3p0 = t2p0;
let t3p1 = createVector(t3p0.x, t2p2.y);
let t3p2 = createVector(x + 31*M/32, t2p1.y);
let t4p0 = createVector(midX, y - 8*M/32);
let t4p1 = createVector(x + 5*M/32, y + 8*M/32);
let t4p2 = createVector(t4p0.x, t4p1.y + 2*M/32);
let t5p0 = t4p0;
let t5p1 = createVector(t5p0.x, t4p2.y);
let t5p2 = createVector(x + 27*M/32, t4p1.y);
let posT0 = createVector(x + M/4, y + 29*M/32, M/3);
let posT1 = createVector(x + 3*M/4, y + 29*M/32, M/3);
let posT2 = createVector(x + 3*M/8, y + 29*M/32, 2*M/3);
let posT3 = createVector(x + 5*M/8, y + 29*M/32, 2*M/3);
let posT4 = createVector(x + 7*M/16, y + 29*M/32, M);
let posT5 = createVector(x + 9*M/16, y + 29*M/32, M);
let q0p0 = createVector(midX, t0p1.y);
let q0p1 = createVector(midX - 6*M/32, q0p0.y);
let q0p2 = createVector(q0p1.x, y + 29*M/32);
let q0p3 = createVector(q0p0.x, y + 31*M/32);
let q1p0 = q0p0;
let q1p1 = q0p3;
let q1p2 = createVector(midX + 6*M/32, q0p2.y);
let q1p3 = createVector(q1p2.x, q1p0.y);
let posQ0 = createVector(x + 15*M/32, y + 29*M/32, M/16);
let posQ1 = createVector(x + 17*M/32, y + 29*M/32, M/16);
let q0N = createVector(-1, 1, 0.2).normalize();
let q1N = createVector(1, 1, 0.2).normalize();
let t0N = createVector(-1, 1, 1).normalize();
let t1N = createVector(1, 1, 1).normalize();
let t2N = createVector(-1, 1, 1.5).normalize();
let t3N = createVector(1, 1, 1.5).normalize();
let t4N = createVector(-1, 1, 2).normalize();
let t5N = createVector(1, 1, 2).normalize();
layer4.push();
{
layer4.noStroke();
// layer4.stroke(strokeColor);
// layer4.strokeWeight(strokeThickness);
PushLighting();
SetEmission(0, 0, 0);
SetAmbient(0.2, 0.15, 0.4);
SetDiffuse(1, 2/3, 1/2);
SetSpecular(1, 0.9, 0.6);
SetKA(0.75);
SetKD(0.5);
SetKS(0.01);
SetShininess(0);
Quad(q0p0, q0p1, q0p2, q0p3, posQ0, q0N, layer4);
Quad(q1p0, q1p1, q1p2, q1p3, posQ1, q1N, layer4);
SetDiffuse(77/255, 1, 106/255);
SetKA(0.75);
SetKD(0.5);
SetKS(0.01);
Tri(t0p0, t0p1, t0p2, posT0, t0N, layer4);
Tri(t1p0, t1p1, t1p2, posT1, t1N, layer4);
SetKD(0.75);
Tri(t2p0, t2p1, t2p2, posT2, t2N, layer4);
Tri(t3p0, t3p1, t3p2, posT3, t3N, layer4);
SetKD(1);
Tri(t4p0, t4p1, t4p2, posT4, t4N, layer4);
Tri(t5p0, t5p1, t5p2, posT5, t5N, layer4);
PopLighting();
}
layer4.pop();
}
function DrawLitVBridge(x, y)
{
// Draw shadow on layer2
layer2.push();
{
layer2.rectMode(CORNERS);
layer2.noStroke();
layer2.fill(shadowColor);
layer2.rect(x + M * 2/32, y + M * 2/32, x + M * 34/32, y + M * 34/32, M * 2/32);
}
layer2.pop();
// Draw bridge on layer3
layer3.rectMode(CORNERS);
layer3.strokeWeight(strokeThickness);
layer3.stroke(strokeColor);
layer3.fill(bridgeColor0);
layer3.rect(x + M * 3/32, y - M * 2/32, x + M * 10/32, y + M * 34/32);
layer3.rect(x + M * 29/32, y - M * 2/32, x + M * 22/32, y + M * 34/32);
layer3.fill(bridgeColor1);
layer3.rect(x + M * 3/32, y - M * 2/32, x + M * 30/32, y + M * 6/32);
layer3.rect(x + M * 2/32, y + M * 6/32, x + M * 29/32, y + M * 14/32);
layer3.rect(x + M * 3/32, y + M * 14/32, x + M * 30/32, y + M * 22/32);
layer3.rect(x + M * 2/32, y + M * 22/32, x + M * 29/32, y + M * 30/32);
// layer3.fill(bridgeColor0);
// layer3.rect(x + M * 3/32, y - M * 8/32, x + M * 8/32, y + M * 2/32);
// layer3.rect(x + M * 29/32, y - M * 8/32, x + M * 24/32, y + M * 2/32);
// layer3.rect(x + M * 3/32, y + M * 18/32, x + M * 8/32, y + M * 28/32);
// layer3.rect(x + M * 29/32, y + M * 18/32, x + M * 24/32, y + M * 28/32);
// layer3.fill(bridgeColor2);
// layer3.rect(x + M * 3/32, y - M * 8/32, x + M * 8/32, y - M * 5/32);
// layer3.rect(x + M * 29/32, y - M * 8/32, x + M * 24/32, y - M * 5/32);
// layer3.rect(x + M * 3/32, y + M * 18/32, x + M * 8/32, y + M * 21/32);
// layer3.rect(x + M * 29/32, y + M * 18/32, x + M * 24/32, y + M * 21/32);
}