【用unity实现100个游戏之10】复刻经典俄罗斯方块游戏

news2024/11/25 5:50:01

文章目录

  • 前言
  • 网格生成
  • Block方块脚本
  • 俄罗斯方块基类,绘制方块形状
  • 移动逻辑
  • 限制移动
  • 自由下落
  • 下落后设置对应风格为不可移动类型
  • 检查当前方块是否可以向指定方向移动
  • 旋转逻辑
  • 消除逻辑
  • 游戏结束逻辑
  • 怪物生成
  • 源码
  • 参考
  • 完结

前言

当今游戏产业中,经典游戏的复刻一直是一项受欢迎且具有挑战性的任务。俄罗斯方块是一个深入人心、令人上瘾的经典游戏,在过去几十年里一直享有广泛的流行度。其简单而富有策略性的玩法吸引了无数玩家的关注。因此,我决定利用Unity引擎来复刻这款经典游戏,以让更多的人重新体验其中的乐趣。

通过使用Unity引擎,我能够利用其强大的工具和功能,从头开始构建一个与原版俄罗斯方块游戏相似的游戏。我将努力保持原版游戏的核心要素,包括七种不同形状的方块(俄罗斯方块),玩家可以通过旋转和移动这些方块来填充完整的水平行,完成消除并得分的目标。

除了保留原版玩法外,我还计划为游戏添加一些额外的功能和改进。例如,增加多样化的难度级别,使得游戏适合任何玩家的技能水平。我还计划添加特殊的道具或技能,使游戏更加丰富有趣。此外,我还将注重游戏的视觉效果和音效,以提升玩家的沉浸感。

我的目标是创造一个令人难以抗拒的游戏体验,让玩家们在回忆经典之余,也能感受到崭新的乐趣。无论是单人挑战高分,还是与朋友们一较高下,这个复刻版的俄罗斯方块游戏都将带给玩家们小时候的回忆和喜悦。

我非常兴奋能够应用Unity引擎来实现这个愿望,并期待将来能与大家分享这款复刻版俄罗斯方块游戏。在这个过程中,我将努力改进和完善游戏,以确保它可以在各种平台上流畅运行,并为玩家们带来最佳的游戏体验。

谢谢大家的支持和关注!让我们一起回味经典,畅享游戏的乐趣吧!

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

网格生成

泛型单例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingleBase<T> : MonoBehaviour where T : class
{
    public static T Instance;

    protected virtual void Awake()
    {
        Instance = this as T;
    }
}

游戏管理类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : SingleBase<GameManager>
{
    protected override void Awake()
    {
        base.Awake();
    }

    private void Start()
    {
        OnStartGame();
    }

    //开始游戏
    void OnStartGame()
    {
        //网格生成
        MapManager.Instance.InitMap();
    }
}

简单工厂类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///<summary>
//简单工厂
///</summary>
public static class SimpleFactory
{
	//创建Resources/Model中的物体
	public static GameObject CreateModel(string name, Transform parent)
    {
        return Object.Instantiate(Resources.Load("Model/" + name), parent) as GameObject;
    }
}

网格地图生成

//常量类
public static class Defines
{
    public static readonly int RowCount = 15;//网格行数
    public static readonly int ColCount = 10;//网格列数
    public static readonly float Offset = 0.9f;//格子间隔
}

网格地图管理器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//网格地图管理器
public class MapManager : SingleBase<MapManager>
{
    //初始化网格地图
    public void InitMap()
    {
        for (int row = 0; row < Defines.RowCount; row++)
        {
            for (int col = 0; col < Defines.ColCount; col++)
            {
                GameObject obj = SimpleFactory.CreateModel("block", transform);
                obj.transform.localPosition = new Vector3(col * Defines.Offset, -row * Defines.Offset, 0);
            }
        }
    }
}

挂载GameManager和MapManager
在这里插入图片描述
运行效果
在这里插入图片描述

Block方块脚本

新建Block 方块脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum BlockType
{
    Empty,//空
    Static,//不动
    Model,//模型
}

//方块脚本
public class Block : MonoBehaviour
{
    public BlockType type;
    public int RowIndex;
    public int ColIndex;
    public SpriteRenderer sp;
    public Sprite normalSprite;//默认的图片
    public Sprite modelSprite;//怪物图片
    public void Init(int row, int col, BlockType type)
    {
        this.type = type;
        this.RowIndex = row;
        this.ColIndex = col;
    }

