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

news2024/12/28 20:32:09

文章目录

  • 前言
  • 素材
  • 开始
    • 一、绘制地图
    • 二、玩家设置
    • 三、玩家移动
    • 四、玩家四方向动画运动切换
  • 五、放置炸弹
    • 六、生成爆炸效果
    • 七、墙壁和可破坏障碍物的判断
    • 八、道具生成和效果
    • 九、玩家死亡
    • 十、简单的敌人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);  // 获取指定单元格的Tile
    if (tile != null)  // 如果爆炸位置有可破坏障碍物
    {
        wallTileMap.SetTile(cell, null);  // 清除Tile

        GameObject 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);
        }
    }
}

效果
在这里插入图片描述

十一、虚拟摇杆

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

待续

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

源码

后面整理好我会放上来

完结

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

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

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

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

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

相关文章

Oracle 遍历变量游标

背景 由于我们的数据库系统中的游标特别多&#xff0c;DBA让我们优化&#xff0c;减少游标的使用。 电脑系统&#xff1a;windows数据库&#xff1a;Oracle数据库图形化界面工具&#xff1a;Toad&#xff0c;DBeaver(我測試的時候用的)记录日期&#xff1a;2023-09-04 具体实…

macbookpro怎么删除软件没有鼠标

macbookpro怎么删除软件没有鼠标,macbookpro触摸板可以替代鼠标进行操作。左右键功能与鼠标相同&#xff0c;可用于执行删除操作。此外&#xff0c;还可以利用键盘上的Delete键来删除选中的文件。 删除软件方法 方法1、打开应用程序&#xff0c;键盘按住control&#xff0c;加点…

解决微信小程序recycle-view使用百分比单位控制宽高时出现的内容溢出问题

recycle-view是微信小程序官方推出的一个经过优化的长列表组件&#xff0c;但是在使用百分比单位控制高宽时有个内容溢出问题&#xff0c;虽然它提供了height和width的参数可以设置宽高&#xff0c;但每次写列表都需要去js里获取宽高并设置是较为麻烦的&#xff0c;所以现在来着…

Vue 3 基础(二)基础 1

API 参考 1、创建一个 Vue 应用 1.1 应用实例 每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例&#xff1a; import { createApp } from vueconst app createApp({/* 根组件选项 */ })1.2 根组件 我们传入 createApp 的对象实际上是一个组件&#xff0c;每个…

uni-app 之 图片

uni-app 之 图片 获取图片 v-bind 动态绑定 image.png <template><view><view>--- 获取图片1 ---<image src"../../static/img/tabbar_home1.png"></image></view><view>--- 获取图片2 v-bind 动态绑定---<image v-bi…

SolVES4.1学习1——安装与使用教程

1、下载并安装 SolVES 4版本是QGIS插件&#xff0c;但实际使用过程中发现在最新版的QGIS安装该插件过程中&#xff0c;会报错或异常。因此需安装特定版本的软件。共需安装如下图软件及Java环境等。 根据官方文档安装好后&#xff0c;可以进行相关操作。 2、设置QGIS环境 QG…

AutoSAR配置与实践(基础篇)3.7 BSW的WatchDog功能(下)

AutoSAR配置与实践(基础篇)3.7 BSW的WatchDog功能(下) BSW的WatchDog功能(下)一、WDG和其他模块交互BSW的WatchDog功能(下) ->返回总目录<- 一、WDG和其他模块交互 模块交互 看门狗模块由WdgM统一管理,这里围绕WdgM模块分析与其他模块交互。通过交互的说明,可以…

css画箭头图标放标题前面,旋转,border的单个边框设置

CSS边框属性_css border dotted_小张biubiu的博客-CSDN博客 你还不知道css的旋转效果怎么实现&#xff1f;来这里看看吧_css旋转效果_我糖呢的博客-CSDN博客 .sub-title{position: relative;margin-left: 59px;& span{color: #1CDBFE;};& span::before{content: "…

MyBatis-Plus深入 —— 条件构造器与插件管理

前言 在前面的文章中&#xff0c;荔枝梳理了一个MyBatis-Plus的基本使用、配置和通用Service接口&#xff0c;我们发现在MyBatis-Plus的辅助增强下我们不再需要通过配置xml文件中的sql语句来实现基本的sql操作了&#xff0c;不愧是最佳搭档&#xff01;在这篇文章中&#xff0c…

