【用unity实现100个游戏之8】用Unity制作一个炸弹人游戏

文章目录

  • 前言
  • 素材
  • 开始
    • 一、绘制地图
    • 二、玩家设置
    • 三、玩家移动
    • 四、玩家四方向动画运动切换
  • 五、放置炸弹
    • 六、生成爆炸效果
    • 七、墙壁和可破坏障碍物的判断
    • 八、道具生成和效果
    • 九、玩家死亡
    • 十、简单的敌人AI
    • 十一、简单敌人AI
    • 十二、随机绘制地图
    • 十三、虚拟摇杆
  • 最终效果
  • 待续
  • 源码
  • 完结

前言

我们将在这个视频中,学习如何在Unity中制作《炸弹人心》,《炸弹人》是—个游戏系列,最初于1983年7月在日本发行,《炸弹人》的游戏玩法包括策略性地放炸弹,在一定时间后以多个方向爆炸,以摧毁障碍物和杀死敌人。

本文重点介绍了实现瓦片地图精灵动画的方法,你可以用许多不同的方式自定义游戏,
想出独特的游戏模式并建立自己的关卡。

先来看看实现的最终效果
在这里插入图片描述

素材

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

开始

一、绘制地图

使用tilemap绘制地图,其实挺简单的,这里我就不再介绍如何使用了,节省大家时间,tilemap还不会用的,可以看我之前的tilemap文章:【Unity小技巧】Unity2D TileMap的探究(最简单,最全面的TileMap使用介绍)

绘制的最终效果,你也可以按自己的喜欢绘制不同的地图
在这里插入图片描述

二、玩家设置

给玩家添加刚体和碰撞器,重力设置为0,注意添加圆形的碰撞器,这样可以有效防止角色转弯时卡在墙角
在这里插入图片描述

新建2d物理材质,设置角摩擦力和弹力为0,防止角色卡墙
在这里插入图片描述
刚体和碰撞器都挂载刚才的2d物理材质
在这里插入图片描述

三、玩家移动

Player代码

public class Player : MonoBehaviour
{Rigidbody2D rb;Vector2 movement;private float horizontalInput;private float verticalInput;public float speed;//移动速度private void Start(){rb = GetComponent<Rigidbody2D>();}void Update(){        horizontalInput = Input.GetAxisRaw("Horizontal");verticalInput = Input.GetAxisRaw("Vertical");movement = new Vector2(horizontalInput, verticalInput).normalized;}private void FixedUpdate(){//移动代码rb.MovePosition(rb.position + movement * speed * Time.fixedDeltaTime);}
}

运行效果
在这里插入图片描述

四、玩家四方向动画运动切换

这里我们使用2D混合动画实现(2D Simple Directional),混合动画的基础使用我之前有说过,不懂得可以回去先看:
零基础带你从小白到超神27——混合状态,混合动画,动画分类
Run混合动画配置(down动画片段是默认人物站立面向观众)
在这里插入图片描述
修改人物移动代码

//控制动画
animator.SetFloat("Horizontal", horizontalInput);
animator.SetFloat("Vertical", verticalInput);

运行效果
在这里插入图片描述
问题
如果你的游戏对细节要求不高,其实到这里就已经算完成了。
但是我本着严谨的态度,会发现人物移动停止时都会面向屏幕(也就是前面的down站立动画),这显然不符合逻辑,我们希望人物最终停止面向对应的位置

那么要如何做呢?方法其实有很多,最简单的方法呢,就是在Run混合动画前面再加一个Idle混合动画
我们通过isRun参数来控制动画的切换
在这里插入图片描述
Run混合动画配置(所有动画片段都是人物不同方向的站立动画)
在这里插入图片描述

修改代码

//控制动画
if (horizontalInput == 0 && verticalInput == 0){animator.SetBool("isRun", false);
} else {animator.SetBool("isRun", true);animator.SetFloat("Horizontal", horizontalInput);animator.SetFloat("Vertical", verticalInput);
}

效果
在这里插入图片描述

五、放置炸弹

炸弹控制脚本