    private void Awake()
    {
        sp = GetComponent<SpriteRenderer>();
        normalSprite = sp.sprite;
        modelSprite = Resources.Load<Sprite>("Icon/gbl");
    }

    private void Start()
    {
        SetTypeToSp();
    }

    public void SetTypeToSp()
    {
        switch (this.type)
        {
            case BlockType.Empty:
                sp.sprite = normalSprite;
                sp.color = Color.white;
                break;
            case BlockType.Static:
                sp.color = Color.red;
                break;
            case BlockType.Model:
                sp.sprite = modelSprite;
                sp.color = Color.white;
                break;
        }

    }
}

网格地图管理器MapManager 调用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//网格地图管理器
public class MapManager : SingleBase<MapManager>
{
    public Block[,] blockArr;
    //初始化网格地图
    public void InitMap()
    {
        blockArr = new Block[Defines.RowCount,Defines.ColCount];
        for (int row = 0; row < Defines.RowCount; row++)
        {
            for (int col = 0; col < Defines.ColCount; col++)
            {
                GameObject obj = SimpleFactory.CreateModel("block", transform);
                obj.transform.localPosition = new Vector3(col * Defines.Offset, -row * Defines.Offset, 0);
                
                Block b = obj.AddComponent<Block>();
                b.Init(row, col, BlockType.Model);
                //存储到二维数组
                blockArr[row, col] = b;
            }
        }
    }
}

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

俄罗斯方块基类,绘制方块形状

MapManager新增方法

//切换对应下标的方块的类型
public void ChangeType(int row, int col, BlockType type)
{
    Block b = blockArr[row, col];
    b.type = type;
    b.SetTypeToSp();
}

俄罗斯方块基类

//俄罗斯方块基类
public class TetrisBase
{
    public int rowIndex;//对应整个网格的行坐标
    public int colIndex;//对应整个网格的列坐标
    public int rowCount;//存储形状的行总数
    public int colCount;//存储形状的列总数
    public BlockType[,] blockArr;//存储枚举的二维数组
                                 //初始化
    public virtual void Init()
    {
    }

    //画自己(更改网格对应的图片精灵)
    public virtual void DrawMe()
    {
        for (int row = 0; row < rowCount; row++)
        {
            for (int col = 0; col < colCount; col++)
            {
                if (blockArr[row, col] != BlockType.Empty)
                {
                    int map_rowIndex = rowIndex + row;
                    int map_colIndex = colIndex + col;
                    MapManager.Instance.ChangeType(map_rowIndex, map_colIndex, blockArr[row, col]);
                }

            }

        }

    }
    //擦除自己
    public virtual void WipeMe()
    {
        for (int row = 0; row < rowCount; row++)
        {
            for (int col = 0; col < colCount; col++)
            {
                if (blockArr[row, col] != BlockType.Empty)
                {
                    int map_rowIndex = rowIndex + row;
                    int map_colIndex = colIndex + col;
                    MapManager.Instance.ChangeType(map_rowIndex, map_colIndex, BlockType.Empty);
                }

            }

        }
    }

    //向下移动
    public virtual void MoveDown()
    {
        rowIndex++;
    }

    //左移动
    public virtual void MoveLeft()
    {
        colIndex--;
    }

    //右移动
    public virtual void MoveRight()
    {
        colIndex++;
    }
}

T形状的俄罗斯方块

//T形状的俄罗斯方块
public class Tetris_T : TetrisBase
{
    public override void Init()
    {
        rowCount = 2;
        colCount = 3;
        blockArr = new BlockType[,]{
            {BlockType.Model,BlockType.Model,BlockType.Model},
            {BlockType.Empty,BlockType.Model,BlockType.Empty}
        };
    }
}

GameManager调用,绘制方块形状

TetrisBase currentTetris;//当前操作的俄罗斯

//开始游戏
void OnStartGame()
{
    //网格生成
    MapManager.Instance.InitMap();
    currentTetris = CreateTetris();
    //画出来
    currentTetris.DrawMe();
}

//创建
TetrisBase CreateTetris()
{
    TetrisBase t = new Tetris_T();
    t.Init();
    t.colIndex = Defines.ColCount / 2 - t.colCount / 2;
    return t;
}

