H5 three.js 实现六年级观察物体

news2024/9/24 13:18:51

o( ̄▽ ̄)ブ 我又带着新的demo来啦~

预览
在这里插入图片描述
功能点

  • 立方体的阴影
  • 立方体的添加
  • 位置记录
  • 最大限制
  • 三视图展示
  • 立方体的移除
  • 答题模式
  • 随机出题
  • 题库出题

源码
注释算是比较全了,可能部分会有点绕,还能够再优化一下~

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">
    <style>
        body {
            user-select: none;
        }

        .panel-container {
            position: absolute;
            top: 0;
            left: 0;
            /* height: 200px; */
            width: 100%;
            background-color: rgba(255, 255, 255, .8);
            padding: 20px;
            box-sizing: border-box;
            display: flex;
            justify-content: space-between;
        }

        .mode-switch {
            display: inline-flex;
            overflow: hidden;
            height: 32px;
            border-radius: 6px;
            background-color: #ccc;
        }

        .mode-switch .mode-switch-item {
            display: inline-block;
            padding: 0 8px;
            line-height: 32px;
            font-size: 12px;
            background-color: transparent;
            cursor: pointer;
        }

        .mode-switch .mode-switch-item.active {
            background-color: #88ccee;
        }

        .mode-switch .mode-switch-item.del.active {
            background-color: #cc3333;
        }

        .mode-switch-item.clear.active,
        .mode-switch-item.again.active {
            display: inline-block;
        }

        .mode-switch-item.clear,
        .mode-switch-item.again {
            display: none;
        }

        .mode-switch-item.clear.active,
        .mode-switch-item.del.active {
            background-color: #cc3333;
            color: #fff;
        }



        .panel-container.bottom {
            top: auto;
            bottom: 0;
            padding-top: 32px;
        }

        .front-view,
        .top-view,
        .left-view {
            width: 25vmin;
            height: 25vmin;
            position: relative;
        }

        .front-view::before,
        .top-view::before,
        .left-view::before {
            position: absolute;
            font-size: 12px;
            top: -16px;
        }

        .front-view::before {
            content: "正视图";
        }

        .top-view::before {
            content: "顶视图";
        }

        .left-view::before {
            content: "左视图";
        }



        .front-view.right::after,
        .top-view.right::after,
        .left-view.right::after {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            z-index: 0;
            background-color: rgba(255, 255, 255, .8);
            background-image: url('./assets/observing-objects/right.png');
            background-size: 50%;
            background-repeat: no-repeat;
            background-position: center;
            content: '';
        }


        .view-cude {
            position: absolute;
            background-image: url('./assets/cubeTexture.jpg');
            background-size: 110%;
            background-position: center;
            transform: translateY(-100%);
        }

        .view-cude.active {
            background: #404040;
        }

        .hint-container {
            position: absolute;
            top: 72px;
            color: #cc3333;
            opacity: .6;
            line-height: 20px;
            font-size: 12px;
            padding: 10px 10px;
        }

        .win-container {
            position: absolute;
            top: 72px;
            bottom: 0;
            left: 0;
            right: 0;
            background-color: rgba(255, 255, 255, .8);
            display: flex;
            justify-content: center;
            align-items: center;
            display: none
        }

        .win-container img {
            width: 50%;
            height: 80%;
            object-fit: contain;
        }
    </style>
</head>

