xxxxxxxxxx
314
let mainBuffer;
let aspect = 16 / 9;
// let aspect = 1;
let tileAtlasColW = 32;
let tileAtlasRowH = 32;
let bufferCols = 16;
let bufferRows = bufferCols / aspect;
let scalingFactor = 2;
let mainBufferW = tileAtlasColW * bufferCols;
let mainBufferH = tileAtlasRowH * bufferRows;
let canvasW = mainBufferW * scalingFactor;
let canvasH = mainBufferH * scalingFactor;
let postNearest;
let postScanline;
let postWeightedLinear;
let postProcessShader;
let defaultColorArray = [0.05, 0.03, 0.3, 1.0];
let heroAtlas;
let atlasCols;
let heroAtlasColW = 64;
let heroAtlasRowH = 64;
let heroX = -24;
let heroY = -24;
let heroPos;
let movementSpeed = 100;
let linearWeight = 1;
let loopMode =
{
loop : 0,
pingPong : 1,
};
let facingR =
{
walk :
{
frames : [0, 1, 2, 3, 4, 5, 6, 7],
delays : [0.1],
mode : loopMode.loop,
toString : () => "walk R",
},
idle :
{
frames : [ 2, 7, 2, 7, 2, 3, 2, 3],
delays : [ 5, 0.1, 0.1, 0.1, 5, 0.1, 0.1, 0.1],
mode : loopMode.loop,
toString : () => "idle R",
},
};
let facingD =
{
walk :
{
frames : [ 8, 9, 10, 11, 12, 13, 14, 15],
delays : [0.1],
mode : loopMode.loop,
toString : () => "walk D",
},
idle :
{
frames : [ 10, 15, 10, 15, 10, 11, 10, 11],
delays : [ 5, 0.1, 0.1, 0.1, 5, 0.1, 0.1, 0.1],
mode : loopMode.loop,
toString : () => "idle D",
},
};
let facingL =
{
walk :
{
frames : [16, 17, 18, 19, 20, 21, 22, 23],
delays : [0.1],
mode : loopMode.loop,
toString : () => "walk L",
},
idle :
{
frames : [ 18, 23, 18, 23, 18, 19, 18, 19],
delays : [ 5, 0.1, 0.1, 0.1, 5, 0.1, 0.1, 0.1],
mode : loopMode.loop,
toString : () => "idle L",
},
};
let facingU =
{
walk :
{
frames : [24, 25, 26, 27, 28, 29, 30, 31],
delays : [0.1],
mode : loopMode.loop,
toString : () => "walk U",
},
idle :
{
frames : [ 26, 31, 26, 31, 26, 27, 26, 27],
delays : [ 5, 0.1, 0.1, 0.1, 5, 0.1, 0.1, 0.1],
mode : loopMode.loop,
toString : () => "idle U",
},
};
let currentFacing = facingD;
let currentState = currentFacing.idle;
let frameIndex = 0;
let animationTimer = 0;
function preload()
{
heroAtlas = loadImage("HeroAtlas.png");
postNearest = loadShader("basic.vert", "postNearest.frag");
postScanline = loadShader("basic.vert", "postScanline.frag");
postWeightedLinear = loadShader("basic.vert", "postWeightedLinear.frag");
}
function setup()
{
createCanvas(canvasW, canvasH, WEBGL);
mainBuffer = createGraphics(mainBufferW, mainBufferH, WEBGL);
atlasCols = heroAtlas.width / heroAtlasColW;
angleMode(DEGREES);
heroPos = createVector(heroX, heroY);
postProcessShader = postWeightedLinear;
}
function draw()
{
let dt = GetDt();
clear();
mainBuffer.background(200, 180, 120);
RectangularMovement(dt);
DrawHero();
UpdateAnimation(dt);
Composite(dt);
}
function RectangularMovement(dt)
{
let deltaPos = createVector();
if (keyIsDown(RIGHT_ARROW))
deltaPos.x += 1;
if (keyIsDown(LEFT_ARROW))
deltaPos.x -= 1;
if (keyIsDown(DOWN_ARROW))
deltaPos.y += 1;
if (keyIsDown(UP_ARROW))
deltaPos.y -= 1;
if (deltaPos.x === 0 && deltaPos.y === 0)
{
if (currentState != currentFacing.idle)
{
frameIndex = 0;
animationTimer = 0;
currentState = currentFacing.idle;
}
return;
}
deltaPos.normalize();
deltaPos.mult(movementSpeed * dt)
heroPos.add(deltaPos);
let angle = atan2(-deltaPos.y, deltaPos.x);
// POSSIBLE ANGLES
// angle >= 67.5
// angle < 112.5
// angle >= 112.5 | angle >= 22.5
// angle < 157.5 \ | / angle < 67.5
// \ | /
// \ | / angle >= -22.5
// angle >= 157.5 ---------+--------- angle < 22.5
// angle < -157.5 / | \
// / | \
// angle >= -157.5 / | \ angle >= -67.5
// angle < -112.5 | angle < -22.5
// angle >= -112.5
// angle < -67.5
if ( -22.5 <= angle && angle < 22.5) // right
{
currentFacing = facingR;
}
else if ( 22.5 <= angle && angle < 67.5) // up right
{
if (currentFacing === facingD)
currentFacing = facingR;
else if (currentFacing === facingL)
currentFacing = facingU;
}
else if ( 67.5 <= angle && angle < 112.5) // up
{
currentFacing = facingU;
}
else if ( 112.5 <= angle && angle < 157.5) // up left
{
if (currentFacing === facingR)
currentFacing = facingU;
else if (currentFacing === facingD)
currentFacing = facingL;
}
else if ( 157.5 <= angle || angle < -157.5) // left -- we need OR here!
{
currentFacing = facingL;
}
else if (-157.5 <= angle && angle < -112.5) // down left
{
if (currentFacing === facingU)
currentFacing = facingL;
else if (currentFacing === facingR)
currentFacing = facingD;
}
else if (-112.5 <= angle && angle < -67.5) // down
{
currentFacing = facingD;
}
else // ( -67.5 <= angle && angle < -22.5) // down right
{
if (currentFacing === facingU)
currentFacing = facingR;
else if (currentFacing === facingL)
currentFacing = facingD;
}
if (currentState != currentFacing.walk)
{
frameIndex = 0;
animationTimer = 0;
currentState = currentFacing.walk;
}
}
function DrawHero()
{
let gPos = createVector(round(heroPos.x), round(heroPos.y));
let currentFrame = currentState.frames[frameIndex];
let atlasIndexX = currentFrame % atlasCols;
let atlasIndexY = int(currentFrame / atlasCols);
let sw = heroAtlasColW;
let sh = heroAtlasRowH;
let sx = atlasIndexX * heroAtlasColW;
let sy = atlasIndexY * heroAtlasRowH;
mainBuffer.image(heroAtlas, gPos.x, gPos.y, sw, sh, sx, sy, sw, sh);
}
function UpdateAnimation(dt)
{
let currentDelay = currentState.delays[frameIndex % currentState.delays.length];
animationTimer += dt;
if (animationTimer >= currentDelay)
{
// animationTimer -= currentDelay;
animationTimer = 0;
frameIndex = (frameIndex + 1) % currentState.frames.length;
}
}
function Composite(dt)
{
if (keyIsDown(88)) // X
linearWeight += dt;
if (keyIsDown(90)) // Z
linearWeight -= dt;
// linearWeight = constrain(linearWeight, 0, 1);
postProcessShader.setUniform("uSource", mainBuffer);
postProcessShader.setUniform("uSourceSize", [mainBufferW, mainBufferH]);
postProcessShader.setUniform("uDestSize", [canvasW, canvasH]);
postProcessShader.setUniform("uDefaultColor", defaultColorArray);
postProcessShader.setUniform("uWeight", linearWeight);
shader(postProcessShader);
rect(0, 0, 0, 0);
}
function keyPressed()
{
if (keyCode === 49)
postProcessShader = postNearest;
if (keyCode === 50)
postProcessShader = postScanline;
if (keyCode === 51)
postProcessShader = postWeightedLinear;
}
function GetDt()
{
return deltaTime / 1000;
}