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

【cocos官方案例改】跳跃牢猫

自制游戏【跳跃牢烟】

案例解析

案例需求,点击鼠标控制白块左右。

资源管理器部分

在body创建一个2d精灵用作玩家。

在地下在创建一个2d精灵用来代表地面。

在body下挂在脚本。

全部脚本如下

(在二次进行复刻时候,发现把代码复制上去无法运行,原来cocos的引入,需要每次在vscode里面挨个打的时候将会自动添加引入,如果直接甩给它,他不会引入任何模块。)

import { _decorator, Component, EventMouse, Input, input, Node } from 'cc';

const { ccclass, property } = _decorator;

 

@ccclass('NewComponent')

export class NewComponent extends Component {

  start() {

    input.on(Input.EventType.MOUSE_DOWN,this.IKUN,this)

  }

  IKUN(event:EventMouse){

    if(event.getButton()==2){

      this.jump(2)

    }

    if(event.getButton()==0){

      this.jump(0)

    }

  }

  jump(kun:number){

    if(kun==2){

      const cur = this.node.position;

      this.node.setPosition(cur.x+40,cur.y,cur.z);

    }

    if(kun==0){

      const cur = this.node.position;

      this.node.setPosition(cur.x-40,cur.y,cur.z);

    }

 

  }

  // protected iikun():void{

  //  input.off(Input.EventType.MOUSE_DOWN,this.IKUN,this);

  // }

  update(deltaTime: number) {

    

  }

}

分段拆解

导入模块

typescript

import { _decorator, Component, EventMouse, Input, input, Node } from 'cc';

const { ccclass, property } = _decorator;

从 'cc' 模块导入了 _decorator、Component、EventMouse、Input、input、Node 等类将 

_decorator 中的 ccclass 和 property 解构出来,用于后续的类装饰。

start 方法

typescript

start() {

    input.on(Input.EventType.MOUSE_DOWN, this.IKUN, this)}

start 方法在组件所在的节点被激活时调用一次。

使用 input.on 方法监听鼠标按下事件 Input.EventType.MOUSE_DOWN,当鼠标按下时,会调用 this.IKUN 方法,并且将当前组件实例 this 作为上下文传递。

IKUN 方法

typescript

IKUN(event: EventMouse) {

    if (event.getButton() == 2) {

        this.jump(2)

    }

    if (event.getButton() == 0) {

        this.jump(0)

    }}

· 当 MOUSE_DOWN 事件发生时,输入系统会调用 IKUN 方法,并将生成的 EventMouse 事件对象作为参数传递给 IKUN 方法,这就是 event 的来源。

· IKUN 方法接收一个 EventMouse 类型的参数。

· 为什么值是eventmouse呢,因为传过来的值是一个鼠标事件(MOUSE_DOWN)嘛

event: EventMouse)也就是说,这个形参的值,是一个EventMouse类型的(鼠标类型)

· 通过 event.getButton() ,意思是获取event里面的getbutton()的值。

· 获取鼠标按下的按钮,2 表示鼠标右键,0 表示鼠标左键。

· 根据按下的按钮不同,调用 this.jump 方法,并传递相应的参数 2 或 0。

jump 方法

typescript

jump(kun: number) {

    if (kun == 2) {

        const cur = this.node.position;

        this.node.setPosition(cur.x + 40, cur.y, cur.z);

    }

    if (kun == 0) {

        const cur = this.node.position;

        this.node.setPosition(cur.x - 40, cur.y, cur.z);

    }}

· jump 方法接收一个 number 类型的参数 kun。

· 如果 kun 为 2,表示鼠标右键按下,将当前节点的 x 坐标增加 40。

· 如果 kun 为 0,表示鼠标左键按下,将当前节点的 x 坐标减少 40。

· 通过 this.node.position 获取当前节点的位置,然后使用 this.node.setPosition 方法设置新的位置。

update 方法

update 方法在每一帧都会被调用,参数 deltaTime 表示从上一帧到当前帧的时间间隔。

· 该方法目前为空,没有实现任何功能。

注释代码

// protected iikun():void{//    input.off(Input.EventType.MOUSE_DOWN,this.IKUN,this);// }

· 这段代码被注释掉了,如果取消注释,iikun 方法会取消监听鼠标按下事件 Input.EventType.MOUSE_DOWN,参数与 input.on 方法相对应,用于移除之前添加的事件监听器

2d视野下的调整