<body>
    <script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/three/build/three.module.js",
                "three/addons/": "https://unpkg.com/three/examples/jsm/"
            }
        }
    </script>

    <div class="panel-container">
        <div class="mode-switch">
            <div class="mode-switch-item new">新增模式</div>
            <div class="mode-switch-item del">删除模式</div>
            <div class="mode-switch-item que">答题模式</div>
        </div>
        <div class="mode-switch">
            <div class="mode-switch-item again">再来一题</div>
            <div class="mode-switch-item clear">清空方块</div>
        </div>
    </div>
    <div class="hint-container">提示:答题模式无法编辑添加方块,通过观察立方体,单击三视图中的方块显示和隐藏来回答问题。</div>

    <div class="panel-container bottom">
        <div class="front-view"></div>
        <div class="top-view"></div>
        <div class="left-view"></div>
    </div>

    <div class="win-container">
        <img src="./assets/rainbow-fart/1.gif">
        <img src="./assets/rainbow-fart/2.gif">
    </div>


    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { Randoms } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/randoms.js";





        let newModeDom = document.querySelector('.mode-switch-item.new')
        let delModeDom = document.querySelector('.mode-switch-item.del')
        let queModeDom = document.querySelector('.mode-switch-item.que')
        let cleModeDom = document.querySelector('.mode-switch-item.clear')
        let agaModeDom = document.querySelector('.mode-switch-item.again')
        let opeModeLis = [newModeDom, delModeDom, queModeDom, cleModeDom, agaModeDom]
        let cubeMap = {}; // 方块存储
        let maximumSize = 4;  // 新建底座 4 x 4 
        let cubeMaterial = null;  // 方块材质
        let mode = 'new' // new 新增 del 删除 que 答题 

        function removeActiveOpeMode() {
            opeModeLis.forEach(item =>
                item.classList.remove('active')
            )
        }
        newModeDom.addEventListener('click', () => {
            mode = 'new';
            removeActiveOpeMode()
            newModeDom.classList.add('active')
            cleModeDom.classList.add('active')
            refreshView()
            winHide()
        })
        delModeDom.addEventListener('click', () => {
            mode = 'del';
            removeActiveOpeMode()
            delModeDom.classList.add('active')
            cleModeDom.classList.add('active')
            refreshView()
            winHide()
        })
        queModeDom.addEventListener('click', () => {
            mode = 'que';
            removeActiveOpeMode()
            queModeDom.classList.add('active')
            agaModeDom.classList.add('active')
            agaModeDom.click()
        })
        cleModeDom.addEventListener('click', () => {
            if (cubeMap) {
                for (const cude of Object.values(cubeMap)) {
                    scene.remove(cude)
                }
                cubeMap = {}
                refreshView()
            }
        })
        agaModeDom.addEventListener('click', () => {
            winHide()
            cleModeDom.click();
            randomMap()
        })



        // newModeDom.click()
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

        const renderer = new THREE.WebGLRenderer();

        scene.background = new THREE.Color(0x88ccee);
        camera.position.set(-10.5, 5, -10.5);
        renderer.shadowMap.enabled = true;
        renderer.setSize(window.innerWidth, window.innerHeight);

        document.body.appendChild(renderer.domElement);

        // 创建平行光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
        directionalLight.position.set(4, 4, -4)
        directionalLight.castShadow = true;
        scene.add(directionalLight);
        // 创建环境光源
        const ambientLight = new THREE.AmbientLight(0x404040); // 灰色的环境光
        scene.add(ambientLight);

        // 材质获取
        const textareaLoader = new THREE.TextureLoader();
        textareaLoader.load("./assets/cubeTexture.jpg", texture => {
            cubeMaterial = new THREE.MeshLambertMaterial({
                map: texture //材质的贴图为加载的图片
            });


            // 材质加载完成
            queModeDom.click();
        })
        // 模型加载
        const gltfLoader = new GLTFLoader().setPath('./assets/observing-objects/');
        gltfLoader.load('left.glb', (gltf) => {
            gltf.scene.position.x = 4.5;
            gltf.scene.position.y = 1.5;
            gltf.scene.position.z = -0.5;
            scene.add(gltf.scene);
        })
        gltfLoader.load('up.glb', (gltf) => {
            gltf.scene.position.x = 0.5;
            gltf.scene.position.y = 4.5;
            gltf.scene.position.z = -0.5;
            scene.add(gltf.scene);
        })
        gltfLoader.load('front.glb', (gltf) => {
            gltf.scene.position.x = 0.5;
            gltf.scene.position.y = 0;
            gltf.scene.position.z = -4.5;
            scene.add(gltf.scene);
        })

        // 平面预设
        for (let x = 0; x < maximumSize; x++) {
            for (let z = 0; z < maximumSize; z++) {
                console.log(x, z);
                const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x999999, side: THREE.DoubleSide });
                const plane = new THREE.Mesh(new THREE.BoxGeometry(1, .01, 1), planeMaterial);
                plane.position.x = x - maximumSize / 2;
                plane.position.z = z - maximumSize / 2;
                plane.name = `plane(${x},${z})`
                plane.receiveShadow = true;
                scene.add(plane);
            }
        }


        // <div class="front-view"></div>
        // <div class="top-view"></div>
        // <div class="left-view"></div>
        // 三视图预设
        let frontViewDom = document.querySelector('.front-view')
        let topViewDom = document.querySelector('.top-view')
        let leftViewDom = document.querySelector('.left-view')
        let viewDomLis = [frontViewDom, topViewDom, leftViewDom]
        // 创建视图方块
        function createViewCude(x, y) {
            let viewCudeDom = document.createElement('div')
            viewCudeDom.classList.add('view-cude')
            viewCudeDom.style.width = `${100 / maximumSize}%`
            viewCudeDom.style.height = `${100 / maximumSize}%`
            viewCudeDom.style.left = (x * 100 / maximumSize) + '%'
            viewCudeDom.style.top = (100 - y * 100 / maximumSize) + '%'
            viewCudeDom.setAttribute('x', x)
            viewCudeDom.setAttribute('y', y)

            viewCudeDom.addEventListener('click', function () {
                if (mode == 'que') {
                    if (viewCudeDom.classList.contains('active')) {
                        viewCudeDom.classList.remove("active")
                    }
                    else {
                        viewCudeDom.classList.add("active")
                    }
                    checkQuestionIsRight()
                }
            })
            return viewCudeDom
        }

        for (let i = 0; i < maximumSize; i++) {
            for (let j = 0; j < maximumSize; j++) {
                frontViewDom.appendChild(createViewCude(j, i))
                topViewDom.appendChild(createViewCude(j, i))
                leftViewDom.appendChild(createViewCude(j, i))
            }
        }
        // 刷新视图
        function refreshView() {
            console.log(cubeMap);
            let cubeMapKeys = Object.keys(cubeMap)

            // 移除正确标签 
            viewDomLis.map(item => {
                item.classList.remove('right')
            })

            // 正视图
            for (let i = 0; i < frontViewDom.children.length; i++) {
                const viewCudeDom = frontViewDom.children.item(i);
                let tmpX = viewCudeDom.getAttribute('x')
                let tmpY = viewCudeDom.getAttribute('y')
                if (cubeMapKeys.find(key => key.startsWith(`${tmpX},${tmpY}`))) viewCudeDom.classList.add('active')
                else viewCudeDom.classList.remove('active')
            }
            // 顶视图
            for (let i = 0; i < topViewDom.children.length; i++) {
                const viewCudeDom = topViewDom.children.item(i);
                let tmpX = viewCudeDom.getAttribute('x')
                let tmpZ = viewCudeDom.getAttribute('y')
                if (cubeMapKeys.find(key => key.startsWith(`${tmpX}`) && key.endsWith(`${tmpZ}`))) viewCudeDom.classList.add('active')
                else viewCudeDom.classList.remove('active')
            }
            // 左视图
            for (let i = 0; i < leftViewDom.children.length; i++) {
                const viewCudeDom = leftViewDom.children.item(i);
                let tmpZ = maximumSize - 1 - +viewCudeDom.getAttribute('x')
                let tmpY = viewCudeDom.getAttribute('y')
                if (cubeMapKeys.find(key => key.endsWith(`${tmpY},${tmpZ}`))) viewCudeDom.classList.add('active')
                else viewCudeDom.classList.remove('active')
            }
        }

        let winDom = document.querySelector('.win-container')   // 胜利
        function winHide() {
            winDom.setAttribute('style', 'display:none')
        }
        function winShow() {
            winDom.setAttribute('style', 'display:flex')
            let winImgCount = winDom.children.length
            let winImgShowIndex = Randoms.getRandomInt(0, winImgCount) // 随机高度 [)

            for (let i = 0; i < winImgCount; i++) {
                const winImg = winDom.children.item(i);
                winImg.setAttribute('style', winImgShowIndex == i ? 'display:flex' : 'display:none')
            }
        }


        // 控制器
        let controls = new OrbitControls(camera, renderer.domElement);
        controls.screenSpacePanning = true;
        controls.minDistance = 5;
        controls.maxDistance = 40;
        controls.target.set(0, 0, 0);
        controls.update();

        //获取鼠标坐标 处理点击某个模型的事件
        let mouse = new THREE.Vector2();
        let raycaster = new THREE.Raycaster();
        // 模型点击事件
        function onmodelclick(event) {
            if (event.type == 'touchstart') {
                let touch = event.changedTouches[0]
                mouse.x = (touch.clientX / window.innerWidth) * 2 - 1;
                mouse.y = -(touch.clientY / window.innerHeight) * 2 + 1;
            }
            else {
                mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
                mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
            }

            raycaster.setFromCamera(mouse, camera);
            const intersects = raycaster.intersectObjects(scene.children);
            const lastObject = intersects.find(o =>
                o.object.name.startsWith('plane') ||
                o.object.name.startsWith('cube')
            ) // 点击的物体是平面或者是立方体

            if (lastObject) { // 存在
                let lastObjectNormal = lastObject.normal // 点击的方向 
                let lastObjectPosition = lastObject.object.position // 物体的位置 
                let isPlane = lastObject.object.name.startsWith('plane'); // 是否点击的是平面

                if (mode == 'new') { // 是否是新增 
                    let x = lastObjectNormal.x + lastObjectPosition.x
                    let y = lastObjectNormal.y + lastObjectPosition.y - (isPlane ? .5 : 0)
                    let z = lastObjectNormal.z + lastObjectPosition.z
                    let checkCanPlaceRes = checkCanPlace(x, y, z)
                    if (isRange(x, y, z) && checkCanPlaceRes) {
                        x = checkCanPlaceRes.x
                        y = checkCanPlaceRes.y
                        z = checkCanPlaceRes.z
                        createCube(x, y, z); // 新建物体 
                    }
                    else {
                        console.log('不能添加');
                    }
                    refreshView()
                }
                else if (mode == 'del' && !isPlane) {
                    let x = lastObjectPosition.x
                    let y = lastObjectPosition.y
                    let z = lastObjectPosition.z
                    removeUpperAndSelf(x, y, z)
                    refreshView()
                }


                console.log('当前地图', Object.keys(cubeMap).map(v => {
                    let [x, y, z] = v.split(',').map(p => +p)
                    return { x, y, z }
                }));
            }

        }
        if (navigator.userAgent.includes('Android') || navigator.userAgent.includes('iPhone') || navigator.userAgent.includes('iPad')) {
            window.addEventListener("touchstart", onmodelclick)
        }
        else {
            window.addEventListener("click", onmodelclick);
        }
        // 是否在范围内
        function isRange(x, y, z) {
            let maxX = maximumSize / 2;
            let minX = -maximumSize / 2;
            let maxZ = maximumSize / 2;
            let minZ = -maximumSize / 2;
            let maxY = maximumSize;
            let minY = 0;

            if (y > maxY) return false
            if (y < minY) return false
            if (x >= maxX) return false;
            if (x < minX) return false;
            if (z >= maxZ) return false;
            if (z < minZ) return false;
            return true;
        }
        // 检查当前位置是否存在物体
        function checkPositionExist(key) {
            return cubeMap[key]
        }

        // 检测是否可以放置
        function checkCanPlace(x, y, z) {
            let standardKey = mapStandardKey(x, y, z)
            let standerdY = +standardKey.split(',')[1]

            for (let i = 0; i <= standerdY; i++) {
                if (!checkPositionExist(mapStandardKey(x, i, z))) {
                    return {
                        x,
                        y: y - standerdY + i,
                        z
                    };
                }
            }
            return false
        }
        // 删除它上面的物体及自身
        function removeUpperAndSelf(x, y, z) {
            let standardKey = mapStandardKey(x, y, z)
            let standerdY = +standardKey.split(',')[1]
            for (let i = standerdY; i < maximumSize; i++) {
                let tmpStandardKey = mapStandardKey(x, i, z)
                let cube = checkPositionExist(tmpStandardKey)

                if (cube) {
                    delete cubeMap[tmpStandardKey]
                    scene.remove(cube)
                }
            }
        }

        // 坐标处理 便于存储
        function mapStandardKey(x, y, z) {
            y = Math.floor(y)
            x = x * -1 + maximumSize / 2 - 1;
            z = z + maximumSize / 2;
            return `${x},${y},${z}`
        }

        // 标准位置 用于3d展示
        function standardToScene(x, y, z) {
            y += .5
            x = x * -1 + maximumSize / 2 - 1;
            z = z - maximumSize / 2;
            return {
                x, y, z
            }
        }




        // 创建方块
        function createCube(x, y, z) {
            const geometry = new THREE.BoxGeometry(1, 1, 1);
            const material = cubeMaterial || new THREE.MeshStandardMaterial({ color: 0x00ff00 });
            const cube = new THREE.Mesh(geometry, material);
            cube.receiveShadow = true
            cube.castShadow = true;

            cube.position.x = x
            cube.position.y = y
            cube.position.z = z

            let standardKey = mapStandardKey(x, y, z) // 获取x,y,z的标准
            cubeMap[standardKey] = cube
            cube.name = `cube(${x},${y},${z})`
            scene.add(cube)
            return cube
        }

        // 出一题
        function randomMap() {
            // 题库出题
            let questionList = [
                [
                    {
                        "x": 0,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 2,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 3,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 1,
                        "y": 1,
                        "z": 2
                    }
                ],
                [
                    {
                        "x": 1,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 0,
                        "y": 0,
                        "z": 1
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 1
                    },
                    {
                        "x": 2,
                        "y": 0,
                        "z": 1
                    },
                    {
                        "x": 1,
                        "y": 1,
                        "z": 1
                    }
                ],
                [
                    {
                        "x": 0,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 2,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 0,
                        "y": 1,
                        "z": 2
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 1
                    }
                ],
                [
                    {
                        "x": 0,
                        "y": 0,
                        "z": 3
                    },
                    {
                        "x": 0,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 0,
                        "y": 0,
                        "z": 1
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 2
                    },
                    {
                        "x": 1,
                        "y": 0,
                        "z": 3
                    },
                    {
                        "x": 2,
                        "y": 0,
                        "z": 3
                    },
                    {
                        "x": 0,
                        "y": 1,
                        "z": 3
                    },
                    {
                        "x": 0,
                        "y": 1,
                        "z": 2
                    },
                    {
                        "x": 0,
                        "y": 2,
                        "z": 3
                    },
                    {
                        "x": 1,
                        "y": 1,
                        "z": 3
                    }
                ]
            ]
            let queIndex = Randoms.getRandomInt(0, questionList.length)
            let que = questionList[queIndex]
            for (let i = 0; i < que.length; i++) {
                let { x, y, z } = que[i];
                createCube(...Object.values(standardToScene(x, y, z)))
            }

            // 随机出题
            // for (let i = 0; i < maximumSize; i++) {
            //     for (let j = 0; j < maximumSize; j++) {
            //         let h = Randoms.getRandomInt(0, maximumSize + 1) // 随机高度 [)
            //         console.log(h);
            //         for (let k = 0; k < h; k++) {
            //             let { x, y, z } = standardToScene(j, k, i) // 输出的坐标
            //             console.log(x, y, z);
            //             createCube(x, y, z)
            //         }
            //     }
            // }
        }

        // 检查问题是否正确
        function checkQuestionIsRight() {
            let cubeMapKeys = Object.keys(cubeMap)
            let frontViewIsRight = true;
            let topViewIsRight = true
            let leftViewIsRight = true
            // 正视图
            for (let i = 0; i < frontViewDom.children.length; i++) {
                const viewCudeDom = frontViewDom.children.item(i);
                let tmpX = viewCudeDom.getAttribute('x')
                let tmpY = viewCudeDom.getAttribute('y')
                let active = viewCudeDom.classList.contains('active')
                let userActive = !!cubeMapKeys.find(key => key.startsWith(`${tmpX},${tmpY}`))
                console.log(tmpX, tmpY, active, userActive);
                if (active != userActive) {
                    frontViewIsRight = false;
                    break;
                }
            }
            // 顶视图
            for (let i = 0; i < topViewDom.children.length; i++) {
                const viewCudeDom = topViewDom.children.item(i);
                let tmpX = viewCudeDom.getAttribute('x')
                let tmpZ = viewCudeDom.getAttribute('y')
                let active = viewCudeDom.classList.contains('active')
                let userActive = !!cubeMapKeys.find(key => key.startsWith(`${tmpX}`) && key.endsWith(`${tmpZ}`))
                if (active != userActive) {
                    topViewIsRight = false;
                    break;
                }
            }

            // 左视图
            for (let i = 0; i < leftViewDom.children.length; i++) {
                const viewCudeDom = leftViewDom.children.item(i);
                let tmpZ = maximumSize - 1 - +viewCudeDom.getAttribute('x')
                let tmpY = viewCudeDom.getAttribute('y')
                let active = viewCudeDom.classList.contains('active')
                let userActive = !!cubeMapKeys.find(key => key.endsWith(`${tmpY},${tmpZ}`))
                if (active != userActive) {
                    leftViewIsRight = false;
                    break;
                }
            }

            if (frontViewIsRight) {
                frontViewDom.classList.add('right')
            }
            if (topViewIsRight) {
                topViewDom.classList.add('right')
            }
            if (leftViewIsRight) {
                leftViewDom.classList.add('right')
            }
            if (frontViewIsRight && topViewIsRight && leftViewIsRight) {
                winShow();
            }
        }




        // 渲染动画
        function animate() {
            renderer.render(scene, camera);
            requestAnimationFrame(animate);

        }

        animate();
    </script>


