第四章:第一个项目

第四章:第一个项目

"千里之行,始于足下。最好的学习方式就是动手实践。"

在前面的章节中,我们了解了Godot的基础知识和编辑器界面。现在,是时候动手创建你的第一个Godot项目了!本章将带你完成一个简单但完整的2D游戏——让一个角色能够移动和跳跃。


4.1 项目规划

4.1.1 项目目标

我们将创建一个简单的2D平台游戏原型:

功能清单:

  • ✅ 可控制的玩家角色
  • ✅ 左右移动
  • ✅ 跳跃功能
  • ✅ 简单的平台地形
  • ✅ 重力效果

学习目标:

  • 创建和管理项目
  • 使用基本节点
  • 编写第一个GDScript脚本
  • 理解场景和节点的关系
  • 运行和测试项目

4.1.2 项目结构规划

MyFirstGame/
├── assets/
│   └── icon.svg          # 使用默认图标作为临时素材
├── scenes/
│   ├── main.tscn         # 主场景
│   └── player.tscn       # 玩家场景
├── scripts/
│   └── player.gd         # 玩家脚本
└── project.godot

4.2 创建项目

4.2.1 新建项目

  1. 启动Godot,在项目管理器中点击"新建"
  1. 填写项目信息:

- 项目名称:MyFirstGame - 项目路径:选择一个合适的位置 - 渲染器:选择 Mobile(适合2D游戏)

  1. 点击"创建并编辑"

4.2.2 项目设置

进入编辑器后,让我们做一些基本设置:

设置窗口大小:

  1. 菜单:项目 → 项目设置
  2. 搜索"window"
  3. 找到 Display → Window
  4. 设置:

- Viewport Width: 1280 - Viewport Height: 720 - Mode: Windowed

设置背景色:

  1. 在项目设置中搜索"clear color"
  2. 找到 Rendering → Environment → Default Clear Color
  3. 设置为浅蓝色:#87CEEB

点击"关闭"保存设置。


4.3 创建场景结构

4.3.1 创建主场景

  1. 创建根节点

- 在场景面板点击"其他节点" - 搜索并选择 Node2D - 重命名为 Main

  1. 保存场景

- 按 Ctrl+S - 创建文件夹 scenes - 保存为 scenes/main.tscn

  1. 设置为主场景

- 项目 → 项目设置 → Application → Run - Main Scene: 选择 res://scenes/main.tscn

4.3.2 创建玩家场景

创建一个可复用的玩家场景:

  1. 新建场景

- 菜单:场景 → 新建场景 - 选择"其他节点"

  1. 添加根节点

- 搜索 CharacterBody2D - 创建并重命名为 Player

  1. 添加子节点

Ctrl+A 添加以下子节点:

`` Player (CharacterBody2D) ├── Sprite2D # 显示玩家图像 └── CollisionShape2D # 碰撞形状 ``

  1. 配置Sprite2D

- 选中 Sprite2D - 在检查器中,将 Texture 设置为项目中的 icon.svg - 设置 Scale: (0.5, 0.5)(缩小图标)

  1. 配置CollisionShape2D

- 选中 CollisionShape2D - 在检查器中,点击 Shape 旁边的 [空] - 选择"新建 RectangleShape2D" - 点击创建的形状,设置 Size: (64, 64)

  1. 保存场景

- 按 Ctrl+S - 保存为 scenes/player.tscn

4.3.3 组装主场景

  1. 切换到主场景

- 双击场景标签中的 main.tscn

  1. 实例化玩家

- 方法1:从文件系统拖动 player.tscn 到场景树 - 方法2:点击场景面板的"实例化子场景"按钮

  1. 设置玩家位置

- 选中 Player 节点 - 在检查器中设置 Position: (640, 300)

  1. 创建地面

- 在 Main 下添加 StaticBody2D,重命名为 Ground - 在 Ground 下添加 CollisionShape2D - 设置 Shape 为 RectangleShape2D,Size: (1280, 50) - 在 Ground 下添加 ColorRect(用于显示地面) - 设置 ColorRect 的 Size: (1280, 50),Color: #8B4513(棕色) - 设置 Ground 的 Position: (640, 680)

