All files / js/visualization canvasDraw.ts

98.31% Statements 58/59
90% Branches 18/20
100% Functions 3/3
98.28% Lines 57/58

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                      15x               494x 494x   494x 3x   491x     494x 494x 494x 494x 91x   494x 114x   494x 117x   494x 172x     494x 494x 494x 494x 3223x   494x 494x       478x       478x 478x 478x   478x 478x   478x 478x 478x 478x 478x     494x   478x 100x 100x 100x 100x 100x 100x     478x 155x 155x 155x 155x 155x 155x     478x 2x 2x 2x 2x 2x 2x      
import {desaturized_idx2color, idx2color} from "./color";
import JsSnake from "../SnakeLogic/JsSnake";
import JsGameState from "../SnakeLogic/JsGameState";
 
export type VisualizationOptions = {
    scale: number,
    bgColor: string,
    foodColor: string,
    blurred: boolean
}
 
export const defaultVisualizationOptions: VisualizationOptions = {
    scale: 20,
    foodColor: "#cc2200",
    bgColor: "#000",
    blurred: false,
}
 
function drawSnake(ctx: CanvasRenderingContext2D, snake: JsSnake, options: VisualizationOptions) {
    const {scale} = options;
    const thickness = 0.8;
    let color;
    if(snake.dead) {
        color = desaturized_idx2color(snake.idx);
    } else {
        color = idx2color(snake.idx)
    }
 
    ctx.fillStyle = color;
    let x = snake.head.x;
    let y = snake.head.y;
    if(snake.headDirection === "right") {
        ctx.fillRect(x*scale+scale/2., y*scale+scale/4, scale/2., scale/2);
    }
    if(snake.headDirection === "left") {
        ctx.fillRect(x*scale, y*scale+scale/4, scale/2., scale/2);
    }
    if(snake.headDirection === "down") {
        ctx.fillRect(x*scale+scale/4., y*scale+scale/2, scale/2., scale/2);
    }
    if(snake.headDirection === "up") {
        ctx.fillRect(x*scale+scale/4., y*scale, scale/2., scale/2);
    }
 
    ctx.lineWidth = thickness*scale;
    ctx.strokeStyle = color;
    ctx.beginPath();
    for(let seg of snake.tail) {
        ctx.lineTo(seg.x*scale + scale/2, seg.y*scale + scale/2);
    }
    ctx.lineTo(x*scale + scale/2, y*scale + scale/2);
    ctx.stroke();
}
 
export function draw(ctx: CanvasRenderingContext2D, state: JsGameState, options: VisualizationOptions) {
    Iif(state === undefined) {
        return;
    }
 
    const {scale, bgColor, foodColor, blurred} = options;
    let width = state.width;
    let height = state.height;
 
    ctx.fillStyle = bgColor;
    ctx.fillRect(0, 0, width*scale, height*scale);
 
    Eif(state.food !== null) {
        ctx.fillStyle = foodColor;
        let x = state.food.x;
        let y = state.food.y;
        ctx.fillRect(x * scale, y * scale, scale, scale);
    }
 
    Object.values(state.snakes).forEach(snake => drawSnake(ctx, snake, options));
 
    if(blurred) {
        ctx.fillStyle = "#cccc22";
        ctx.textAlign = "center";
        ctx.font = "30px Arial";
        ctx.fillText("Click here!", width * scale / 2, height * scale / 4);
        ctx.font = "15px Arial";
        ctx.fillText("For your key presses to be registered", width * scale / 2, height * scale / 4 + 25);
    }
 
    if(state.paused) {
        ctx.fillStyle = "#aaaaaa";
        ctx.font = "30px Arial";
        ctx.textAlign = "center";
        ctx.fillText("Paused", width * scale / 2, height * scale / 2);
        ctx.font = "15px Arial";
        ctx.fillText("Press 'WASD' to steer your Snake", width * scale / 2, height * scale / 2 + 25);
    }
 
    if(state.gameOver) {
        ctx.fillStyle = "#aaaaaa";
        ctx.font = "30px Arial";
        ctx.textAlign = "center";
        ctx.fillText("Game Over!", width * scale / 2, height * scale /4 * 3);
        ctx.font = "15px Arial";
        ctx.fillText("Press 'R' to restart the game", width * scale / 2, height * scale / 4 * 3 + 25);
    }
}