Particle Displacement

Inspired by the idea of Allomancy. I wondered what would happen if a ship had to fly through a dense asteroid or debris field. Obviously the traditional scifi solution is a shield, but that's a tad boring. Why not instead have an allomancer on board who can simply Push the metals in the asteroids away from the ship? Then, just for the cool factor, I made it so the asteroids return to their original positions.

by djwelsh

HTML

<canvas id="c" width="400" height="400"></canvas>
<div id="debug"></div>

CSS

#c {
    outline: 1px solid #ccc;
    width: 400px;
    height: 400px;
    margin: 10px;
}
#debug {
    position: fixed;
    right: 0px;
    top: 0px;
    width: 120px;
}

JavaScript

//Element stuff
var main_canvas, 
    main_ctx;

//Dimensions of canvas
var canvas_width, canvas_height;

//Store the ship and the other objects
var ship = null;
var asteroids = [];

//Position of the mouse on the canvas.
var mouse = {
    x : 0,
    y : 0
};
var mouse_offset = {
    x : 0,
    y : 0
};


//Called every frame
function draw() {
    
    main_ctx.clearRect(0,0,canvas_width,canvas_height);
    
    //Draw the background and ship
    drawStuff(main_ctx);
    
    requestAnimationFrame(draw);
}



function drawStuff(context) {
    
    //Draw dummies
    for (var i = 0; i < asteroids.length; i++) {
        asteroids[i].updatePosition(context);
    }
    
    //Draw ship
    ship.updatePosition(context);
    
}










/*********************************/
/* CLASSES ***********************/
/*********************************/

function Vector (obj) {
    this.x = obj.x;
    this.y = obj.y;
}
Vector.prototype.magnitude = function () {
    return Math.sqrt(this.x * this.x + this.y * this.y);
};
Vector.prototype.normalize = function () {
    var mag = this.magnitude();
    if (mag === 0) mag = 0.0000001;
    var normalizedX = this.x / mag;
    var normalizedY = this.y / mag;
    
    return new Vector({ x : normalizedX, y : normalizedY });
};

function Ship(obj) {
    this.x = obj.x;
    this.y = obj.y;
    this.vx = 0;
    this.vy = 0;
    this.size = obj.size;
    
    this.speed = 0;
    
    this.repulsorRange = 50;
    
    this.strokeStyle = "#333";
    this.fillStyle = "#ccc";
    
}
//Calculate where we were, what our velocity is, and where we thus should be next. Calls draw() function after calculation.
Ship.prototype.updatePosition = function (context) {
    
    //New vx/vy is a vector based on mouse position relative to ship
    //For stability we can change ship xy to half canvas w and h
    var V_DirectionOfShip = new Vector({
        x : mouse.x - ship.x,
        y : mouse.y - ship.y
//        x : mouse.x - canvas_width / 2,
//        y :...