Godot Zelda教程练习1

提示:B站链接:Godot Zelda教程练习
资产链接:项目资产
Godot版本:4.3

文章目录

  • 一、新建项目
    • 1、创建项目
    • 2、设置项目标签
    • 3、项目基本设置
    • 4、导入资产
  • 二、图块集和自动平铺
    • 1、创建TileMapLayer
    • 2、创建Terrian Set
      • 1、Match Siders(边缘匹配)
      • 2、Match Corners(角落匹配)
      • 3、Match Corners and Siders(角落匹配和边缘匹配)
      • 4、图块概率设置
  • 三、水的瓦片集(water TileSet)
    • 1、加入TileSetWater.png图块
    • 2、创建WaterLightGrass
    • 3、创建Water的瓦片
  • 四、桥梁的瓦片集(Bridge TileSet)
  • 五、雪、高山以及楼梯
    • 1、添加瓦片集
    • 2、添加地形元素
  • 六、简单关卡和装饰
    • 1、绘制草
    • 2、添加水
    • 3、移动桥
    • 4、其它装饰
    • 5、添加TilesetNature装饰
  • 七、基本角色移动
    • 1、新建场景
    • 2、创建动画
      • 1、定义其他帧
      • 2、创建Camera2D
      • 3、角色移动
  • 八、添加碰撞以及移动动画
    • 1、添加碰撞
      • 1、为water设置碰撞
      • 2、为桥设置碰撞
      • 3、为楼梯设置碰撞器
      • 4、为其他装饰物设置碰撞器
    • 2、移动动画
  • 九、添加碰撞 - 拾取物品和库存物品
    • 1、新建文件夹Resources
    • 2、新建资源文件gold_coin.tres
    • 3、编写inventory_item.gd
    • 4、新建PickUpItem场景
    • 5、设置金币和玩家碰撞
    • 6、为PickUpItem创建脚本
    • 7、实例化子场景
  • 十、库存槽


一、新建项目

1、创建项目

项目名称:ZeldaCourse
点击创建并编辑即可。
在这里插入图片描述

2、设置项目标签

可以为项目设置标签,便于管理
在这里插入图片描述

3、项目基本设置

设置默认纹理过滤为Linear
可以为项目设置标签,便于管理

4、导入资产

新建Assets文件夹,将资产解压导入到该文件夹中。

二、图块集和自动平铺

1、创建TileMapLayer

  1. 创建Scenes文件夹,并且创建一个node空节点,命名为main,保存场景到Scenes文件夹。
  2. 为main节点创建一个child node,命名为TileLayers
  3. 为TileLayers创建一个TileMapLayers节点,取名为GroundTileLayer
  4. 为GroundTileLayer创建Tile Set
    步骤4
  5. 点击TileSet ,将res://Assets/Sprites/Backgrounds/Tilesets/TilesetFloor.png拖动到图快区域
    步骤5

2、创建Terrian Set

如下图,在GroundTileLayer节点上,创建Terrian Set,名称为LightGrass,Color为0cc214
在这里插入图片描述
完成地形集创建之后,需要在绘制中添加对应的图块。
在这里插入图片描述

1、Match Siders(边缘匹配)

在这里插入图片描述
模式选择Match Siders,然后我们选择两个图块,然后进入TileMap查看有两个图块。可以绘制。
在这里插入图片描述

2、Match Corners(角落匹配)

在这里插入图片描述
使用矩形绘制如下:
在这里插入图片描述
在这里插入图片描述
两个矩形叠加的时候,会出现如上图所示的凸出的部分,这是因为边缘和角落冲突了,所以我们修改模式为Match Corners and Siders

3、Match Corners and Siders(角落匹配和边缘匹配)

在这里插入图片描述
重新绘制之后如下图所示:
在这里插入图片描述

还是发现了一些其他的问题,如下:
在这里插入图片描述
我们再加上如下设置
在这里插入图片描述
修复角落:
在这里插入图片描述
我们最终的图块如下设置:
在这里插入图片描述
设置纹理渲染为Nearest

4、图块概率设置

选择这两个土块,绘制后,上面有路的纹理,现在我们不需要这两个图块的频率很大,可以设置概率。
在这里插入图片描述
在这里插入图片描述

现在很稀疏了
在这里插入图片描述

三、水的瓦片集(water TileSet)

1、加入TileSetWater.png图块

将TileSetWater.png加入到图块。

2、创建WaterLightGrass

颜色设置为3070c5
在这里插入图片描述