</body>

</html>

在线预览
https://linyisonger.github.io/H5.Examples/
源码仓库
https://github.com/linyisonger/H5.Examples.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机+proteus+(DS1302+DS18B20)

目录 1.温度传感器检测&#xff08;DS18B20&#xff09; 1.1基本概念 1.1.1 DS18B20的简介 1.1.2 DS18B20的框图 ​编辑 1.1.3 DS18B20的指令 1.1.4 总线时序协议 1.2代码 1.2.1DS18B20的初始化代码 1.2.2DS18B20的读代码 1.2.3DS18B20的写时序 ​编辑 1.2.4DS18B20…

[C语言]第九节 函数一基础知识到高级技巧的全景探索

目录 9.1 函数的概念 9.2 库函数 9.2.1 标准库与库函数 示例&#xff1a;常见库函数 9.2.2 标准库与头文件的关系 参考资料和学习工具 如何使用库函数 ​编辑 9.3 ⾃定义函数 9.3.1 函数的语法形式 9.3.2函数的举例 9.4 实参与形参 9.4.1 什么是实参&#xff1f; 9…

嵌入式单片机中数码管基本实现方法

1. 点亮数码管 本节课利用已经学习的LED知识去控制一个8位数码管。 本节的原理比较简单。不需要多少时间讲。 更多时间是跟大家一起编码调试,从中学习一些编码思路和学习方法。 1.1. 什么是数码管 数码管是什么?下图就是一个数码管 从硬件上个看,其实就是8个LED组合…

