{}const=>[]async()letfn</>var
Lua開発

Luaを一晩で学ぼう:ゼロからテキストRPGクエストまで数ステップで

Lua言語をゼロから理解しましょう。退屈なことなく、ミームを使って。Luaをインストールし、変数、テーブル、関数、ループを分析し、最後に戦闘システム、トラップ、インベントリを備えた本格的なテキストRPGクエストを作成します。すべてを一度に。

К

Kodik

著者

6分で読める

新しいプログラミング言語を始めて最初の20分間、「これは簡単だ」と思う感覚を知っていますか?そして、問題が始まります。括弧が間違っています、セミコロンを忘れています、コンパイラが午前3時に上の隣人のようにあなたに叫んでいます。

Luaではすべてが異なります。真面目に。この言語は非常に簡潔なので、コーヒーを飲みながらその基本を学ぶことができます。そして、夜には完全に機能するミニプロジェクトを組み立てることができます。信じられない?では、確認してみましょう。

Luaとは何ですか?なぜ必要ですか?

Lua(ルアではなく「ルーア」と読みますが、正直なところ、誰もが好きなように話します)は、1993年にブラジルで生まれた軽いスクリプト言語です。はい、それはほとんどのJavaScriptフレームワークよりも古いです。そして、それらとは異なり、まだ非推奨ではありません。

Luaの使用例:

  • ゲーム — Roblox、World of Warcraft、Garry's Mod、Love2D。WoWのアドオンを書いたことがあるなら、あなたはすでにLua開発者です。おめでとうございます。

  • NginxとOpenResty — 高負荷のWebサーバーは、Luaスクリプトを実行してリクエストを処理します。

  • Neovim — コードを書くよりもエディターを設定する方が長い場合、Luaはあなたの新しい親友です。

  • 組み込みシステムとIoT - Luaは非常に軽量なので、Pythonが息苦しくなるような場所でも動作します。

要するに、Luaはスイスアーミーナイフのようなものですが、栓抜きはありません。コンパクトで便利、そして驚くほどパワフルです。

🔥 10万人以上の学生が参加中

理論を読むのに疲れた?
コーディングの時間だ!

Kodik — 実践でプログラミングを学ぶアプリ。AIメンター、インタラクティブなレッスン、実際のプロジェクト。

🤖 AI 24時間
🎓 修了証
💰 無料
🚀 始める
今日参加

ステップ0:インストール(npmインストールよりも高速)

Linux/macOS:

# Ubuntu / Debian
sudo apt install lua5.4

# macOS
brew install lua

Windows:

LuaBinariesをダウンロード 公式サイト またはscoopを介して配置します。

scoop install lua

確認事項:

lua -v
# Lua 5.4.x  Copyright (C) ...

準備完了。 Dockerも仮想環境も、300行のpackage.jsonもありません。ただ動作します。

ステップ1: Hello Worldと最初の基本

ファイルを作成する hello.lua:

print("Hello, World!")
print("Lua is easier than you thought")

開始:

lua hello.lua

以上です。public static void mainなし、import sysなし、use strictなし。書いて実行するだけです。

変数:型なし、問題なし

local name = "Alexey"
local age = 25
local is_developer = true

print(name .. " — developer: " .. tostring(is_developer))

注意:..は文字列の連結です。+ ではなく、テンプレート文字列ではありません。2つの控えめな点。Luaはミニマリストです。

条件は古き良き古典

local level = 42

if level >= 100 then
    print("You're a legend!")
elseif level >= 50 then
    print("Almost there!")
else
    print("Keep swinging")
end

注意:大括弧の代わりに thenend を使用します。最初は慣れないが、1時間後にはもう気づかなくなる。

サイクル — すべての場合に対応する3つのタイプ

-- Цикл for (классический)
for i = 1, 5 do
    print("Iteration: " .. i)
end

-- Цикл while
local count = 0
while count < 3 do
    count = count + 1
    print("Counter: " .. count)
end

-- Перебор таблицы (о таблицах — ниже)
local fruits = {"apple", "banana", "mango"}
for index, fruit in ipairs(fruits) do
    print(index .. ". " .. fruit)
end

ステップ2:テーブルは唯一のデータ構造です(それで十分です)

Luaには、配列、辞書、オブジェクト、セット、タプル、デッキはありません。テーブルがあります。そして、それらはすべてを置き換えます。これは、JavaScriptオブジェクトと配列が1つのエンティティにマージされたようなものです。

-- Как массив
local colors = {"Red", "Green", "Blue"}
print(colors[1])  -- "Red" (индексация с 1, да-да)

-- Как словарь
local player = {
    name = "Hero",
    hp = 100,
    level = 1
}
print(player.name)  -- "Hero"
print(player["hp"]) -- 100 (тоже работает)