3、创建Water的瓦片

如下设置:
在这里插入图片描述
添加一些装饰,并且设置概率是0.1
在这里插入图片描述
在这里插入图片描述
绘制完成如下:
在这里插入图片描述

四、桥梁的瓦片集(Bridge TileSet)

在Terrian Sets添加Bridge地形,颜色设置为c05505
在这里插入图片描述
设置如下规则:
在这里插入图片描述
设置概率:
在这里插入图片描述

1、为TileLayers节点新建DecorationTileMapLayers节点(TileMapLayers)
2、将原来的TileSet另存为。保存的位置是res://TileSets,当然要新建TileSets文件夹,并且命名为tileset.tres
在这里插入图片描述
3、选择DecorationTileMapLayers节点,然后TileSet选择刚才保存的tileset.tres
在这里插入图片描述
4、绘制桥梁
在这里插入图片描述
在这里插入图片描述

五、雪、高山以及楼梯

1、添加瓦片集

将res://Assets/Sprites/Backgrounds/Tilesets/TilesetRelief.png添加到瓦片集中。
在这里插入图片描述

2、添加地形元素

设置地形元素名称为SnowRidge,颜色为5c544d
在这里插入图片描述
设置瓦片集
在这里插入图片描述
创建SnowRidgeWall地形元素,颜色设置为:5c544d。图块设置如下:
在这里插入图片描述
创建Staris地形元素,颜色设置为:c2008c。然后将res://Assets/Sprites/Backgrounds/Tilesets/TilesetHouse.png添加到TileSet中,图中存在楼梯。
在这里插入图片描述

在GroundTileLayer绘制SnowRidgeWall和SnowRidge,在DecorationTileMapLayers绘制Stairs
在这里插入图片描述
在这里插入图片描述
效果如下:
在这里插入图片描述

六、简单关卡和装饰

1、绘制草

按照如下步骤绘制:
在这里插入图片描述
然后再使用LightGrass地形修正:
在这里插入图片描述

2、添加水

在这里插入图片描述

3、移动桥

选择图块,选择桥,然后就可以移动。
在这里插入图片描述

4、其它装饰

添加这个墩子
在这里插入图片描述
上述绘制完成之后,在图案选择这个墩子,直接移动到图案中,后续使用。
在这里插入图片描述
还有一个洞穴的方式同样如此操作。
在这里插入图片描述

5、添加TilesetNature装饰

res://Assets/Sprites/Backgrounds/Tilesets/TilesetNature.png,将这个图块加入进来。
选择图块->选择照片->TileMap->选择树木->选择绘制
在这里插入图片描述
同样拖到图案中。
最后绘制如下:
在这里插入图片描述

七、基本角色移动

1、新建场景

1、创建CharacterBody2D节点
2、添加子节点AnimatedSprite2D
在这里插入图片描述

2、创建动画

选择AnimatedSprite2D节点,在检查器中新建Sprites Frames,然后选择这里

在这里插入图片描述
在这里插入图片描述
选择:res://Assets/Sprites/Actor/Characters/FighterWhite,然后打开SpriteSheet.png

在这里插入图片描述
设置垂直为7,和图片匹配
在这里插入图片描述
选择第一幅,添加帧
在这里插入图片描述
创建节点CollisionShape2D,作为CharacterBody2D的子节点。
设置碰撞器的形状为原型,半径为7,然后调整碰撞器,保存场景为player.tscn
在这里插入图片描述
修改名称为font_idle,然后点击自动播放。
在这里插入图片描述
切换到main场景
在这里插入图片描述
实例化子场景
在这里插入图片描述
在这里插入图片描述

1、定义其他帧

分别是back_idle、left_idle、right_idle
在这里插入图片描述

2、创建Camera2D

在这里插入图片描述
设置Zoom为3
在这里插入图片描述

3、角色移动

1、切换到main场景
2、打开项目设置
3、选择输入映射
在这里插入图片描述
在后面的+号绑定键盘
在这里插入图片描述
修改节点名称为Player
在这里插入图片描述
Player节点添加脚本:保存到res下面的Scripts文件夹(需要创建),名称为player.gd
在这里插入图片描述
脚本如下:

extends CharacterBody2Dconst SPEED = 5000.0func _physics_process(delta: float) -> void:#获取向量var direction=Input.get_vector("left","right","up","down")if direction :velocity=direction * SPEED * delta;else :# float move_toward(from: float, to: float, delta: float)# 将 from 向 to 移动,移动的长度是 delta。不会超过 to。velocity.x= move_toward(velocity.x, 0, SPEED * delta)velocity.y= move_toward(velocity.y, 0, SPEED * delta)# 根据velocity速度移动该物体move_and_slide()