效果
在这里插入图片描述

移动逻辑

定义移动方向枚举

//移动方向
public enum Direction
{
    None,
    Right,
    Left,
    Down
}

修改俄罗斯方块基类TetrisBase

//根据方向移动
public virtual void MoveByDir(Direction dir)
{
    //擦除自己
    WipeMe();
    switch (dir)
    {
        case Direction.None:
            break;
        case Direction.Right:
            MoveRight();
            break;
        case Direction.Left:
            MoveLeft();
            break;
        case Direction.Down:
            MoveDown();
            break;
    }
    DrawMe();//画自己
}

GameManager新增用户操作

void Update(){
    InputCtl();
}
//用户操作
public void InputCtl()
{
    if (Input.GetKeyDown(KeyCode.A))
        currentTetris.MoveByDir(Direction.Left);
    if (Input.GetKeyDown(KeyCode.D))
        currentTetris.MoveByDir(Direction.Right);
    if (Input.GetKeyDown(KeyCode.S))
        currentTetris.MoveByDir(Direction.Down);
}

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

限制移动

俄罗斯方块基类TetrisBase新增方法

//是否能移动的方向
public virtual bool IsCanMove(Direction dir)
{
    int _rowIndex = rowIndex;
    int _colIndex = colIndex;
    switch (dir)
    {
        case Direction.None:
            break;
        case Direction.Right:
            _colIndex++;
            break;
        case Direction.Left:
            _colIndex--;
            break;
        case Direction.Down:
            _rowIndex++;
            break;
    }

    //超出网格
    if (_colIndex < 0 || _colIndex + colCount > Defines.ColCount || _rowIndex + rowCount > Defines.RowCount)
    {
        return false;
    }
    return true;
}

GameManager调用

//用户操作
public void InputCtl()
{
    if (Input.GetKeyDown(KeyCode.A))
    {
        if (currentTetris.IsCanMove(Direction.Left))
        {
            currentTetris.MoveByDir(Direction.Left);
        }
    }
    if (Input.GetKeyDown(KeyCode.D))
    {
        if (currentTetris.IsCanMove(Direction.Right))
        {
            currentTetris.MoveByDir(Direction.Right);
        }
    }
    if (Input.GetKeyDown(KeyCode.S))
    {
        if (currentTetris.IsCanMove(Direction.Down))
        {
            currentTetris.MoveByDir(Direction.Down);
        }
    }
}

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

自由下落

Defines新增常用类

public static readonly float downTime = 1;//下落时间间隔

修改GameManager

float timer;

//开始游戏
void OnStartGame()
{
    timer = Defines.downTime;
}
void Update()
{
    AutoMoveDown();
}

//自动下落
public void AutoMoveDown()
{
    timer -= Time.deltaTime;
    if (timer <= 0)
    {
        timer = Defines.downTime;
        if (currentTetris.IsCanMove(Direction.Down))
        {
            currentTetris.MoveByDir(Direction.Down);
        }
        else
        {
            //不能移动重新创建
            currentTetris = CreateTetris();
            currentTetris.DrawMe();
        }
    }
}

效果
在这里插入图片描述

下落后设置对应风格为不可移动类型

MapManager新增方法

//设置不可移动后的俄罗斯方块对应的位置为Static类型
public void SetStatic(TetrisBase t)
{
    for (int row = 0; row < t.rowCount; row++)
    {
        for (int col = 0; col < t.colCount; col++)
        {
            if (t.blockArr[row, col] != BlockType.Empty)
            {
                int map_rowIndex = row + t.rowIndex;
                int map_colIndex = col + t.colIndex;
                ChangeType(map_rowIndex, map_colIndex, BlockType.Static);
            }
        }
    }
}

GameManager调用

if (!currentTetris.IsCanMove(Direction.Down))
{
    //设置不可移动类型
    MapManager.Instance.SetStatic(currentTetris);
}

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

检查当前方块是否可以向指定方向移动

解决方块下落重叠的问题

修改俄罗斯方块基类TetrisBase的IsCanMove方法

遍历当前方块的每个单元格,如果单元格不为空且对应最近的地图单元格是静态的(即已经被其他方块占据),则返回false表示不能移动,否则返回true表示可以移动

