在Ruby中制作基于RPG文本的游戏。如何存储和运行控件和场景?

时间:2017-02-02 14:00:34

标签: ruby

我是Ruby的新手,并且经历了一些尝试和学习的资源。我完成了Codecadamy的Ruby课程,通过Learn Ruby the Hard Way我大约75%。此外,我已经阅读了大约100页的Eloquent Ruby和pickaxe Ruby书籍(但是那些还没有点击给我)。

我正在尝试用Ruby制作一个基于文本的RPG游戏进行练习。我决定重新制作Chrono Trigger,因为我对比赛很了解,我不想花时间思考角色和故事;只是想练习编码。

我尝试为播放器制作四个简单的控件,但是我觉得很难在场景中加入。

例如,我有控件“talk”,我使用'if / else'语句根据用户输入的内容运行场景。如果用户多次输入“talk”,我发现自己必须经历无休止的if / else场景。

以下是我的代码。这是一个非常混乱,因为我是一个初学者,但如果有人可以看看它并给我一些建议,如何让它工作,这将是伟大的!

---------欢迎方法-----------

def welcome
    puts "Welcome to Chrono Trigger: Ruby Edition!"
    puts "Let's discuss the controls to help you become familiar with the game."
    puts ""
    puts "We are going to break the controls down into categories to help make it easier to understand"
    puts "Anytime you get stuck just type 'help' to bring the controls back up."
    puts ""
    puts "The controls are 'talk' 'action' 'attack' 'flee'."
    puts ""
    puts "Simple enough? Type 'start' to begin!"

    print "> "
    response = $stdin.gets.chomp
        if response == "start" then chapter_1_start end
end

--------- Crono接下来要做什么?------

def crono_next
    puts "What should Crono do next?"
    @next_task = $stdin.gets.chomp
end


def chapter_1_start
    puts "(Bells Ringing)"
    puts "\"Crono....Crono...\""
    puts "\"Time to get up!\""
    puts ""
    puts "Crono wakes up from bed."
    puts "Crono is standing in the middle of his bedroom"
    print "> "
    response = $stdin.gets.chomp
    if response == "help"
        help
    elsif response == "action"
        puts "Crono closes the curtains."
        puts "Then he leaves the room"
        chapter_1_start2
    elsif response == "talk"
        puts "Crono talks to himself"
    else
        puts "..."
    end    
end

def chapter_1_start2

    def talk
        puts "Mom: \"Oh Crono, don't forget to stop by your friend Lucca's house before you head to the Millenial Fair.\""
        crono_next
        if @next_task == "talk"
            puts "Mom: \"I almost forgot. Here's 200 gil to buys some cat food while you're out.\""
            crono_next
            if @next_task == "talk"
                puts "Mom: \"You really should be leaving now Crono\""
                chapter_1_start3
            elsif @next_task == "action"
                puts "Crono pets his cat."
                puts "'Meow'" 
                chapter_1_start3
            else
                chapter_1_start3
            end    

        elsif @next_task == "action"
            action
        else
            "Mom: \"You really should be leaving now Crono\""
            chapter_1_start3
        end
    end

    def action
        puts "Crono pets his cat."
        puts "'Meow'" 
        crono_next
        if @next_task == "talk"
            talk
        elsif @next_task == "action"
            action
        else
            "Crono does nothing."
        end    
    end
    puts "Crono heads downstairs and sees his mom in the kitchen and his cat in the living room."
    crono_next
    if @next_task == "talk"
        talk
    elsif @next_task == "action"
        action
    else
        puts "Let's try that again."
        chapter_1_start2
    end    
end

def chapter_1_start3
    puts ""
    puts "Crono begins walking away from his house"
    puts "If he travels West he will be heading in the direction of Lucca's house."
    puts "If he travels East he will be headed to the Millenial Fair."
    puts crono_next   

----------------帮助菜单----------------