八、添加碰撞以及移动动画

1、添加碰撞

切换到main场景,在项目设置中,设置如下的Layer
在这里插入图片描述

1、为water设置碰撞

切换到Player场景,添加碰撞
在这里插入图片描述
为GroundTileLayer添加物理层碰撞
在这里插入图片描述
在这里插入图片描述
选择展开,栅格吸附为8
在这里插入图片描述
完成之后运行游戏,发现角色不能进入水的范围。
设置水的土块的物理层:
在这里插入图片描述
设置另外一块水的物理层:
在这里插入图片描述
带来了新的问题,角色无法跨越过桥
在这里插入图片描述
在选择中,对如下的两个图块添加备选图块
在这里插入图片描述
然后删除这些物理层:
在这里插入图片描述

将备选图块放入桥的边缘。
在这里插入图片描述
在这里插入图片描述

运行游戏,角色可以穿过桥了。
带来新的问题,角色可以从桥进入水中了。

2、为桥设置碰撞

为桥设置碰撞器,首先要点击TileSet才会出现物理层。
在这里插入图片描述

在这里插入图片描述
为桥设置栏杆物理层:
在这里插入图片描述
运行游戏,发现角色不能从桥进入水中,带来的新问题是:角色不能从桥的侧面上桥。
在这里插入图片描述
桥的六个图块添加备选
在这里插入图片描述
对桥的角落重新绘制即可。
在这里插入图片描述
此时运行游戏发现正常上桥。

3、为楼梯设置碰撞器

为了更加清晰的看到碰撞区域,我们在调试中勾选如下:
在这里插入图片描述
为楼梯设置物理层:
在这里插入图片描述
运行游戏,发现碰撞层生效,但是无法上楼梯:
在这里插入图片描述
操作方式还是创建备选图块,重新绘制楼梯口。
在这里插入图片描述

此时楼梯的栏杆失去了作用:
在这里插入图片描述
同理,加碰撞层。
在这里插入图片描述
优化下边缘:
在这里插入图片描述
发现楼梯那里有点缝隙,可以调整粉色框和格子纵向对齐:
在这里插入图片描述

4、为其他装饰物设置碰撞器

1、大树根
在这里插入图片描述
2、树块
在这里插入图片描述
还有装饰一些其他,不再赘述。
我设置的有问题,这些应该在物理层1中完成绘制。

2、移动动画

修改节点CharacterBody2D为Player
在这里插入图片描述
创建脚本:animation_controller.gd
在这里插入图片描述

extends AnimatedSprite2D
class_name AnimationControllerfunc _ready() -> void:pass func _process(delta: float) -> void:pass

然后打开play.gd

extends CharacterBody2Dclass_name Player#@onready 注解:确保变量在节点准备好后才被赋值。这意味着即使在 _ready() 函数之前调用这个变量,也不会导致 null 或未初始化的错误。
#变量类型:animated_sprite_2d 被声明为 AnimationPlayer 类型。这是 Godot 中用于播放动画的节点类型。但是,根据您的描述,
#  $AnimatedSprite2D 应该是一个 AnimatedSprite2D 节点,而不是 AnimationPlayer。因此,变量类型应该改为 AnimatedSprite2D。
#路径表达式:$AnimatedSprite2D 是一个路径表达式,表示从当前节点开始查找名为 AnimatedSprite2D 的子节点。@onready var animated_sprite_2d:AnimationController = $AnimatedSprite2Dconst SPEED = 5000.0func _physics_process(delta: float) -> void:#获取向量var direction=Input.get_vector("left","right","up","down")if direction :velocity=direction * SPEED * delta;else :# float move_toward(from: float, to: float, delta: float)# 将 from 向 to 移动,移动的长度是 delta。不会超过 to。velocity.x= move_toward(velocity.x, 0, SPEED * delta)velocity.y= move_toward(velocity.y, 0, SPEED * delta)# 根据velocity速度移动该物体move_and_slide()

1、新建动画,命名为front_walk,添加帧。
2、重复上述动作,新建其他的动画,加帧。
在这里插入图片描述
在这里插入图片描述
编写脚本animation_controller.gd