//是否能移动的方向
public virtual bool IsCanMove(Direction dir)
{
    int _rowIndex = rowIndex;
    int _colIndex = colIndex;
    switch (dir)
    {
        case Direction.None:
            break;
        case Direction.Right:
            _colIndex++;
            break;
        case Direction.Left:
            _colIndex--;
            break;
        case Direction.Down:
            _rowIndex++;
            break;
    }

    //超出网格
    if (_colIndex < 0 || _colIndex + colCount > Defines.ColCount || _rowIndex + rowCount > Defines.RowCount)
    {
        return false;
    }
	//检查当前方块是否可以向指定方向移动
    for (int row = 0; row < rowCount; row++)
    {
        for (int col = 0; col < colCount; col++)
        {
            if (blockArr[row, col] != BlockType.Empty)
            {
                int map_rowIndex = _rowIndex + row;
                int map_colIndex = _colIndex + col;
                Block b = MapManager.Instance.blockArr[map_rowIndex, map_colIndex];
                if (b.type == BlockType.Static)
                {
                    return false;
                }
            }
        }
    }
    return true;
}

效果
在这里插入图片描述

旋转逻辑

TetrisBase俄罗斯方块基类新增控制旋转方法

//旋转
public void Rotate()
{
    //二维数组互换
    int new_rowCount = colCount;
    int new_colCount = rowCount;
    //互换行列后是否超出网格
    if (rowIndex + new_rowCount > Defines.RowCount || colIndex + new_colCount > Defines.ColCount) return;
    BlockType[,] tempArr = new BlockType[new_rowCount, new_colCount];
    for (int row = 0; row < new_rowCount; row++)
    {
        for (int col = 0; col < new_colCount; col++)
        {
            tempArr[row, col] = blockArr[new_colCount - 1 - col, row];
            if (tempArr[row, col] != BlockType.Empty)
            {
                //对应位置是静态类型static不能旋转
                if (MapManager.Instance.blockArr[row + this.rowIndex, col + this.colIndex].type == BlockType.Static) return;
            }
        }
    }
    //擦除
    WipeMe();
    rowCount = new_rowCount;
    colCount = new_colCount;
    blockArr = tempArr;
    DrawMe();//画
}

GameManager调用

if (Input.GetKeyDown(KeyCode.W)) currentTetris.Rotate();

效果
在这里插入图片描述

消除逻辑

GameManager新增方法

# 调用
//检测删除行
CheckDelete();

//检测删除行
public void CheckDelete()
{
    //最后一行开始遍历
    for (int row = Defines.RowCount - 1; row >= 0; row--)
    {
        int count = 0;//静态类型的个数
        for
        (int col = 0; col < Defines.ColCount; col++)
        {
            BlockType type = MapManager.Instance.blockArr[row, col].type;
            if (type == BlockType.Static)
                count++;
        }
        if
        (count == Defines.ColCount)
        {
            for (int dropRow = row; dropRow > 1; dropRow--)
            {
                for (int dropCol = 0; dropCol < Defines.ColCount; dropCol++)
                {
                    //上一行类型覆盖当前行
                    BlockType type = MapManager.Instance.blockArr[dropRow - 1, dropCol].type;
                    MapManager.Instance.ChangeType(dropRow, dropCol, type);
                }
            }
            row++;
        }
    }
}

效果
在这里插入图片描述

游戏结束逻辑

修改GameManager代码

bool isStop = false;//游戏结束标识

//开始游戏
void OnStartGame()
{
    isStop = false;
}

void Update()
{
    if (isStop == true)
    {
        return;
    }
}

//当前俄罗斯生成的时候对应位置是不可移动(覆盖)说明游戏结束
public bool IsGameOver()
{
    for (int row = 0; row < currentTetris.rowCount; row++)
    {
        for (int col = 0; col < currentTetris.colCount; col++)
        {
            BlockType type = currentTetris.blockArr[row, col];
            if (type != BlockType.Empty)
            {
                int map_rowIndex = row + currentTetris.rowIndex;
                int map_colIndex = col + currentTetris.colIndex;
                if (MapManager.Instance.blockArr[map_rowIndex, map_colIndex].type == BlockType.Static) return true;
            }
        }
    }
    return false;
}

调用