-- Комбинированный вариант
local config = {
    title = "My Game",
    resolution = {1920, 1080},
    fullscreen = true
}

1からのインデックス — はい、インデックスがゼロの言語の後はショックです。でも、そのうち慣れるよ。たぶん。いつか。

ステップ3:機能は第一級市民

-- Обычная функция
local function greet(name)
    return "Hi, " .. name .. "!"
end

print(greet("world"))

-- Функция как переменная (анонимная)
local square = function(x)
    return x * x
end

print(square(7))  -- 49

-- Множественный возврат (это Lua-суперсила!)
local function get_player_stats()
    return "Hero", 100, 15
end

local name, hp, attack = get_player_stats()
print(name .. " | HP: " .. hp .. " | ATK: " .. attack)

複数の値を返すことは、Lua で「なぜどこでもそうではないのか?」と嘆くようなことの一つです。

ステップ4:ミニプロジェクトを組み立てる—テキストクエスト!

理論は良いですが、ここでは講義を読んでいません。それでは、テキスト RPG クエストという、実際のミニプロジェクトを作成してみましょう。あなたはダンジョンを探索し、モンスターと戦い、(おそらく)生き残ることになります。

ファイル dungeon.lua を作成します。

-- === ТЕКСТОВЫЙ КВЕСТ: ПОДЗЕМЕЛЬЕ ===

math.randomseed(os.time())

-- Состояние игрока
local player = {
    name = "",
    hp = 100,
    attack = 15,
    potions = 3
}

-- Список монстров
local monsters = {
    {name = "Goblin", hp = 30, attack = 8, xp = 10},
    {name = "Skeleton", hp = 50, attack = 12, xp = 20},
    {name = "Dark Mage", hp = 40, attack = 18, xp = 25},
    {name = "Ogr", hp = 80, attack = 10, xp = 30},
}

-- Вспомогательные функции
local function separator()
    print(string.rep("-", 40))
end

local function show_status()
    separator()
    print("HP: " .. player.hp .. " | Potions: " .. player.potions)
    separator()
end

local function ask(question, options)
    print("\n" .. question)
    for i, opt in ipairs(options) do
        print("  " .. i .. ") " .. opt)
    end
    io.write("Your choice: ")
    local choice = tonumber(io.read())
    if not choice or choice < 1 or choice > #options then
        print("Incomprehensible choice, try again.")
        return ask(question, options)
    end
    return choice
end

-- Система боя
local function battle(monster)
    print("\n⚔️  Appears in front of you " .. monster.name .. "! (HP: " .. monster.hp .. ")")

    local enemy_hp = monster.hp

    while enemy_hp > 0 and player.hp > 0 do
        show_status()
        local action = ask("What are you doing?", {"Attack", "Drink the potion", "Try to escape"})

        if action == 1 then
            local damage = math.random(player.attack - 5, player.attack + 5)
            enemy_hp = enemy_hp - damage
            print("You inflict " .. damage .. " damage!")

            if enemy_hp > 0 then
                local enemy_damage = math.random(monster.attack - 3, monster.attack + 3)
                player.hp = player.hp - enemy_damage
                print(monster.name .. " beats you on " .. enemy_damage .. " damage!")
            end

        elseif action == 2 then
            if player.potions > 0 then
                local heal = math.random(20, 35)
                player.hp = player.hp + heal
                player.potions = player.potions - 1
                print("You are restoring " .. heal .. " HP!")
            else
                print("You don't have any potions! You lose a turn...")
            end
            local enemy_damage = math.random(monster.attack - 3, monster.attack + 3)
            player.hp = player.hp - enemy_damage
            print(monster.name .. " beats you on " .. enemy_damage .. " damage!")

        elseif action == 3 then
            if math.random(1, 100) <= 40 then
                print("You managed to escape!")
                return false
            else
                print("Couldn't escape!")
                local enemy_damage = math.random(monster.attack - 3, monster.attack + 5)
                player.hp = player.hp - enemy_damage
                print(monster.name .. " beats you on " .. enemy_damage .. " damage!")
            end
        end
    end

    if enemy_hp <= 0 then
        print("\n🎉 " .. monster.name .. " defeated!")
        if math.random(1, 100) <= 30 then
            player.potions = player.potions + 1
            print("You find a potion!")
        end
        return true
    end

    return false
end