extends AnimatedSprite2Dclass_name AnimationControllerconst MOVEMENT_TO_IDLE={"back_walk" : "back_idle","front_walk" : "front_idle","right_walk" : "right_idle","left_walk" : "left_idle"
}func play_movement_animation(velovity:Vector2):if(velovity.x>0):play("right_walk")elif (velovity.x<0):play("left_walk")if(velovity.y>0):play("front_walk")elif (velovity.y<0):play("back_walk")func play_idle_animation():if MOVEMENT_TO_IDLE.keys().has(animation):play(MOVEMENT_TO_IDLE[animation])

编写play.gd

func _physics_process(delta: float) -> void:#获取向量var direction=Input.get_vector("left","right","up","down")if direction :velocity=direction * SPEED * delta;else :# float move_toward(from: float, to: float, delta: float)# 将 from 向 to 移动,移动的长度是 delta。不会超过 to。velocity.x= move_toward(velocity.x, 0, SPEED * delta)velocity.y= move_toward(velocity.y, 0, SPEED * delta)# 根据velocity速度移动该物体# 动画处理if velocity != Vector2.ZERO:animated_sprite_2d.play_movement_animation(velocity)else :animated_sprite_2d.play_idle_animation()move_and_slide()

运行游戏即可运动。

九、添加碰撞 - 拾取物品和库存物品

1、新建文件夹Resources

res://Resources/
在这里插入图片描述

2、新建资源文件gold_coin.tres

在这里插入图片描述

在这里插入图片描述

3、编写inventory_item.gd

创建脚本:res://Scripts/inventory_item.gd

inventory_item.gd

extends Resourceclass_name InventoryItemvar stacks=1@export_enum("Right_Hand","Left_Hand","Potions","NotEquipable")
var slot_type:String="NotEquipable"@export var ground_collision_shape:RectangleShape2D
@export var name:String=""
@export var texture:Texture2D
@export var side_texture:Texture2D
@export var max_stacks:int
@export var price:int

然后gold_coin.tres快速加载这个脚本:
在这里插入图片描述

4、新建PickUpItem场景

新建场景,类型为Area2D,
重命名为PickUpItem,保存为:
pickup_item.tscn
为PickUpItem新建如下的两个子节点:
在这里插入图片描述
选择Sprite2D节点,设置金币纹理:
把res://Assets/Sprites/Items/Treasure/GoldCoin.png图片托入进去。
在这里插入图片描述
选择CollisionShape2D节点,然后选择新建RectangleShape2D
在这里插入图片描述
设置碰撞如下:
在这里插入图片描述

然后如下:
在这里插入图片描述
保存到res://Resources/GoldCoin/目录下,GoldCoin需要新建。名称为:gold_coin_clollision_shape.tres。并且把gold_coin.tres移动到该文件夹下。

为gold_coin.tres设置属性:

在这里插入图片描述

5、设置金币和玩家碰撞

在项目设置中设置2D物理:
在这里插入图片描述
设置碰撞:
在这里插入图片描述

6、为PickUpItem创建脚本

名称为pickup_item.gd
在这里插入图片描述
编写代码:

extends Area2Dclass_name PickUpItem
@export var inventory_item:InventoryItemfunc _ready() -> void:$Sprite2D.texture=inventory_item.texture$CollisionShape2D.shape=inventory_item.ground_collision_shape

7、实例化子场景

在这里插入图片描述
加载资源:
在这里插入图片描述
跳转到Player场景,新建Area2D节点,为其创建子节点CollisionShape2D:
在这里插入图片描述

然后选择图中的节点,另存为资源res://Resources/Player/player_collision_shape.tres
Player文件夹需要新建。
在这里插入图片描述
在节点CollisionShape2D中加载保存的资源:
在这里插入图片描述

调整碰撞:
在这里插入图片描述

选择第一个函数,右键连接:
在这里插入图片描述
在这里插入图片描述

函数编写:

func _on_area_2d_area_entered(area: Area2D) -> void:if area is PickUpItem:area.queue_free()

Player:碰撞设置如下:
在这里插入图片描述
Area2D如下:
在这里插入图片描述
运行游戏可以见到金币。

十、库存槽

1、新建场景VBoxContainer
2、在Scenes新建UI文件夹
3、保存场景:res://Scenes/UI/inventory_slot.tscn
4、在VBoxContainer新建子节点NinePatchRect
5、将FacesetBox.png拖入到NinePatchRect的纹理中
在这里插入图片描述
6、为NinePatchRect的Layout设置尺寸为60
在这里插入图片描述
7、为NinePatchRect新建子节点MenuButton,并且锚点预设为整个矩形。