项目设置-》项目数据-》设计宽度(高度)

视野跟随指定物体移动

在层级管理器里面把摄像机(camera)放在指定物体下面

渲染画布外面的部分

Canvas-》属性检查器-》xx.canvas->align canvas wlith screen

小方块缓慢的移动

凭借上述的代码,可以实现小方块的移动,但这样的结果过于僵硬,我们可以通过别的方法来让小方块自然一些。

首先看全部的代码,随后进行分段讲解。

import { _decorator, Component, EventMouse, Input, input, Node } from 'cc';

const { ccclass, property } = _decorator;

@ccclass('NewComponent')

export class NewComponent extends Component {

  private starikun = false;

  private _jumptime = 0.2;

  private _ttime = 0;

  private _ikunsp =0;

  start() {

    input.on(Input.EventType.MOUSE_DOWN,this.IKUN,this)

  }

  IKUN(event:EventMouse){

    if(event.getButton()==2){

      this.jump(2)

    }

    if(event.getButton()==0){

      this.jump(-2)

    }

  }

  jump(kun:number){

    

    this.starikun = true;

    this._ttime = 0;

    this._ikunsp = kun*20/this._jumptime;

  }

  // protected iikun():void{

  //  input.off(Input.EventType.MOUSE_DOWN,this.IKUN,this);

  // }

  update(dt: number) {

   if(this.starikun=true){

    this._ttime+=dt;

    if(this._ttime>this._jumptime){

      this.starikun=false;

    }else{

      const cupikun =this.node.position;

      this.node.setPosition(cupikun.x+this._ikunsp*dt,cupikun.y,cupikun.z);

    }

   } 

  }

}

第一段,基本上没有区别,单纯的增加了几个变量

import { _decorator, Component, EventMouse, Input, input, Node } from 'cc';

const { ccclass, property } = _decorator;

@ccclass('NewComponent')

export class NewComponent extends Component {

   private starikun = false;

  private _jumptime = 0.2;

  private _ttime = 0;

  private _ikunsp =0;

  start() {

    input.on(Input.EventType.MOUSE_DOWN,this.IKUN,this)

  }

  IKUN(event:EventMouse){

    if(event.getButton()==2){

      this.jump(2)

    }

    if(event.getButton()==0){

      this.jump(-2)

    }

  }

starikun 用来判断到时候该不该移动

_jumptime是小方块移动的时候占据多少时间

Titime是当作计时器使用

Ikunsp用来当作速度

第二段

把之前让小方块移动的代码删除了,换做更为复杂的代码,但是这让小方块看起来流畅很多。

这将会使用内置函数update,所以jump函数的作用不再是直接控制移动了。

jump(kun:number){

    

     this.starikun = true;

    this._ttime = 0;

    this._ikunsp = kun*20/this._jumptime;  }

starikun 更改为true,下面有用

_ttime 表示时间为0,初始化时间。

this._ikunsp = kun*20/this._jumptime;  }

是求速度的,因为速度等于路程/时间

最后一段是利用update函数,因为updata函数每一帧都会执行一次,借助特性来使达到想要的缓慢到达目标地点的方块方法。

 update(dt: number) {

   if(this.starikun=true){

    this._ttime+=dt;

    

    if(this._ttime>this._jumptime){

      this.starikun=false;

    }else{

      const cupikun =this.node.position;

      this.node.setPosition(cupikun.x+this._ikunsp*dt,cupikun.y,cupikun.z);

    }

   } 

  }

 update(dt: number) ,把每针的时间定义为dt。

  if(this.starikun=true),starikun变量等于true时候执行。下面全部的函数。

 this._ttime+=dt;使计时器增加,每次增加一帧的时间。

下面进行逻辑判断,如果计时器的时间大于要求的跳跃时间,那么starikun改变,也就进行运动了。

如果没有大于,那么每次都使当前时间乘速度,让小球位移。因为一帧一帧移动,所以看起来会缓和许多,不会过于生硬。

但这时候通过编辑器预览发现小方块的移动并非是完全与速度与时间的乘积相等。

我推测是帧率的时间问题,可能大个几毫秒或者少于几毫秒。

具体的解决措施是将小方块最后移动到该移动的位置。

如何让小方块移动的更加精准

在start函数上方定义两个私有变量。一个是用来保存当前位置,一个是用来保存小方块最终移动位置。

 private _zdp = new Vec3;

 private _zd = new Vec3;

_zdp是最终的位置

