微信小程序|从零动手实现俄罗斯方块

news2025/7/9 0:46:27

📌个人主页:个人主页
​🧀 推荐专栏:小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏!从个人到商业的全套开发教程,实打实的干货分享,确定不来看看? 😻😻】
📝作者简介从web开发,再到大数据算法,踩过了无数的坑,用心总结经验教训,助你在技术生涯一臂之力!若想获取更多精彩内容,敬请订阅专栏或者关注😁😂🤣😃😆😉😊😋😍😘🥰
⭐️您的小小关注是我持续输出的动力!⭐️


干货内容推荐

🥇入门和进阶小程序开发,不可错误的精彩内容🥇 :

  • 《小程序开发必备功能的吐血整理【个人中心界面样式大全】》
  • 《微信小程序 | 动手实现双十一红包雨》
  • 《微信小程序 | 人脸识别的最终解决方案》
  • 《来接私活吧?小程序接私活必备功能-婚恋交友【附完整代码】》
  • 《吐血整理的几十款小程序登陆界面【附完整代码】》

文章目录

  • 干货内容推荐
    • 需求背景
    • 一、效果预览
    • 二、技术关键点
      • 2.1 技术栈
      • 2.2 技术难点
    • 三、完整源码


需求背景

俄罗斯方块作为童年时期的经典怀旧游戏,该游戏我们更多的是在接机或者是pc端进行的体验,这次我们自己动手实现一次在web端,以及在移动端的俄罗斯方块,想要什么效果那我们自己造。😁😂🤣😃😄😅😆


一、效果预览

在这里插入图片描述


二、技术关键点

2.1 技术栈

  • 项目使用了Vue 2.0的语法规则,并非原生的微信小程序语法!
  • 兼容了uniapp框架的扩展能力!可以借助uniapp技术将vue的语法构建打包成微信小程序语法。

2.2 技术难点

  • (1)方块的移动

俄罗斯方块中最重要的模块莫非在于这个宫格棋盘。在宫格棋盘中要实现模块的运动和变化,其中关键点在于控制某个模块形状在棋盘中的现实状态。

对于棋盘我们使用一个二维数组实现: block[][]
特别对其下落的模块进行形状的预先定义,然后再根据用户操作进行选取:
在这里插入图片描述

  • (2)键盘的控制
    要控制方块的下落和形状,我们得采用键盘对方块进行控制。

这时我们需要采用监听键盘得事件:

	document.addEventListener('keydown', function(e) {
			 
				// console.log("----->当前按键keyCode:" + e.keyCode);
			 
				switch (e.keyCode) {
					case 37:
						that.moveLeft();
						break;
					case 38:
						that.rotateBlock();
						break;
					case 39:
						that.moveRight();
						break;
					case 40:
						that.moveDown();
						break;
				}
			 
			})

三、完整源码