在这里插入图片描述
8、为MenuButton新建子节点CenterContainer,并且锚点预设为整个矩形。
9、为CenterContainer新建子节点TextureRect
10、为TextureRect设置属性
在这里插入图片描述
11、在NinePatchRect节点下新建子节点Button,命名为OnClickButton
在这里插入图片描述
12 、为OnClickButton设置属性:
在这里插入图片描述
13、为NinePatchRect节点新建Label标签节点,拖到如下位置:
在这里插入图片描述
在这里插入图片描述
重命名Label为StacksLabel
14、VBoxContainer节点新建子节点Label,命名为NameLabel
15、VBoxContainer节点新建子节点Label,命名为PriceLabel,并且隐藏
在这里插入图片描述
16、重命名VBoxContainer为InventorySlot
17、新建脚本inventory_slot.gd

extends VBoxContainerclass_name InventorySlotvar is_empty=true
var is_selected=false@export var single_button_press=false
@export var starting_texture:Texture
@export var start_label:String@onready  var texture_rect:TextureRect= $NinePatchRect/MenuButton/CenterContainer
@onready  var name_label:Label= $NameLabel
@onready  var stacks_label:Label= $NinePatchRect/StacksLabel
@onready  var on_click_button:Button=$NinePatchRect/OnClickButton
@onready  var price_label:Label=$PriceLabel
@onready  var menu_button:MenuButton=$NinePatchRect/MenuButtonvar slot_to_equip="NotEquipable"func _ready() -> void:if starting_texture!=null:texture_rect.texture=starting_textureif start_label!=null:name_label.text=start_labelmenu_button.disabled=single_button_presson_click_button.disabled=!single_button_presson_click_button.visible=single_button_pressvar popup_menu=menu_button.get_popup()popup_menu.id_pressed.connect(on_popup_menu_item_pressed)func on_popup_menu_item_pressed(id:int):print_debug(id)

为MenuButton设置属性
在这里插入图片描述

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

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

相关文章

【案例】旗帜飘动

开发平台&#xff1a;Unity 6.0 开发工具&#xff1a;Shader Graph 参考视频&#xff1a;Unity Shader Graph 旗帜飘动特效   一、效果图 二、Shader Graph 路线图 三、案例分析 核心思路&#xff1a;顶点偏移计算 与 顶点偏移忽略 3.1 纹理偏移 视觉上让旗帜保持动态飘动&a…

Android亮屏Job的功耗优化方案

