主頁 > 企業開發 > 【一統江湖的大前端(8)】matter.js 經典物理

【一統江湖的大前端(8)】matter.js 經典物理

2020-09-30 23:43:50 企業開發

【一統江湖的大前端(8)】matter.js 經典物理

示例代碼托管在:http://www.github.com/dashnowords/blogs

博客園地址:《大史住在大前端》原創博文目錄

華為云社區地址:【你要的前端打怪升級指南】

目錄
  • 【一統江湖的大前端(8)】matter.js 經典物理
    • 一.經典力學回顧
    • 二. 仿真的實作原理
      • 2.1 基本動力學模擬
      • 2.2 碰撞模擬
    • 三. 物理引擎matter.js
      • 3.1 《憤怒的小鳥》的物理特性分析
      • 3.2 使用matter.js 構建物理模型
      • 3.3 物理引擎牽手游戲引擎

在前端開發領域,物理引擎是一個相對小眾的話題,它通常都是作為游戲開發引擎的附屬工具而出現的,獨立的功能演示作品常常給人好玩但是無處可用的感覺,仿真就是在計算機的虛擬世界中模擬物體在真實世界的表現(動力學仿真最為常見),仿真能讓畫面中物體的運動表現更符合玩家對現實世界的認知,比如在《憤怒的小鳥》游戲中被彈弓發射出去小鳥或是因為被撞擊而坍塌的物體堆,還有在《割繩子》小游戲中割斷繩子后物體所發生的單擺或是墜落運動,都和現實世界的表現近乎相同,游戲體驗通常也會更好,

用物理引擎可以幫助開發者更快速地實作諸如碰撞反彈、摩擦力、單擺、彈簧、布料等等不同型別的仿真效果,物理引擎通常并不需要處理和畫面渲染相關的事務,而只需要完成計算仿真的部分就可以了,你可以把它理解成MVC模型中的M層,它和用于渲染畫面的V層理論上是獨立,matter.js提供了基于canvas2D API的渲染引擎,p2.js在示例代碼中提供了一個基于WebGL實作的渲染器,在開發社區也可以找到p2.js與CreateJS或Egret聯合使用的示例,游戲引擎和物理引擎的聯合使用并沒有想象中那么復雜,實際上只需要完成不同引擎之間的坐標系映射就可以了,熟練地開發者可能會喜歡這種“低耦合”帶來的靈活性,但對于初級開發者而言無疑又提高了使用門檻,

一.經典力學回顧

經典力學的基本定律就是牛頓三大運動定律或與其相關的力學原理,它可以用來描述宏觀世界低速狀態下的物體運動規律,也為游戲開發中的物理仿真提供了計算依據,大多數仿真都是基于經典力學的公式或其簡化形式進行計算模擬的,使用率較高的公式定律包括:

  • 牛頓第一定律

    牛頓第一定律又稱慣性定律,它指出任何物體都要保持勻速直線運動或靜止狀態,直到外力迫使它改變運動狀態為止,

  • 牛頓第二定律

    牛頓第二定律是指物體的加速度與它所受的外力成正比,與物體的質量成反比,加速度的方向與物體所受合外力速度相同,它可以模擬物體加速減速的程序,計算公式為(F為合外力,m為物體質量,a為加速度):

  • 動量守恒定理

    如果一個系統不受外力或所受外力的矢量和為零,那么這個系統的總動量保持不變,動量即質量m和速度v的乘積,它通常被用于模擬兩物體碰撞,動量守恒定律的計算公式可以由牛頓第二定律推導得出(F為合外力,t為作用時長,m為物體質量,v2為末速度,v1為初速度):

  • 動能定理
    合外力對物體所做的功,等于物體動能的變化量,公式表達如下(W為合外力做功,m為物體質量,v2為末速度,v1為初速度):

當合外力為一個恒定的力時,它所做的功可以通過如下公式進行計算(W為合外力做功,F為合外力大小,S為物體運動的距離):

  • 胡克定律

    胡克定律指出當彈簧發生彈性形變時,彈簧的彈力F和其伸長量(或壓縮量)x成正比,它是物理仿真中進行彈性相關計算的主要依據,相關公式如下(F表示彈力,k表示彈性系數,x表示彈簧長度和無彈力時的長度差):

