从奶牛NPC到完整场景构建

Godot 4教程:打造生动2D游戏世界------从奶牛NPC到完整场景构建

学习视频:https://player.bilibili.com/player.html?bvid=BV1NC4y1q7bZ\&autoplay=0

资源下载:https://cupnooble.itch.io/sprout-lands-asset-pack

https://www.patreon.com/posts/scripts-godot-4-68719570

原视频地址:https://www.youtube.com/watch?v=Luf2Kr5s3BM

🎮 项目概览

在上一篇教程中,我们已经实现了玩家的移动、动画和基础碰撞检测。现在,我们将继续丰富游戏世界,添加随机移动的奶牛NPC可交互的静态物体 ,以及使用多层瓦片地图构建复杂场景,最终完成一个完整的2D游戏原型。


🐄 第一部分:创建随机移动的奶牛NPC

状态管理与动画系统

奶牛NPC使用**枚举类型(enum)**来管理两种状态:

  • Idle:闲置状态
  • Walk:行走状态

通过**动画树(AnimationTree)动画播放器(AnimationPlayer)**配合,我们可以控制奶牛在不同方向的行走与闲置动画。

gdscript 复制代码
enum CowState { IDLE, WALK }
var current_state = CowState.IDLE

随机方向移动算法

奶牛在行走时会随机选择8个方向之一进行移动:

gdscript 复制代码
func select_new_direction():
    var move_direction = Vector2(
        randi_range(-1, 1),
        randi_range(-1, 1)
    ).normalized()
    return move_direction

定时状态切换机制

通过Timer节点控制状态切换时间:

gdscript 复制代码
@export var idle_time: float = 5.0
@export var walk_time: float = 2.0

func change_state(new_state):
    current_state = new_state
    if current_state == CowState.WALK:
        $Timer.start(walk_time)
        select_new_direction()
    else:
        $Timer.start(idle_time)

碰撞与渲染层级

  1. 添加CollisionShape2D使奶牛能与玩家和其他物体碰撞
  2. 启用**Y排序(Y-sorting)**确保垂直位置上的正确显示顺序
  3. 设置精灵翻转,使奶牛朝移动方向正确显示
gdscript 复制代码
if move_direction.x < 0:
    $Sprite2D.flip_h = true
elif move_direction.x > 0:
    $Sprite2D.flip_h = false

gdscript 复制代码
extends CharacterBody2D

enum COW_STATE{ IDLE, WALK }
@export var move_speed : float = 10
@export var idle_time : float = 5
@export var walk_time : float = 2

@onready var animation_tree = $AnimationTree
@onready var state_machine = animation_tree.get("parameters/playback")
@onready var sprint2d = $Sprite2D
@onready var timer = $Timer

var move_direction : Vector2 = Vector2.ZERO
var current_state: COW_STATE = COW_STATE.IDLE

func _ready() -> void:
	
	pick_new_state()
	
func _physics_process(delta: float) -> void:
	if(current_state == COW_STATE.WALK):
		velocity = move_direction * move_speed
		move_and_slide()

func select_direction() -> void:
	move_direction = Vector2(
		randi_range(-1, 1),
		randi_range(-1, 1)
	)
	
	if(move_direction.x < 0):
		sprint2d.flip_h = true
	elif(move_direction.x > 0):
		sprint2d.flip_h = false
	

func pick_new_state() -> void:
	if(current_state == COW_STATE.IDLE):
		state_machine.travel("Walk_right")
		current_state = COW_STATE.WALK
		select_direction()
		timer.start(walk_time)
	else:
		state_machine.travel("Idle_right")
		current_state = COW_STATE.IDLE
		select_direction()
		timer.start(idle_time)

func _on_timer_timeout() -> void:
	pick_new_state()

🧱 第二部分:添加静态与可交互物体

宝箱(Chest)的实现

  1. 创建宝箱场景

    • 添加Sprite2D显示宝箱外观
    • 使用StaticBody2DCollisionShape2D实现碰撞
  2. 快速实例化

    • 将宝箱保存为独立场景(.tscn文件)
    • 在游戏场景中拖拽实例化多个宝箱
  3. 碰撞形状调整

    • 使用矩形碰撞形状
    • 调整大小以匹配精灵外观

床铺(Bed)的制作技巧

  1. 精灵区域裁剪

    • 使用Region功能从精灵图中提取单个家具
    • 启用网格吸附(16×16像素)精准选择区域
  2. 精细化碰撞设计

    • 根据家具的实际形状调整碰撞区域
    • 如床铺只阻挡底部,顶部留空增加真实感
  3. 场景实例化技巧

    • 确保主节点位置归零,避免实例化时位置偏移
    • 使用场景复制功能快速创建变体


🏡 第三部分:多层瓦片地图构建复杂场景

图层系统管理

创建多个瓦片图层实现视觉层级分离:

yaml 复制代码
图层结构:
- base_ground (Z-index: -5):基础地面
- top_ground (Z-index: -5):上层地面装饰
- high_ground_walls (Z-index: 0):高墙和障碍
- roof (Z-index: 5):屋顶(在最上层)

自定义碰撞形状

  1. 为瓦片添加碰撞

    • 在瓦片集中选择"物理层"设置
    • 为每个需要碰撞的瓦片绘制多边形碰撞形状
  2. 精确碰撞调整

    • 使用顶点编辑工具微调碰撞形状
    • 确保相邻瓦片的碰撞边界无缝连接
    • 避免玩家被"隐形墙"卡住的问题

