当前位置: 首页 > news >正文

Vue3集成Phaser-飞机大战游戏(设计与源码)

在这里插入图片描述

文章目录

  • 引言
  • 项目初始化
  • 游戏设计和结构
  • 游戏程序实现
    • Vue页面嵌入Phaser
    • Preloader 场景加载
    • 游戏场景功能实现
    • 功能类定义
      • Boom爆炸类
      • Bullet子弹类
      • Enemy敌军类
      • Player玩家类
      • End游戏结束类
  • 总结

更多相关内容可查看

引言

飞机大战(也被称为射击游戏或空战游戏)是一种非常受欢迎的休闲游戏类型。在这个博客中,我们将探讨如何使用 Vue.js 框架来构建一个简单的飞机大战游戏。我们将从基本的游戏逻辑开始,逐步增加游戏元素和交互性,代码详解可参考注释,最终展示画面在文章底部

项目初始化

git地址:https://gitee.com/its-a-little-bad/vue-project—aircraft-battle.git
node版本:20.8.1

游戏设计和结构

在 Vue.js 中,我们通常将游戏的各个部分分解为不同的场景。

主场景

Game.vue:游戏的主界面,包含背景、飞机、敌机、子弹等。
Plane.vue:玩家的飞机,可以移动和发射子弹。
Enemy.vue:敌机,从屏幕上方随机出现并向下移动。
Bullet.vue:子弹,从玩家飞机发射并向上移动。

游戏场景
在这里插入图片描述

游戏程序实现

Vue页面嵌入Phaser

在 Vue 应用中嵌入一个 Phaser 游戏

