主頁 > 後端開發 > 臥槽!搶不到就自己寫,用代碼實作一個冰墩墩,太秀了~!

臥槽!搶不到就自己寫,用代碼實作一個冰墩墩,太秀了~!

2022-02-15 06:46:35 後端開發

作者:dragonir
來源:https://segmentfault.com/a/1190000041363089

背景

迎冬奧,一起向未來!2022冬奧會馬上就要開始了,本文使用 Three.js + React 技術堆疊,實作冬日和奧運元素,制作了一個充滿趣味和紀念意義的冬奧主題 3D 頁面,

本文涉及到的知識點主要包括:TorusGeometry 圓環面、MeshLambertMaterial 非光澤表面材質、MeshDepthMaterial 深度網格材質、custromMaterial 自定義材質、Points 粒子、PointsMaterial 點材質等,

效果

實作效果如以下 ?? 動圖所示,頁面主要由 2022 冬奧會吉祥物 冰墩墩 、奧運五環、舞動的旗幟 ??、樹木 ?? 以及下雪效果 ?? 等組成,按住滑鼠左鍵移動可以改為相機位置,獲得不同視圖,

?? 在線預覽:https://dragonir.github.io/3d/#/olympic

(部署在 GitHub,加載速度可能會有點慢 ??

實作

引入資源

首先引入開發頁面所需要的庫和外部資源,OrbitControls 用于鏡頭軌道控制、TWEEN 用于補間影片實作、GLTFLoader 用于加載 glbgltf 格式的 3D 模型、以及一些其他模型、貼圖等資源,

import React from 'react';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import bingdundunModel from './models/bingdundun.glb';
// ...

頁面DOM結構

頁面 DOM 結構非常簡單,只有渲染 3D 元素的 #container 容器和顯示加載進度的 .olympic_loading元素,

<div>
  <div id="container"></div>
  {this.state.loadingProcess === 100 ? '' : (
    <div className="olympic_loading">
      <div className="box">{this.state.loadingProcess} %</div>
    </div>
  )}
</div>

場景初始化

初始化渲染容器、場景、相機,關于這部分內容的詳細知識點,可以查閱我往期的文章,本文中不再贅述,

container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.background = new THREE.TextureLoader().load(skyTexture);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 30, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));

添加光源

本示例中主要添加了兩種光源:DirectionalLight 用于產生陰影,調節頁面亮度、AmbientLight 用于渲染環境氛圍,

// 直射光
const light = new THREE.DirectionalLight(0xffffff, 1);
light.intensity = 1;
light.position.set(16, 16, 8);
light.castShadow = true;
light.shadow.mapSize.width = 512 * 12;
light.shadow.mapSize.height = 512 * 12;
light.shadow.camera.top = 40;
light.shadow.camera.bottom = -40;
light.shadow.camera.left = -40;
light.shadow.camera.right = 40;
scene.add(light);
// 環境光
const ambientLight = new THREE.AmbientLight(0xcfffff);
ambientLight.intensity = 1;
scene.add(ambientLight);

加載進度管理

使用 THREE.LoadingManager 管理頁面模型加載進度,在它的回呼函式中執行一些與加載進度相關的方法,本例中的頁面加載進度就是在 onProgress 中完成的,當頁面加載進度為 100% 時,執行 TWEEN 鏡頭補間影片,

const manager = new THREE.LoadingManager();
manager.onStart = (url, loaded, total) => {};
manager.onLoad = () => { console.log('Loading complete!')};
manager.onProgress = (url, loaded, total) => {
  if (Math.floor(loaded / total * 100) === 100) {
    this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
    // 鏡頭補間影片
    Animations.animateCamera(camera, controls, { x: 0, y: -1, z: 20 }, { x: 0, y: 0, z: 0 }, 3600, () => {});
  } else {
    this.setState({ loadingProcess: Math.floor(loaded / total * 100) });
  }
};

創建地面

本示例中凹凸起伏的地面是使用 Blender 構建模型,然后匯出 glb 格式加載創建的,當然也可以只使用 Three.js 自帶平面網格加凹凸貼圖也可以實作類似的效果,使用 Blender 自建模型的優點在于可以自由可視化地調整地面的起伏效果,