//自动下落
public void AutoMoveDown()
{
    timer -= Time.deltaTime;
    if (timer <= 0)
    {
        timer = Defines.downTime;
        if (currentTetris.IsCanMove(Direction.Down))
        {
            currentTetris.MoveByDir(Direction.Down);
        }
        else
        {
            //设置不可移动类型
            MapManager.Instance.SetStatic(currentTetris);
            //检测删除行
            CheckDelete();
            //不能移动重新创建
            currentTetris = CreateTetris();
            if (IsGameOver() == true)
            {
                isStop = true;
                Debug.Log("game over");
                return;
            }
            currentTetris.DrawMe();
        }
    }
}

效果
在这里插入图片描述

怪物生成

修改GameManager代码

//检测删除行
public void CheckDelete()
{
    //最后一行开始遍历
    for (int row = Defines.RowCount - 1; row >= 0; row--)
    {
   		//。。。
        if(count == Defines.ColCount)
        {
            for (int dropCol = 0; dropCol < Defines.ColCount; dropCol++)
            {
                //当前行生成哥布林
                SimpleFactory.CreateModel("gbl", null).transform.position = MapManager.Instance.blockArr[row, dropCol].transform.position;
            }
            //。。。
        }
    }
}

怪物触碰boss造成伤害和特效,还有游戏结束效果,就自己扩展了,也很简单,还有不同形状的方块

效果
在这里插入图片描述

源码

要啥源码,好好看,好好学!

参考

【视频】https://www.bilibili.com/video/BV1Fr4y1x7mx

完结

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

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

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

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

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

相关文章

基于SSM的校园美食交流系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

开开心心带你学习MySQL数据库之第六篇下