Python实用的27个实例,涵盖从基础到进阶的所有领域!

Python 是一种广泛使用的高级编程语言&#xff0c;以其简洁的语法和丰富的库支持而受到开发者们的喜爱。以下列出了 27 个实用的 Python 实例&#xff0c;涵盖从基础到进阶的不同领域&#xff0c;帮助你提升编程技能。 1. 打印 "Hello, World!" print("Hello,…

企业微信如何利用群聊机器人定时推送消息

背景&#xff1a;公司其他部门有在群聊中新建机器人并定时推送消息的需求&#xff0c;webhook已准备好 1、准备一台服务器或者虚拟机&#xff0c;编写脚本 [rootlocalhost opt]# vim crontab.sh curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key4d38964b-04f2-44…

【Arduino】国产arduino驱动

买的国产 arduino&#xff0c;如果 windows识别不到。或者用 Arduino自带的Driver程序仍不能驱动。又不想用驱动精灵&#xff0c;可以直接安装驱动程序 99%大概率是CH340芯片&#xff0c;驱动下载连接如下。 你可以从 WCH 官方网站 下载并安装 CH340 驱动程序 安装即可用&am…

进阶岛 renwu5: 茴香豆:企业级知识问答工具实践闯关任务

进阶岛 renwu5: 茴香豆&#xff1a;企业级知识问答工具实践闯关任务 renwu: https://kkgithub.com/InternLM/Tutorial/blob/camp3/docs/L2/Huixiangdou/task.md 在 InternStudio 中利用 Internlm2-7b 搭建标准版茴香豆知识助手&#xff0c;并使用 Gradio 界面完成 2 轮问答&a…