最终的场景结构:

Main (Node2D)
├── Player (player.tscn实例)
└── Ground (StaticBody2D)
    ├── CollisionShape2D
    └── ColorRect

4.4 编写玩家脚本

现在来编写控制玩家移动的脚本。

4.4.1 创建脚本

  1. 双击打开 player.tscn
  1. 附加脚本

- 选中 Player 节点 - 点击场景面板上方的"附加脚本"按钮(📜) - 或右键 → 附加脚本

  1. 设置脚本

- 语言:GDScript - 继承:CharacterBody2D - 路径:res://scripts/player.gd - 点击"创建"

4.4.2 理解脚本模板

Godot自动生成的模板:

extends CharacterBody2D

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

func _physics_process(delta: float) -> void:
    # 添加重力
    if not is_on_floor():
        velocity += get_gravity() * delta

    # 处理跳跃
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # 获取输入方向
    var direction := Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)

    move_and_slide()

代码解析:

代码说明
extends CharacterBody2D继承自CharacterBody2D
const SPEED = 300.0移动速度常量
const JUMP_VELOCITY = -400.0跳跃速度(负数向上)
physicsprocess(delta)物理帧回调,每物理帧执行
isonfloor()检测是否在地面上
get_gravity()获取项目设置的重力
velocityCharacterBody2D的内置速度属性
Input.isactionjust_pressed()检测按键刚被按下
Input.get_axis()获取轴向输入(-1到1)
moveandslide()执行移动和碰撞检测

4.4.3 完善脚本

让我们添加一些改进:

extends CharacterBody2D

## 玩家移动速度
@export var speed: float = 300.0
## 跳跃力度
@export var jump_velocity: float = -400.0

func _physics_process(delta: float) -> void:
    # 应用重力
    if not is_on_floor():
        velocity += get_gravity() * delta

    # 处理跳跃(空格键或W键)
    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = jump_velocity
        print("跳跃!")

    # 获取水平输入
    var direction := Input.get_axis("ui_left", "ui_right")
    
    if direction != 0:
        velocity.x = direction * speed
    else:
        # 无输入时减速
        velocity.x = move_toward(velocity.x, 0, speed)

    # 执行移动
    move_and_slide()

func _ready() -> void:
    print("玩家已就绪!")

改进说明:

  • @export 使变量在检查器中可编辑
  • 添加了 print() 调试信息
  • 添加了注释说明

4.5 运行测试

4.5.1 首次运行

  1. 保存所有场景

- 按 Ctrl+Shift+S 保存所有

  1. 运行项目

- 按 F5 或点击右上角的▶按钮 - 首次运行会询问选择主场景,选择 main.tscn

  1. 测试操作

- 左右方向键:移动 - 空格键:跳跃

4.5.2 调试技巧

查看输出:

  • 底部面板 → 输出
  • 可以看到 print() 的输出

常见问题排查:

问题可能原因解决方案
玩家不移动脚本未附加检查脚本是否正确附加
玩家穿过地面碰撞层未设置确保都在同一碰撞层
玩家看不见Sprite未设置纹理检查Sprite2D的Texture
无法跳跃不在地面上检查碰撞形状是否接触

4.5.3 调整参数

在编辑器中调整:

由于我们使用了 @export,可以直接在检查器中调整参数:

  1. 选中 player.tscn 中的 Player 节点
  2. 在检查器中找到 "Player.gd" 部分
  3. 调整 SpeedJump Velocity
  4. 运行测试效果

4.6 项目导出

虽然这只是一个简单的原型,但让我们学习如何导出项目。

4.6.1 导出预设

  1. 打开导出设置

- 菜单:项目 → 导出

  1. 添加导出预设

- 点击"添加..." - 选择目标平台(如 Windows Desktop)

  1. 下载导出模板

- 如果提示缺少导出模板 - 点击"管理导出模板" - 下载当前版本的模板

4.6.2 导出设置

Windows导出设置:

设置说明
Export Path导出路径和文件名
Architecture选择x86_64
Embed PCK嵌入资源包到exe