_zd用来存储当前位置。

Vec3是一个存储三维数据的一个变量。

New是对象与类的基本知识。

在jump函数的部分让_zd获取当前的位置,让_zdp获取最终位置。

this._zd = this.node.position;

//this.node.getPosition(this._zd);

这两种方法都可以。

一个是把当前的位置赋值给变量。

一个是把node当前的位置通过getposition传递给this.zd。

之后是推测最终位置,把最终地点的坐标传递给_zdp

 this._zdp = new Vec3(this._zd.x+jumpp,this._zd.y,this._zd.z);

其中的jumpp是把固定的距离变成了一个变量,这样想更改距离的时候就不用挨个去更改了,只要直接改一下jumpp的数值就好。

在jump函数第一行定义了一个   const jumpp = kun*20;

其中 this._zdp = new Vec3(this._zd.x+jumpp,this._zd.y,this._zd.z);也可以用vec.add来替换。

Vec3.add(this._zdp,this._zd,new Vec3(jumpp,0,0));

这段代码表示,将第二位与第三位参数相加并传递给第一个参数。

然后就是等函数整体运行之后把位置改变为_zdp位置。

在updata函数里面的 if(this._ttime>this._jumptime)的末尾加上一个

this.node.setPosition(this._zdp);

解决重复按下鼠标导致位置发生偏移的问题。

在jump函数下,第一行增加一句

if(this.starikun)return

意思是starikun为true的话后面代码直接不执行,涉及到if基本知识和return基本知识。

跳跃动画

添加跳跃动画组件

首先选中要添加跳跃动画的组件,在下方动画编辑器里面为其创建,或者在选中组件的时候在右侧添加动画组件(animation)

创建动画剪辑资源

在下方动画编辑器之中创建动画剪辑资源,这时候观测到有两个明显属性。

1节点列表2属性列表

选中某个节点或子节点,对其该节点的某个或多个属性进行修改。

属性列表关键帧

剪辑基础知识,过。

通过简单捅咕即可学会创建一个动画,接下来使代码与动画连接。

不要忘记保存动画,在场景编辑器的那个。

这时候如果选择已经加载好动画的节点,为其animation属性勾选上加载后跳动,那将会在加载此节点的时候执行一次默认动画。

代码部分。

引入动画模块,使其节点可以加载刚才的动画。

@property(Animation)

public bodyiAnim:Animation =null;

@property是一个装饰器(decorator),它主要用于将一个类的成员变量进行属性化处理。

属性化后就可以在节点的部分直接看见。

Animation 在这里是一个类型说明,表明了被装饰的成员变量的类型。

这时候观测该节点的父节点,单击后查看右侧部分,就会神奇的发现多了个节点属性。

注意,在引入Animation容易产生错误,因为有同名的其他,引入cc下的才是正确的。

扩展

在上述学习之中已经了解@property是cocos之中将一个类的成员变量进行属性化处理。尝试自定义一个进行尝试。

代码部分

@property(Number)

   myNumber: number = 42;

返回父节点进行观测,发现新增一个属性,名称为myNumber,数值是42。

在写完代码后,返回cocos属性面板,这时候bodyiAnim=null;,将存在动画的子节点拖入该区域。

当你把节点拖入 bodyiAnim 属性时,实际上是在告诉 Cocos:“我希望 bodyiAnim 变量引用这个节点上的动画组件。

在跳跃时候播放动画

在jump函数里面,也就是准备跳的时候执行动画的播放即可。

代码部分

This.bodyiAnim.play(“动画名”);

这时候运行就可以跳跃了。

接下来目的是创建一个新的动画,让跳一步和两步的动画分开,并在程序中进行判断,如果是一步调用那个动画,两部调用那个动画。

首先是如何创建一个新的动画,在选中节点后,在下方动画编辑器之中进行,动画剪辑-》下标-》新建剪辑动画.

代码部分。

在之前This.bodyiAnim.play(“动画名”);进行修改,使其增加一个判断,如果是左键播放什么动画,右键播放什么动画。

if(kun==2){

        this.bodyani.play("animation");

    }

    if(kun==4){

        this.bodyani.play("animation-001");

    }

这时候发现动画的时间和移动的时间又不一样了,那么可以选择更改动画,让动画时间与移动的时间相等,或者让移动时间等于动画的时间。

这里根据教程使用的是让移动时间等于动画时间。

代码部分

const aniname= kun==2?'animation':'animation-001';