什么是java的spi?

Java SPI&#xff08;Service Provider Interface&#xff09;是一种提供服务发现机制的设计模式&#xff0c;允许在运行时动态地发现、加载和替换服务的实现。SPI机制的核心思想是&#xff1a;通过接口定义服务&#xff0c;并且使用外部的实现类来提供该服务的具体功能。 目录…

这些学校就业不错且好考,努努力就能上岸的江浙沪学校!

这些学校就业不错且好考&#xff0c;努努力就能上岸&#xff0c;搭配历年数据&#xff0c;供大家参考~ 目录 ① 南京信息工程大学 ② 南京工业大学 ③ 浙江工业大学 ④ 中国计量大学 ⑤ 上海电力大学 ① 南京信息工程大学 复试线招生人数 双一流高校&#xff0c;金牛湖…

3.4.2 __ipipe_init_early之fixup_percpu_data()

点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 3.4.2 __ipipe_init_early之fixup_percpu_data() 这个函数只有在CPU是SMP对称多core的情况下&#xff0c;才会真正运作&#xff0c;否则就是个空函数。 #ifdef CONFIG_SMPstatic inline void fixup_percpu_data…

约瑟夫环和一元多项式修正版

这里先附上上一篇博文的链接大家可以对比着看&#xff0c;错误已经改正https://blog.csdn.net/2302_78946488/article/details/141751514?spm1001.2014.3001.5501 约瑟夫环 以下是详细代码 //约瑟夫环 #include<stdio.h> #include<stdlib.h> //建立链表结点 str…