利用經典力學的相關原理,就可以在計算機中模擬物體的物理特性,對于勻速圓周運動、單擺、電磁場等的模擬都可以依據相關的物理原理進行仿真,本節中不再展開,

二. 仿真的實作原理

2.1 基本動力學模擬

Canvas影片是一個逐幀繪制的程序,物理引擎作用的原理就是為抽象物體增加物理屬性,在每一幀中更新它們的值并計算這些物理量造成的影響,然后再執行繪制的命令,對物體進行動力學模擬時需要使用到質量、合外力、速度、加速度等屬性,其中質量是標量值(即沒有方向的值),而合外力、速度、加速度都是矢量值(有方向的值),無論在2D還是3D圖形學計算中,向量計算的頻率都是極高的,如果不進行封裝,代碼中可能就會充斥著大量底層數學計算代碼,影響代碼的可讀性,為了方便計算,我們先將二維向量的常見操作封裝起來:

/*二維向量類定義*/
class Vector2{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    copy() {
        return new Vector2(this.x, this.y); 
    }
    length() { 
        return Math.sqrt(this.x * this.x + this.y * this.y);
    }
    sqrLength() { 
        return this.x * this.x + this.y * this.y; 
    }
    normalize:() { 
        var inv = 1 / this.length(); 
        return new Vector2(this.x * inv, this.y * inv);
    }
    negate() { 
        return new Vector2(-this.x, -this.y); 
    }
    add(v) { 
        return new Vector2(this.x + v.x, this.y + v.y); 
    }
    subtract(v) { 
        return new Vector2(this.x - v.x, this.y - v.y); 
    }
    multiply(f) { 
        return new Vector2(this.x * f, this.y * f); 
    }
    divide(f) { 
        var invf = 1 / f; 
        return new Vector2(this.x * invf, this.y * invf);
    }
    dot(v) { 
        return this.x * v.x + this.y * v.y; 
    }
}

為了讓物體實體都擁有仿真必要的屬性結構,可以定義一個抽象類,再用物體的類去繼承它就可以了,這和你平時撰寫React應用時用自定義類繼承React.Component是一樣的,偽代碼示例如下:

class AbstractSprite{
    constructor(){
            this.mass = 1; //物體質量
            this.velocity = new Vector2(0, 0);//速度
            this.force = new Vector2(0, 0);//合外力
            this.position = new Vector2(0, 0);//物體的初始位置
            this.rotate = 0; //物體相對于自己對稱中心的旋轉角度
    }
}

我們并沒有在其中添加加速度屬性,使用合外力和質量就可以計算出它,position屬性用來確定物件繪制的位置,rotate屬性用來確定物件的偏轉角度,上面列舉的屬性在計算常見的線性運動場景中就足夠了,事實上屬性的取舍并沒有統一的標準,比如要模擬天體運動,可能還需要添加自轉角速度、公轉角速度等,如果要模擬彈簧,可能就需要添加彈性系數、平衡長度等,如果要模擬臺球滾動時的表現,就需要添加摩擦力,所選取的屬性通常都是直接或間接影響物體在畫布上最終可見形態的,你可以在子類中宣告這些特定場景中才會使用到的屬性,宣告一個新的物體類的示例代碼如下:

class AirPlane extends AbstractSprite{
    constructor(props){
        super(props);
        /* 宣告一些子屬性 */
        this.someProp = props.someProps;
    }
    /* 定義如何更新引數 */
    update(){}
    /* 定義如何繪制 */
    paint(){}
}

上面的模板代碼相信你已經非常熟悉了,狀態屬性的更新代碼撰寫在update函式中即可,更新函式理論上的執行間隔大約是16.7ms,計算程序中可以近似認為屬性是不變的,我們知道加速度在時間維度的積累影響了速度,速度在時間上的積累影響位移:

仿真中程序中的Δt是自定義的,你可以根據期望的視覺效果去調整它,Δt越大,同樣大小的物理量在每一幀中造成的可見影響就越顯著,更新時使用向量計算來進行:

this.velocity = this.velocity.add(this.force.divide(this.mass).multiply(t));
this.position = this.position.add(this.velocity.multiply(t));