def help
    puts "What do you need help with? 'controls', 'hints', 'quit'"
    print "> "
    help_subject = $stdin.gets.chomp
    if help_subject == "controls"
        puts "The controls are 'talk' 'action' 'attack' 'flee'."
    elsif help_subject == "hints"
        puts "I got nothing"
    elsif help_subject == "quit"
        puts "Are you sure you want to quit?(Your game will not be saved)"
        print "> "
        sure_quit = $stdin.gets.chomp
        if sure_quit.include? "y"
            exit(0)
        else
            help
        end
    else
        puts "Guess you didn't really need help after all."
    end
end

----------------帮助菜单-----------------

def talk(person)
    @person = person
end

welcome

1 个答案:

答案 0 :(得分:2)

基于文本的游戏实际上非常复杂,并且最终遵循许多与传统视频游戏相同的逻辑和设计模式。你可能想要浏览游戏设计指南 - 它们有很多,而且基础知识适用于任何编程语言。

话虽这么说,如果你想继续你的游戏,而不是迷失在无尽的if语句中,你应该使用类来管理你的场景。

每个游戏都有一个主循环,这是一个无限循环,处理3个主要任务:向屏幕显示内容,收集用户输入,以及计算游戏状态的变化。这种情况一次又一次地发生:

#main.rb
scene = Scene.new(:chapter_1)
while true
  scene.display
  print "> "
  action = $stdin.gets.chomp
  if command == 'talk'
    scene = scene.talk
  elsif command == 'action'
    scene = scene.action
  elsif command = 'attack'
    scene = scene.attack
  elsif command = 'flee'
    scene = scene.flee
  else
    puts 'unknown command!'
  end
end

场景类基本上只保存每个场景的文本以及哪些动作链接哪些场景与其他场景。这种结构称为状态机,它是跟踪游戏状态的最简单方法:

#scene.rb
class Scene
  def initialize beginning_state
    @state = beginning_state
    @scenes = {
      chapter_1: [
        "Hello and welcome to chapter 1 of my game!", 
        :ch1_talk, 
        :ch1_action,
        :ch1_attack,
        :chapter_2],
      ch1_talk: [
        "Please stop talking while I'm talking!",
        :ch1_talk, 
        :ch1_action,
        :ch1_attack,
        :chapter_2],
      ch1_action: [
        "W-what are you doing?!",
        :ch1_talk, 
        :ch1_action,
        :ch1_attack,
        :chapter_2],
      ch1_attack: [ 
        "Stop, that hurts :c",
        :ch1_talk, 
        :ch1_action,
        :ch1_attack,
        :chapter_2],
      chapter_2: [ 
        "Congratulations, you have entered...\n chapter 2!",
        :ch2_talk, 
        :ch2_action,
        :ch2_attack,
        :ch2_flee],
      ch2_talk: [
        "I'm ignoring you",
        :ch2_talk, 
        :ch2_action,
        :ch2_attack,
        :ch2_flee],
      ch2_action: [
        "I don't even care",
        :ch2_talk, 
        :ch2_action,
        :ch2_attack,
        :ch2_flee],
      ch2_attack: [ 
        "You're no match for me",
        :ch2_talk, 
        :ch2_action,
        :ch2_attack,
        :ch2_flee],
      ch2_flee: [
        "Okay, goodbye!",
        :ch2_talk, 
        :ch2_action,
        :ch2_attack,
        :ch2_flee],
    }
  end

  def display
    puts @scenes[@state][0]
  end

  def talk
    @state = @scenes[@state][1]
  end

  def action
    @state = @scenes[@state][2]
  end

  def attack
    @state = @scenes[@state][3]
  end

  def flee
    @state = @scenes[@state][4]
  end
end

对不起,这有点复杂,但游戏有点复杂。理想情况下,您可以将场景保存在特殊格式的文本文件中,然后将它们加载到游戏中,而不是像我一样在源代码中定义它们。