哈夫曼编码——CSP-J1真题讲解

假设有一组字符{a,b,c,d,e,f}&#xff0c;对应的频率分别为5%、9%、12%、13%、16%、45%。请问以下哪个选项是字符a,b,c,d,e,f分别对应的一组哈夫曼编码?( ) A. 1111&#xff0c;1110&#xff0c;101&#xff0c;100&#xff0c;110&#xff0c;0 B. 1010&#xff0c;1001&…

视频工具EasyDarwin生成RTMP给WVP拉流列表

效果 运行 登录 http://127.0.0.1:10086/ admin/admin 创建RTMP服务

离线数仓ODS层准备

离线数仓ODS层设计-Operational Data Store ODS层设计要点ODS层-日志表-json表SERDEhive导入json表&#xff08;hive表和json表 字段不一致 解决方案&#xff09; 复杂数据类型日志表-建表语句 ODS层设计要点 &#xff08;1&#xff09;ODS层的表结构设计依托于从业务系统同步…

Qt 菜单栏、工具栏、状态栏、标签、铆接部件(浮动窗口) 设置窗口核心部件(文本编辑控件)的基本使用

效果 代码 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QToolBar> #include<QDebug> #include<QPushButton> #include<QStatusBar> #include<QLabel> #include<QDockWidget> #include<QTextEdi…