運動仿真中需要對那些體積較小但速度較快的物體多加留意,因為基于包圍盒的檢測很可能會失效,例如在粒子仿真相關的場景中,粒子是基于引力作用而運動的,初始距離較遠的粒子在相互靠近的程序中速度是越來越快的,這就可能使得在連續的兩幀計算中,兩個粒子的包圍盒都沒有重疊,但實際上它們已經發生過碰撞了,而計算機仿真中就會因為逐幀影片的離散性而錯過碰撞的畫面,這時兩個粒子又會開始做減速運動而相互遠離,整體的運動狀態就呈現為簡諧振動的形式,所以在針對粒子系統的碰撞檢測時,除了包圍盒以外,通常還會結合速度和加速度的數值和方向變化來進行綜合判定,

2.2 碰撞模擬

碰撞,是指兩個或兩個物體在運動中相互靠近或發生接觸時,在較短的時間內發生強相互作用的程序,它通常都會造成物體運動狀態的變化,碰撞模擬一般使用完全彈性碰撞來進行計算,它是一種假定碰撞程序中不發生能量損失的理想狀況,這樣的碰撞程序就可以利用動量守恒定律和動能守恒定律進行計算:

公式中只有V1’和V2’是未知量,聯立方程就可以求得碰撞后速度的計算公式:

在引擎檢測到碰撞發生時只需要根據公式來計算碰撞后的速度就可以了,可以看到公式中使用到的屬性都已經在抽象物體類中進行了宣告,需要注意的是速度合成需要進行矢量運算,完全彈性碰撞只是為了方便計算的假設情況,大多數情況下我們并不需要知道碰撞造成的能量損失的確切數值,所以如果想要模擬碰撞造成的能量損失,可以在每次碰撞后將系統的總動能乘以0~1之間的系數來達到目的,

另一種典型的場景是物體之間發生非對心碰撞,也就是物體運動方向的延長線并不經過另一個物體的質心,運動模擬時為了簡化計算通常會忽略物體因碰撞造成的旋轉,將物體的速度先分解為指向另一物體質心方向的分量和垂直于該連線的分量,接著使用彈性對心碰撞的公式來求解對心碰撞的部分,最后再將碰撞后的速度與之前的垂直分量進行合成得到碰撞后的速度,

你不必擔心物理仿真中繁瑣的計算細節,大多數常用的場景都可以使用物理引擎快速實作,學習原理并不是為了重復去制造一些簡陋的“輪子”,而是讓你在面對引擎不適用的場景時可以自己去實作相應的開發,

三. 物理引擎matter.js

3.1 《憤怒的小鳥》的物理特性分析

《憤怒的小鳥》是一款物理元素非常豐富的游戲,本節中以此為例進行一個簡易的練習,游戲中首先需要實作一個模擬的地面,否則所有物體就會直接墜落到畫布以外,接著需要制作一個彈弓,當玩家在彈弓上按下滑鼠并向左拖動時,彈弓皮筋就會被拉長,且中間部位就會出現一只即將被彈射出去的小鳥,當玩家松開滑鼠時,彈弓皮筋由于拉長而積蓄的彈性勢能會逐漸轉變成小鳥的動能,從而將小鳥發射出去,這時小鳥的初速度是向斜上方的,在后續的運動程序中會因為受到重力和空氣阻力的影響而逐漸改變,重力垂直向下且大小不變,而空氣阻力與合速度方向相反,整個飛行程序中就需要在每一幀中更新小鳥的速度,畫面的右側通常是一個由各種各樣不同材質的物體布景和綠色的豬頭組成的靜態物體堆,當小鳥撞擊到物體堆后,物體堆會發生坍塌,物體堆的各個組成部分都會遵循物理定律的約束而改版狀態,從而呈現出仿真的效果,坍塌的物體堆壓到綠色豬頭后會將其消滅,當所有的豬頭都被消滅后,就可以進入下一關了,

我們先使用matter.js為整個場景建立物理模型,然后再使用CreateJS建立渲染模型,通過坐標和角度同步來為各個物理模型添加靜態或動態的貼圖,為了降低建模的難度,本節的示例中將彈弓皮筋的模型簡化為一個彈簧,只要可以將小鳥彈射出去即可,

3.2 使用matter.js 構建物理模型

matter.js的官方網站提供的示例代碼如下,它可以幫助開發者熟悉基本概念和開發流程,你可以在【官方代碼倉】中找到更多示例代碼:

var Engine = Matter.Engine,
     Render = Matter.Render,
   World = Matter.World,
     Bodies = Matter.Bodies;

