Window_Book v3.0 (First Standalone Public Release)

Discussion in 'RGSS3 Scripts (RMVX Ace)' started by Enelvon, Jul 5, 2014.

  1. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    Window Book v3.0
    by Enelvon


    Introduction
    This script is essentially a scripter's resource, but it has been optimized for use by those with little-to-no experience in scripting. It provides a parent class for multi-page windows, with a focus on those used to display information (though it is also possible, with some additions, to include pages with selectable areas). Its write_page_text method draws text in a similar manner to the draw_text_ex method, allowing you to use any control character that you would normally use in game text (with the exception of those that control timing). Further down, I have included a tutorial on creating a basic guide to a game's controls as an example of a simple use of the script. By reading the tutorial, a non-scripter can learn how to easily create and call a book window. I had a non-scripter friend try it out, and within ten minutes they had written a functional battle guide. Try it out and see what you can make!

    Usage
    In most cases, this is just going to be a superclass for other scripts. If you are interested in learning how to use it to make something yourself, refer to the tutorial in the spoiler below.

    This script serves as a resource to create multi-page windows. I will use this space to give an example of how to make and display a simple book that contains the controls for the game.

    The first thing that we have to do is create a new window class. Let's call it Guide.
     

    class Guide < Window_BookOkay, so we've opened our class. Now we need to define our initialize method. It will contain our definition of @pagetext.
     

    class Guide < Window_Book  def initialize    @pagetext = {      2 => ["In this mini guide you will be given a basic introduction to playing the game. I hope it proves informative."],      3 => ["\\c[16]Button Controls:", "", "\\c[16]Movement:",              "Use the direction keys to move your character on the map, and your cursor when in menus. Hold down Shift to run. When you are in a character-related menu, you can use Q, W, PgDn, and PgUp to move between characters.",               "", "\\c[16]Opening the Menu:",               "Press X, 0 on the number pad, or Esc to open the menu when you are on the map.",               "", "\\c[16]Selection:",               "Press Z, Space or Enter to interact with characters and items on the map, or to make a selection when in a menu.",               "", "\\c[16]Cancelling:",               "Press X, 0 on the number pad, or Esc to go back in a menu or cancel a choice."],      4 => ["\\c[16]File Operations:", "", "\\c[16]Saving Your Game:",               "Select \\c[16]Save \\c[0]from the in-game menu and choose a slot in which to save your game.",               "", "\\c[16]Loading Your Game:",               "If you are currently in the game, return to the title screen. Select \\c[16]Load Game \\c[0]and choose the slot you want to load."],      5 => ["Have fun, and good luck!"]    }    super  endSorry about how long those text lines are, but going down to a new line and having indentations causes the formatting to be hideous when the text is drawn. Anyway, as you can see, we're able to use control characters from the game's message windows in our text. Always make sure to use two (rather than one) backslashes for the control character, and that it is attached to the first word/character that it is intended to affect. I skipped page 1 because we'll do that a little differently - we're going to center the text for it and place it near the top of the page, as it's the cover of the book.
     

    class Guide < Window_Book  def initialize    @pagetext = {      2 => ["In this mini guide you will be given a basic introduction to playing the game. I hope it proves informative."],      3 => ["\\c[16]Button Controls:", "", "\\c[16]Movement:",              "Use the direction keys to move your character on the map, and your cursor when in menus. Hold down Shift to run. When you are in a character-related menu, you can use Q, W, PgDn, and PgUp to move between characters.",               "", "\\c[16]Opening the Menu:",               "Press X, 0 on the number pad, or Esc to open the menu when you are on the map.",               "", "\\c[16]Selection:",               "Press Z, Space or Enter to interact with characters and items on the map, or to make a selection when in a menu.",               "", "\\c[16]Cancelling:",               "Press X, 0 on the number pad, or Esc to go back in a menu or cancel a choice."],      4 => ["\\c[16]File Operations:", "", "\\c[16]Saving Your Game:",               "Select \\c[16]Save \\c[0]from the in-game menu and choose a slot in which to save your game.",               "", "\\c[16]Loading Your Game:",               "If you are currently in the game, return to the title screen. Select \\c[16]Load Game \\c[0]and choose the slot you want to load."],      5 => ["Have fun, and good luck!"]    }    super  end   def draw_page1    x = (contents_width - text_size("Game Guide").width) / 2    y = (contents_height - line_height) / 4    draw_text_ex(x, y, "\\c[14]Game Guide")  endHere we find the center of the book page horizontally and 1/4 of the page vertically, then draw the text there. Now we have five pages in our book (four in the @pagetext hash and one defined explicitly), so the next thing we should do is define max_pages.
     

    class Guide < Window_Book  def initialize    @pagetext = {      2 => ["In this mini guide you will be given a basic introduction to playing the game. I hope it proves informative."],      3 => ["\\c[16]Button Controls:", "", "\\c[16]Movement:",              "Use the direction keys to move your character on the map, and your cursor when in menus. Hold down Shift to run. When you are in a character-related menu, you can use Q, W, PgDn, and PgUp to move between characters.",               "", "\\c[16]Opening the Menu:",               "Press X, 0 on the number pad, or Esc to open the menu when you are on the map.",               "", "\\c[16]Selection:",               "Press Z, Space or Enter to interact with characters and items on the map, or to make a selection when in a menu.",               "", "\\c[16]Cancelling:",               "Press X, 0 on the number pad, or Esc to go back in a menu or cancel a choice."],      4 => ["\\c[16]File Operations:", "", "\\c[16]Saving Your Game:",               "Select \\c[16]Save \\c[0]from the in-game menu and choose a slot in which to save your game.",               "", "\\c[16]Loading Your Game:",               "If you are currently in the game, return to the title screen. Select \\c[16]Load Game \\c[0]and choose the slot you want to load."],      5 => ["Have fun, and good luck!"]    }    super  end   def draw_page1    x = (contents_width - text_size("Game Guide").width) / 2    y = (contents_height - line_height) / 4    draw_text_ex(x, y, "\\c[14]Game Guide")  end  def max_pages; 5; endendThere we go! As you can see, I ended the Guide class after defining max_pages. Why? Because it's done! We created a five-page book in 20 lines, and 7 of those were used to define the contents of the pages! Isn't that easy?

    We're not quite done, though. We have one more task ahead of us: calling the window for display. Prior to version 1.3, this had to be done by creating a new class and calling that. 1.3 introduced the Scene_Book class, which simplified this for basic users - advanced books will still need their own classes if they're going to be used for anything but simple reading. To call the default book scene with the guide, put this in an event:
     

    show_book(Guide, Scene_Map)That will display the book, as I've added the show_book command to the Game Interpreter class. You could also use this:
     

    SceneManager.goto(Scene_Book)SceneManager.scene.set_book(Guide, Scene_Map)show_book is a little faster, though. You can replace Guide with the name of your book to show whatever you'd like - let's say we have a book window named Biology_Textbook. We would use this:
     

    show_book(Biology_Textbook, Scene_Map)Note that show_book will return to the scene that you enter as its second parameter when the book is closed. It defaults to Scene_Map if no scene is given - I simply included Scene_Map in the examples to show that you can designate a scene.

    That's it! Congratulations, you've created a guide! Your players will never have to puzzle over the controls again!

    Anyway, I hope you can see how easy it is to use this as a base to make your own books. I can't wait to see what you come up with - make sure to let me know if you use it! Feel free to read over the rest of the script if you're learning to write code or are simply curious - it's my most thoroughly commented to date and may be able to give you some pointers.
    Script
    This script is available from  SES VX Ace.

    Installation
    Place below Materials and above all other custom scripts, or with the Window_* classes if you want to keep things organized.

    Credit and Thanks
    • Enelvon
    Author's Notes
    This script is made available under the terms of the MIT Expat license. View this page for more information.

    Edit: Just noticed how hideous my tutorial became due to the formatting. Fixed that.
     
    Last edited by a moderator: Jul 6, 2014
    #1
  2. lexietanium

    lexietanium Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    Location:
    Under yo beds o.o
    First Language:
    Tagalog :P
    Hi! Just showin luv since I see you guys working hard on some nice scripts~ Thank you!
     
    Last edited by a moderator: Jul 5, 2014
    #2
  3. lexietanium

    lexietanium Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    Location:
    Under yo beds o.o
    First Language:
    Tagalog :P
    =) So, a couple questions if you don't mind! First, is there a way to have the books as obtainable items where they also have their own menu? I was planning on doing like a skyrim thing where you can view the books in your inventory =). Second, is there a way to put pictures on the pages? 

    > :D thank thee in advance!

    PS: I think I'm also doing the custom window skin wrong xD 
     
    Last edited by a moderator: Jul 5, 2014
    #3
  4. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    I'm glad you like the script! As for your questions:

    1) You can absolutely have books as obtainable items. All you have to do is have them call a common event that contains a show_book script call!

    2) Yes, of course. That falls under the heading of more advanced use, so bear with me for a moment!

    What you'll have to do is explicitly define the contents of a page. You can use something like this:

    def draw_page2  src_bitmap = Cache.battler('Slime', 0)  src_rect = Rect.new(0, 0, src_bitmap.width, src_bitmap.height)  xpos, ypos = (contents_width - width) / 2, (contents_height - height) / 2  dest_rect = Rect.new(xpos, ypos, src_bitmap.width, src_bitmap.height)  contents.stretch_blt(dest_rect, src_bitmap, src_rect)endPage 2 would now have the Slime's battler drawn on its center. If you want to learn more about advanced use of Window_Book, take a look at the bestiary that I posted yesterday - it uses Window_Book as a parent and thus serves as an excellent example of what can be done with a little time and patience!

    3) I can't really tell if you're doing a custom windowskin right or wrong without seeing what you're doing! Feel free to post what you've done here or send it in a PM so that I can take a look.
     
    Last edited by a moderator: Jul 6, 2014
    #4
  5. lexietanium

    lexietanium Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    Location:
    Under yo beds o.o
    First Language:
    Tagalog :P
    =) Hi Hi! thank you for the fast reply. 

    I did the script to define the content of the page. When I tried it on the guide book to test it out it didn't work so I changed "def page2" to "def draw_page2" xD now it shows but it's all the way to the top right corner and the page text isn't showing anymore. Also would there be a way to use the pictures folder instead?

    Also, I read on the instruction you can set windowskin on this one?

    def initialize(x = 0, y = 0, width = Graphics.width, height = Graphics.height,

                     wrap_type = :word, draw_scroll_for_one = false, skin = nil)

     

    I tried changing nil to "Window_Save" but it didn't show xD the picture is on the system folder

     

    I was also looking at this one but I'm not sure how to proceed (and everything I tried failed)

     

    @skin = skin || 

                ($imported["ESSA - Window Swap"] ? Cache.windows("Book Window") :

                                                   Cache.system("Child Window"))

        @wrap = wrap_type and @pagetext ||= {} and @pagetext.default = []

        @draw_scroll_for_one = draw_scroll_for_one

        super(x, y, width, height)

     

    Sorry u.u I'm still learning how scripting works. =) but it may not be much, I can assign different custom windows for the save menu, character menu,  etc. by myself~ It's an achievement for me in terms of scripting hahaha =)

     

     

     
     
    #5
  6. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    Ha, yes - that was my mistake. I was replying quickly, ahaha! I'll correct my previous post in a moment. You can load any bitmap - that was a simple example. Cache.picture will allow you to access pictures stored in the Graphics/Pictures folder!

    As for the windowskin thing: you can pass it any valid windowskin image there. An example call to super from a child class's initialize method might look something like this:

    super(0, 0, Graphics.width, Graphics.height, :word, false, Cache.system('Save Window'))
    The code that you're referring to checks for the presence of a script that I wrote a while ago that allowed for easy use of multiple windowskins - I believe the topic in which it was posted is archived now, though.
     
    #6
  7. mlogan

    mlogan Global Moderators Global Mod

    Messages:
    13,665
    Likes Received:
    7,533
    Location:
    Texas
    First Language:
    English
    Primarily Uses:
    RMMV
    Checking this out... looks like it could be quite useful.
     
    #7
  8. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    Do let me know if you have any questions about how to do something with it! The tutorial contained in the header provides a base for making simple, text-only books. You can also look over the SES Bestiary for an example of a more complicated use, and I have a couple of other things in the works that will demonstrate various other uses.
     
    #8
    mlogan likes this.
  9. brandos

    brandos Veteran Veteran

    Messages:
    147
    Likes Received:
    31
    First Language:
    German
    Can you post some screenshots maybe?
     
    #9
  10. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    There's nothing to screenshot. This script does nothing on its own - it relies entirely on the end user or serves as a prerequisite for other scripts. Two of the screenshots present in the Bestiary thread show examples of something created with this script, though.
     
    #10
  11. mlogan

    mlogan Global Moderators Global Mod

    Messages:
    13,665
    Likes Received:
    7,533
    Location:
    Texas
    First Language:
    English
    Primarily Uses:
    RMMV
    I think that's what Brandos meant - screenshots of the end result.

    And thanks, I will definitely let you know. I just installed it and skimmed the how-to before I had to go. I'm looking forward to working with it and seeing what can be made.

    Edit: Been reading through this some more. I follow pretty well what all you've done setting up the class and initialize. I just wanted to make sure I'm understanding correctly: Say I wanted to have two books, may Fairy Tales and Dictionary (random things come off the top of my head, oy), so I would do class Fairy Tales < Window_Book and class Dictionary < Window_Book and then do all of the define initialization stuff, right? But where exactly do I put those pieces within the script?
     
    Last edited by a moderator: Jul 6, 2014
    #11
  12. Enelvon

    Enelvon Slumbering Goddess Veteran

    Messages:
    240
    Likes Received:
    134
    Location:
    Dreamland
    First Language:
    English
    Yes, you would define two separate classes. They don't go within the script, but rather in one or more separate script slots - each one is essentially a new script. What you're doing by following the tutorial is writing a new window class. You can create one script slot to hold all of your books, in which case its contents would be something like this:

    class Fairy_Tales < Window_Book  ...CODE HERE...end class Dictionary < Window_Book  ...CODE HERE...end class Some_Book < Window_Book  ...CODE HERE...end
    And so on. If you prefer keeping things separate, it's fine to have as many script slots as you want dedicated to books. The only thing to be careful about is making sure that the Window_Book script stays above any books you create!
     
    #12
  13. mlogan

    mlogan Global Moderators Global Mod

    Messages:
    13,665
    Likes Received:
    7,533
    Location:
    Texas
    First Language:
    English
    Primarily Uses:
    RMMV
    Oh okay! Thanks Envelon! I will give that a try and see how it goes.
     
    #13

Share This Page