<template>
	<view class="content">
		<view class="title">
			<view>分数:{{score[0]}}</view>
			<view class="blockMinMap">
				<view v-for="(line, i) in blocks[nextBlock[0]][nextBlock[1]]" :key="'minimap-line-'+i" class="line">
					<view v-for="(b, j) in line" :key="'minimap-line-'+i+'-block-'+j" :class="{'block':b=1}"></view>
				</view>
			</view>
			<view>等级:{{parseInt(score[0]/score[1])}}</view>
		</view>
		<view class="gameView" :style="{height:gameViewHeight+'px'}">
			<view v-for="(line, i) in getTrueMap()" :key="'map-line-'+i" class="line">
				<view v-for="(b, j) in line" :key="'map-line-'+i+'-block-'+j" :class="{'block':b>0}"
				 :style="{width:getGameViewBlockSize()+'px', height:getGameViewBlockSize()+'px'}"
				></view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				randomIndex:1,
				//地图大小
				mapSize:[18, 10],
				//下降时间:开始,结束,每升一级减少等待时间
				downSpeed: [1500, 200, 100],
				//分数:现在分数,多少分升一级, step
				score: [0, 10, 1],
				//地图
				map: [],
				//7种方块,及其朝向
				blocks: [
					[[[0,1,1],[1,1,0]],[[1,0],[1,1],[0,1]]],
					[[[1,1,0],[0,1,1]],[[0,1],[1,1],[1,0]]],
					[[[1,1,1,1]],[[1],[1],[1],[1]]],
					[[[1,1],[1,1]]],
					[[[0,1,0],[1,1,1]],[[0,1],[1,1],[0,1]],[[1,1,1],[0,1,0]],[[1,0],[1,1],[1,0]]],
					[[[0,0,1],[1,1,1]],[[1,1],[0,1],[0,1]],[[1,1,1],[1,0,0]],[[1,0],[1,0],[1,1]]],
					[[[1,0,0],[1,1,1]],[[0,1],[0,1],[1,1]],[[1,1,1],[0,0,1]],[[1,1],[1,0],[1,0]]],
				],
				//方块开始位置
				startPosition:[0,4],
				//方块现在位置
				blockPosition:[0,0],
				//当前方块限制:方块种类,方块朝向
				nowBlock:[0,0],
				//下一个方块限制: 方块种类,方块朝向
				nextBlock:[0,0],
				//游戏窗口高度:
				gameViewHeight:450,
				//游戏结束
				gameOver:false,
				//游戏循环体
				gameUpdateFunc:null,
			}
		},
		mounted() {
			this.refreshNextBlock()
			this.refreshNextBlock()
		},
		onLoad() {
			this.initGame()
			var that = this
			
			document.addEventListener('keydown', function(e) {
			 
				// console.log("----->当前按键keyCode:" + e.keyCode);
			 
				switch (e.keyCode) {
					case 37:
						that.moveLeft();
						break;
					case 38:
						that.rotateBlock();
						break;
					case 39:
						that.moveRight();
						break;
					case 40:
						that.moveDown();
						break;
				}
			 
			})
			
		},
		methods: {
			initGame(){
				var that = this;
				this.initMap()
				this.score[0] = 0;
				this.refreshNextBlock()
				this.refreshNextBlock()
				this.gameOver = false;
				clearInterval(that.gameUpdateFunc)
				that.gameUpdateFunc = null;
				this.$nextTick(function(){
					that.tryGetGameHeight()
					that.gameUpdate()
				})
			},
			gameUpdate(){
				var that = this;
				
				that.randomIndex = Math.floor(Math.random()*5+1)
										
				
				that.gameOver = false;
				that.gameUpdateFunc = setInterval(()=>{
					
					
					//游戏循环体
					that.moveDown()
								
					
					//更新
					clearInterval(that.gameUpdateFunc)
					//游戏未结束时触发
					if(!that.gameOver){
						that.gameUpdate()
					}
					else{
						uni.showModal({
							showCancel:false,
							confirmText:'再来一局',
							title:'游戏结束',
							content:'最终分数:'+this.score[0],
							success:(res)=>{
								if(res.confirm){
									that.initGame()
								}
							}
						})
					}
				}, Math.max(
					(this.downSpeed[0]-this.downSpeed[2]*parseInt(this.score[0]/this.score[1])), 
					this.downSpeed[1]
				))
			},
			moveDown(){
				//获取底部砖块情况
				if(this.gameOver) return;
				var bottomPosition = []
				var theBlock = this.blocks[this.nowBlock[0]][this.nowBlock[1]]
				for (var i=0;i<theBlock[0].length;i++){
					bottomPosition.push(0)
				}
				for (var i=0;i<theBlock.length;i++){
					for (var j=0;j<theBlock[i].length;j++){
						if(theBlock[i][j] > 0){
							bottomPosition[j] = Math.max(bottomPosition[j], i)
						}
					}
				}
				// console.log(bottomPosition)
				var canMove = true;
				for (var i=0;i<bottomPosition.length;i++){
					if(this.blockPosition[0]+bottomPosition[i]+1 >= this.mapSize[0]){
						canMove = false;
						break;
					}
					else if(this.map[
							this.blockPosition[0]+bottomPosition[i]+1
						][
							this.blockPosition[1]+i
						] > 0){
						canMove = false;
						break;
					}
				}
				if(canMove){
					this.blockPosition[0]+=1;
					this.$forceUpdate()
				}
				else{
					//如果当前Y坐标依旧是0,游戏结束
					if(this.blockPosition[0]<=0){
						this.gameOver = true;
					}
					//触底不能移动, 锁死方块,将方块的值赋予map
					else{
						for (var i=0;i<theBlock.length;i++){
							for (var j=0;j < theBlock[i].length;j++){
								// console.log(this.blockPosition[0]+i, this.blockPosition[1]+j)
								// console.log(this.map.length, this.map[0].length)
								this.map[this.blockPosition[0]+i][this.blockPosition[1]+j] = 
									Math.max(theBlock[i][j], 
										this.map[this.blockPosition[0]+i][this.blockPosition[1]+j]);
							}
						}
						this.$forceUpdate()
						//判断当前是否有无可能消除行
						this.checkMapScore()
						//更新下个方块
						this.refreshNextBlock()
					}
				}
			},
			rotateBlock(){
				if(this.gameOver) return;
				var nextStyle = (this.nowBlock[1]+1) % this.blocks[this.nowBlock[0]].length;
				//判断当前的状态是否存在位置
				var canChange = true;
				var changeBlock = this.blocks[this.nowBlock[0]][nextStyle];
				if(this.blockPosition[1]+changeBlock[0].length > this.mapSize[1]){
					//x超出
					canChange = false;
				}
				else if(this.blockPosition[0]+changeBlock.length > this.mapSize[0]){
					//y超出
					canChange = false;
				}
				else{
					for (var i=0;i<changeBlock.length;i++){
						for (var j=0;j<changeBlock[i].length;j++){
							//旋转后部分和原始map重合
							if (changeBlock[i][j] > 0 && 
								this.map[this.blockPosition[0]+i][this.blockPosition[1]+j] > 0){
									canChange = false;
									break;
								}
						}
					}
				}
				if(canChange){
					this.nowBlock[1] = nextStyle
					this.$forceUpdate()
				}
			},
			moveLeft(){
				//判断是否可以左移
				if(this.gameOver) return;
				var theBlock = this.blocks[this.nowBlock[0]][this.nowBlock[1]];
				var leftPosition = [];
				for (var i=0;i<theBlock.length;i++){
					leftPosition.push(-1)
					for (var j=0;j<theBlock[i].length;j++){
						if(leftPosition[i] === -1 && theBlock[i][j] > 0){
							leftPosition[i] = j;
						}
					}
				}
				// console.log(leftPosition)
				var canMove = true;
				for (var i=0;i<leftPosition.length;i++){
					if (this.blockPosition[1]+leftPosition[i] == 0){
						canMove = false;
						break;
					}
					else if (this.map[
								this.blockPosition[0]+i
							][
								this.blockPosition[1]+leftPosition[i]-1
							] > 0){
						canMove = false;
						break;
					}
				}
				if(canMove){
					this.blockPosition[1] -= 1;
					this.$forceUpdate()
				}
			},
			moveRight(){
				//判断是否可以左移
				if(this.gameOver) return;
				var theBlock = this.blocks[this.nowBlock[0]][this.nowBlock[1]];
				var rightPosition = [];
				for (var i=0;i<theBlock.length;i++){
					rightPosition.push(0)
					for (var j=0;j<theBlock[i].length;j++){
						if(theBlock[i][j] > 0){
							rightPosition[i] = j;
						}
					}
				}
				// console.log(rightPosition)
				var canMove = true;
				for (var i=0;i<rightPosition.length;i++){
					if (this.blockPosition[1]+rightPosition[i]+1 >= this.mapSize[1]){
						canMove = false;
						break;
					}
					else if (this.map[
								this.blockPosition[0]+i
							][
								this.blockPosition[1]+rightPosition[i]+1
							] > 0){
						canMove = false;
						break;
					}
				}
				if(canMove){
					this.blockPosition[1] += 1;
					this.$forceUpdate()
				}
			},
			checkMapScore(){
				var newMap = []
				// 计算score并消去满足的行
				for (var i=0; i < this.map.length; i++){
					var lineSum = 0;
					for(var j=0; j < this.map[i].length;j++){
						lineSum += Math.min(this.map[i][j], 1);
					}
					// console.log(i, lineSum)
					if(lineSum >= this.map[i].length){
						this.score[0] += this.score[2];
					}
					else{
						newMap.push(JSON.parse(JSON.stringify(this.map[i])))
					}
				}
				//补充缺失的行
				while (newMap.length < this.map.length){
					var aline = []
					for (var i=0;i<this.map[0].length;i++) aline.push(0)
					newMap.unshift(aline)
				}
				this.map = newMap;
				this.$forceUpdate();
			},
			initMap(){
				this.map = []
				for (var i=0;i<this.mapSize[0];i++){
					this.map.push([])
					for (var j=0;j<this.mapSize[1];j++){
						this.map[i].push(0)
					}
				}
			},
			tryGetGameHeight(){
				var that = this;
				this.$nextTick(function(){
					that.gameViewHeight = uni.getSystemInfoSync().windowHeight - 170;
				})
			},
			getGameViewBlockSize(){
				var padding = 40
				return Math.min(
					parseInt((this.gameViewHeight-padding)/this.mapSize[0]),
					parseInt((uni.getSystemInfoSync().windowWidth-padding)/this.mapSize[1])
				)
			},
			refreshNextBlock(){
				this.nowBlock = this.nextBlock
				var nextBlock = [
					parseInt(Math.random()*this.blocks.length),
					0
				]
				nextBlock[1] = parseInt(this.blocks[nextBlock[0]].length*Math.random())
				this.nextBlock = nextBlock
				this.blockPosition = JSON.parse(JSON.stringify(this.startPosition));
				// console.log(this.blockPosition)
				this.$forceUpdate()
			},
			getTrueMap(){
				//实际map是原始map+当前方块位置
				if(this.map.length != this.mapSize[0] || this.mapSize[1] != this.map[0].length){
					return this.map;
				}
				var trueMap = JSON.parse(JSON.stringify(this.map))
				var theBlock = this.blocks[this.nowBlock[0]][this.nowBlock[1]]
				// console.log(theBlock)
				for(var i=0; i<theBlock.length; i++){
					for(var j=0; j<theBlock[i].length; j++){
						// console.log(i+this.blockPosition[0], j+this.blockPosition[1])
						trueMap[i+this.blockPosition[0]][j+this.blockPosition[1]] = Math.max(
							theBlock[i][j],
							trueMap[i+this.blockPosition[0]][j+this.blockPosition[1]]
						);
					}
				}
				// console.log(trueMap)
				return trueMap;
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		    background-color: #020000d4;
			    height: 100vh;
	}
	
	.title{
		display: flex;
		flex-direction: row;
		justify-content: space-around;
		align-items: center;
		width: 90%;
		padding: 8% 5px;
		height:58px;
		border: #d9d9d9 solid 5px;
		    color: #fff;
		    border-radius: 10px;
		    font-weight: bold;
			margin-top: 10px;
			background: #3da5c482;
	}
	
	.blockMinMap{
		display: flex;
		flex-direction: column;
		width: 48px;
		height: 48px;
		align-items: center;
		justify-content: center;
	}
	
	.blockMinMap .line, .gameView .line{
		display: flex;
		flex-direction: row;
		align-items: center;
	}
	
	.blockMinMap .line view{
		width: 12px;
		height: 12px;
	}
	
	.gameView .line view{
		border: 1px solid #e6e6e6;
		width: 40upx;
		height: 40upx;
	}
	
	.blockMinMap .line .block{
		border: 1px solid #333333;
		width: 10px;
		height: 10px;
	}
	
	.gameView .line .block{
		border: 1px solid #333333;
		background-color: #4CD964;
		/* width: 40upx;
		height: 40upx; */
	}
	
	
	
	.block1{
		border: 1px solid #333333;
		background-color: #4CD964;
		/* width: 40upx;
		height: 40upx; */
	}
	
	.block2{
		border: 1px solid #333333;
		background-color: #0055ff;
	}
	 .block3{
		border: 1px solid #333333;
		background-color: #ff007f;
	}
	.block4{
		border: 1px solid #333333;
		background-color: #ffaa00;
	}
	.block5{
		border: 1px solid #333333;
		background-color: #ff55ff;
	}
	
	
	
	.gameView{
		width: 100%;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}
	
	.buttonView{
		width: 90%;
		padding: 5% 5px;
		border-top: #C0C0C0 solid 1px;
		background-color: #FFFFFF;
		display: flex;
		flex-direction: row;
		justify-content: space-between;
	}
	
	.buttonView view{
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		width: 30%;
		border: #555555 solid 1px;
		border-radius: 10px;
		height: 30px;
		background-color: #FFFFFF;
	}
	
	.buttonView view:active{
		background-color: #C0C0C0;
	}
</style>


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

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

相关文章

[Linux]----进程间通信之管道通信

文章目录前言一、进程间通信目的二、进程间通信发展三、进程间通信分类四、管道1. 匿名管道2. 管道内核代码3. 站在文件描述符角度-深度理解管道4. 站在内核角度-管道本质5. 管道的特征总结五、命名管道1. 创建命名管道总结前言 首先我基于通信背景来带大家了解进程间通讯&…

HTTP协议详细总结

目录 1.HTTP协议是什么? 2.什么叫做应用层协议 3.HTTP协议的工作流程 4.HTTP报文格式 请求报文: 响应报文: 5.URL 6.方法的认识 1.GET 2.POST 3.GET和POST的区别 4.其他方法 7.报头的认识 用户登陆过程: 8.状态码的认识 9.HTTPS 9.1HTTPS是什么? 9.2HTTPS的…

现代c++中实现精确延时方法总结

程序中实现延时有很多种办法&#xff0c;但是有些不建议用。比如还在用sleep()或者空转计数的方式延时&#xff1f;要么移植性不好&#xff0c;要么不够精确且效率太低。这里总结下现代c中推荐的一种实现精确延时的方法。 之前的一些用法 粗暴空转 long wait 0; while(wait…

十二、Mysql的索引

Mysql的索引十二、Mysql的索引一、什么是索引二、常见索引的种类(算法)三、B树 基于不同的查找算法分类介绍1、B树结构2、B-树四、索引的功能性分类1、辅助索引(S)及构建B树结构2、聚集索引(C)及构建B树结构3、聚集索引和辅助索引构成区别4、关于索引树的高度受什么影响五、索引…

Vue快速入门一:官网、下载、定义变量

Vue官网&#xff1a;Vue.js - 渐进式 JavaScript 框架 | Vue.js Vue2中文文档&#xff1a;Vue.js介绍 — Vue.jsVue.js Vue3中文文档&#xff1a;快速上手 | Vue.js Vue下载&#xff1a; Vue2下载&#xff1a; 引入Vue2版本&#xff1a;打开上面的中文文档&#xff0c;找到这…

Flink窗口及其分类-详细说明

文章目录&#x1f48e;Flink窗口的概念⚽窗口的分类&#x1faa9;窗口 API 概览⚾窗口分配器&#xff08;Window Assigners&#xff09;&#x1f603;&#x1f603;&#x1f603;&#x1f603;&#x1f603; 更多资源链接&#xff0c;欢迎访问作者gitee仓库&#xff1a;https:/…

Hive:BUG记录,错误使用动态分区导致的插入失败

1.场景 在Hive中&#xff0c;插入数据时可以指定动态分区&#xff0c;如果通过partition(day_partition)指定动态分区&#xff0c;而实际的select语句是直接把这个属性值写死了&#xff08;如‘2022-10-13’&#xff09;&#xff0c;就可以不需要指定hive变量set hive.exec.dy…

【牛客】四选一多路器

描述 制作一个四选一的多路选择器&#xff0c;要求输出定义上为线网类型 状态转换&#xff1a; d0 11 d1 10 d2 01 d3 00 信号示意图&#xff1a; 波形示意图&#xff1a; 输入描述&#xff1a; 输入信号 d1,d2,d3,d4 sel 类型 wire 输出描述&#xff1a; 输出信…

【信号处理】扩展卡尔曼滤波EKF(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

学习 MongoDB5 这一篇就够了

文章目录一、相关概念1.1、业务场景1.2、简介1.3、体系结构1.4、数据模型二、安装三、基本常用命令3.1、数据库操作3.2、集合操作3.3、文档基本CRUD1、插入2、查询3、更新4、删除3.4、分页查询3.5、更多查询3.6、小结四、索引4.1、概述4.2、类型4.3、管理操作4.4、索引的使用4.…

四十五、壁面函数理论及y+的确定

0. 前言 什么叫做壁面函数&#xff0c;为什么引入壁面函数的概念?? 因为流体无论流动&#xff0c;还是传热、传质都存在边界层。而之所以有壁面函数这个东西&#xff0c;根源就在于边界层理论。 1. 边界层理论 大家都知道什么是边界层理论&#xff0c;我们想要理解壁面函数…

美国这几年的人口死亡数据

2015年&#xff1a;总死亡271.20万&#xff0c;平均死亡年龄78.8 2016年&#xff1a;总死亡274.40万&#xff0c;平均死亡年龄78.6 2017年&#xff1a;总死亡281.35万&#xff0c;平均死亡年龄78.6 2018年&#xff1a;总死亡283.90万&#xff0c;平均死亡年龄78.7 2019年&#…

Java中的方法是什么?(Java系列2)

目录 前言&#xff1a; 1.什么是方法 2.方法的定义 3.方法调用的执行过程 4.实参和形参的关系 5.方法重载 6.方法签名 7.递归 8.关于“调用栈” 结束语&#xff1a; 前言&#xff1a; 在上一次博客中小编主要和大家分享了Java中的一些基础知识&#xff0c;与小编之前…

Python多任务编程

1.进程与多任务 1. 1 多任务的介绍 1.使用多任务能充分利用CPU资源&#xff0c;提高程序的执行效率&#xff0c;让程序具备处理多任务的能力。 2.多任务执行方式有两种&#xff1a; 并发&#xff1a;在一段时间内交替执行多个任务。 并行&#xff1a;在一段时间内真正的同…

第三周 青海之行——练练构图,培养你的摄影眼

目录3.1 油菜花海&#xff0c;怎么拍更好看&#xff1f;3.2 构图的元素&#xff1a;线条、形状、图案(一)3.3 构图的元素&#xff1a;光影、留白、框景(二)3.4 摄影构图 补充内容构图作业3.1 油菜花海&#xff0c;怎么拍更好看&#xff1f; 祁连山下的百里油菜花海 门源 雪山下…

冲冲冲!!!python计算机二级每日一套_8

文章目录一、选择题二、基本操作三、简单应用四、综合应用声明&#xff1a;例题均来源于网络&#xff0c;仅供学习笔记&#xff0c;若涉侵权请联系删除。所属练题来源于《小黑课堂》一、选择题 1、树的度为3&#xff0c;共有31个结点&#xff0c;但没有度为1和2的结点。则该树…

C++ Reference: Standard C++ Library reference: Containers: deque: deque: clear

C官网参考链接&#xff1a;https://cplusplus.com/reference/deque/deque/clear/ 公有成员函数 <deque> std::deque::clear C98 void clear(); C11 void clear() noexcept;清除内容 从deque中删除所有元素&#xff08;已销毁&#xff09;&#xff0c;使容器的size为0。…

MBIST BAP(Bist Access Port)直接访问接口(1)

More articles You can follow the official account&#xff1a;“IC练习生” IC民工不定期更新 BAP BAP会覆盖掉连接到BAP上的memory的一些默认操作模式; 通过消除串行配置控制器的shift cycle,大大缩短测试时间,代价是在BAP和控制器之间额外的连接; BAP的高级访问属性部分…

【渝偲】DSPE-PEG-Mannose磷脂聚乙二醇甘露糖;科研试剂

DSPE-PEG-Mannose磷脂聚乙二醇甘露糖 DSPE-PEG-Mannose 磷脂聚乙二醇甘露糖 英文名称:DSPE-PEG-Mannose 中文名称:磷脂聚乙二醇甘露糖 结构式&#xff1a; 性状: PEG2000分子量为白色粉末溶剂:溶于大部分有机溶剂&#xff0c;如&#xff1a;DCM、DMF、DMSO、THF等等。在水中…

【Linux进程间通信】 管道

这里写目录标题管道有名管道无名管道在使用无名管道时为什么要关闭不使用的另外一端&#xff1f;IPC机制&#xff1a;管道&#xff0c;信号量&#xff0c;共享队列&#xff0c;消息队列&#xff0c; 套接字。 管道&#xff0c;信号量&#xff0c;共享队列&#xff0c;消息队列…