// create an engine
var engine = Engine.create();

// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine
});

// create two boxes and a ground
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

// add all of the bodies to the world
World.add(engine.world, [boxA, boxB, ground]);

// run the engine
Engine.run(engine);

// run the renderer
Render.run(render);

示例代碼中使用到的主要概念包括負責物理計算的Engine(引擎)、負責渲染畫面的Render(渲染器)、負責管理物件的World(世界)以及用于剛體繪制的Bodies(物體),當然這只是matter.js的基本功能,Matter.Render通過改變傳入的引數,就可以在畫面中標記處物體的速度、加速度、方向及其他除錯資訊,也可以直接將物體渲染為線框模型,它在除錯環境或一些簡單場景中非常易用,但面對諸如精靈影片管理等更為復雜的需求時,就需要對其進行手動擴展或是直接替換渲染器,

在《憤怒的小鳥》物理建模程序中,static屬性設定為true的剛體都默認擁有無限大的質量,這類剛體不參與碰撞計算,只會將碰到它們的物體反彈回去,如果你不想讓世界中的物體飛出畫布的邊界,只需要在畫布的4個邊分別添加靜態剛體就可以了,物體堆的建立也非常容易,常用的矩形、圓、多邊形等輪廓都可以使用Bodies物件直接創建,位置坐標默認的參考點是物體的中心,當世界中的物體初始位置已經發生區域重疊時,引擎就會在作業時直接依據碰撞來處理,這可能就會導致一些物體擁有意料之外的初速度,在除錯程序中,可以通過激活剛體模型的isStatic屬性來將其宣告為靜態剛體,靜態剛體就會停留在自己的位置上而不會因為碰撞檢測的關系發生運動,這樣就可以對模型的初始狀態進行檢測了,如下圖所示:

構建彈簧模型的技術被稱為“約束”,相關的方法保存在約束模塊Matter.Constraint上,單獨存在的約束并沒有什么實際意義,它需要關聯兩個物體,用來表示被關聯物體之間的約束關系,如果只關聯了一個物體,則表示這個物體和固定錨點坐標之間的約束關系,固定坐標默認為(0,0),可以通過pointA或pointB屬性調整固定錨點的位置,《憤怒的小鳥》中使用的彈簧模型就是后一種單端固定的形式,我們只需要找到小鳥被彈射出去時經過彈弓橫切面的位置,建立一個包含坐標值的物件作為錨點,然后再建立一個動態剛體B作為滑鼠拉動彈簧時小鳥圖案的附著點,最后在這兩個物件之間創建約束就可以了,創建約束時需要宣告彈性系數stiffness,它表明了約束發生形變的難易程度,這個示例中約束兩端的平衡位置是重合在一起的,當玩家使用滑鼠拖動小鳥圖案附著點離開平衡位置后,就可以看到畫面上渲染出的兩點之間的彈簧約束,當用戶松開滑鼠后,彈簧就收縮,附著點就會回到初始位置,回彈的程序是一個類似于阻尼振動的程序,約束的彈性系數越大,端點回彈時在平衡位置波動就越小,當需要模擬彈簧被壓縮時,就需要通過length屬性來定義約束的平衡距離,約束復原時就會恢復到這個平衡距離,示例代碼如下:

birdOptions = { mass: 10 },
bird = Matter.Bodies.circle(200, 340, 16, birdOptions),
anchor = { x: 200, y: 340 },
elastic = Matter.Constraint.create({
            pointA: anchor,
            bodyB: bird,
            length: 0.01, 
            stiffness: 0.25
        });

滑鼠模塊Matter.Mouse和滑鼠約束模塊Matter.MouseConstraint提供了滑鼠事件跟蹤與用戶互動相關的能力,配合Matter.Events模塊就可以對滑鼠的移動、點擊、物體拖拽等典型事件進行監聽,使用方式相對固定,你只需要瀏覽一下官方檔案,熟悉一下引擎支持的事件就可以了,相關示例代碼如下:

//創建滑鼠物件
var mouse = Mouse.create(render.canvas);

//創建滑鼠約束
Var mouseConstraint = MouseConstraint.create(engine, {
            mouse: mouse,
            constraint: {
                stiffness: 0.2,
                render: {
                    visible: false
                }
            }
        });

 //監聽全域滑鼠拖拽事件
