Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // See result at http://gfycat.com/ValuableIdioticAfricanpiedkingfisher
- // Settings
- var cellWidth = 15;
- var cellHeight = 15;
- var cellOffsetX = -1;
- var cellOffsetY = -1;
- var rows = 20;
- var cols = 20;
- var startX = 7;
- var startY = 0;
- var startDir = 2;
- var rotateDivide = 5;
- // Return 0 for empty, 1 for snake, 2 for apple
- function getCellContent(frame, cellX, cellY) {
- if (cellX < 0 || cellX >= cols ||
- cellY < 0 || cellY >= rows) {
- return 0;
- }
- var pixelX = cellX * cellWidth + cellOffsetX;
- var pixelY = cellY * cellHeight + cellOffsetY;
- var snakeX = pixelX + 7;
- var snakeY = pixelY + 7;
- var appleX = pixelX + 11;
- var appleY = pixelY + 11;
- var snakeTestPixel = frame.getPixel(snakeX, snakeY);
- var appleTestPixel = frame.getPixel(appleX, appleY);
- if (appleTestPixel.red == 255) {
- return 2;
- } else if (snakeTestPixel.red == 255) {
- return 1;
- } else {
- return 0;
- }
- }
- function getDirOffsetX(dir) {
- if (dir == 2) {
- return -1;
- } else if (dir == 3) {
- return 1;
- } else {
- return 0;
- }
- }
- function getDirOffsetY(dir) {
- if (dir == 0) {
- return -1;
- } else if (dir == 1) {
- return 1;
- } else {
- return 0;
- }
- }
- // Return the next position as a triplet
- // 0 = up, 1 = down, 2 = left, 3 = right, -1 = no head movement
- // [x, y, dir] (coordinates in cells unit)
- function findNextMove(previousFrame, frame, lastX, lastY) {
- for (var dir = 0; dir <= 3; ++dir) {
- var checkX = lastX + getDirOffsetX(dir);
- var checkY = lastY + getDirOffsetY(dir);
- var oldContent = getCellContent(previousFrame, checkX, checkY);
- if (oldContent == 1) {
- continue;
- }
- var newContent = getCellContent(frame, checkX, checkY);
- if (newContent == 1) {
- return [checkX, checkY, dir];
- }
- }
- return [lastX, lastY, -1];
- }
- function fillMoves(source) {
- var frameCount = source.frameCount;
- var previousFrame = source.getFrame(0);
- var lastX = startX;
- var lastY = startY;
- var moves = [[startX, startY, startDir]];
- for (var currentFrame = 1; currentFrame < frameCount; ++currentFrame) {
- var frame = source.getFrame(currentFrame);
- var move = findNextMove(previousFrame, frame, lastX, lastY);
- moves[moves.length] = move;
- lastX = move[0];
- lastY = move[1];
- previousFrame = frame;
- }
- return moves;
- }
- function dirToAngle(dir) {
- switch (dir) {
- case 0: return 0;
- case 1: return Math.PI;
- case 2: return Math.PI / 2;
- case 3: return -Math.PI / 2;
- }
- }
- function transformCenter(canvas, cellX, cellY, angle) {
- canvas.identity();
- canvas.translate(canvas.width / 2 -cellX * cellWidth - cellOffsetX - cellWidth / 2, canvas.height / 2 -cellY * cellHeight - cellOffsetY - cellHeight / 2);
- if (angle != 0) {
- canvas.rotatecenter(angle, cellX * cellWidth + cellOffsetX + cellWidth / 2, cellY * cellHeight + cellOffsetY + cellHeight / 2);
- }
- }
- function blankCanvas(canvas, color) {
- canvas.identity();
- canvas.scale(canvas.width, canvas.height);
- canvas.fillRect(color);
- }
- function computeAngleOffset(oldDir, newDir) {
- // TODO wake up brain to write this correctly
- var dir;
- switch (oldDir) {
- case 0:
- switch(newDir) {
- case 2: dir = 1; break;
- case 3: dir = -1; break;
- }
- break;
- case 1:
- switch(newDir) {
- case 2: dir = -1; break;
- case 3: dir = 1; break; // OK
- }
- break;
- case 2:
- switch(newDir) {
- case 0: dir = -1; break;
- case 1: dir = 1; break; // OK
- }
- break;
- case 3:
- switch(newDir) {
- case 0: dir = 1; break; // OK
- case 1: dir = -1; break;
- }
- break;
- }
- return dir * Math.PI / 2;
- }
- function render(source, dest, moves, doRotate) {
- var black = new Color(0, 0, 0, 255);
- var frame = source.getFrame(0);
- var w = frame.width * 2;
- var h = frame.height * 2;
- var canvas = new Canvas(w, h);
- var frameCount = source.frameCount;
- var previousDir = moves[0][2];
- if (moves[0][2] == -1) {
- // Failsafe
- moves[0][2] = 0;
- }
- if (!doRotate) {
- previousDir = 0;
- }
- blankCanvas(canvas, black);
- transformCenter(canvas, moves[0][0], moves[0][1], dirToAngle(moves[0][2]));
- canvas.drawImage(frame);
- dest.addCanvas(canvas, source.getFrameDelay(0));
- for (var currentFrame = 1; currentFrame < frameCount; ++currentFrame) {
- print("Rendering frame " + (currentFrame + 1) + " out of " + frameCount);
- if (doRotate) {
- var newDir = moves[currentFrame][2];
- if (newDir != previousDir && newDir != -1) {
- // Do a rotation sequence
- var oldAngle = dirToAngle(previousDir);
- var offset = computeAngleOffset(previousDir, newDir) / rotateDivide;
- for (var angleIter = 1; angleIter < (rotateDivide + 1); ++angleIter) {
- blankCanvas(canvas, black);
- transformCenter(canvas, moves[currentFrame - 1][0], moves[currentFrame - 1][1], oldAngle + offset * angleIter);
- canvas.drawImage(frame);
- dest.addCanvas(canvas, source.getFrameDelay(currentFrame - 1));
- }
- previousDir = newDir;
- }
- }
- blankCanvas(canvas, black);
- frame = source.getFrame(currentFrame);
- transformCenter(canvas, moves[currentFrame][0], moves[currentFrame][1], dirToAngle(previousDir));
- canvas.drawImage(frame);
- dest.addCanvas(canvas, source.getFrameDelay(currentFrame));
- }
- }
- var source = new FrameSource("e:/src.gif");
- var moves = fillMoves(source);
- //var dest = new FrameSink("e:/dst1.gif");
- var dest2 = new FrameSink("e:/dst2.gif");
- //var dest2 = new FrameSink("e:/t2");
- //render(source, dest, moves, false);
- render(source, dest2, moves, true);
- //dest.close();
- dest2.close();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement