Git Product home page Git Product logo

the-nature-of-code-javascript's People

Contributors

cyclegtx avatar

Watchers

 avatar  avatar

the-nature-of-code-javascript's Issues

向量、力、加速度

向量、力、加速度

向量在运动模拟中如何使用,在网上有很多文章可以参考,这里就不再介绍了。这里使用的向量类是根据p5.js(p5.js是Processing的js版本)中的向量修改得来,将exports的导出方法去掉。因为这里只想介绍向量的使用方式不想加入Commonjs规范的引用方式来增加使用的复杂度,所以这里直接引用vector.js并使用全局变量Vector就可以了。p5.js/blob/master/src/math/p5.Vector.js

管理运动物体的类

我们首先建立一个Mover类用来管理运动物体的属性:

  1. velocity速度
  2. location位置
function Mover(){
  //速度
  this.velocity = new Vector(0,0);
  //位置
  this.location = new Vector(0,0);
}
//逐帧 计算 速度 位置
Mover.prototype.calc = function() {
    ...
}
//绘制物体    
Mover.prototype.draw = function() {
    ...
}   
//逐帧 将属性更新到视图中
Mover.prototype.update = function(){
    ...
}

首先将velocity location 初始化为2个向量Vecotr(0,0)。接下来的函数都是围绕着2个向量来做文章:

  1. draw 绘制物体
  2. calc 在每一帧中根据速度计算位置
  3. update 在每一帧中将最新的位置更新到物体上

为什么不把draw绘制函数放到初始化函数里面?calc update都是每帧都要运行的函数为什么不合并成一个?

这里将这三个函数单独分开是为了减少物体运动计算与渲染之间的耦合。如果我们决定不再使用Pixi.js在canvas中渲染这个物体,而是换做DOM来渲染,那么只需要重新定义一遍draw update即可,类似于面向对象中的覆盖。在后面会举例说明这样写的好处。

calc 很简单只需要将当前的速度加到位置上就可以了,速度与位置都是向量,只需要做向量的加法就可以了。

//逐帧 计算 速度 位置
Mover.prototype.calc = function() {
    //根据速度计算位置
    this.location.add(this.velocity);
}

draw这里使用PIXI.js在屏幕绘制一个圆,(0,0,20)位置为0,0半径为20,这里的位置是相对位置,物体在屏幕中的位置用this.graphics.x``this.graphics.y来控制。

//绘制物体  
Mover.prototype.draw = function() {
    this.graphics = new PIXI.Graphics();
    this.graphics.lineStyle(4, 0xffd900, 1);
    this.graphics.beginFill(0x1ff1a7);
    this.graphics.drawCircle(0,0, 20);
    this.graphics.endFill();      
}

updatelocation向量中的x,y分别赋值给this.graphics剩下的就交由PIXI处理,将位置更新到屏幕中。

//逐帧 将属性更新到视图中    
Mover.prototype.update = function(){
    //将位置更新到屏幕中
    this.graphics.x = this.location.x;
    this.graphics.y = this.location.y;
}

剩下的代码将Mover实例化,使用过PIXI的朋友应该比较熟悉。这里在实例化后指定了mover的位置与速度,并且运行了draw方法,这样mover才被渲染到页面之中。在动画循环中,还执行了mover.calc() mover.update()。这两个函数将逐帧改变物体在屏幕中的位置,每一帧沿着y轴向下1像素。

//初始化PIXI画布
var renderer = new PIXI.WebGLRenderer(800, 600);
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();

//实例化mover类
var mover = new Mover();
//将mover移动到屏幕顶部中间
mover.location.x = 400;
mover.location.y = 0;
mover.draw();
//将速度设为延y轴向下1个像素
mover.velocity.y = 1;

//将mover添加到画布中
stage.addChild(mover.graphics);

//动画循环 
animate();
function animate() {
  requestAnimationFrame(animate);
  mover.calc();
  mover.update();  
  renderer.render(stage);
}

DEMO: Chapter1/1/1.html

灵活的渲染方法

draw update calc 将这三个方法分开看似啰嗦,但是提供了很大的灵活性。下面我们就换一种方式不再使用PIXI在canvas中渲染,而是直接使用css3改变DIV的位置来演示Mover类。

我们完全可以不改变之前的代码,即使Mover类已经被打包成单独的文件也完全不用担心。因为只需要在Mover的后面重写drawupdate就可以了。

//覆盖Mover类中draw和update方法
Mover.prototype.draw = function() {
    this.dom = document.getElementById('mover');
    this.dom.style.transform = 'translate3d('+this.location.x+'px,'+this.location.y+'px,0px)';
}
Mover.prototype.update = function(){
    //将位置更新到屏幕中
    this.dom.style.transform = 'translate3d('+this.location.x+'px,'+this.location.y+'px,0px)';
}

把渲染方法完全从Mover类中移除似乎是一个更合理的方法,Mover只维护物体的速度等属性,只通过calc计算,把渲染的任务交给别的方法,在动画循环中,将Mover类中的属性赋值给屏幕中的元素。这就是Box2d等著名的物理引擎所采用的方法,这样做使得物理引擎可以搭配任何渲染引擎使用。但是这样使得同一个物体的属性分散在多处加大了理解的难度,所以从代码易读性上考虑暂时采用同一个类的方法。

DEMO: Chapter1/1/1-2.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.