繁体   English   中英

Canvas简单游戏DRY重构

[英]Canvas simple game DRY refactoring

我是该站点的每日读者,但不是很多作家。 由于我学习JavaScript已有数周的时间,因此我基于少量对象制作了一个小型canvas / JS跨游戏游戏,并且我试图对其进行改进。 游戏非常简单:您可以在此处查看完整的代码并进行游戏: https//jsfiddle.net/vhrqb5xb/1/以及此处: http : //codepen.io/Pggo/pen/NGyQXK

    // The car variable 
    var Car = {}

    // How I create it
    var resetCar = function () {

      Car.x = 300 + (Math.random() * (canvas.width-600));
      Car.y = -10

    };


    // How it's drawn
    function drawCar(){

      ctx.beginPath();
      ctx.rect(Car.x,Car.y,32,32);
      ctx.fillStyle = 'white';
      ctx.fill();
      Car.y += Math.random() * 80

      if (Car.y > canvas.height){
        resetCar();
      };

    }


    // How game is reseit if player touch car
    function drawTouchCar(){

    // Evaluate coordonates of both objects, reset of touch
    if (
      player.x <= (Car.x + 32)
      && Car.x <= (player.x + 10)
      && player.y <= (Car.y + 30) &&
      Car.y <= (player.y + 10)
      ){
    ++numberOfDeaths; // +1 Die
    resetPlayer();
    }
    // if player pass arival line
    if(player.x > (canvas.width - 170 )){
      resetPlayer();
    ++numberOfWins; // +1 Win
    }
    }

现在,我使用的技巧是,我有一个快的汽车速度来渲染它,以至于看起来好像不止一个,但是我的游戏仅依赖于一个对象,即汽车。 我希望能够动态添加更多的汽车(而不是通过自己创建car2对象)。 为了使用原型创建对象,我已经进行了研究和尝试,可以轻松创建更多对象,但是我的问题是我无法访问它们的x和y属性以将其用作碰撞函数。

因此,问题来了,我该如何处理为实际对象汽车实现的原型,该原型可以动态创建新的汽车对象并返回其x和y属性,以便可以在碰撞函数中重新使用它。 实际上,我只是在这里了解原因,因为我被卡住了,但我并不是在寻找开箱即用的可行解决方案。

预先感谢您的回复,祝您一切顺利

有多种创建对象的方法。 每种方法都有其优点和缺点。

最快的方法是使用对象工厂添加临时对象,以根据需要创建未命名的对象。 此方法创建最快的代码。

var drawCar = function () { // function to draw a car;
    ctx.beginPath();
    // "this" is the car object and should be bound to a car object
    ctx.rect(this.x, this.y, 32, 32);
    ctx.fillStyle = 'red';
    ctx.fill();
    // do your test to see if car is over the line
    // and call
    this.reset(); // to reset the car
}

var resetCar = function () {
    // car reset function TODO add your reset code
}

var carFactory = function () { // creates add hoc unnamed car objects
    var car = {}; // create a new object;
    car.x = 0; // give it properties
    car.y = 0;
    // add the reset function to the car and bind it to the new car
    car.reset = resetCar.bind(car);
    car.draw = drawCar.bind(car); // same for draw
    car.reset(); // reset the car ready to go;
    return car; // return the new car
}

var testCar = function (car) { // function to test if car hits player
    if (
        player.x <= (car.x + 32) // access the car position by its x and y properties
         && car.x <= (player.x + 10)
         && player.y <= (car.y + 30) &&
        car.y <= (player.y + 10)) {
        ++numberOfDeaths; // +1 Die
        resetPlayer();
    }
}

var car1 = carFactory(); // create a new car
var car2 = carFactory(); // and another;

var mainLoop() { // called once every frame
    car1.draw();
    car2.draw();
    testCar(car1);
    testCar(car2);
    // TODO the other stuff
}

接下来是形式化方法,它稍微慢一点,因为引擎盖下发生了更多的事情(可以这么说)

function Car() {
    // "this" is bound automatic to the car object with the call new Car()
    // the car also is a named type in Javascript
    this.x = 0;
    this.y = 0;
    this.reset(); // reset the new car

    // "this" is returned here automatically like in the factory but in this 
    // case you dont have to type it in 
}

// add draw to the car prototype
Car.prototype.draw = function () { // function to draw a car;
    ctx.beginPath();
    ctx.rect(this.x, this.y, 32, 32);
    ctx.fillStyle = 'red';
    ctx.fill();
    // this.reset(); // to reset the car
}

// add reset to the car prototype
Car.prototype.reset = function () {
    // car reset function TODO add your reset code }
}

var testCar = function (car) { // function to test if car hits player
    if (
        player.x <= (car.x + 32) // access the car position by its x and y properties
         && car.x <= (player.x + 10)
         && player.y <= (car.y + 30) &&
        car.y <= (player.y + 10)) {
        ++numberOfDeaths; // +1 Die
        resetPlayer();
    }
}
var car1 = new Car(); // create a new car
var car2 = new Car(); // and another;


var mainLoop() { // called once every frame
    car1.draw();
    car2.draw();
    testCar(car1);
    testCar(car2);
}

您还可以使用class在ECMAScript 6中创建汽车。还可以在Car函数中声明所有原型,从而允许您使用闭包添加隐藏属性。 创建新车的速度稍慢,但是运行新车的速度稍快。

如果要绝对控制,则可以直接使用Object方法,从而创建具有可写,可枚举,可配置选项的属性,可以创建getter和setter,可以冻结对象以及更多整个堆。 我个人将这些东西留给专家咨询。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM