Godot Engine SQLite 完整介绍与实例 – wiki词典

Godot Engine SQLite 完整介绍与实例

引言

在游戏开发中,数据存储是不可或缺的一部分。无论是保存玩家进度、管理物品库存、存储用户设置,还是处理动态任务数据,选择一个高效且易于集成的数据库解决方案都至关重要。对于Godot Engine项目而言,SQLite是一个极佳的选择。它是一个轻量级、无服务器、自包含且基于文件的关系型数据库管理系统,避免了独立数据库服务器的开销,非常适合本地数据存储需求。

本文将详细介绍如何在Godot Engine中集成和使用SQLite,包括插件安装、数据库连接、以及基本的CRUD(创建、读取、更新、删除)操作。

1. Godot-SQLite 插件设置

在Godot 4.x 项目中,推荐使用 godot-sqlite 插件来集成SQLite,该插件可在Godot资源库中找到。

安装步骤:

  1. 打开 Godot Engine: 启动您的Godot项目。
  2. 访问 AssetLib: 点击编辑器顶部的 “AssetLib” 标签。
  3. 搜索 “godot-sqlite”: 在搜索栏中输入 “godot-sqlite” 并从结果中选择该插件。
  4. 下载并安装: 点击 “Download”,下载完成后点击 “Install”。
  5. 激活插件: 进入 项目(Project) -> 项目设置(Project Settings) -> 插件(Plugins),确保 Godot-SQLite 插件已启用。

2. 核心概念与使用实例

安装并启用插件后,您可以使用GDScript与SQLite数据库进行交互。

2.1. 初始化和数据库连接

首先,您需要预加载SQLite类并创建一个实例。path 变量指定数据库文件的存储位置。如果数据库文件不存在,它将被创建。您可以将数据库存储在 res://(项目资源,导出后只读)或 user://(用户特定数据,可写入)目录。

“`gdscript
extends Node

const SQLite = preload(“res://addons/godot-sqlite/bin/gdsqlite.gdns”) # 插件 GDNative 脚本路径
var db: SQLite
var db_path: String = “user://game_data.db” # 数据库文件将存储在用户数据目录

func _ready():
db = SQLite.new()
db.path = db_path

if db.open_db() != OK:
    print("无法打开数据库: ", db.error_message)
    return
print("数据库成功打开。")

# 示例调用 (下文将定义)
create_player_table()
insert_player_data("Alice", 100)
insert_player_data("Bob", 150)
insert_player_data_with_bindings("Charlie", 200)
query_all_players()
update_player_score("Alice", 120)
query_player_by_name("Alice")
delete_player_data("Bob")
query_all_players()

db.close_db()
print("数据库已关闭。")

“`

2.2. 创建表

您可以使用 create_table() 方法或执行原始SQL CREATE TABLE 语句来创建表。create_table() 方法期望一个字典来定义表结构。

“`gdscript
func create_player_table():
var table_schema = {
“table_name”: “players”,
“columns”: [
{“name”: “id”, “type”: “INTEGER”, “primary_key”: true, “autoincrement”: true},
{“name”: “name”, “type”: “TEXT”, “not_null”: true},
{“name”: “score”, “type”: “INTEGER”, “default”: 0}
]
}

var result = db.create_table(table_schema)
if result != OK:
    print("无法创建表 'players': ", db.error_message)
else:
    print("表 'players' 已创建或已存在。")

# 或者,使用原始 SQL:
# var query = "CREATE TABLE IF NOT EXISTS highscores (id INTEGER PRIMARY KEY AUTOINCREMENT, player_name TEXT NOT NULL, score INTEGER DEFAULT 0);"
# var result_raw = db.query(query)
# if result_raw.size() == 0 and db.error_message != "":
#     print("无法使用原始SQL创建表 'highscores': ", db.error_message)
# else:
#     print("表 'highscores' 已创建或已存在 (原始SQL)。")

“`

2.3. 插入数据

您可以使用 insert_row() 进行简单的键值插入,或者使用 query_with_bindings() 进行更复杂或参数化的 INSERT 语句。使用绑定对于防止SQL注入至关重要。