ping: www.baidu.com: Name or service not known 写了DNS还是不行

环境描述&#xff1a;ESXI平台上&#xff0c;一台Centos7虚拟主机。 问题描述&#xff1a;平台上的其他的虚拟机可以正常ping通&#xff0c;就这台ping IP地址可以通&#xff0c;ping域名解析失败。 排查过程&#xff1a; 1、检查网卡配置文件和/etc/resolv.conf配置文件是否…

【综述+3D】基于NeRF的三维视觉2023年度进展报告(截止2023.06.10)

论文&#xff1a;2003.Representing Scenes as Neural Radiance Fields for View Synthesis 官方网站&#xff1a;https://www.matthewtancik.com/nerf 突破性后续改进&#xff1a; Instant Neural Graphics Primitives with a Multiresolution Hash Encoding | 展示官网&#…

K8S的介绍和架构

仅供入门 K8S的介绍和架构 一. 什么是kubernetes二、Kubernetes架构和组件 2.1 核心组件 2.1.1 Kubernetes Master控制组件&#xff0c;调度管理整个系统&#xff08;集群&#xff09;&#xff0c;包含如下组件: a、Kubernetes API Serverb、Kubernetes Schedulerc、Kubernet…

【前端】CSS-Grid网格布局

目录 一、grid布局是什么二、grid布局的属性三、容器属性1、display①、语句②、属性值 2、grid-template-columns属性、grid-template-rows属性①、定义②、属性值1&#xff09;、固定的列宽和行高2&#xff09;、repeat()函数3&#xff09;、auto-fill关键字4&#xff09;、f…

Vue指令之战:v-if vs. v-show -你应该使用哪一个?

在Vue.js中&#xff0c;条件渲染是一项常见任务&#xff0c;而v-if和v-show是两个最常用的指令。这两个指令在实现方式上有所不同&#xff0c;对于开发者来说选择正确的指令可能具有挑战性。本文将深入探讨Vue 2和Vue 3中的v-if和v-show指令的区别&#xff0c;并结合实际应用场…

Linux的命令

Linux的命令分为四个类型&#xff1a;文件操作命令、系统操作命令、文本处理命令和网络操作命令。下面简单介绍一下常用的Linux命令&#xff1a; 文件操作命令 ls&#xff1a;列出目录下的所有文件和目录。 cd&#xff1a;切换当前目录。 mkdir&#xff1a;创建一个新目录。…

<图像处理> 可分离滤波器核

可分离滤波器核 空间滤波器核是一个二维矩阵&#xff0c;若它能够表示为两个一维矩阵的乘积时&#xff0c;则表示该滤波器核是可分离的。 例如&#xff0c;一个3x3的核&#xff0c; w [ 1 1 1 1 1 1 1 1 1 ] w\begin{bmatrix} 1 & 1 & 1\\ 1 & 1& 1\\ 1 &am…

操作系统(OS)与系统进程

操作系统&#xff08;OS&#xff09;与系统进程 冯诺依曼体系结构操作系统(Operator System)进程基本概念进程的描述&#xff08;PCB&#xff09;查看进程通过系统调用获取进程标示符&#xff08;PID&#xff09;通过系统调用创建进程&#xff08;fork&#xff09;进程状态&…

安防监控/视频汇聚/云存储/AI智能视频融合平台页面新增地图展示功能

AI智能分析网关包含有20多种算法&#xff0c;包括人脸、人体、车辆、车牌、行为分析、烟火、入侵、聚集、安全帽、反光衣等等&#xff0c;可应用在安全生产、通用园区、智慧食安、智慧城管、智慧煤矿等场景中。将网关硬件结合我们的视频汇聚/安防监控/视频融合平台EasyCVR一起使…

使用Python进行健身手表数据分析

健身手表(Fitness Watch)数据分析涉及分析健身可穿戴设备或智能手表收集的数据&#xff0c;以深入了解用户的健康和活动模式。这些设备可以跟踪所走的步数、消耗的能量、步行速度等指标。本文将带您完成使用Python进行Fitness Watch数据分析的任务。 Fitness Watch数据分析是健…