using System.Collections;
using UnityEngine;public class Bomb : MonoBehaviour
{[Header("Bomb")]private KeyCode inputKey = KeyCode.Space;  // 输入的按键public GameObject bombPrefab;  // 炸弹预制体public float bombFuseTime = 3f;  // 炸弹引线时间public int bombAmount = 1;  // 炸弹数量private int bombsRemaining;  // 剩余炸弹数量private void OnEnable(){bombsRemaining = bombAmount;  // 初始化剩余炸弹数量}private void Update(){if (bombsRemaining > 0 && Input.GetKeyDown(inputKey))  // 如果还有剩余炸弹且按下了指定按键{StartCoroutine(PlaceBomb());  // 放置炸弹}}private IEnumerator PlaceBomb(){Vector2 position = transform.position;  // 获取当前位置position.x = Mathf.Round(position.x)-0.5f;  // 四舍五入x坐标-0.5偏移量position.y = Mathf.Round(position.y)-0.5f;  // 四舍五入y坐标-0.5偏移量GameObject bomb = Instantiate(bombPrefab, position, Quaternion.identity);  // 实例化炸弹bombsRemaining--;  // 剩余炸弹数量减一yield return new WaitForSeconds(bombFuseTime);  // 等待炸弹引线时间Destroy(bomb.gameObject);  // 销毁炸弹游戏对象bombsRemaining++;  // 剩余炸弹数量加一}//炸弹默认是触发器 角色离开时开启碰撞效果private void OnTriggerExit2D(Collider2D other){if (other.gameObject.layer == LayerMask.NameToLayer("Bomb"))  // 如果离开触发器的物体属于Bomb层{other.isTrigger = false;  // 取消触发器属性}}
}

角色绑定脚本,配置参数,记得Bomb预制体开启触发器,并指定图层为Bomb
在这里插入图片描述
运行效果
在这里插入图片描述

六、生成爆炸效果

新增爆炸效果代码

[Header("爆炸")]
public GameObject explosionEnd; // 爆炸结束
public GameObject explosionMiddle; // 爆炸中间
public GameObject explosionStart; // 爆炸结束
public int explosionRange;//爆炸范围//生成爆炸效果
public void createExplosion(Vector2 position)
{//爆炸中心GameObject explosionStartData = Instantiate(explosionStart, position, Quaternion.identity);Destroy(explosionStartData, 0.5f);for (int i = 1; i <= explosionRange; i++){ClearDestructible(new Vector2(position.x + i, position.y), i, 0);ClearDestructible(new Vector2(position.x - i, position.y), i, 180);ClearDestructible(new Vector2(position.x, position.y + i), i, 90);ClearDestructible(new Vector2(position.x, position.y -i), i, -90);}
}private bool ClearDestructible(Vector2 position, int i, int rotate)
{//是不是最后爆炸区if (i == explosionRange){GameObject explosionEndData = Instantiate(explosionEnd, position, Quaternion.identity);//设置爆炸效果的方向explosionEndData.transform.eulerAngles = new Vector3(0, 0, rotate);Destroy(explosionEndData, 0.5f);}else{GameObject explosionMiddleData = Instantiate(explosionMiddle, position, Quaternion.identity);//设置爆炸效果的方向explosionMiddleData.transform.eulerAngles = new Vector3(0, 0, rotate);Destroy(explosionMiddleData, 0.5f);}return true;
}

效果
在这里插入图片描述

七、墙壁和可破坏障碍物的判断

修改代码

