Q: O this está assumindo o valor de Window Eu não sei o que tem de errado neste código. Dentro do construtor da função EvilCircle, o this funciona direitinho, mas em EvilCircle.prototype.draw não funciona. Parece que ele se transforma no Window.
function Shape(x, y, velX, velY, exists) {
  this.x = x;
  this.y = y;
  this.velX = velX;
  this.velY = velY;
  this.exists = exists;
}

// EvilCircle
function EvilCircle(x, y, exists) {
  Shape.call(this, x, y, 20, 20, exists);
  this.color = 'white';
  this.size = 10;
}
EvilCircle.prototype = Object.create(Shape.prototype);
EvilCircle.prototype.constructor = EvilCircle;

// Draw;
EvilCircle.prototype.draw = () => {
  console.log(this);
};


A: Isso está acontecendo porque você está utilizando uma arrow function, cujo this binding possui funcionamento léxico. Isso significa que o this não irá se referir à instância de EvilCircle, mas sim ao this do escopo superior que, nesse caso, é window.
Saiba mais nesta outra pergunta. A documentação também pode ser clarificadora nessa matéria.
Para corrigir, então, utilize uma expressão de função:
EvilCircle.prototype.draw = function() {
  console.log(this);
  console.log(this instanceof EvilCircle); //=> true
};


Sobre programação orientada a objetos em JavaScript, o funcionamento sempre será prototípico. Mas vale a pena utilizar a nova sintaxe de classes, introduzida no ECMAScript 2015 (ES6) para simplificar o seu código, principalmente na parte relacionada à herança.
class Shape {
  constructor(x, y, velX, velY, exists) {
    this.x = x;
    this.y = y;
    this.velX = velX;
    this.velY = velY;
    this.exists = exists;
  }
}

class EvilCircle extends Shape {
  constructor(x, y, exists) {
    // Chama o construtor da classe pai:
    super(this, x, y, 20, 20, exists);

    this.color = 'white';
    this.size = 10;
  }

  draw() {
    console.log(this);
  }
}