-- Комнаты подземелья
local function explore_room(room_number)
    separator()
    print("\n🚪 Room " .. room_number)

    local events = {"monster", "monster", "treasure", "trap", "empty"}
    local event = events[math.random(1, #events)]

    if event == "monster" then
        local monster = monsters[math.random(1, #monsters)]
        return battle(monster)

    elseif event == "treasure" then
        print("You find a treasure chest!")
        local bonus = ask("What are you taking?", {"Health Potion (+1)", "Grinding stone (+3 to attack)"})
        if bonus == 1 then
            player.potions = player.potions + 1
            print("Potions: " .. player.potions)
        else
            player.attack = player.attack + 3
            print("Attack now: " .. player.attack)
        end
        return true

    elseif event == "trap" then
        print("Trap! Thorns shoot out of the wall!")
        local trap_damage = math.random(5, 15)
        player.hp = player.hp - trap_damage
        print("You get " .. trap_damage .. " damage.")
        return true

    else
        print("An empty room. Silence and dust.")
        if math.random(1, 100) <= 20 then
            print("You find a potion in the corner!")
            player.potions = player.potions + 1
        end
        return true
    end
end

-- === НАЧАЛО ИГРЫ ===

print("╔══════════════════════════════════════╗")
print("║     DUNGEON: TEXT QUEST     ║")
print("║         Written in Lua              ║")
print("╚══════════════════════════════════════╝")

io.write("What's your name, adventurer? ")
player.name = io.read()
print("\nWelcome, " .. player.name .. "!")
print("You are facing the entrance to a dungeon with 5 rooms.")
print("Go through them all and become a legend.\n")

local rooms_cleared = 0

for room = 1, 5 do
    if player.hp <= 0 then
        break
    end

    explore_room(room)

    if player.hp <= 0 then
        break
    end

    rooms_cleared = rooms_cleared + 1

    if room < 5 then
        show_status()
        local choice = ask("Going further?", {"Go ahead!", "Enough for today"})
        if choice == 2 then
            print("\nYou decide to return. Sometimes retreating is also wise.")
            break
        end
    end
end

separator()
separator()

if player.hp <= 0 then
    print("\n💀 " .. player.name .. " fell into the dungeon...")
    print("Rooms passed: " .. rooms_cleared .. " of 5")
    print("Try again — the dungeon is waiting!")
else
    if rooms_cleared == 5 then
        print("\n🏆 " .. player.name .. " completed the entire dungeon!")
        print("HP: " .. player.hp .. " | Remaining potions: " .. player.potions)
        print("You are a true legend!")
    else
        print("\n🏠 " .. player.name .. " returned from the dungeon.")
        print("Rooms passed: " .. rooms_cleared .. " of 5")
    end
end

print("\nThank you for playing! 🎮")

起動:

lua dungeon.lua

そして、あなたはすでにLuaで本格的なプロジェクトを書いています。戦闘システム、ランダム、インベントリ、そして複数の物語の展開を備えています。単なる計算機ではなく、本物のゲームです。

次は何ですか?どこに成長しますか?

Luaは素晴らしいエントリーポイントであり、ここから次の場所に移動できます。

  • Love2D — Luaの2Dゲームのフレームワーク。テキストクエストが入力された場合、グラフィックスで何が起こるかを想像してみてください。

  • Neovimプラグイン — Luaで書かれたエディター用のプラグインは、別の楽しみです。

  • OpenResty — Luaスクリプトをnginxに直接組み込み、何百万ものリクエストを処理します。

  • Roblox - 本当に、Robloxでは実際にお金を稼ぐことができます。そして、すべてのロジックはLuaで書かれています。

もっと勉強したいですか?
コディックに入ってください!

理論から実践まで一度に学べるこの形式がお好きなら、きっと気に入るはずです。 コディックこれはプログラミングを学ぶためのアプリです。各レッスンは単なるテキストではなく、実際に手を動かして解決するタスクです。Python、JavaScript、HTML、CSSなどの技術は、すべて実際の練習で、水や退屈なものではありません。

また、当社には テレグラムチャンネル、役立つ投稿が定期的に公開されます。コンセプトの分析、チートシート、ミニタスク、開発者向けのミームなどがあります。これは、通勤途中、昼休み、または就寝前に「あと5分」のときに、便利な形式でプログラミングを繰り返すのに最適な方法です。チャンネル登録して、プログラミングを毎日の一部にしましょう。

Luaは、強力であるために複雑である必要はないことを証明する言語です。あなたは、ある夜、print("Hello")から戦闘システムを備えたテキストRPGクエストまでの道のりを歩みました。そして、単一の依存関係をインストールせず、単一の構成を書かず、単一のpackage-lock.jsonを壊すこともありませんでした。

これで、あなたは作業プロジェクトを持ち、基本と成長の方向性を理解しています。これは、「来週からプログラミングを学び始めよう」と思っている人々の90%以上の人々よりも多いです。

やってみよう。 🚀

🎯先延ばしをやめよう

記事は気に入った?
実践の時間だ!

Kodikでは読むだけでなく、すぐにコードを書く。理論 + 実践 = 本当のスキル。

即座に実践
🧠AIがコードを説明
🏆修了証

登録不要 • カード不要