插入查询结果 把查询和新增联合起来. 把查询结果作为新增的数据 例子:把student1表的查询结果作为新增数据插入到student2表中. create table student1(id int, name varchar(20));create table student2(id int, name varchar(20));insert into student1 values(1, 张三), (2…

NFT 合约部署教程

本篇文章主要介绍如何将您的 NFT(ERC-721 Token) 通过智能合约部署到去中心化网络中 Init Project //创建一款ocean的NFT mkdir nft-ocean//进入目录 cd nft-ocean//初始化项目&#xff0c;根据提示填写即可&#xff0c;packname和description填写即可 npm init//添加hardhat…

【JAVA】Object类与抽象类

作者主页&#xff1a;paper jie_的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和…

批量剪辑神器:AI智剪技巧全攻略

在视频剪辑的工作流程中&#xff0c;效率和质量都是至关重要的。有时候&#xff0c;我们需要对大量的视频进行剪辑&#xff0c;这可能会耗费大量的时间和人力。然而&#xff0c;随着技术的发展&#xff0c;AI智能剪辑工具如固乔智剪软件的出现&#xff0c;大大提高了剪辑的效率…

架构师之如何定位问题

1. 什么是问题 很多人对问题的理解不一样&#xff0c;有人认为问题就是解决方案中的难点&#xff0c;有人认为问题是现实和目标的差距&#xff0c;这些解读我觉得都还不够精确&#xff0c;尝试从毛主席的矛盾论中得到比较合理的解释&#xff1a; 问题就是事物的矛盾。哪里有没…

Ubuntu22.04 安装 MongoDB 7.0

稍微查了一些文章发现普遍比较过时。有的是使用旧版本的Ubuntu&#xff0c;或者安装的旧版本的MongoDB。英语可以的朋友可以移步Install MongoDB Community Edition on Ubuntu — MongoDB Manual&#xff0c;按照官方安装文档操作。伸手党或者英语略差的朋友可以按照本文一步步…

计算机重点学科评级B-,山东省属重点高校考情分析

山东科技大学(B-) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1175字预计阅读&#xff1a;3分钟 2023考情概况 山东科技大学计…

stable diffusion webui升级bug问题解决思路(纯干货)

个人网站&#xff1a;https://tianfeng.space/ 文章目录 一、前言二、个人方案1.扼杀在萌芽中A.解压后点击启动器运行依赖&#xff0c;然后点击A启动器B.更新本体和扩展&#xff08;全部到最新版本&#xff09;C.把controlnet1.1放入stable diffusion 中D.插件转移E.模型转移F…

怎么选动捕设备?惯性动作捕捉还是光学动捕?

动捕设备在3D角色动画、影视制作中使用&#xff0c;通过动捕设备记录真人演员的动作&#xff0c;然后将其转换为数字模型的动作生成三维的计算机动画&#xff0c;使用动捕设备可以让动画角色更逼真地移动。 目前市面上主要分为光学动捕设备与惯性动作捕捉设备&#xff0c;这二…

基于SSM的学生课外知识学习网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

电水壶上要求亚马逊美国站SOR/2016-181和CSA22.1标准?

电水壶作为一种常见的小家电&#xff0c;受到了广大消费者的喜爱。然而&#xff0c;由于安全问题的日益重视&#xff0c;亚马逊加拿大站决定加强对电水壶产品的审核&#xff0c;以确保消费者的安全和权益。 近日&#xff0c;亚马逊平台发布公告&#xff0c;要求在加拿大站销售…

跨越时空,亲临其境:3D展示技术让你在家就能游览全球旅游景区

随着科技的不断发展&#xff0c;3D虚拟现实技术在文旅景区中的应用越来越广泛。相比传统的游览方式&#xff0c;3D展示技术具有以下优点&#xff1a; 一、真实感强 3D全景展示可以将文旅景区的真实场景以三维的方式呈现出来&#xff0c;让游客可以在虚拟的环境中感受到真实的场…

电子产品出口欧盟做什么认证?电子产品CE认证标准有哪些?

CE认证是产品出口到欧盟的通行证&#xff0c;没有CE认证标志的产品是不允许在欧盟市场上销售的&#xff0c;今天就给大家介绍常见的电子产品的CE认证标准有哪些&#xff1f; 电子产品CE认证标准有哪些&#xff1f; 常见的电子产品办理CE认证&#xff0c;做的认证指令是EMC指令…

方案丨TSINGSEE青犀视频AI智能算法助力智慧农业高质量建设

我国是农业大国&#xff0c;随着AI等新兴技术的飞速发展&#xff0c;大数据、互联网等技术业运用到了农业生产的各个环节&#xff0c;为提高土地利用率、减少热工成本&#xff0c;提高生产效率&#xff0c;智慧农业应运而生。 旭帆科技TSINGSEE青犀视频AI智慧农业解决方案&…

如何在SOLIDWORKS中更改单位-硕迪科技

SOLIDWORKS中的单位系统 SOLIDWORKS中的单位系统可以针对单个文件修改、一次修改多个文件以及在默认模板中进行修改。每个SOLIDWORKS文件都有一个单位系统&#xff0c;该单位系统由该文件的文档属性控制。默认情况下&#xff0c;SOLIDWORKS零件、装配体和工程图模板各自规定了…

外贸erp软件条码管理解决方案,应对外贸客户变化多样性

在国际贸易市场下&#xff0c;仓库对于市场和企业之间是商品的流量和储存是必不可少的。其中&#xff0c;条形码在仓储物流中&#xff0c;主要的作用是对物料跟踪管理、建立完整的产品档案&#xff0c;保障仓储的稳定运行&#xff0c;利用仓储空间&#xff0c;提高服务质量。 …

(DXE_DRIVER)PciHostBridge

UEFI-PciHostBridge 1、PciHostBridge简介 PciHostBridge: 提供PCI配置空间,IO,MEM空间访问接口以及统一维护平台相关的PCI资源,提供gEfiPciHostBridgeResourceAllocationProtocolGuid,创建RootBridge等为PciBusDxe提供服务; 2、PciHostBridge 配置空间 PCI桥可管理其下PCI子…

table 单元格中嵌套子表格 样式撑开问题

如图&#xff0c;表格中的td嵌套表格&#xff0c;里边表格把外层撑开&#xff0c;不能按100%显示&#xff1b; 解决办法 给父级table 加一个table-layout:fixed;样式

Tomcat启动! 一文带你知道什么是Tomcat以及如何安装

前言&#xff1a; Tomcat&#xff08;全称为Apache Tomcat&#xff09;是一个开源的Java Servlet容器&#xff0c;也是JavaServer Pages&#xff08;JSP&#xff09;的引擎。它是Apache软件基金会的一个项目&#xff0c;用于使Java应用能够在Web服务器上运行。Tomcat充当Web服务…