4.6.3 执行导出

  1. 设置导出路径(如 builds/MyFirstGame.exe
  2. 点击"导出项目"
  3. 在导出文件夹中找到生成的文件
  4. 双击运行测试

4.7 扩展练习

完成基础项目后,尝试以下扩展练习来巩固学习:

练习1:添加更多平台

提示:
1. 复制Ground节点
2. 调整位置和大小
3. 创建阶梯状布局

练习2:添加双段跳

# 在脚本中添加:
@export var max_jumps: int = 2
var jump_count: int = 0

func _physics_process(delta: float) -> void:
    if not is_on_floor():
        velocity += get_gravity() * delta
    else:
        jump_count = 0  # 落地时重置跳跃次数
    
    # 修改跳跃逻辑
    if Input.is_action_just_pressed("ui_accept") and jump_count < max_jumps:
        velocity.y = jump_velocity
        jump_count += 1
    
    # ... 其余代码不变

练习3:添加边界限制

# 在_physics_process末尾添加:
func _physics_process(delta: float) -> void:
    # ... 现有代码 ...
    
    move_and_slide()
    
    # 限制玩家不超出屏幕
    position.x = clamp(position.x, 0, 1280)
    
    # 掉出屏幕重置位置
    if position.y > 800:
        position = Vector2(640, 300)

练习4:添加简单动画

步骤:
1. 将Sprite2D替换为AnimatedSprite2D
2. 创建SpriteFrames资源
3. 添加idle和run动画帧
4. 在脚本中根据移动状态播放动画

4.8 常见问题解答

Q1:为什么玩家会穿过地面?

可能原因:

  • CollisionShape2D没有正确设置形状
  • Player和Ground不在同一碰撞层
  • CollisionShape2D节点被禁用

解决方案:

  1. 检查两个CollisionShape2D都有有效的Shape
  2. 确保碰撞层和遮罩设置正确(默认Layer 1)
  3. 确保节点可见且启用

Q2:如何修改重力大小?

方法1:项目设置

  • 项目设置 → Physics → 2D → Default Gravity
  • 默认值是980

方法2:代码中覆盖

# 使用自定义重力
var custom_gravity: float = 1500.0

func _physics_process(delta: float) -> void:
    if not is_on_floor():
        velocity.y += custom_gravity * delta

Q3:如何让角色面向移动方向?

# 在处理移动的代码后添加:
if direction > 0:
    $Sprite2D.flip_h = false
elif direction < 0:
    $Sprite2D.flip_h = true

Q4:如何添加自定义输入映射?

if Input.is_action_just_pressed("jump"):
    # 跳跃逻辑

本章小结

恭喜!你已经完成了第一个Godot项目。在本章中,你学会了:

  1. 项目创建:新建项目、配置项目设置
  2. 场景管理:创建场景、保存场景、实例化场景
  3. 节点使用:CharacterBody2D、Sprite2D、CollisionShape2D、StaticBody2D
  4. 脚本编写:GDScript基础、物理处理、输入检测
  5. 调试测试:运行项目、查看输出、调整参数
  6. 项目导出:配置导出预设、生成可执行文件

这只是开始!接下来的章节将深入讲解GDScript编程语言,让你能够创建更复杂、更有趣的游戏。


第一部分总结

至此,我们完成了《Godot游戏开发权威指南》第一部分:入门基础。

学习回顾:

章节主要内容
前言学习游戏开发的意义、Godot的优势
第一章Godot概述、设计哲学、与其他引擎对比
第二章环境搭建、安装配置、开发工具
第三章编辑器界面、视口操作、面板功能
第四章第一个项目、场景节点、脚本编写

你已经掌握了:

  • ✅ Godot的核心概念:节点和场景
  • ✅ 编辑器的基本操作
  • ✅ 创建和管理项目
  • ✅ 编写简单的GDScript脚本
  • ✅ 运行和测试游戏

下一步:

第二部分将深入学习GDScript编程语言,包括:

  • 基础语法
  • 变量与数据类型
  • 控制流程
  • 函数与方法
  • 面向对象编程
  • 信号系统

准备好继续你的Godot学习之旅了吗?


上一章:用户界面详解

下一部分:GDScript编程

← 返回目录