“`gdscript
func insert_player_data(name: String, score: int):
var data = {
“name”: name,
“score”: score
}
var result = db.insert_row(“players”, data)
if result != OK:
print(“无法插入玩家数据: “, db.error_message)
else:
print(“已插入玩家: %s 成绩: %d” % [name, score])

func insert_player_data_with_bindings(name: String, score: int):
var query = “INSERT INTO players (name, score) VALUES (?, ?);”
var bindings = [name, score]
var result = db.query_with_bindings(query, bindings)
if result.size() == 0 and db.error_message != “”:
print(“无法通过绑定插入玩家数据: “, db.error_message)
else:
print(“已插入玩家 (通过绑定): %s 成绩: %d” % [name, score])
“`

2.4. 查询数据 (SELECT)

使用 query() 进行原始SQL查询,或使用 query_with_bindings() 进行参数化查询。结果是一个 Array,其中包含 Dictionaries,每个字典代表一行数据。

“`gdscript
func query_all_players():
var query = “SELECT id, name, score FROM players ORDER BY score DESC;”
var result = db.query(query)

if result.size() == 0 and db.error_message != "":
    print("无法查询所有玩家: ", db.error_message)
    return

print("--- 所有玩家 ---")
for row in result:
    print("ID: %d, 姓名: %s, 成绩: %d" % [row["id"], row["name"], row["score"]])
print("-------------------")

func query_player_by_name(name: String):
var query = “SELECT id, name, score FROM players WHERE name = ?;”
var bindings = [name]
var result = db.query_with_bindings(query, bindings)

if result.size() == 0 and db.error_message != "":
    print("无法按姓名查询玩家: ", db.error_message)
    return

if result.empty():
    print("未找到玩家 '%s'。" % name)
else:
    var player_data = result[0]
    print("找到玩家: ID: %d, 姓名: %s, 成绩: %d" % [player_data["id"], player_data["name"], player_data["score"]])

“`

2.5. 更新数据

使用 update_row()query_with_bindings()(用于 UPDATE 语句)来更新现有记录。

“`gdscript
func update_player_score(name: String, new_score: int):
var data_to_update = {
“score”: new_score
}
var where_clause = {
“name”: name
}
var result = db.update_row(“players”, data_to_update, where_clause)
if result != OK:
print(“无法更新玩家 ‘%s’ 的成绩: ” % name, db.error_message)
else:
print(“已将玩家 ‘%s’ 的成绩更新为 %d。” % [name, new_score])

# 或者,使用带有绑定的原始SQL:
# var query = "UPDATE players SET score = ? WHERE name = ?;"
# var bindings = [new_score, name]
# var result_raw = db.query_with_bindings(query, bindings)
# if result_raw.size() == 0 and db.error_message != "":
#     print("无法使用原始SQL更新玩家 '%s' 的成绩: " % name, db.error_message)
# else:
#     print("已将玩家 '%s' 的成绩更新为 %d (原始SQL)。" % [name, new_score])

“`

2.6. 删除数据

使用 delete_row()query_with_bindings()(用于 DELETE 语句)来删除记录。

“`gdscript
func delete_player_data(name: String):
var where_clause = {
“name”: name
}
var result = db.delete_row(“players”, where_clause)
if result != OK:
print(“无法删除玩家 ‘%s’: ” % name, db.error_message)
else:
print(“已删除玩家: %s。” % name)

# 或者,使用带有绑定的原始SQL:
# var query = "DELETE FROM players WHERE name = ?;"
# var bindings = [name]
# var result_raw = db.query_with_bindings(query, bindings)
# if result_raw.size() == 0 and db.error_message != "":
#     print("无法使用原始SQL删除玩家 '%s': " % name, db.error_message)
# else:
#     print("已删除玩家 '%s' (原始SQL)。" % name)

“`

2.7. 错误处理

始终检查数据库操作的返回值和 db.error_message 属性来处理潜在问题。

“`gdscript

错误处理已在上述每个函数中演示。

如果操作失败,db.error_message 属性将包含一个人类可读的错误字符串。

“`

结论

通过 godot-sqlite 插件,Godot Engine 项目可以轻松地集成和利用SQLite数据库进行本地数据存储。本文详细介绍了从插件安装到各种数据库操作的完整流程,并提供了GDScript实例。请记住,在实际开发中,始终使用参数化查询(query_with_bindings)来有效防止SQL注入漏洞,确保游戏数据的安全性和完整性。

滚动至顶部