const anistate=this.bodyani.getState(aniname);

this.jumptime=anistate.duration;

const aniname= kun==2?'animation':'animation-001';利用三元表达式,如果kun的值是2,那么返回值animation,否则返回值animation-001。并把值返回给常量aniname。

getState 通常可以被理解为 “获取状态”。翻译一下就是获取bodyani下的aniname的动画的状态。

最后这行代码是把找到的动画状态(anistate)里的 duration 属性的值取出来,存储在 this.jumptime 中。

在此时,前面写的if分支if(kun==2){可以删除了,换成this.bodyani.play(aniname);就可以了。

随机生成地图

生成预制体

在层级管理器之中将地面拖入到资源管理器之中,这会生成一个预制体。

创建一个新的脚本和一个新的空节点,将脚本挂在到新的节点上。

在脚本内需要对预制体进行引用,还要创建一个参数用来保存到底生成多少格子,将他们属性化是一个很好的方法。

代码部分

 @property(Prefab)

    public boxprefab:Prefab =null;

    @property

    public roalength =50;

将资源管理器之中准备好的预制体地面放进刚才创建的节点的刚刚代码创建的属性值之上。

然后创建一个枚举类型。用来表示方块应该是那种状态。

代码部分

enum bolkeType{

    BT_none,

BT_white}

enum 是枚举(Enumeration)的缩写,它是一种数据类型,用于定义一组具名的常量。在这个例子中,bolkeType 是枚举的名称。

BT_none 和 BT_white 是 bolkeType 枚举中的成员。

使用 enum 定义枚举时,这些成员会被自动赋值为数字。BT_none 会被赋值为 0,BT_white 会被赋值为 1。

创建一个 _road变量,让其存储刚才定义的枚举类型。

代码部分

 private _road:bolkeType[]=[];

bolkeType[]:这是变量的类型,表明 _road 是一个数组,该数组的元素类型是 之前定义的bolkeType 枚举类型里面的类型。这意味着该数组中的每个元素都应该是 bolkeType 枚举中定义的成员,如 BT_none 或 BT_white。

在start函数里面调用一个自创的函数,具体操作将写在这里。

代码部分

start() {

        this.generate();

    }

    generate(){

        this.node.removeAllChildren();

This._road=[];

this._road.push(bolkeType.BT_white);

}

 this.node.removeAllChildren();销毁该节点下所有子节点。防止被多次调用。This._road同理

push() 是数组的一个内置方法,它的作用是向数组的末尾添加一个元素。

循环生成道路方块。

接下来通过代码来生成地面方块,通过for循环可以简单构成下面代码,这个循环存在于generate之中。

for(let i=1;i<this.roalength;i++){

        }

然后通过生成一个随机的数值,来确定生成哪一个地板块。

for(let i=1;i<this.roalength;i++){

            //Math.round(Math.random());

           this._road.push( Math.random()<0.5?0:1);

        }

Math.random() 是一个 JavaScript 内置的方法,它会生成一个范围在 [0, 1] 之间的随机浮点数,即大于或等于 0 且小于 1 的随机数。

Math.random() < 0.5? 0 : 1:

这是一个三元运算符。它会检查 Math.random() 的结果是否小于 0.5。如果小于 0.5,表达式的值为 0;如果大于或等于 0.5,表达式的值为 1。

Math.round():

这也是 JavaScript 中的一个内置函数,它的作用是将一个数字四舍五入为最接近的整数。对于 Math.round(x),如果 x 的小数部分小于 0.5,则将 x 向下取整;如果 x 的小数部分大于或等于 0.5,则将 x 向上取整。

但要考虑如果连续生成两个块为空,那么将无法进行,所以要进行逻辑判断,如果上一个为空块,则这次必须是白块。

代码部分

for(let i=1;i<this.roalength;i++){

            if(this._road[i-1]==bolkeType.BT_none){

                this._road.push(bolkeType.BT_white);

            }else{

                this._road.push( Math.random()<0.5?0:1);

            }

        }

上述代码是生成了小方块应该出现的类型,但是并没有真正的去生成方块,那么通过应该出现的类型来简单生成方块。

首先通过for循环去遍历,然后通过判断是否应该生成白块来确定方块的生成。

 for( let j=1;j<this.roalength;j++){

            if(this._road[j]==bolkeType.BT_white){

                const box =instantiate(this.boxprefab);

                box.setParent(this.node);

                box.setPosition(j*40,0,0);

            }

        }

if (this._road[j] == bolkeType.BT_white):

this._road[j]:从 this._road 数组中取出索引为 j 的元素。

bolkeType.BT_white:这是之前定义的枚举类型 bolkeType 中的一个枚举成员。

这里的条件判断是为了检查 this._road[j] 是否等于 bolkeType.BT_white,如果相等,则执行 if 语句块内的代码。

this.boxprefab 是一个预制体,类似于一个魔法模具。

instantiate 函数根据 this.boxprefab 创建一个新的对象,这个对象存储在 box 中,如同用模具做出一个新的物品。

setParent(this.node) 就像是给这个 “饼干” 找一个 “盘子”。this.node 就是这个 “盘子”,把 box 放在 this.node 下面,就表示让 box 成为 this.node 的子节点

box.setParent(this.node):将 box 的父节点设置为 this.node。这在游戏开发或节点树结构中很常见,用于组织和管理对象的层次结构。

box.setPosition(j * 40, 0, 0);:

box.setPosition(j * 40, 0, 0):调用 box 的 setPosition 方法,将 box 的位置设置为 (j * 40, 0, 0)。这里的 j * 40 表示 x 轴上的位置,根据 j 的不同会有所变化,而 y 和 z 轴的位置始终为 0。 就是在给这个 “饼干” 找到一个合适的位置。

创建ui

在场景的根节点处,再次创建一个画布节点,用于创建ui等,与之前的游戏画布节点呈现兄弟关系。

在ui画布下面创建一个空节点,在次空节点上创建一个精灵图。

找一个图片当作背景,对其进行拉伸处理,在精灵图属性之中,UItransform里面content sizi属性进行更改。

对精灵图的精灵属性进行修改,让其type属性更改为 SLICED 将鼠标悬停到type属性上的三个点,系统会说明该属性的用处。

创建一个开始按钮,一个积分器的文本label。

渲染问题

当两个摄像机模块存在时候,会导致一个物体被渲染两次,造成非常鬼畜的样子。

选择摄像机,更改其属性,Visibility。这将会告诉摄像机,该摄像机渲染那些类型的层。

选择画布,更改其属性,node属性的layer属性。告诉画布,其下的子节点包括自身是属于什么layer。

将游戏的那区域改为defxxx层,记得勾选连同子节点一起更改。

就是让一个摄像机渲染ui,一个渲染游戏,画布和摄像机为一个组合,这时候总共两个组合,画布下的所有东西定义为一个图层组,另一个也是,让摄像机分别只渲染自己组的画布。

返回之前写地面的脚本。

定义一个枚举类型,已用来保存游戏状态。

代码部分

enum Gamestate{

    GS_ui,

    GS_PLAYER

}

如果是ui状态,那么点击不应该触发小方块跳动,如果是play状态,那么那些ui组件应该隐藏。

设置一个方法,方法内判断当前状态,是Gs-ui还是gs_player

代码部分

start() {

          this.setcurstate(Gamestate.GS_ui);

    }

    setcurstate(vl:Gamestate){

        if(vl===Gamestate.GS_ui){

            this.generate();

        }else if(vl===Gamestate.GS_PLAYER){

        }

    }

这里更改了原先的start()方法,原先的start()方法会直接调用 this.generate();来生成地面。

现在的逻辑是判断是什么状态,再决定生不生成地面。

那么在vl===Gamestate.GS_ui的时候,需要让其禁用掉鼠标的监听。

返回让小方块跳动的代码部分。

取消掉star()开始函数里面的一切。

创建一个公共类型的函数,如果函数内的值为真,注册监听函数,如果为假,取消掉注册函数。

返回地面生成的脚本,添加一个引入。这里将会引入小方块脚本。

然后看之前写的setcurstate函数部分,通过下面的方法来控制另一个脚本的值。

两者有唏嘘差别,具体写时候具体理解。

将层级管理器的小方块节点引入。

之后处理对于ui界面的引用

将层级管理器的ui部分拖拽进去。

更改之前的setcurstate部分,使其让ui部分隐藏

在按钮部分,选择其属性,将cilick events设置为1。

这时候可以设置激活那个节点的哪个属性的那个方法。

让其调用地面脚本的属性。

在小方块的脚本上创建一个公共变量,默认值为0,在每次跳动时候加上跳动的步数,然后创建一个监听,在每次小方块结束移动时候。在使用地面脚本进行监听该事件。

 创建一个公共变量

public fenshu:number=0;

每次跳动时候加上跳动的步数

 this.fenshu+=xx;

然后创建一个监听事件,让地面脚本去监听这个fenshu

 this.node.emit("jumpend",this.fenshu);

这个是放在update函数里面的跳跃结束时候的下面。

if(this.stazz==true){

            if(this.tti>this.time){

                this.stazz=false;

                this.node.setPosition(this.zzwz);

                this.node.emit("jumpend",this.fenshu);

this.node.emit() 是 Cocos Creator 中的一个方法,用于在当前节点上触发一个自定义事件。

事件的名称是 "jumpend",后面跟着的是传递给事件处理程序的参数 this.fenshu。

然后回到地面脚本,在start监听上面的参数。

因为之前引入过小方块脚本,所以直接监听即可。

this.player.node.on("jumpend",this.onjumpend,this);

this.player.node 表示获取 this.player 所引用的节点。

然后,通过调用 on 方法,将一个名为 jumpend 的事件绑定到该节点上。当这个节点上触发 jumpend 事件时,就会调用 this.onjumpend 方法。

创建一个onjumpend方法。

 onjumpend(value:number){

        this.ui_labl.string=value.toString();

}

ui_labl之前没有,是新创建的,创建一个公共变量ui_labl,用于引用ui界面的文本,该文本作为积分器使用。

返回cocos的层级管理器,创建一个label。

然后回到代码部分,把.ui_labl属性化,将label拖入进去。

这样,游戏开始时候进行一个监听,监听的代码又会改变label节点的内容,每次小方块停止移动都会发送一个信号,然后被监听到,然后监听的代码又会改变label节点的内容......

当完成上述代码,游戏只差最后一个是否失败,以及是否通关的判定了,大段代码如下。

这时候发现路并没有回归原点,通过在小方块里面创建一个公用变量,将当前节点的位置更改为0.将之前传参的分数,也设置为0.

 public endfang(){

            this.node.setPosition(0,0,0);

            this.fenshu=0;

        }

然后在地面脚本的判断游戏状态(判断当前是ui还是游戏的那个)里面进行一个调用,让每次生成前先归零参数。

 setcurstate(vl:Gamestate){

        if(vl===Gamestate.GS_ui){

            this.player.endfang();

这时候,每次死亡后发现计数器并不会直接为0,实际上参数已经为0了,但是没有传输过去,所以需要一个手动的更新。

setcurstate(vl:Gamestate){

        if(vl===Gamestate.GS_ui){

            this.player.endfang();

            this.ui_labl.string='0';

相关文章:

【cocos官方案例改】跳跃牢猫

自制游戏【跳跃牢烟】 案例解析 案例需求&#xff0c;点击鼠标控制白块左右。 资源管理器部分 在body创建一个2d精灵用作玩家。 在地下在创建一个2d精灵用来代表地面。 在body下挂在脚本。 全部脚本如下 &#xff08;在二次进行复刻时候&#xff0c;发现把代码复制上去无法…...

基于Python的药物相互作用预测模型AI构建与优化(上.文字部分)

一、引言 1.1 研究背景与意义 在临床用药过程中,药物相互作用(Drug - Drug Interaction, DDI)是一个不可忽视的重要问题。当患者同时服用两种或两种以上药物时,药物之间可能会发生相互作用,从而改变药物的疗效、增加不良反应的发生风险,甚至危及患者的生命安全。例如,…...

Day51:type()函数

在 Python 中&#xff0c;type() 是一个内置函数&#xff0c;用于返回对象的类型。它可以用于检查变量的类型&#xff0c;也可以用于动态创建新的类型。今天&#xff0c;我们将深入了解 type() 函数的使用方法。 1. 使用 type() 获取变量的类型 最常见的使用方式是将一个对象…...

因果推断与机器学习—用机器学习解决因果推断问题

Judea Pearl 将当前备受瞩目的机器学习研究戏谑地称为“仅限于曲线拟合”,然而,曲线拟合的实现绝非易事。机器学习模型在图像识别、语音识别、自然语言处理、蛋白质分子结构预测以及搜索推荐等多个领域均展现出显著的应用效果。 在因果推断任务中,在完成因果效应识别之后,需…...

计算机网络一点事(21)

第四章 网络层 功能&#xff1a;服务传输层&#xff0c;封装ip数据报&#xff08;主机到主机&#xff09; IP地址以32b表示&#xff0c;以8b为一组记十进制数 异构网络互连&#xff1a;网络结构&#xff0c;主机类型不同 路由器相互配合出IP数据报生成表&#xff0c;根据表…...

springboot使用rabbitmq

使用springboot创建rabbitMQ的链接。 整个项目结构如下&#xff1a; 1.maven依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>3.4.1</version> </dependency>application.y…...

【微服务与分布式实践】探索 Eureka

服务注册中心 心跳检测机制&#xff1a;剔除失效服务自我保护机制 统计心跳失败的比例在15分钟之内是否低于85%&#xff0c;如果出现低于的情况&#xff0c;Eureka Server会将当前的实例注册信息保护起来&#xff0c;让这些实例不会过期。当节点在短时间内丢失过多的心跳时&am…...

Day48:获取字典键的值

在 Python 中&#xff0c;字典是一种无序的集合类型&#xff0c;它以键-值对的形式存储数据。字典的每个元素都有一个唯一的键&#xff0c;并且每个键都对应一个值。获取字典中的值是字典操作的常见任务&#xff0c;今天我们将学习如何从字典中获取键对应的值。 1. 使用方括号…...

Java锁自定义实现到aqs的理解

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 理解锁&#xff0c;能自定义实现锁通过自定义锁的实现复习Thread和Object的相关方法开始尝试理解Aqs, 这样后续基于Aqs的的各种实现将能更好的理解 目录 锁的…...

仿真设计|基于51单片机的温度与烟雾报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602实时监测及显示温度值和烟雾浓度值&#xff1b; &#xff08;2…...

文件读写操作

写入文本文件 #include <iostream> #include <fstream>//ofstream类需要包含的头文件 using namespace std;void test01() {//1、包含头文件 fstream//2、创建流对象ofstream fout;/*3、指定打开方式&#xff1a;1.ios::out、ios::trunc 清除文件内容后打开2.ios:…...

【后端开发】字节跳动青训营Cloudwego脚手架

Cloudwego脚手架使用 cwgo脚手架 cwgo脚手架 安装的命令&#xff1a; GOPROXYhttps://goproxy.cn/,direct go install github.com/cloudwego/cwgolatest依赖thriftgo的安装&#xff1a; go install github.com/cloudwego/thriftgolatest编辑echo.thrift文件用于生成项目&…...

SQL UCASE() 函数详解

SQL UCASE() 函数详解 在SQL中&#xff0c;UCASE() 函数是一个非常有用的字符串处理函数&#xff0c;它可以将字符串中的所有小写字母转换为大写字母。本文将详细介绍UCASE() 函数的用法、语法、示例以及其在实际应用中的优势。 一、UCASE() 函数简介 UCASE() 函数是SQL标准…...

99.23 金融难点通俗解释:小卖部经营比喻PPI(生产者物价指数)vsCPI(消费者物价指数)

目录 0. 承前1. 简述&#xff1a;价格指数对比2. 比喻&#xff1a;两大指数对比2.1 简单对比2.2 生动比喻 3. 实际应用3.1 价格传导现象 4. 总结5. 有趣的对比6. 数据获取实现代码7. 数据可视化实现代码 0. 承前 本文主旨&#xff1a; 本文使用小卖部比喻PPI和CPI&#xff0c;…...

【Elasticsearch】match_bool_prefix 查询 vs match_phrase_prefix 查询

Match Bool Prefix Query vs. Match Phrase Prefix Query 在 Elasticsearch 中&#xff0c;match_bool_prefix 查询和 match_phrase_prefix 查询虽然都支持前缀匹配&#xff0c;但它们的行为和用途有所不同。以下是它们之间的主要区别&#xff1a; 1. match_bool_prefix 查询…...

H. Mad City

题目链接&#xff1a;Problem - H - Codeforces 题目大意&#xff1a;给定一个带环的图&#xff0c; 以及a, b两点 判断再图上不断的移动&#xff0c; b想不与a相遇&#xff0c; a想捉到b, 并且二者只能移动一步。 若b跑不掉 NO 否则YES. 具体题目看链接 输入&#xff1a; …...

【图床配置】PicGO+Gitee方案

【图床配置】PicGOGitee方案 文章目录 【图床配置】PicGOGitee方案为啥要用图床图床是什么配置步骤下载安装PicGoPicGo配置创建Gitee仓库Typora中的设置 为啥要用图床 在Markdown中&#xff0c;图片默认是以路径的形式存在的&#xff0c;类似这样 可以看到这是本地路径&#x…...

《程序人生》工作2年感悟

一些杂七杂八的感悟&#xff1a; 1.把事做好比什么都重要&#xff0c; 先树立量良好的形象&#xff0c;再横向发展。 2.职场就是人情世故&#xff0c;但也不要被人情世故绑架。 3.要常怀感恩的心&#xff0c;要记住帮助过你的人&#xff0c;愿意和你分享的人&#xff0c;有能力…...

当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)

当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib) 当当网近30日热销书籍官网写在前面 实验目的:实现当当网近30日热销图书的数据采集与可视化分析。 电脑系统:Windows 使用软件:Visual Studio Code Python版本:python 3.12.4 技术需求:scrapy、…...

unity学习25:用 transform 进行旋转和移动,简单的太阳地球月亮模型,以及父子级关系

目录 备注内容 1游戏物体的父子级关系 1.1 父子物体 1.2 坐标关系 1.3 父子物体实际是用 每个gameobject的tranform来关联的 2 获取gameObject的静态数据 2.1 具体命令 2.2 具体代码 2.3 输出结果 3 获取gameObject 的方向 3.1 游戏里默认的3个方向 3.2 获取方向代…...

【项目集成Husky】

项目集成Husky 安装初始化 Husky在.husky → pre-commit文件中添加想要执行的命令 安装 使用 Husky 可以帮助你在 Git 钩子中运行脚本&#xff0c;例如在提交代码前运行测试或格式化代码pnpm add --save-dev husky初始化 Husky npx husky init这会在项目根目录下创建一个 .hu…...

基于Spring Security 6的OAuth2 系列之七 - 授权服务器--自定义数据库客户端信息

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)

1. 简介 柱状图作为科研论文中常用的实验结果对比图&#xff0c;本文采用了3组实验对比的效果展示图&#xff0c;代码已调试好&#xff0c;只需替换数据即可生成相关柱状图&#xff0c;为科研加分。通过获得Nature配色的柱状图&#xff0c;让你的论文看起来档次更高&#xff0…...

Java 大视界 -- Java 大数据在生物信息学中的应用与挑战(67)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

.NET Core 中依赖注入的使用

ASP.NET Core中服务注入的地方 在ASP.NET Core项目中一般不需要自己创建ServiceCollection、IServiceProvider。在Program.cs的builder.Build()之前向builder.Services中注入。在Controller中可以通过构造方法注入服务。 低使用频率的服务 把Action用到的服务通过Action的参…...

deepseek 潜在变量Z的计算;变分自编码器(VAE); 高斯混合模型(GMM)

潜在注意力:潜在变量 Z Z Z的计算 潜在变量 Z Z Z...

rsync安装与使用-linux015

使用 rsync 可以非常高效地将文件或目录从一个服务器传输到另一个服务器。 能力&#xff1a; 支持 64 位文件、64 位 inode、64 位时间戳、64 位长整型支持套接字对、符号链接、符号链接时间、硬链接、硬链接特殊文件、硬链接符号链接支持 IPv6、访问时间&#xff08;atimes&…...

CAP 定理的 P 是什么

分布式系统 CAP 定理 P 代表什么含义 作者之前在看 CAP 定理时抱有很大的疑惑&#xff0c;CAP 定理的定义是指在分布式系统中三者只能满足其二&#xff0c;也就是存在分布式 CA 系统的。作者在网络上查阅了很多关于 CAP 文章&#xff0c;虽然这些文章对于 P 的解释五花八门&am…...

【multi-agent-system】ubuntu24.04 安装uv python包管理器及安装依赖

uv包管理器是跨平台的 参考sudo apt-get update sudo apt-get install -y build-essential我的开发环境是ubuntu24.04 (base) root@k8s-master-pfsrv:/home/zhangbin/perfwork/01_ai/08_multi-agent-system# uv venv 找不到命令 “uv”,但可以通过以下软件...

JavaScript原型链与继承:优化与扩展的深度探索

在 JavaScript 的世界里&#xff0c;万物皆对象&#xff0c;而每个对象都有一个与之关联的原型对象&#xff0c;这就构成了原型链的基础。原型链&#xff0c;简单来说&#xff0c;是一个由对象的原型相互连接形成的链式结构 。每个对象都有一个内部属性[[Prototype]]&#xff0…...