摘要: Job运行时会带来持锁的现象,目前灭屏放电Job的锁托管已经有doze和绿盟标准监管,但是亮屏时仍旧存在过长的持锁现象,故为了优化功耗和不影响用户体验下,新增亮屏放电下如果满足冻结和已运行过一次Job,则进行job限制,当非冻结时恢复的策略 1.现象: (gms_schedu…

Java面试经典 150 题.P55. 跳跃游戏(009)

本题来自&#xff1a;力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解&#xff1a; class Solution {public boolean canJump(int[] nums) {int…

源码解析篇 | YOLO11:计算机视觉领域的新突破 !对比YOLOv8如何 ?

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。在2024年9月27日盛大举行的YOLO Vision 2024活动上&#xff0c;Ultralytics公司震撼发布了YOLO系列的最新成员—YOLO11。作为Ultralytics YOLO系列实时目标检测器的最新迭代&#xff0c;YOLO11凭借尖端的准确性、速度和效率…

mac m1 docker本地部署canal 监听mysql的binglog日志

mac m1 docker本地部署canal监听mysql的binglog日志(虚拟机同理) 根据黑马视频部署 1.docker 部署mysql 1.docker拉取mysql 镜像 因为m1是arm架构.需要多加一条信息 正常拉取 docker pull mysql:tagm1拉取 5.7的版本. tag需要自己指定版本 docker pull --platform linux/x…

复现LLM:带你从零训练tokenizer

1. 引言 分词器是每个大语言模型必不可少的组件&#xff0c;但每个大语言模型的分词器几乎都不相同。如果要训练自己的分词器&#xff0c;可以使用huggingface的tokenizers框架&#xff0c;tokenizers包含以下主要组件&#xff1a; Tokenizer: 分词器的核心组件&#xff0c;定…

Nginx防盗链配置

1. 什么是盗链? 盗链是指服务提供商自己不提供服务的内容&#xff0c;通过技术手段绕过其它有利益的最终用户界面&#xff08;如广告&#xff09;&#xff0c;直接在自己的网站上向最终用户提供其它服务提供商的服务内容&#xff0c;骗取最终用户的浏览和点击率。受益者不提供…

DAY53|| 42. 接雨水|84.柱状图中最大的矩形

42. 接雨水(超经典款&#xff09; 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2…

字节跳动(抖音)软件测试月薪23K岗、技术二面面试题最新出炉

测试人员在测试中的任务是什么&#xff1f; ① 尽可能早地找出系统中的bug&#xff1b; ② 避免软件开发过程中缺陷的出现&#xff1b; ③ 协助开发定位bug.以及后续bug跟踪 ④ 一切以用户的需求为标准&#xff0c;确保软件的质量 HTTP与HTTPS协议的区别&#xff1f; …

新160个crackme - 091-DOSKEY-CRACKME2

运行分析 需破解Name和Password PE分析 upx壳&#xff0c;32位 手动脱壳 x32dbg打开程序&#xff0c;按一下F8&#xff0c;根据ESP定律&#xff0c;在此处下断点按一下F9&#xff0c;两下F8&#xff0c;来到OEP处00401000打开Scylla&#xff0c;点击转储保存文件点击IAT自动搜索…

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

ClickHouse安装

一&#xff0c;ClickHouse介绍 ClickHouse 是一个开源的列式数据库管理系统&#xff08;Column-Oriented DBMS&#xff09;&#xff0c;由俄罗斯的 Yandex 公司开发。它最初是为 Yandex 的 Metrica 分析服务设计的&#xff0c;用于处理大规模的数据分析任务。ClickHouse 能够提…

网络设置:静态IP与动态IP,何去何从?

在配置网络设备时&#xff0c;一个基础而重要的选择便是决定使用静态IP地址还是动态IP地址。这一决策直接影响到网络的连接性、管理便捷性以及安全性。静态IP与动态IP各有其独特的优势与适用场景&#xff0c;选择何种方式&#xff0c;需根据实际需求与网络环境来权衡。本文旨在…

po、dto、vo的使用场景

现在项目中有两类模型类&#xff1a;DTO数据传输对象、PO持久化对象&#xff0c;DTO用于接口层向业务层之间传输数据&#xff0c;PO用于业务层与持久层之间传输数据&#xff0c;有些项目还会设置VO对象&#xff0c;VO对象用在前端与接口层之间传输数据&#xff0c;如下图&#…

不用买PSP,画质甚至更好,这款免费神器让你玩遍经典游戏

作为掌机游戏爱好者的福音&#xff0c;PPSSPP模拟器为玩家带来了前所未有的PSP游戏体验&#xff0c;彻底改变了掌机游戏的体验方式。这款精湛的软件不仅完美复刻了PSP主机的游戏体验&#xff0c;更通过先进的模拟技术&#xff0c;将经典游戏提升到了全新的高度。对于那些珍藏PS…

如何新建CANoe工程

本文将从启动CANoe软件开始&#xff0c;一步步引导您完成新工程的创建与基本配置&#xff0c;确保您的仿真测试工作能够顺利进行。 启动CANoe软件&#xff1a;打开CANoe软件&#xff0c;进入主界面。 新建工程&#xff1a;点击菜单栏的 File --> New --> CAN FD&#x…

Facebook群控策略详解

Facebook群控早在前几年就很火爆了&#xff0c;对于做Facebook营销或者电商的跨境选手来说&#xff0c;这是个不错的提高效率扩大增长的办法。具体来说&#xff0c;Facebook群控是一种通过同时管理多个Facebook账户进行自动化推广活动的方法&#xff0c;它可以实现自动发布帖子…

通讯概念-全双工、串行、同步等

1.单工&#xff0c;半双工&#xff0c;双工概念 2.串行和并行&#xff1a; 并行多根数据总线同时传输&#xff0c;需要考虑波特率情况&#xff0c;串行波特率可以很大&#xff0c;不需要考虑传输总线限制 3.同步和异步概念&#xff1a; 同步需要时钟同步&#xff0c;发送和接收…

经济下行,电商人效通过小程序快速实现多端引流

中国经济下行周期&#xff0c;消费者趋向于理性消费&#xff0c;更注重产品的实用性和性价比。中端商品的需求减少&#xff0c;低端消费人群的消费能力下降&#xff0c;导致“消费降级”现象明显。 许多线下实体店以及传统电商&#xff0c;仅仅依靠现在的模式&#xff0c;很难…

Fish Agent:集成 ASR 和 TTS 的端到端语音处理模型,支持多语言转换

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…