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               490x 490x   490x 2x   488x     490x 490x 490x 490x 94x   490x 107x   490x 109x   490x 180x     490x 490x 490x 490x 2650x   490x 490x       477x       477x 477x 477x   477x 477x   477x 477x 477x 477x 477x     490x   477x 102x 102x 102x 102x 102x 102x     477x 155x 155x 155x 155x 155x 155x     477x 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);
    }
}