[Header("爆炸")]
public Tilemap wallTileMap; // 可破坏物墙壁的Tilemap组件
public GameObject explosionEnd; // 爆炸结束预制体
public GameObject explosionMiddle; // 爆炸中间预制体
public GameObject explosionStart; // 爆炸结束预制体
public GameObject brickWall;//破坏的墙
public int explosionRange;//爆炸范围
public LayerMask explosionLayerMask;  // 墙壁层级//生成爆炸效果
public void createExplosion(Vector2 position)
{//爆炸中心GameObject explosionStartData = Instantiate(explosionStart, position, Quaternion.identity);Destroy(explosionStartData, 0.5f);for (int i = 1; i <= explosionRange; i++){bool res = ClearDestructible(new Vector2(position.x + i, position.y), i, 0);if (!res) break;}for (int i = 1; i <= explosionRange; i++){bool res = ClearDestructible(new Vector2(position.x - i, position.y), i, 180);if (!res) break;}for (int i = 1; i <= explosionRange; i++){bool res = ClearDestructible(new Vector2(position.x, position.y + i), i, 90);if (!res) break;}for (int i = 1; i <= explosionRange; i++){bool res = ClearDestructible(new Vector2(position.x, position.y - i), i, -90);if (!res) break;} 
}private bool ClearDestructible(Vector2 position, int i, int rotate)
{if (Physics2D.OverlapBox(position, new Vector2(0.5f, 0.5f), 0f, explosionLayerMask))  // 如果爆炸位置有墙壁{return false;}Vector3Int cell = wallTileMap.WorldToCell(position);  // 将世界坐标转换为Tilemap的单元格坐标TileBase tile = wallTileMap.GetTile(cell);  // 获取指定单元格的Tileif (tile != null)  // 如果爆炸位置有可破坏障碍物{wallTileMap.SetTile(cell, null);  // 清除TileGameObject brickWallData = Instantiate(brickWall, position, Quaternion.identity);  // 实例化可破坏物体Destroy(brickWallData, 0.5f);return false;} else {//是不是最后爆炸区if (i == explosionRange){GameObject explosionEndData = Instantiate(explosionEnd, position, Quaternion.identity);//设置爆炸效果的方向explosionEndData.transform.eulerAngles = new Vector3(0, 0, rotate);Destroy(explosionEndData, 0.5f);} else {GameObject explosionMiddleData = Instantiate(explosionMiddle, position, Quaternion.identity);//设置爆炸效果的方向explosionMiddleData.transform.eulerAngles = new Vector3(0, 0, rotate);Destroy(explosionMiddleData, 0.5f);}return true;}
}

效果,记得先设置和配置好墙壁的层级
在这里插入图片描述

八、道具生成和效果

新建破坏的墙脚本

public class BrickWall : MonoBehaviour
{public float destructionTime = 1f;[Range(0f, 1f)]public float itemSpawnChance = 0.2f;//生成道具的概率public GameObject[] spawnableItems;private void Start(){Destroy(gameObject, destructionTime);}//销毁时按比例生成道具private void OnDestroy(){if (spawnableItems.Length > 0 && Random.value < itemSpawnChance){int randomIndex = Random.Range(0, spawnableItems.Length);Instantiate(spawnableItems[randomIndex], transform.position, Quaternion.identity);}}
}

新增道具代码