<template><!-- Phaser 游戏的容器 --><div id="container"></div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted } from "vue";
import { Game, AUTO, Scale } from "phaser";
import { Preloader } from "./game/Preloader";
import { Main } from "./game/Main";
import { End } from "./game/End";// 使用正则表达式检测当前设备是否为移动设备
let isMobile = /(iPhone|iPad|Android)/i.test(navigator.userAgent);// 定义了一个 game 变量来存储 Phaser 游戏实例
let game: Game;
onMounted(() => {game = new Game({parent: "container",type: AUTO,width: 375,//游戏的大小根据设备类型进行调整。如果设备是移动设备,则高度会根据设备的纵横比计算得出。height: isMobile ? (window.innerHeight / window.innerWidth) * 375 : 667,//游戏的缩放模式也根据设备类型进行设置。移动设备使用 Scale.FIT,这意味着游戏将尽可能地适应屏幕大小,//而不会保持其原始纵横比。非移动设备则使用 Scale.NONE,这意味着游戏将保持其原始大小。scale: {mode: isMobile ? Scale.FIT : Scale.NONE,},physics: {default: "arcade",arcade: {debug: false,},},scene: [Preloader, Main, End],});
});onUnmounted(() => {game.destroy(true);
});
</script><style>
body {margin: 0;
}
#app {height: 100%;
}
</style>

Preloader 场景加载

创建一个 Preloader 场景来加载游戏所需的资源和设置一些基本的游戏元素,示例如下
在这里插入图片描述
程序实现:

import { Scene } from "phaser";  
import backgroundImg from "../assets/images/background.jpg";  
import enemyImg from "../assets/images/enemy.png";  
import playerImg from "../assets/images/player.png";  
import bulletImg from "../assets/images/bullet.png";  
import boomImg from "../assets/images/boom.png";  
import spritesImg from "../assets/images/sprites.png";  
import spritesJson from "../assets/json/sprites.json?url";  
import bgmAudio from "../assets/audio/bgm.mp3";  
import boomAudio from "../assets/audio/boom.mp3";  
import bulletAudio from "../assets/audio/bullet.mp3";  export class Preloader extends Scene {  // 构造函数,定义场景名称为 "Preloader"  constructor() {  super("Preloader");  }  // 预加载资源的方法  preload() {  // 加载背景图片  this.load.image("background", backgroundImg);  // 加载敌人图片  this.load.image("enemy", enemyImg);  // 加载玩家图片  this.load.image("player", playerImg);  // 加载子弹图片  this.load.image("bullet", bulletImg);  // 加载爆炸动画的精灵表(spritesheet)  this.load.spritesheet("boom", boomImg, {  frameWidth: 64,  frameHeight: 48,  });  // 加载精灵图集(atlas)  this.load.atlas("sprites", spritesImg, spritesJson);  // 加载背景音乐  this.load.audio("bgm", bgmAudio);  // 加载爆炸音效  this.load.audio("boom", boomAudio);  // 加载子弹音效  this.load.audio("bullet", bulletAudio);  }  // 创建场景的方法  create() {  const { width, height } = this.cameras.main;  // 显示背景(通常在Preloader场景中不展示实际游戏内容,这里仅为示例)  this.add.tileSprite(0, 0, width, height, "background").setOrigin(0, 0);  // 播放背景音乐(在Preloader场景中播放通常是为了给玩家一个等待的反馈)  this.sound.play("bgm", { loop: true }); // 循环播放背景音乐  // 添加标题(通常也不在Preloader场景中,但可以作为加载提示)  this.add  .text(width / 2, height / 4, "飞机大战", {  fontFamily: "Arial",  fontSize: 60,  color: "#e3f2ed",  stroke: "#203c5b",  strokeThickness: 6,  })  .setOrigin(0.5);  // 添加开始按钮(通常用于在加载完成后切换到主场景)  let button = this.add  .image(width / 2, (height / 4) * 3, "sprites", "button") // 假设"sprites"图集中有名为"button"的帧  .setScale(3, 2)  .setInteractive()  .on("pointerdown", () => {  // 当按钮被点击时,切换到主场景(这里主场景名为'Main')  this.scene.start('Main');  });  // 按钮文案this.add.text(button.x, button.y, "开始游戏", {fontFamily: "Arial",fontSize: 20,color: "#e3f2ed",}).setOrigin(0.5); }  // 创建动画,命名为 boom,后面使用this.anims.create({key: "boom",frames: this.anims.generateFrameNumbers("boom", { start: 0, end: 18 }),repeat: 0,});
}

在Phaser 3框架中,从一个场景(如Preloader)切换到另一个场景(如Main)通常使用this.scene.start(‘Main’)这样的代码来实现。这是Phaser场景管理系统的一部分,它允许你动态地加载、创建、运行和销毁游戏的不同部分。

游戏场景功能实现

在这里插入图片描述

程序实现

// 定义 Main 场景类,继承自 Phaser 的 Scene 类  
import { Scene, Physics, GameObjects } from "phaser";
import { Player } from "./Player";
import { Bullet } from "./Bullet";
import { Enemy } from "./Enemy";
import { Boom } from "./Boom";// 场景元素
let background: GameObjects.TileSprite;
let player: Player;
let enemys: Physics.Arcade.Group;
let bullets: Physics.Arcade.Group;
let booms: GameObjects.Group;
let scoreText: GameObjects.Text;// 场景数据
let score: number;export class Main extends Scene {constructor() {super("Main");}create() {let { width, height } = this.cameras.main;// 创建背景background = this.add.tileSprite(0, 0, width, height, "background").setOrigin(0, 0);// 创建玩家,调用Player类player = new Player(this);// 创建敌军组// 注解:enemys 是一个 Phaser 的物理组,用于存储和管理多个 Enemy 对象// frameQuantity 表示从 enemy 纹理集中加载的帧数,key 是纹理集的名称// enable, active, visible 分别是启用物理、激活和可见性标志// classType 指示组中新创建对象的类型enemys = this.physics.add.group({frameQuantity: 30,key: "enemy",enable: false,// 在此初始状态下不启用物理 active: false,// 在此初始状态下不激活  visible: false,// 在此初始状态下不可见classType: Enemy,// 当组中添加新对象时使用的类});// 创建子弹// 注解:与敌军组类似,但用于存储和管理多个 Bullet 对象 bullets = this.physics.add.group({frameQuantity: 15,key: "bullet",enable: false,active: false,visible: false,classType: Bullet,});// 创建爆炸// 注解:booms 组用于存储和管理多个 Boom 对象,可能是用于显示爆炸动画booms = this.add.group({frameQuantity: 30,key: "boom",active: false,visible: false,classType: Boom,});// 分数// 注解:score 变量用于跟踪玩家的分数,scoreText 是显示分数的文本对象 score = 0;scoreText = this.add.text(10, 10, "0", {fontFamily: "Arial",fontSize: 20,});// 注册事件this.addEvent();}// 注册事件addEvent() {// 定时器// 注解:此定时器每 400 毫秒触发一次回调,生成敌军和发射子弹 this.time.addEvent({delay: 400,callback: () => {// 生成2个敌军for (let i = 0; i < 2; i++) {enemys.getFirstDead()?.born();}// 发射1颗子弹bullets.getFirstDead()?.fire(player.x, player.y - 32);},callbackScope: this,repeat: -1,});// 子弹和敌军碰撞,会调用 hit 方法this.physics.add.overlap(bullets, enemys, this.hit, null, this);// 玩家和敌军碰撞,会调用 gameOver 方法this.physics.add.overlap(player, enemys, this.gameOver, null, this);}// 子弹击中敌军hit(bullet, enemy) {// 子弹和敌军隐藏enemy.disableBody(true, true);bullet.disableBody(true, true);// 显示爆炸booms.getFirstDead()?.show(enemy.x, enemy.y);// 分数增加scoreText.text = String(++score);}// 游戏结束gameOver() {// 暂停当前场景,并没有销毁this.sys.pause();// 保存分数this.registry.set("score", score);// 打开结束场景this.game.scene.start("End");}update() {// 设置背景瓦片不断移动background.tilePositionY -= 1;}
}

功能类定义

Boom爆炸类

import { GameObjects, Scene } from "phaser";export class Boom extends GameObjects.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {// 创建对象super(scene, x, y, texture);// 爆炸动画播放结束事件this.on("animationcomplete-boom", this.hide, this);}/*** 显示爆炸* @param x 爆炸x坐标* @param y 爆炸y坐标*/show(x: number, y: number) {this.x = x;this.y = y;this.setActive(true);this.setVisible(true);// 爆炸动画this.play("boom");// 爆炸音效this.scene.sound.play("boom");}/*** 隐藏爆炸*/hide() {this.setActive(false);this.setVisible(false);}
}

Bullet子弹类

import { Physics, Scene } from "phaser";export class Bullet extends Physics.Arcade.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {super(scene, x, y, texture);// 设置属性this.setScale(0.25);}/*** 发射子弹* @param x 子弹x坐标* @param y 子弹y坐标*/fire(x: number, y: number) {this.enableBody(true, x, y, true, true);this.setVelocityY(-300);this.scene.sound.play("bullet");}preUpdate(time: number, delta: number) {super.preUpdate(time, delta);// 子弹走到头,销毁if (this.y <= -14) {this.disableBody(true, true);}}
}

Enemy敌军类

import { Physics, Math, Scene } from "phaser";export class Enemy extends Physics.Arcade.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {// 创建对象super(scene, x, y, texture);scene.add.existing(this);scene.physics.add.existing(this);// 设置属性this.setScale(0.5);this.body.setSize(100, 60);}/*** 生成敌军*/born() {let x = Math.Between(30, 345);let y = Math.Between(-20, -40);this.enableBody(true, x, y, true, true);this.setVelocityY(Math.Between(150, 300));}preUpdate(time: number, delta: number) {super.preUpdate(time, delta);let { height } = this.scene.cameras.main;// 敌军走到头,销毁if (this.y >= height + 20) {this.disableBody(true, true)}}
}

Player玩家类

import { Physics, Scene } from "phaser";export class Player extends Physics.Arcade.Sprite {isDown: boolean = false;downX: number;downY: number;constructor(scene: Scene) {// 创建对象let { width, height } = scene.cameras.main;super(scene, width / 2, height - 80, "player");scene.add.existing(this);scene.physics.add.existing(this);// 设置属性this.setInteractive();this.setScale(0.5);this.setCollideWorldBounds(true);this.body.setSize(120, 120);// 注册事件this.addEvent();}/*** 注册事件*/addEvent() {// 手指按下我方飞机this.on("pointerdown", () => {this.isDown = true;this.downX = this.x;this.downY = this.y;});// 手指抬起this.scene.input.on("pointerup", () => {this.isDown = false;});// 手指移动this.scene.input.on("pointermove", (pointer) => {if (this.isDown) {this.x = this.downX + pointer.x - pointer.downX;this.y = this.downY + pointer.y - pointer.downY;}});}
}

End游戏结束类

import { Scene } from "phaser";export class End extends Scene {constructor() {super("End");}create() {let { width, height } = this.cameras.main;// 结束面板this.add.image(width / 2, height / 2, "sprites", "result").setScale(2.5);// 标题this.add.text(width / 2, height / 2 - 85, "游戏结束", {fontFamily: "Arial",fontSize: 24,}).setOrigin(0.5);// 当前得分let score = this.registry.get("score");this.add.text(width / 2, height / 2 - 10, `当前得分:${score}`, {fontFamily: "Arial",fontSize: 20,}).setOrigin(0.5);// 重新开始按钮let button = this.add.image(width / 2, height / 2 + 50, "sprites", "button").setScale(3, 2).setInteractive().on("pointerdown", () => {// 点击事件:关闭当前场景,打开Main场景this.scene.start("Main");});// 按钮文案this.add.text(button.x, button.y, "重新开始", {fontFamily: "Arial",fontSize: 20,}).setOrigin(0.5);}
}

总结

通过使用 Vue.js 框架,我们可以轻松地构建出一个简单而有趣的飞机大战游戏。从基本的游戏逻辑开始,逐步增加游戏元素和交互性,最终得到一个完整且吸引人的游戏作品。希望这个博客能对你有所启发,并鼓励你尝试使用 Vue.js 来开发更多有趣的游戏和应用程序!

相关文章:

Vue3集成Phaser-飞机大战游戏(设计与源码)

文章目录 引言项目初始化游戏设计和结构游戏程序实现Vue页面嵌入PhaserPreloader 场景加载游戏场景功能实现功能类定义Boom爆炸类Bullet子弹类Enemy敌军类Player玩家类End游戏结束类 总结 更多相关内容可查看 引言 飞机大战&#xff08;也被称为射击游戏或空战游戏&#xff09…...

C51学习归纳1 --- led点亮、led闪烁、led流水灯

第一节主要是针对LED的控制学习。这个过程中我们需要掌握的&#xff1a;1、控制的实现方法&#xff0c;控制实现的方法在后续的学习中是通用的。2、如何知道谁控制谁&#xff0c;通过查找开发板原理图获取&#xff0c;原理图的阅读的能力&#xff0c;在日后也是非常常用的。 一…...

使用STM32和TB6600驱动器控制42BYGH步进电机

项目概述 1. 系统组成 STM32微控制器&#xff1a;作为主控制器&#xff0c;负责发出控制指令。TB6600驱动器&#xff1a;用于接收STM32的指令并驱动步进电机。42BYGH步进电机&#xff1a;作为执行元件&#xff0c;根据控制信号进行转动。电源&#xff1a;为STM32、TB6600和步…...

【Qt】对话框

文章目录 1 :peach:对话框介绍:peach:2 :peach:对话框的分类:peach:2.1 :apple:模态对话框:apple:2.2 :apple:非模态对话框:apple:2.3 :apple:混合属性对话框:apple: 3 :peach:Qt 内置对话框:peach:3.1 :apple:消息对话框 QMessageBox:apple: 1 &#x1f351;对话框介绍&#x…...

Python | 武理刷题

1. 为什么是非法的&#xff1f; a1a1 在Python&#xff08;以及大多数其他编程语言&#xff09;中&#xff0c;表达式 a1a1 是非法的&#xff0c;因为它试图将一个值&#xff08;a1 的结果&#xff09;赋给一个表达式&#xff08;a1 本身&#xff09;&#xff0c;而不是一个…...

如何设置让背景颜色不包括 padding 部分,顺带全面学习 background-clip 属性(可以实现文字渐变)

先解决需求 实现背景颜色不包括 padding 部分&#xff0c;直接给容器添加 css 属性&#xff1a;background-clip:content-box; 示例代码&#xff1a; .content-box-example {background-color: lightblue;padding: 20px;border: 1px solid black;background-clip: content-bo…...

Oracle 序列-SEQUENCE

文章目录 序列-SEQUENCE创建序列访问序列序列的修改和删除查询序列信息 序列-SEQUENCE 创建序列 访问序列 序列的修改和删除 DROP SEQUENCE SEQ_EKPO;查询序列信息 可以通过视图 dba/all/user_sequences 查询序列的相关信息 SELECT SEQUENCE_NAME FROM DBA_SEQUENCES WHERE …...

8岁儿童学编程基础好吗:探索早期编程教育的利与弊

8岁儿童学编程基础好吗&#xff1a;探索早期编程教育的利与弊 在数字化快速发展的今天&#xff0c;编程技能已成为一项重要的能力。许多家长开始思考&#xff0c;是否应该让8岁的孩子学习编程基础。这个问题看似简单&#xff0c;实则涉及多个层面的考量。下面&#xff0c;我们…...

vue3加axios配合element-plus实现图片等文件本地上传,并获取服务器返回的真实地址数据,前端写法

小白写法嘿嘿 开发工具和关键词 开发工具&#xff1a; vscode 关键词&#xff1a;vue3、element-plus、axios 后端 后端业务逻辑处理使用的是unicloud的云函数&#xff0c;大家可以看我上一篇文章。 思路 1、禁止element-plus的el-upload组件自动上传&#xff0c;变成手动上传…...

面试题:谈谈你对观察者和订阅发布的理解

面试题&#xff1a;谈谈你对观察者和订阅发布的理解 1. 观察者设计模式 场景引入之杂志订阅&#xff1a;小王想要购买一本尚未出版的杂志&#xff0c;他向出版社预订该杂志并提供联系方式&#xff0c;一旦该杂志出版&#xff0c;出版社就会根据小王预留的联系方式通知他可以来…...

下载文件流

export function downloadFile(file, name, type) { const link document.createElement(‘a’) link.href window.URL.createObjectURL(new Blob([file], { type: type })) link.target ‘_blank’ link.download name document.body.appendChild(link) link.click() docu…...

有开源软件,也有开源硬件?

开源软件或库有很多&#xff0c;例如 Linux 操作系统的内核 The Linux Kernel Archiveshttps://www.kernel.org/ 开源的各种Linux发行版本&#xff0c;Ubuntu 、CentOS等 Enterprise Open Source and Linux | Ubuntuhttps://ubuntu.com/ 开源的视觉函数库&#xff0c;OpenC…...

【TensorFlow深度学习】卷积层变种与深度残差网络原理

卷积层变种与深度残差网络原理 卷积层变种与深度残差网络&#xff1a;探究卷积神经网络的进化与优化策略卷积层&#xff1a;深度学习的基石变种与卷积层变种深差网络&#xff1a;深度网络的优化策略实战代码示例&#xff1a;ResNet模块实现结语 卷积层变种与深度残差网络&#…...

每日一题《leetcode-- LCR 025.两数相加||》

https://leetcode.cn/problems/lMSNwu/ 分别把给定的两个链表翻转&#xff0c;然后从头开始相加。 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ //反转链表 struct ListNode* reverselist(struct ListNode*h…...

MySQL数据库的约束

MySQL对于数据库存储的数据, 做出一些限制性要求, 就叫做数据库的"约束". 在每一列的 列名, 类型 后面加上"约束". 一. not null (非空) 指定某列不能存储null值. 二. unique (唯一) 保证这一列的每行必须有唯一值. 我们可以看到, 给 table 的 sn 列插…...

计算机毕业设计 | springboot+vue会议室管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 随着企业规模的不断扩大&#xff0c;会议室管理愈加复杂。传统的手工预约会议室的方式已经无法满足现代企业的需求&#xff0c;因此&#xff0c;开发一套会议室系统方案变得尤为重要。会议室系统可以实现会议室的在线预约、会议室资源的有效利…...

常见端口及其脆弱点

端口及脆弱性 ⚫ FTP (21/TCP) 1.默认用户名密码anonymous:anonymous 2.暴力破解密码 3.VSFTP 某版本后门 ⚫ SSH (22/TCP) 1.部分版本 SSH 存在漏洞可枚举用户名 2.暴力破解密码 ⚫ Telent (23/TCP) 1.暴力破解密码 2.嗅探抓取明文密码 ⚫ SMTP (25/TCP) 1.无认证…...

JS函数的进阶

目录 递归和堆栈Rest参数与Spread语法闭包全局对象高阶函数函数对象和绑定装饰者模式和转发深入理解箭头函数递归和堆栈 递归 递归是一种编程技巧,函数在其定义中直接或间接地调用自身,通常用来解决具有明确递归结构的问题,如树形结构遍历、排序算法(如快速排序)、数学问…...

【UE+GIS】UE5GIS CAD或shp构建3D地形

贴合地形的矢量图形实现方法 一、灰度图的制作和拉伸换算1、基于高程点集实现2、基于等高线实现3、拉伸计算 二、生成地形模型的实现方案1、3Dmax导入灰度图2、使用ArcMap/Arcpro/FME等GIS数据处理工具3、UE导入灰度图 三、地形上叠加地形渲染效果的实现方案1、贴花2、数据渲染…...

Unity学习笔记---音视频播放

音频 Audiolistener组件 AudioListener组件是音频监听器&#xff0c;将组件挂在角色或camera上面&#xff0c;每个场景中最多只有一个AudioListener组件。 AudioSource组件 AudioSource组件是音源&#xff0c;用来播放音频AudioClip.将他挂在产生声音的物体上&#xff0c;可…...

项目集成过程中的makefile记录

项目集成过程中的makefile记录 文章目录 项目集成过程中的makefile记录1.基础概念注释打印赋值方式常用变量$ 伪目标函数wildcard 多目录、文件操作 2.思路梳理**需求分析**目录结构 3.可行示例 持续更新中1.基础概念 注释 # 示例&#xff1a; # 项目名称打印 echo "H…...

Vue3 -Computed计算属性

前言&#xff1a; Computed属性属于Vue3中的响应式核心(与之共同说明的还有ref&#xff0c;reactive&#xff0c;watch...) 接受一个 getter 函数&#xff0c;返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set…...

MySQL—函数—日期函数(基础)

一、引言 接下来讨论和学习关于函数的第三个方面——日期函数。 常见的MySQL当中的日期函数。 注意&#xff1a; 1、CURDATE()&#xff1a;cur&#xff1a;current 当前的&#xff0c;返回的是当前日期。 2、CURTIME()&#xff1a;当前时间。 3、NOW&#xff1a;当前的日期和…...

Java+SVNCloud+Mysql课程设计

文章目录 1、主要内容2、所需准备3、与sql访问的中间类&#xff1a;SqlMessage4、窗口界面5、main方法 1、主要内容 课程设计&#xff0c;主要通过Javas wing创建窗口&#xff0c;jdbc连接云端mysql数据库进行基本操作&#xff0c;支持随机生成数据并用动态展示数据结果。 先…...

MySQL之创建高性能的索引(四)

创建高性能的索引 空间数据索引(R-Tree) MyISAM表支持空间索引&#xff0c;可以用作地理数据存储。和B-Tree索引不同&#xff0c;这类索引无须前缀查询。空间索引会从所有维度来索引数据。查询时&#xff0c;可以有效地使用任意维度来组合查询。必须使用MySQL的GIS相关函数如…...

Python 限制输入数的范围

Python 限制输入数的范围 在 Python 编程中&#xff0c;我们经常需要限制用户输入的数据范围&#xff0c;以避免一些可能出现的问题。例如&#xff0c;在一个游戏程序中&#xff0c;我们可能想要确保玩家的分数在某个范围内&#xff0c;而不是太高或太低。在这个博文中&#x…...

STM32两轮平衡小车原理详解

STM32两轮平衡小车是一种基于STM32微控制器的智能机器人&#xff0c;它能够通过传感器和算法实现自我平衡。以下是对STM32两轮平衡小车原理的详解&#xff0c;以及一些基础的代码示例。 原理详解 1. 系统组成 主控制器&#xff1a;STM32系列微控制器&#xff0c;作为小车的大…...

(笔记)如何评价一个数仓的好坏

如何评价一个数仓的好坏 1数据质量产生原因评估方法流程 2模型建设产生问题原因评估方法流程 3数据安全产生问题原因评估方法流程 4成本/性能产生问题原因评估方法流程 5 用户用数体验产生问题原因评估方法流程 6数据资产覆盖产生问题原因评估方法流程 数仓评价好坏是对数仓全流…...

友善RK3399v2平台利用rkmpp实现硬件编解码加速

测试VPU 编译mpp sudo apt update sudo apt install gcc g cmake make cd ~ git clone https://github.com/rockchip-linux/mpp.git cd mpp/build/linux/aarch64/ sed -i s/aarch64-linux-gnu-gcc/gcc/g ./arm.linux.cross.cmake sed -i s/aarch64-linux-gnu-g/g/g ./arm.lin…...

Mysql 8.0 主从复制及读写分离搭建记录

前言 搭建参考&#xff1a;搭建Mysql主从复制 为什么要做主从复制&#xff1f; 做数据的热备&#xff0c;作为后备数据库&#xff0c;主数据库服务器故障后&#xff0c;可切换到从数据库继续工作&#xff0c;避免数据丢失。架构的扩展。业务量越来越大&#xff0c;I/O访问频…...