第1步win10宿主机与虚拟机通过NAT共享上网互通

VM的CentOS采用NAT共用宿主机网卡宿主机器无法连接到虚拟CentOS 要实现宿主机与虚拟机通信&#xff0c;原理就是给宿主机的网卡配置一个与虚拟机网关相同网段的IP地址&#xff0c;实现可以互通。 1、查看虚拟机的IP地址 2、编辑虚拟机的虚拟网络的NAT和DHCP的配置&#xff0c;…

springboot3.X版本集成mybatis遇到的问题

由于我本地springboot为3.x版本&#xff0c;如下图所示&#xff0c;最新版本 当我参照如下搜索的内容去集成mybatis的时候&#xff0c;会出现各种各样的报错 最根本的原因是搜出来的配置是参照springboot2.X版本&#xff0c;当我们使用springboot3.x版本之后&#xff0c;需要配…

【C++】STL--string(上)

前言 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0c;而且底层空间需要用户自己管理&#xff0c;稍不留…

8个前端库-小且美

前提&#xff1a;前端有很多小而美的库&#xff0c;接入成本很低又能满足日常开发需求&#xff0c;同时无论是 npm 方式引入还是直接复制到本地使用都可以。 1.radash radash相比与 lodash&#xff0c;更加面向现代&#xff0c;提供更多新功能&#xff08;tryit&#xff0c;…

前端层面----监控与埋点

前言&#xff1a; 站在产品的视角&#xff0c;经常会问如下几个问题&#xff1a; 产品有没有用户使用 用户用得怎么样 系统会不会经常出现异常 如何更好地满足用户需求服务用户 当站在技术视角时&#xff0c;经常会问如下几个问题&#xff1a; 系统出现异常的频率如何 异常…