using UnityEngine;//道具代码
public class Prop : MonoBehaviour
{public enum ItemType{ExtraBomb,BlastRadius,SpeedIncrease,}public ItemType type;private void OnItemPickup(GameObject player){switch (type){case ItemType.ExtraBomb:player.GetComponent<Bomb>().bombAmount++;  // 炸弹数量加一player.GetComponent<Bomb>().bombsRemaining++;  // 剩余炸弹数量加一break;case ItemType.BlastRadius:player.GetComponent<Bomb>().explosionRange++;//爆炸范围增加break;case ItemType.SpeedIncrease:player.GetComponent<Player>().speed++;//移动速度增加break;}Destroy(gameObject);}private void OnTriggerEnter2D(Collider2D other){if (other.CompareTag("Player")) {OnItemPickup(other.gameObject);}}
}

挂载脚本和配置好道具参数,这里为了测试方便我就把生成道具的概率先设置为1
在这里插入图片描述
效果
在这里插入图片描述

九、玩家死亡

角色添加代码

//检测碰撞 玩家死亡
private void OnTriggerEnter2D(Collider2D other)
{if (other.gameObject.layer == LayerMask.NameToLayer("Explosion")) {animator.SetTrigger("isDeath");//播放死亡动画//TODO:结束游戏}
}

效果
在这里插入图片描述

十、简单的敌人AI

实现敌人碰壁随机往其他可移动的方向移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyAI : MonoBehaviour
{private float speed = 0.05f;private Rigidbody2D rig;private SpriteRenderer spriteRenderer;private Color color;/// <summary>/// 方向:0上 1下 2左 3右/// </summary>private int dirId = 0;private Vector2 dirVector;private float rayDistance = 0.7f;private float x;private float y;private void Awake(){Physics2D.queriesStartInColliders = false;spriteRenderer = GetComponent<SpriteRenderer>();color = spriteRenderer.color;rig = GetComponent<Rigidbody2D>();InitDir(Random.Range(0, 4));}private void Update(){//移动rig.MovePosition(rig.position + dirVector * speed);}private void InitDir(int dir){Debug.Log(dir);dirId = dir;switch (dirId){case 0:dirVector = Vector2.up;//控制偏移量x = Mathf.Round(rig.position.x) < rig.position.x ? Mathf.Round(rig.position.x) + 0.5f : Mathf.Round(rig.position.x) - 0.5f;transform.position = new Vector2(x, transform.position.y);break;case 1:dirVector = Vector2.down;x = Mathf.Round(rig.position.x) < rig.position.x ? Mathf.Round(rig.position.x) + 0.5f : Mathf.Round(rig.position.x) - 0.5f;transform.position = new Vector2(x, transform.position.y);break;case 2:dirVector = Vector2.left;y = Mathf.Round(rig.position.y) < rig.position.y ? Mathf.Round(rig.position.y) + 0.5f : Mathf.Round(rig.position.y) - 0.5f;transform.position = new Vector2(transform.position.x, y);break;case 3:dirVector = Vector2.right;y = Mathf.Round(rig.position.y) < rig.position.y ? Mathf.Round(rig.position.y) + 0.5f : Mathf.Round(rig.position.y) - 0.5f;transform.position = new Vector2(transform.position.x, y);break;default:break;}}private void ChangeDir(){List<int> dirList = new List<int>();if (Physics2D.Raycast(transform.position, Vector2.up, rayDistance).collider == null){dirList.Add(0);}if (Physics2D.Raycast(transform.position, Vector2.down, rayDistance).collider == null){dirList.Add(1);}if (Physics2D.Raycast(transform.position, Vector2.left, rayDistance).collider == null){dirList.Add(2);}if (Physics2D.Raycast(transform.position, Vector2.right, rayDistance).collider == null){dirList.Add(3);}if (dirList.Count > 0){int index = Random.Range(0, dirList.Count);InitDir(dirList[index]);}}//画辅助线private void OnDrawGizmos(){Gizmos.color = Color.red;Gizmos.DrawLine(transform.position, transform.position + new Vector3(0, rayDistance, 0));Gizmos.color = Color.blue;Gizmos.DrawLine(transform.position, transform.position + new Vector3(0, -rayDistance, 0));Gizmos.DrawLine(transform.position, transform.position + new Vector3(-rayDistance, 0, 0));Gizmos.DrawLine(transform.position, transform.position + new Vector3(rayDistance, 0, 0));}//碰撞检测private void OnCollisionEnter2D(Collision2D collision){//碰到层级if (collision.gameObject.layer == LayerMask.NameToLayer("Wall") || collision.gameObject.layer == LayerMask.NameToLayer("BrickWall") || collision.gameObject.layer == LayerMask.NameToLayer("Bomb")){ChangeDir();}}//检测敌人死亡private void OnTriggerEnter2D(Collider2D other){if (other.gameObject.layer == LayerMask.NameToLayer("Explosion")){Destroy(gameObject);}}
}

效果
在这里插入图片描述

十一、简单敌人AI

实现敌人随机移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyAI : MonoBehaviour
{private float speed = 0.05f;private Rigidbody2D rig;private SpriteRenderer spriteRenderer;private Color color;/// <summary>/// 方向:0上 1下 2左 3右/// </summary>private int dirId = 0;private Vector2 dirVector;private float rayDistance = 0.7f;private float x;private float y;private void Awake(){Physics2D.queriesStartInColliders = false;spriteRenderer = GetComponent<SpriteRenderer>();color = spriteRenderer.color;rig = GetComponent<Rigidbody2D>();InitDir(Random.Range(0, 4));}private void Update(){if (GameApp.instance.enemyMove){//移动rig.MovePosition(rig.position + dirVector * speed);}}private void InitDir(int dir){dirId = dir;switch (dirId){case 0:dirVector = Vector2.up;//控制偏移量x = Mathf.Round(rig.position.x) < rig.position.x ? Mathf.Round(rig.position.x) + 0.5f : Mathf.Round(rig.position.x) - 0.5f;transform.position = new Vector2(x, transform.position.y);break;case 1:dirVector = Vector2.down;x = Mathf.Round(rig.position.x) < rig.position.x ? Mathf.Round(rig.position.x) + 0.5f : Mathf.Round(rig.position.x) - 0.5f;transform.position = new Vector2(x, transform.position.y);break;case 2:dirVector = Vector2.left;y = Mathf.Round(rig.position.y) < rig.position.y ? Mathf.Round(rig.position.y) + 0.5f : Mathf.Round(rig.position.y) - 0.5f;transform.position = new Vector2(transform.position.x, y);break;case 3:dirVector = Vector2.right;y = Mathf.Round(rig.position.y) < rig.position.y ? Mathf.Round(rig.position.y) + 0.5f : Mathf.Round(rig.position.y) - 0.5f;transform.position = new Vector2(transform.position.x, y);break;default:break;}}private void ChangeDir(){List<int> dirList = new List<int>();if (Physics2D.Raycast(transform.position, Vector2.up, rayDistance).collider == null){dirList.Add(0);}if (Physics2D.Raycast(transform.position, Vector2.down, rayDistance).collider == null){dirList.Add(1);}if (Physics2D.Raycast(transform.position, Vector2.left, rayDistance).collider == null){dirList.Add(2);}if (Physics2D.Raycast(transform.position, Vector2.right, rayDistance).collider == null){dirList.Add(3);}if (dirList.Count > 0){int index = Random.Range(0, dirList.Count);InitDir(dirList[index]);}}//画辅助线private void OnDrawGizmos(){Gizmos.color = Color.red;Gizmos.DrawLine(transform.position, transform.position + new Vector3(0, rayDistance, 0));Gizmos.color = Color.blue;Gizmos.DrawLine(transform.position, transform.position + new Vector3(0, -rayDistance, 0));Gizmos.DrawLine(transform.position, transform.position + new Vector3(-rayDistance, 0, 0));Gizmos.DrawLine(transform.position, transform.position + new Vector3(rayDistance, 0, 0));}//碰撞检测private void OnCollisionEnter2D(Collision2D collision){//碰到层级if (collision.gameObject.layer == LayerMask.NameToLayer("Wall") || collision.gameObject.layer == LayerMask.NameToLayer("BrickWall") || collision.gameObject.layer == LayerMask.NameToLayer("Bomb")){ChangeDir();}}//检测敌人死亡private void OnTriggerEnter2D(Collider2D other){//碰到炸弹层级,换方向if (other.gameObject.layer == LayerMask.NameToLayer("Bomb")){ChangeDir();}if (other.gameObject.layer == LayerMask.NameToLayer("Explosion")){GameApp.instance.deathEnemyCount++;GameApp.instance.score++;Destroy(gameObject);}}
}

效果
在这里插入图片描述

十二、随机绘制地图

using System.Globalization;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Collections;
//随机生成可破坏瓦片
public class MapController : MonoBehaviour
{public static MapController instance;[Range(0f, 1f)]public float itemSpawnChance = 0.2f;//生成瓦片的概率public Tilemap map;// 瓦片资源基类通过它可以得到瓦片资源public TileBase tileBase;private List<Vector3> emptyPosition;//保存所有的空位private List<Vector3> wallPosition;//保存所有的可破坏墙的位置public GameObject enemy;//怪物预制体public GameObject door;//门预制体public GameObject playerData;//主角预制体private int mapWidth;private int mapHeight;private void Awake(){if (instance == null){instance = this;}else{if (instance != this){Destroy(gameObject);}}DontDestroyOnLoad(gameObject);emptyPosition = new List<Vector3>();wallPosition = new List<Vector3>();mapWidth = 16;mapHeight = 8;}public void Init(){// 1.清空瓦片地图map.ClearAllTiles();for (int i = 0; i <= mapWidth; i++){for (int j = 0; j <= mapHeight; j++){//跳过砖块if (i % 2 != 0 && j % 2 != 0){continue;}Vector3 position = new Vector3(-7.5f + i, 3.5f - j, 0);Vector3Int cell = map.WorldToCell(position);  // 将世界坐标转换为Tilemap的单元格坐标if (Random.value < itemSpawnChance){map.SetTile(cell, tileBase); // 设置wallPosition.Add(position);}else{emptyPosition.Add(position);}}}addPlayer();addEnemy();addDoor();//清空地图的炸弹GameObject[] res = GameObject.FindGameObjectsWithTag("Bomb");foreach (GameObject item in res){Destroy(item);}//清空地图的道具res = GameObject.FindGameObjectsWithTag("Props");foreach (GameObject item in res){Destroy(item);}}//生成主角private void addPlayer(){GameObject res = GameObject.Find("Player(Clone)");if (res != null){Destroy(res);}GameObject player = Instantiate(playerData);//生成在左下角player.transform.position = new Vector2(-7.5f, -4.5f);//去除相邻的mapmap.SetTile(map.WorldToCell(new Vector2(-7.5f, -4.5f)), null);map.SetTile(map.WorldToCell(new Vector2(-6.5f, -4.5f)), null);map.SetTile(map.WorldToCell(new Vector2(-7.5f, -3.5f)), null);emptyPosition.Remove(new Vector3(-7.5f, -4.5f, 0));emptyPosition.Remove(new Vector3(-6.5f, -4.5f, 0));emptyPosition.Remove(new Vector3(-7.5f, -3.5f, 0));}//生成怪物private void addEnemy(){//清空地图上的所有敌人GameObject[] res = GameObject.FindGameObjectsWithTag("Enemy");foreach (GameObject item in res){Destroy(item);}if (emptyPosition.Count > 0){for (int i = 0; i < GameApp.instance.enemyCount; i++){int index = Random.Range(0, emptyPosition.Count);Instantiate(enemy, emptyPosition[index], Quaternion.identity);}}}
}

效果,每次进来地图都不一样
在这里插入图片描述

十三、虚拟摇杆

引入虚拟摇杆,实现玩家移动,不懂的可以看我这篇文章:3种实现虚拟移动摇杆控制人物移动的方法

效果
在这里插入图片描述

最终效果

在这里插入图片描述

待续

后面还准备了一些内容,有空再补充,包括音频管理器、随机生成地图和敌人、通关门效果、主角生命值,游戏开始和结束UI界面,关卡选择界面、保存主角属性到下一关、更多的敌人(可能加入boss)、优化代码架构、完善虚拟摇杆、发布游戏到微信小游戏

源码

后面整理好我会放上来

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库设计DDL

DDL&#xff1a;数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表&#xff09; DDL&#xff08;数据库操作&#xff09; 查询&#xff1a; 查询所有数据库&#xff1a;show databases; 查询当前数据库&#xff1a;select database(); 使用&#xff1a; 使用…

第P3周:天气识别

一、前期准备 1、设置GPU import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision from torchvision import transforms, datasetsimport os,PIL,pathlibdevice torch.device("cuda" if torch.cuda.is_available() …

华为数通方向HCIP-DataCom H12-821题库(拖拽题,知识点总结)

以下是我在现有题库中整理的需要重点关注的考点内容,如有遗漏小伙伴可以留言补充。

插入排序(Insertion Sort)

C自学精简教程 目录(必读) 插入排序 每次选择未排序子数组中的第一个元素&#xff0c;从后往前&#xff0c;插入放到已排序子数组中&#xff0c;保持子数组有序。 打扑克牌&#xff0c;起牌。 输入数据 42 20 17 13 28 14 23 15 执行过程 完整代码 #include <iostream…

python爬虫关于ip代理池的获取和随机生成

前言 在进行爬虫开发时&#xff0c;代理IP池是一个非常重要的概念。代理IP池是指一个包含多个可用代理IP的集合&#xff0c;这些代理IP可以用来绕过网站的防爬虫策略&#xff0c;从而提高爬取数据的成功率。 在本文中&#xff0c;我们将介绍如何获取代理IP池&#xff0c;并且随…

指针进阶(1)

指针进阶 朋友们&#xff0c;好久不见&#xff0c;这次追秋给大家带来的是内容丰富精彩的指针知识的拓展内容&#xff0c;喜欢的朋友们三连走一波&#xff01;&#xff01;&#xff01; 字符指针 在指针的类型中我们知道有一种指针类型为字符指针 char* &#xff1b; 使用方法如…

Clion 使用ffmpeg 学习1 开发环境配置

Clion 使用ffmpeg 学习1 开发环境配置 一、准备工作1. 准备环境2. 下载FFmpeg 二、操作步骤1. Clion 新建一个C项目2. 修改 CMakeLists.txt3. 修改配置4. 运行测试5. 打印rtsp 流信息的 demo 一、准备工作 在视频处理和多媒体应用程序开发中&#xff0c;FFmpeg 是一个强大的开…

Jenkins自动构建(Gitee)

Gitee简介安装JenkinsCLI https://blog.csdn.net/tongxin_tongmeng/article/details/132632743 安装Gitee jenkins-cli install-plugin gitee:1.2.7 # https://plugins.jenkins.io/gitee/releases获取安装命令(稍作变更) JenkinsURL Dashboard-->配置-->Jenkins Locatio…

华为云银河麒麟V10安装libmcrypt

本次安装是在华为云上执行。cpu是鲲鹏&#xff0c;操作系统是银河麒麟V10. 先下载安装包&#xff1a; wget http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz 解包&#xff0c;进入目录中。 执行如下命令&#xff1a; ./configure make make install 执…

视频汇聚/视频云存储/视频监控管理平台EasyCVR启动时打印starting server:listen tcp,该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&#xff0c;…

OJ题库:计算日期到天数转换、打印从1到最大的n位数 、尼科彻斯定理

前言&#xff1a;在部分大厂笔试时经常会使用OJ题目&#xff0c;这里对《华为机试》和《剑指offer》中的部分题目进行思路分析和讲解&#xff0c;希望对各位读者有所帮助。 题目来自牛客网&#xff0c;欢迎各位积极挑战&#xff1a; HJ73:计算日期到天数转换_牛客网 JZ17:打印…

linux入门---动静态库的加载

目录标题 为什么会有动态库和静态库静态库的实现动态库的实现动静态库的加载 为什么会有动态库和静态库 我们来模拟一个场景&#xff0c;首先创建两个头文件 根据文件名便可以得知add.h头文件中存放的是加法函数的声明&#xff0c;sub.h头文件中存放的是减法函数的声明&#…

算法面试-深度学习基础面试题整理(2023.8.29开始,每天下午持续更新....)

一、无监督相关&#xff08;聚类、异常检测&#xff09; 1、常见的距离度量方法有哪些&#xff1f;写一下距离计算公式。 1&#xff09;连续数据的距离计算&#xff1a; 闵可夫斯基距离家族&#xff1a; 当p 1时&#xff0c;为曼哈顿距离&#xff1b;p 2时&#xff0c;为欧…

[MySQL]查看数据库大小

查看库大小 例如&#xff1a;查看当前MySQL中数据总量超过2GB的库&#xff1a; select table_schema as 数据库,table_rows as 记录数,data_size as 数据容量(GB),index_size as 索引容量(MB) from (selecttable_schema,sum(table_rows) as table_rows,sum(truncate(data_leng…

Qt中布局管理使用总结

目录 1. 五大布局 1.1 QVBoxLayout垂直布局 1.2 QHBoxLayout水平布局 1.3 QGridLayout网格布局 1.4 QFormLayout表单布局 1.5 QStackedLayout分组布局 1.6 五大布局综合应用 2. 分割窗口 3. 滚动区域 4. 停靠区域 1. 五大布局 1.1 QVBoxLayout垂直布局 #include <…

Sentinel 流量控制框架

1. Sentinel 是什么&#xff1f; Sentinel是由阿里中间件团队开源的&#xff0c;面向分布式服务架构的轻量级高可用流量控制组件。 2. 主要优势和特性 轻量级&#xff0c;核心库无多余依赖&#xff0c;性能损耗小。 方便接入&#xff0c;开源生态广泛。 丰富的流量控制场景。 …

图神经网络和分子表征:4. PAINN

如果说 SchNet 带来了【3D】的火种&#xff0c;DimeNet 燃起了【几何】的火苗&#xff0c;那么 PAINN 则以星火燎原之势跨入 【等变】时代。 在 上一节 中&#xff0c;我们提到&#xff0c; PAINN 在看到 DimeNet 取得的成就之后&#xff0c;从另一个角度解决了三体几何问题&a…

『PyQt5-Qt Designer篇』| 08 Qt Designer中容器布局和绝对布局的使用

08 Qt Designer中容器布局和绝对布局的使用 1 容器布局1.1 设计容器布局1.2 保存文件并执行2 绝对布局2.1 设计绝对布局2.2 保存文件并执行1 容器布局 1.1 设计容器布局 先拖入一个容器Frame容器,然后拖入几个控件: 把拖入的控件拖入容器中: 选中容器,右键-布局-栅格布局:…

Node基础and包管理工具

Node基础 fs 模块 fs 全称为 file system&#xff0c;称之为 文件系统&#xff0c;是 Node.js 中的 内置模块&#xff0c;可以对计算机中的磁盘进行操作。 本章节会介绍如下几个操作&#xff1a; 1. 文件写入 2. 文件读取 3. 文件移动与重命名 4. 文件删除 5. 文件夹操作 6. …

mysql索引为什么提高查询速度(底层原理)

一、索引原理图 二、索引数据存储到硬盘而不是内存&#xff1f; 硬盘内存 成本低成本高 容量大容量小 读写速度一般读取速度快 断电后数据永久存储断电后数据清空 三、硬盘数据为什么要读取到内存&#xff1f;为啥不直接…