Events.on(mouseConstraint, 'startdrag', function(event){
    console.log(event);
})

物理引擎的更新也是逐幀進行的,可以利用Matter.Events模塊來監聽引擎發出的事件,以每次更新計算后發出的afterUpdate事件為例,在回呼函式中判斷是否需要將小鳥彈射出去,彈射是在玩家使用滑鼠向畫面左下方拖動并松開滑鼠后發生的,我們可以依據小鳥附著點的位置進行彈射判定,當小鳥處于錨點右上側并超過一定距離時,將其判定為可發射,發射的邏輯是生成一個新的小鳥附著點,將原約束中的bodyB進行替換,原本的附著點在約束解除后就表現為具有一定初速度的拋物運動,飛向物體堆,示例代碼如下:

const ejectDistance = 4; //定義彈射判斷的位移閾值
const anchorX = 200; //定義彈簧錨點的x坐標
const anchorY = 350; //定義彈簧錨點的y坐標

//每輪更新后判斷是否需要更新約束
Events.on(engine, 'afterUpdate', function () {
     if (mouseConstraint.mouse.button === -1 
&& bird.position.x > (anchorX + ejectDistance) 
&& bird.position.y < (anchorY - ejectDistance)) {
              bird = Bodies.circle(anchorX, anchorY, 16, birdOptions);
              World.add(engine.world, bird);
              elastic.bodyB = bird;
        }
    });

需要注意的是matter.js構建的剛體模型會以物體幾何中心作為定位參考點的,至此,簡易的物理模型就構建好了,線框圖效果如下所示:

盡管看起來有些簡陋,但它已經可以模擬很多物理特性了,下一小節我們為模型進行貼圖后,它就會看起來就比較像游戲了,物理模型的完整代碼可以在我的代碼倉庫中獲取到,

3.3 物理引擎牽手游戲引擎

matter.js提供的渲染器模塊Matter.Render非常適合物理模型的除錯,但在面對游戲制作時還不夠強大,比如原生Render模塊為模型貼圖時僅支持靜態圖片,而游戲中則往往會大量使用精靈影片來增加趣味性,這時將物理引擎和游戲引擎聯合起來使用就是非常好的選擇,

當你將Matter.Render相關的代碼都洗掉后,頁面上就不再繪制圖案了,但是如果你在控制臺輸出一些資訊的話,就會發現示例中監聽afterUpdate事件的監聽器函式仍然在不斷執行,這就意味著物理引擎仍然在持續作業,不斷重繪著模型的物理屬性數值,只是沒有將畫面渲染到畫布上而已,渲染的作業,自然就要交給渲染引擎來處理,當使用CreateJS來開發游戲時,渲染引擎使用的就是Easel.js,首先,使用Easel.js對所有保存在物理空間engine.world.bodies陣列中的模型建立對應的視圖模型,所謂視圖模型,就是指物體的可見外觀,比如一個長方形,可能代表木頭,也可能代表石塊,這取決于你使用什么樣的貼圖來表示它,視圖模型可以是精靈表、位圖或是自定義圖形等任何Easel.js支持的圖形,建立后將它們依次添加到舞臺實體stage中,這樣每個物體實際上有兩個模型與之對應,物理空間中的模型依靠物理引擎更新,負責在每一幀中為對應物體提供位置坐標和旋轉角度,并確保變化趨勢符合物理定律;渲染舞臺中的模型保存著物體的外觀樣式,依靠渲染引擎來更新和繪制,你只需要在每一幀更新物體屬性時將物理模型的關鍵資訊(通常是位置坐標和旋轉角度)同步給渲染模型就可以了,基本的邏輯流程如下所示:

按照上面的流程擴展之前的代碼并不困難,完成后的游戲畫面看起來有趣多了:

完整的代碼已上傳至代碼倉庫,相信你已經發現,最侄訓面里的物體布局和物理引擎中的布局是一樣的,物理引擎的本質,就是為每個渲染模型提供正確的坐標和角度,并保證這些資料在逐幀更新程序中的變化和相互影響符合物理定律,如果第三方物理引擎無法滿足你的需求,那么動手去實作自己的引擎吧,相信你已經知道該如何開始了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/143539.html

標籤:JavaScript

上一篇:為什么學習javascript

下一篇:js陣列去重(最優方法)筆記

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more