房屋建造实战示例

开始建造房屋
基础地面层
墙壁层
门窗装饰
屋顶层
碰撞设置
完成房屋

  1. 多层组合建造

    • 底层:基础地面瓦片
    • 中层:墙壁和门窗
    • 顶层:屋顶瓦片
  2. 快速复制技巧

    • 使用Ctrl+C/Ctrl+V复制选中的瓦片区块
    • 在不同位置粘贴创建相同结构的建筑
    • 分别调整各图层的瓦片以创建变体
  3. 碰撞优化

    • 只为墙壁和障碍物添加碰撞
    • 屋顶和装饰物不设碰撞,允许玩家"走过"下方
    • 使用多层碰撞实现"高低地形"效果


🎥 第四部分:相机系统与游戏体验优化

跟随相机实现

  1. 基础相机设置

    gdscript 复制代码
    # 添加Camera2D节点
    $Camera2D.current = true
  2. 平滑跟随

    • 添加RemoteTransform2D节点到玩家
    • 将相机目标指向该远程变换节点
    • 启用平滑选项(像素游戏建议关闭避免抖动)

世界构建与氛围营造

  1. 边界定义

    • 使用围栏瓦片创建游戏区域边界
    • 为边界添加碰撞防止玩家走出地图
  2. 随机散布系统

    • 使用"散布"工具随机放置装饰物
    • 调整散布密度创建自然的环境效果
  3. 视觉层次优化

    • 确保所有游戏对象正确使用Y排序
    • 调整Z-index控制渲染顺序
    • 使用图层透明度创建深度效果

🏁 第五部分:项目总结与扩展方向

已完成功能清单

核心系统

  • 玩家角色移动与八方向动画
  • 物理碰撞检测与响应
  • 状态机驱动的动画系统

游戏世界

  • 多层瓦片地图系统
  • 随机移动的NPC(奶牛)
  • 可交互的静态物体
  • 复杂建筑结构

用户体验

  • 跟随相机系统
  • 正确的渲染层级管理
  • 像素完美的显示效果

🚀 下一步扩展建议

1. 游戏机制扩展
  • 敌人AI系统:添加巡逻、追逐、攻击行为的敌人
  • 物品交互:拾取物品、背包系统、物品使用
  • 任务系统:NPC对话、任务接取与完成
2. 场景与关卡
  • 室内外切换:可进入的房屋与场景过渡
  • 多关卡系统:不同主题的游戏区域
  • 动态环境:昼夜循环、天气系统
3. 视听体验提升
  • 音效系统:脚步声、环境音、交互音效
  • 背景音乐:动态音乐切换
  • 视觉特效:粒子系统、光影效果
4. 发布与优化
  • 性能优化:对象池、纹理集、代码优化
  • 多平台支持:PC、移动端、网页版导出
  • 游戏发布:Steam、itch.io等平台发布

📚 学习资源推荐

  1. 官方文档:Godot 4官方文档(最权威的学习资料)
  2. 社区资源
    • Godot官方论坛
    • Reddit的r/godot社区
    • Discord上的Godot开发者频道
  3. 进阶教程
    • 着色器编程
    • 网络多人游戏
    • 高级AI行为树

💡 开发者心得

通过这个项目,我们不仅学习了Godot 4的基本功能,更重要的是掌握了游戏开发的工作流程

  1. 从简单开始:先实现核心玩法,再逐步添加功能
  2. 模块化设计:将角色、NPC、物体设计为可重用的场景
  3. 迭代优化:不断测试和调整游戏体验
  4. 资源管理:合理组织项目文件夹结构和资源引用

记住:游戏开发是一个创造性的过程,不要害怕尝试新的想法。每个成功的游戏都是从简单的原型开始的。


🎬 视频教程信息

  • 教程作者:Chris
  • 视频时长:约1小时40分钟
  • 难度等级:初级到中级
  • 所需前置知识:基本编程概念,无Godot经验要求

如果你也想尝试用Godot 4制作自己的2D游戏,不妨从这个教程开始,一步步构建属于你的像素世界!

本教程基于Godot 4 Alpha版本,部分功能在正式版中可能有所变化,请以最新文档为准。

相关推荐
郝学胜-神的一滴3 天前
QtOpenGL多线程渲染方案深度解析
c++·qt·unity·游戏引擎·godot·图形渲染·unreal engine
习惯就好zz3 天前
地图编辑部分教程总结
godot·camera·tilemap·2d·game·tileset
我的golang之路果然有问题4 天前
unity 资源导入 godot
unity·游戏引擎·godot
习惯就好zz5 天前
Godot Player CharacterBody2D 移动和停止配置
游戏引擎·godot·characterbody2d·animationplayer·animationtree
郝学胜-神的一滴8 天前
深入解析Mipmap层级判定原理:从理论到实践
c++·unity·godot·游戏程序·图形渲染·unreal engine
Mars-xq9 天前
godot 毛玻璃效果着色器shader
游戏引擎·godot·着色器
一个笔记本13 天前
godot log | 修改main scene
游戏引擎·godot
技术小甜甜14 天前
【Godot】【入门】信号系统从 0 到 1(UI/玩法彻底解耦的通用写法)
ui·游戏引擎·godot
Mars-xq14 天前
Android godot 交互数据监听
android·godot·交互