var loader = new THREE.GLTFLoader(manager);
loader.load(landModel, function (mesh) {
  mesh.scene.traverse(function (child) {
    if (child.isMesh) {
      child.material.metalness = .1;
      child.material.roughness = .8;
      // 地面
      if (child.name === 'Mesh_2') {
        child.material.metalness = .5;
        child.receiveShadow = true;
      }
  });
  mesh.scene.rotation.y = Math.PI / 4;
  mesh.scene.position.set(15, -20, 0);
  mesh.scene.scale.set(.9, .9, .9);
  land = mesh.scene;
  scene.add(land);
});

創建冬奧吉祥物冰墩墩

現在添加可愛的冬奧會吉祥物熊貓冰墩墩 ??,冰墩墩同樣是使用 glb 格式模型加載的,它的原始模型來源于這里,從這個網站免費現在模型后,原模型是使用 3D max 建的我發現并不能直接用在網頁中,需要在 Blender 中轉換模型格式,還需要調整調整模型的貼圖法線,才能還原渲染圖效果,

原模型

冰墩墩貼圖:

轉換成Blender支持的模型,并在Blender中調整模型貼圖法線、并添加貼圖:

匯出glb格式:

仔細觀察冰墩墩 ??可以發現,它的外面有一層透明塑料或玻璃質感外殼,這個效果可以通過修改模型的透明度、金屬度、粗糙度等材質引數實作,最后就可以渲染出如 ?? banner圖 所示的那種效果,具體如以下代碼所示,

loader.load(bingdundunModel, mesh => {
  mesh.scene.traverse(child => {
    if (child.isMesh) {
      // 內部
      if (child.name === 'oldtiger001') {
        child.material.metalness = .5
        child.material.roughness = .8
      }
      // 半透明外殼
      if (child.name === 'oldtiger002') {
        child.material.transparent = true;
        child.material.opacity = .5
        child.material.metalness = .2
        child.material.roughness = 0
        child.material.refractionRatio = 1
        child.castShadow = true;
      }
    }
  });
  mesh.scene.rotation.y = Math.PI / 24;
  mesh.scene.position.set(-8, -12, 0);
  mesh.scene.scale.set(24, 24, 24);
  scene.add(mesh.scene);
});

創建奧運五環

奧運五環由基礎幾何模型圓環面 TorusGeometry 來實作,創建五個圓環面,并調整它們的材質顏色和位置來構成藍黑紅黃綠順序的五環結構,五環材質使用的是 MeshLambertMaterial

const fiveCycles = [
  { key: 'cycle_0', color: 0x0885c2, position: { x: -250, y: 0, z: 0 }},
  { key: 'cycle_1', color: 0x000000, position: { x: -10, y: 0, z: 5 }},
  { key: 'cycle_2', color: 0xed334e, position: { x: 230, y: 0, z: 0 }},
  { key: 'cycle_3', color: 0xfbb132, position: { x: -125, y: -100, z: -5 }},
  { key: 'cycle_4', color: 0x1c8b3c, position: { x: 115, y: -100, z: 10 }}
];
fiveCycles.map(item => {
  let cycleMesh = new THREE.Mesh(new THREE.TorusGeometry(100, 10, 10, 50), new THREE.MeshLambertMaterial({
    color: new THREE.Color(item.color),
    side: THREE.DoubleSide
  }));
  cycleMesh.castShadow = true;
  cycleMesh.position.set(item.position.x, item.position.y, item.position.z);
  meshes.push(cycleMesh);
  fiveCyclesGroup.add(cycleMesh);
});
fiveCyclesGroup.scale.set(.036, .036, .036);
fiveCyclesGroup.position.set(0, 10, -8);
scene.add(fiveCyclesGroup);

?? TorusGeometry 圓環面

TorusGeometry 一個用于生成圓環幾何體的類,

建構式

TorusGeometry(radius: Float, tube: Float, radialSegments: Integer, tubularSegments: Integer, arc: Float)
  • radius:圓環的半徑,從圓環的中心到管道(橫截面)的中心,默認值是 1
  • tube:管道的半徑,默認值為 0.4
  • radialSegments:圓環的分段數,默認值為 8
  • tubularSegments:管道的分段數,默認值為 6
  • arc:圓環的圓心角(單位是弧度),默認值為 Math.PI * 2

?? MeshLambertMaterial 非光澤表面材質

一種非光澤表面的材質,沒有鏡面高光,該材質使用基于非物理的 Lambertian 模型來計算反射率,這可以很好地模擬一些表面(例如未經處理的木材或石材),但不能模擬具有鏡面高光的光澤表面(例如涂漆木材),

建構式

MeshLambertMaterial(parameters : Object)
  • parameters:(可選)用于定義材質外觀的物件,具有一個或多個屬性,材質的任何屬性都可以從此處傳入,

創建旗幟

旗面模型是從sketchfab下載的,還需要一個旗桿,可以在 Blender中添加了一個柱狀立方體,并調整好合適的長寬高和旗面結合起來,

旗面貼圖

旗面添加了影片,需要在代碼中執行影片幀播放,

loader.load(flagModel, mesh => {
  mesh.scene.traverse(child => {
    if (child.isMesh) {
      child.castShadow = true;
      // 旗幟
      if (child.name === 'mesh_0001') {
        child.material.metalness = .1;
        child.material.roughness = .1;
        child.material.map = new THREE.TextureLoader().load(flagTexture);
      }
      // 旗桿
      if (child.name === '柱體') {
        child.material.metalness = .6;
        child.material.roughness = 0;
        child.material.refractionRatio = 1;
        child.material.color = new THREE.Color(0xeeeeee);
      }
    }
  });
  mesh.scene.rotation.y = Math.PI / 24;
  mesh.scene.position.set(2, -7, -1);
  mesh.scene.scale.set(4, 4, 4);
  // 影片
  let meshAnimation = mesh.animations[0];
  mixer = new THREE.AnimationMixer(mesh.scene);
  let animationClip = meshAnimation;
  let clipAction = mixer.clipAction(animationClip).play();
  animationClip = clipAction.getClip();
  scene.add(mesh.scene);
});

創建樹木

為了充實畫面,營造冬日氛圍,于是就添加了幾棵松樹 ?? 作為裝飾,添加松樹的時候用到一個技巧非常重要:我們知道因為樹的模型非常復雜,有非常多的面數,面數太多會降低頁面性能,造成卡頓,本文中使用兩個如下圖 ?? 所示的兩個交叉的面來作為樹的基座,這樣的話樹只有兩個面數,使用這個技巧可以和大程度上優化頁面性能,而且樹 ?? 的樣子看起來也是有 3D 感的,

材質貼圖

為了使樹只在貼圖透明部分透明、其他地方不透明,并且可以產生樹狀陰影而不是長方體陰影,需要給樹模型添加如下 MeshPhysicalMaterialMeshDepthMaterial 兩種材質,兩種材質使用同樣的紋理貼圖,其中 MeshDepthMaterial 添加到模型的 custromMaterial 屬性上,

 let treeMaterial = new THREE.MeshPhysicalMaterial({
  map: new THREE.TextureLoader().load(treeTexture),
  transparent: true,
  side: THREE.DoubleSide,
  metalness: .2,
  roughness: .8,
  depthTest: true,
  depthWrite: false,
  skinning: false,
  fog: false,
  reflectivity: 0.1,
  refractionRatio: 0,
});
let treeCustomDepthMaterial = new THREE.MeshDepthMaterial({
  depthPacking: THREE.RGBADepthPacking,
  map: new THREE.TextureLoader().load(treeTexture),
  alphaTest: 0.5
});
loader.load(treeModel, mesh => {
  mesh.scene.traverse(child =>{
    if (child.isMesh) {
      child.material = treeMaterial;
      child.custromMaterial = treeCustomDepthMaterial;
    }
  });
  mesh.scene.position.set(14, -9, 0);
  mesh.scene.scale.set(16, 16, 16);
  scene.add(mesh.scene);
  // 克隆另兩棵樹
  let tree2 = mesh.scene.clone();
  tree2.position.set(10, -8, -15);
  tree2.scale.set(18, 18, 18);
  scene.add(tree2)
  // ...
});

實作效果也可以從 ?? 上面 Banner 圖中可以看到,為了畫面更好看,我取消了樹的陰影顯示,

??3D 功能開發中,一些不重要的裝飾模型都可以采取這種策略來優化,

?? MeshDepthMaterial 深度網格材質

一種按深度繪制幾何體的材質,深度基于相機遠近平面,白色最近,黑色最遠,

建構式

MeshDepthMaterial(parameters: Object)
  • parameters:(可選)用于定義材質外觀的物件,具有一個或多個屬性,材質的任何屬性都可以從此處傳入,

特殊屬性

  • .depthPacking[Constant]depth packing 的編碼,默認為 BasicDepthPacking
  • .displacementMap[Texture]:位移貼圖會影響網格頂點的位置,與僅影響材質的光照和陰影的其他貼圖不同,移位的頂點可以投射陰影,阻擋其他物件,以及充當真實的幾何體,
  • .displacementScale[Float]:位移貼圖對網格的影響程度(黑色是無位移,白色是最大位移),如果沒有設定位移貼圖,則不會應用此值,默認值為 1
  • .displacementBias[Float]:位移貼圖在網格頂點上的偏移量,如果沒有設定位移貼圖,則不會應用此值,默認值為 0

?? custromMaterial 自定義材質

給網格添加 custromMaterial 自定義材質屬性,可以實作透明外圍 png 圖片貼圖的內容區域陰影,

創建雪花

創建雪花 ??,就要用到粒子知識THREE.Points 是用來創建點的類,也用來批量管理粒子,本例中創建了 1500 個雪花粒子,并為它們設定了限定三維空間的隨機坐標及橫向和豎向的隨機移動速度,

// 雪花貼圖
let texture = new THREE.TextureLoader().load(snowTexture);
let geometry = new THREE.Geometry();
let range = 100;
let pointsMaterial = new THREE.PointsMaterial({
  size: 1,
  transparent: true,
  opacity: 0.8,
  map: texture,
  // 背景融合
  blending: THREE.AdditiveBlending,
  // 景深衰弱
  sizeAttenuation: true,
  depthTest: false
});
for (let i = 0; i < 1500; i++) {
  let vertice = new THREE.Vector3(Math.random() * range - range / 2, Math.random() * range * 1.5, Math.random() * range - range / 2);
  // 縱向移速
  vertice.velocityY = 0.1 + Math.random() / 3;
  // 橫向移速
  vertice.velocityX = (Math.random() - 0.5) / 3;
  // 加入到幾何
  geometry.vertices.push(vertice);
}
geometry.center();
points = new THREE.Points(geometry, pointsMaterial);
points.position.y = -30;
scene.add(points);

?? Points 粒子

Three.js 中,雨 ???、雪 ??、云 ??、星辰 ? 等生活中常見的粒子都可以使用 Points 來模擬實作,

建構式

new THREE.Points(geometry, material);
  • 建構式可以接受兩個引數,一個幾何體和一個材質,幾何體引數用來制定粒子的位置坐標,材質引數用來格式化粒子;
  • 可以基于簡單幾何體物件如 BoxGeometrySphereGeometry等作為粒子系統的引數;
  • 一般來講,需要自己指定頂點來確定粒子的位置,

?? PointsMaterial 點材質

通過 THREE.PointsMaterial 可以設定粒子的屬性引數,是 Points 使用的默認材質,

建構式

PointsMaterial(parameters : Object)
  • parameters:(可選)用于定義材質外觀的物件,具有一個或多個屬性,材質的任何屬性都可以從此處傳入,

?? 材質屬性 .blending

材質的.blending 屬性主要控制紋理融合的疊加方式,.blending 屬性的值包括:

  • THREE.NormalBlending:默認值
  • THREE.AdditiveBlending:加法融合模式
  • THREE.SubtractiveBlending:減法融合模式
  • THREE.MultiplyBlending:乘法融合模式
  • THREE.CustomBlending:自定義融合模式,與 .blendSrc, .blendDst.blendEquation 屬性組合使用

?? 材質屬性 .sizeAttenuation

粒子的大小是否會被相機深度衰減,默認為 true(僅限透視相機),

?? Three.js 向量

幾維向量就有幾個分量,二維向量 Vector2xy 兩個分量,三維向量 Vector3xyz 三個分量,四維向量 Vector4xyzw 四個分量,

相關API

  • Vector2:二維向量
  • Vector3:三維向量
  • Vector4:四維向量

鏡頭控制、縮放適配、影片

controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enableDamping = true;
// 禁用平移
controls.enablePan = false;
// 禁用縮放
controls.enableZoom = false;
// 垂直旋轉角度限制
controls.minPolarAngle = 1.4;
controls.maxPolarAngle = 1.8;
// 水平旋轉角度限制
controls.minAzimuthAngle = -.6;
controls.maxAzimuthAngle = .6;
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}, false);
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  controls && controls.update();
  // 旗幟影片更新
  mixer && mixer.update(new THREE.Clock().getDelta());
  // 鏡頭影片
  TWEEN && TWEEN.update();
  // 五環自轉
  fiveCyclesGroup && (fiveCyclesGroup.rotation.y += .01);
  // 頂點變動之后需要更新,否則無法實作雨滴特效
  points.geometry.verticesNeedUpdate = true;
  // 雪花影片更新
  let vertices = points.geometry.vertices;
  vertices.forEach(function (v) {
    v.y = v.y - (v.velocityY);
    v.x = v.x - (v.velocityX);
    if (v.y <= 0) v.y = 60;
    if (v.x <= -20 || v.x >= 20) v.velocityX = v.velocityX * -1;
  });
}

?? 完整代碼:https://github.com/dragonir/3d/tree/master/src/containers/Olympic

總結

?? 本文中主要包含的新知識點包括:

  • TorusGeometry 圓環面
  • MeshLambertMaterial 非光澤表面材質
  • MeshDepthMaterial 深度網格材質
  • custromMaterial 自定義材質
  • Points 粒子
  • PointsMaterial 點材質
  • 材質屬性 .blending.sizeAttenuation
  • Three.js 向量

進一步優化的空間:

  • 添加更多的互動功能、界面樣式進一步優化;
  • 吉祥物冰墩墩添加骨骼影片,并可以通過滑鼠和鍵盤控制其移動和互動,

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了,,,

3.Spring Boot 2.x 教程,太全了!

4.20w 程式員紅包封面,快快領取,,,

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

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

標籤:其他

上一篇:女朋友讓我深夜十二點催她睡覺,我有Python我就不干

下一篇:技巧大集合,熬夜總結53個Python使用技巧和攻擊方法

標籤雲
其他(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)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more