Simple Scripting Tuts #2

0 Members and 1 Guest are viewing this topic.

*******
Rep:
Level 89
Returned from the dead.
I decided to remake this, as my other one became necro, just so I can add stuff when I feel and people can ask questions

If a mod or admin doesn't agree with this, then feel free to delete this topic. ;)

Spoiler for Introduction to Ruby/RGSS:
RGSS was originated from ruby.
Ruby is a an exciting new, pure, object oriented programming language. While few people in the West have heard of Ruby yet, it has taken off like wildfire in Japan---already overtaking the Python language in popularity.

What makes Ruby so popular? Ruby weaves the best features of the best programming languages into a seamless, concise whole. Ruby is:
Powerful -- Ruby combines the pure object-oriented power of the classic OO language Smalltalk with the expressiveness and convenience of a scripting language such as Perl. Ruby programs are compact, yet very readable and maintainable; you can get a lot done in a few lines, without being cryptic.

Simple -- The syntax and semantics are intuitive and very clean. There aren't any "special cases" you have to remember. For instance, integers, classes, and nil are all objects, just like everything else. Once you learn the basics, it's easy to guess how to do new things---and guess correctly.

Transparent -- Ruby frees you from the drudgery of spoon-feeding the compiler. More than any other language we've worked with, Ruby stays out of your way, so you can concentrate on solving the problem at hand.

Available -- Ruby is open source and freely available for both development and deployment. Unlike some other new languages, Ruby does not restrict you to a single platform or vendor. You can run Ruby under Unix or Linux, Microsoft Windows, or specialized systems such as BeOS and others.
Most of all, Ruby puts the fun back into programming. When was the last time you had fun writing a program---a program that worked the first time; a program that you could read next week, next month, or next year and still understand exactly what it does? We find Ruby to be a breath of fresh air in the dense, often hectic world of programming. In fact, we see nothing but smiles after we present Ruby to programmers.
(Copied from another site, I have no understanding of Ruby, only RGSS)

Spoiler for Making a Window:
To make a window, you need to make at least two definitions, def initialize, and def refresh.

def initialize

To start with, you need to name your window
For example:
Code: [Select]
class Window_MyWindow < Window_Base
Remember that RGSS is case sensitive, if something isnt the right case then you will most likely get an error, always check something is in the right case.

Now for def initialize, to start this, just type on a new line: def initialize
Simple enough?
Now type
Code: [Select]
super(0, 0, 128, 128)
This line calls the window
The numbers can be changed, the first number is the x co-ordinates of where the top left corner will appear on-screen, the second number is the y co-ordinates of the position of the window (both these are in pixels)
If both the first numbers are at 0 then the window will appear the top left corner of the screen
The third number is the x co-ordinates of the window itself (in pixels)
The last number is the y co-ords of the window (in pixels)
x goes up to 640 and y goes to 480
So a window can be at maximum, 640 x 480 pixels without going offscreen
(Try and keep the numbers as multiples of 32, they fit better this way)

Then, use
Code: [Select]
self.contents = Bitmap.new(width - 32, height - 32)
You don't change anything here, i'm not sure what this line does, so i've never edited it myself

Then, if you like, you can add
Code: [Select]
self.contents.font.name = $defaultfonttype
self.contents.font.size = $defaultfontsize
If you don't add this here, then you can add it in def refresh
you can change $defaultfonttype to "Tahoma", "Arial" or any other font, and you can replace $defaultfontsize to any number you want, this determines the font's size.

Then put refresh, then end.
so your Window so far should look like this:
Code: [Select]
class Window_MyWindow < Window_Base
  def initialize
    super(0, 0, 128, 96)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = $defaultfonttype
    self.contents.font.size = $defaultfontsize
    refresh
  end

def refresh

Now you've made the window, you need to give it some contents
Code: [Select]
def refresh
  self.contents.clear
I think this line clears the window so that suff can be added to it
You can now add the two font lines in if you like, once that's done you may want to use this
Code: [Select]
self.contents.font.color = normal_color
The colors can all be found in Window_Base, and to create a color, change normal_color to Color.new(r, g, b)
r = red g = green b = blue
Code: [Select]
self.contents.draw_text(0, 0, 128, 32, "TEXT!!!!")
This line creates text, the first and second numbers determine where the text appears (x and y), and the second two numbers determine thespace the text can fit into, (Number 3 = x, Number 4 = y (usually 32))
Always put text in quotation marks, otherwise the program sees it as a method and searches for the definition for it
To add icons, battlers, charsets etc, use this syntax
Code: [Select]
bitmap = RPG::Cache.type of bitmap("Name of bitmap")
self.contents.blt(x, y, bitmap, Rect.new(0, 0, x that bitmap has to fit in, y that bitmap has to fit in))
That should be pretty self explanatory...

So now your Window should look something like this
Code: [Select]
class Window_MyWindow < Window_Base
  def initialize
    super(0, 0, 128, 96)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = $defaultfonttype
    self.contents.font.size = $defaultfontsize
    refresh
  end
  def refresh
    self.contents.clear
    self.contents.font.color = Color.new(255, 0, 0)
    self.contents.draw_text(0, 0, 128, 32, "TEXT!!!")
    bitmap = RPG::Cache.icon("001-Weapon01")
    self.contents.blt(0, 64, bitmap, Rect.new(0, 0, 24, 24))
  end
end
Add that extra end at the end (so there's two ends) to round off your window
You will get a syntax error if there are too many or not enough ends

Spoiler for CMS:
I couldn't think of anything to go between windows and Menu Systems, if you think there should be something in-between these, then just say so ;)

Most scripters start their scripts with comment lines, there are two ways (that I know of) of doing this
One is to put a # at the start of every comment line, note that you can put these after parts in a script on the same line, to explain what each line does, for example
Code: [Select]
$scene = Scene_Menu.new(3) #Calls the Menu and starts at the 4th option (Will be explained later in the tutorial)
But, you CANNOT use a comment, then use a scripting syntax, e.g.
Code: [Select]
#To call the menu# $scene = Scene_Menu.new(3)
The syntax itself will be seen as a comment and therefore ignored
To save the time and trouble of putting a # on every line, most scripters use these
Code: [Select]
=begin
This begins a section of comments
Code: [Select]
=end
And this ends it, pretty self-explanatory I think
All scripts released on forums or whatnot should include comments so that the user knows exactly what they're doing

def initialize

Now the comments are over, name your scene, for example, the default menu is called Scene_Menu, so we'll call it that.
So, start off with
Code: [Select]
class Scene_Menu
So that's over and done with, now type def initialize
The way I do my menus (the only way I know) may be different to what other scripters use
So... on the SAME LINE as def initialize, type (menu_index = 0), I think this presets the starting option for when you access the menu, in scripting, most things start at 0, so 0 = 1, 1 = 2, 2 = 3 etc etc etc
So your def initialize should look like this now,
Code: [Select]
def initialize(menu_index = 0)
Now, you need to define what menu_index actually is, to do this
Code: [Select]
@menu_index = menu_index
can be used.
Now end your def initialize
So your CMS should look like this now,
Code: [Select]
class Scene_Menu
  def initialize(menu_index = 0)
    @menu_index = menu_index
  end
Short eh?
That's only the very beginning

def main

Start off your def main as, well, def main
Now to make the options for your menu
Code: [Select]
s1 = "Items"
That would be an option for your menu, keep in mind that the options here don't start at 0, so s1 would be the first option, you could also put
Code: [Select]
s1 = $data_system.words.item
This searches the last page of the database for whatever you have named "Items", note that this only works for item, skill and equip, make all your options
Once you're done you should have something like this
Code: [Select]
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "Save"
s6 = "Quit"
Remember that you can add options and remove them as you please, i've no idea why, but the program automatically sees these as menu_index
Now, it's decision time, is your menu not going to cover the whole screen? If so, do you want to see the map instead of blackness? If so, add this line
Code: [Select]
@spriteset = Spriteset_Map.new
Now, to make your options appear, you need to put them in a window, use this to do that
Code: [Select]
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])
The number is the width (x) of the window, and the options appear at the end, remember to update these whenever you add or remove options
Now to set the index for Window_Command
Code: [Select]
@command_window.index = @menu_index
This sets Window_Command to menu_index
You can disable options if contitions are not met, like not enough characters
Code: [Select]
if $game_party.actors.size == 0
  @command_window.disable_item(0)
  @command_window.disable_item(1)
  @command_window.disable_item(2)
  @command_window.disable_item(3)
end
The == is not a typo, you need that to determine that if your party has no more, no less than 0 characters then those options will be disabled, notice they start from 0
Now to disable saving
Code: [Select]
if $game_system.save_disabled
  @command_window.disable_item(4)
end
That means that if save is disabled then "Save" will turn grey, you can actually disable it later
Code: [Select]
@playtime_window = Window_PlayTime.new
@playtime_window.x = #Set the x co-ordinates of where the playtime window will appear
@playtime_window.y = #Set the playtime window's y co-ords
@steps_window = Window_Steps.new
@steps_window.x = #The x co-ords of the steps window
@steps_window.y = #The steps window's y co-ords
@gold_window = Window_Gold.new
@gold_window.x = #The x of the gold window
@gold_window.y = #The y of the gold window
@status_window = Window_MenuStatus.new
@status_window.x = #The x of the menustatus window
@status_window.y = #The y of the menustatus window
Here you can set wher each window goes, and what each window is, a menu only really needs a command_window and a status_window, but you can add or remove windows as you please
Code: [Select]
Graphics.transition
loop do
  Graphics.update
  Input.update
  update
These lines set the transition
Code: [Select]
  if $scene != self
    break
  end
end
This means that if the current scene isn't the menu, then loop do breaks
Code: [Select]
  Graphics.freeze
  @spriteset.dispose
  @command_window.dispose
  @playtime_window.dispose
  @steps_window.dispose
  @gold_window.dispose
  @status_window.dispose
end
These lines dispose of all the windows when the menu is exited, you don't need the spriteset line if you didn't add the line earlier, and the end ends def main

def update

Code: [Select]
def update
  @spriteset.update
  @command_window.update
  @playtime_window.update
  @steps_window.update
  @gold_window.update
  @status_window.update
Again, don't put the spriteset line if you didn't before
These lines update each window every frame or so I think
Code: [Select]
  if @command_window.active
    update_command
    return
  end
These lines mean that if the cursor is on the command window, then it tells the program to go to the definition of update_command
Code: [Select]
  if @status_window.active
    update_status
    return
  end
end
These lines do the same but for the status window (the window you go to when you are selecting the characters)
And the last end ends def update

def update_command

Code: [Select]
def update_command
  if Input.trigger?(Input::B)
    $game_system.se_play($data_system.cancel_se)
    $scene = Scene_Map.new
    return
  end
These lines mean that if the cancel button is pressed then you go back to the map
Code: [Select]
if Input.trigger?(Input::C)
  if $game_party.actors.size == 0 and @command_window.index < 4
    $game_system.se_play($data_system.buzzer_se)
    return
  end
These lines mean that if the party has exactly 0 characters and the option you have chosen is less than 4 (starting from 0) Then it plays a buzzer and returns to the command window
Code: [Select]
case @command_window.index
This line means that the response changes for each option in the command window
Code: [Select]
when 0
  $game_system.se_play($data_system.decision_se)
  $scene = Scene_Item.new
This is the basic response for a selection, though it can get more advanced than that
Code: [Select]
when 1
  $game_system.se_play($data_system.decision_se)
  @command_window.active = false
  @status_window.active = true
  @status_window.index = 0
when 2
  $game_system.se_play($data_system.decision_se)
  @command_window.active = false
  @status_window.active = true
  @status_window.index = 0
when 3
  $game_system.se_play($data_system.decision_se)
  @command_window.active = false
  @status_window.active = true
  @status_window.index = 0
Those 3 are skill, equip and status, they appear the same, but for the responses, see def update_status
Code: [Select]
when 4
  if $game_system.save_disabled
    $game_system.se_play($data_system.buzzer_se)
    return
  end
  $game_system.se_play($data_system.decision_se)
  $scene = Scene_Save.new
That means that if save is disabled, then it plays a buzzer and returns to the command window
If save is enabled then it goes to the save screen
Code: [Select]
    when 5
      $game_system.se_play($data_system.decision_se)
      $scene = Scene_End.new
    end
    return
  end
end
This calls the end screen when Quit is selected
Then the ends end everything except class Scene_Menu

def update_status

Code: [Select]
def update_status
  if Input.trigger?(Input::B)
    $game_system.se_play($data_system.cancel_se)
    @command_window.active = true
    @status_window.active = false
    @status_window.index = -1
    return
  end
Those lines make it so when the cancel button is pressed and the status screen is active, then it goes back to the command window
Code: [Select]
if Input.trigger?(Input::C)
  case @command_window.index
  when 1
    if $game_party.actors[@status_window.index].restriction >= 2
      $game_system.se_play($data_system.buzzer_se)
      return
    end
    $game_system.se_play($data_system.decision_se)
    $scene = Scene_Skill.new(@status_window.index)
This makes it go to the skill screen, i've no idea what the first lines under when 1 do...
Code: [Select]
      when 2
        $game_system.se_play($data_system.decision_se)
        $scene = Scene_Equip.new(@status_window.index)
      when 3
        $game_system.se_play($data_system.decision_se)
        $scene = Scene_Status.new(@status_window.index)
      end
      return
    end
  end
end
The rest of the lines seem pretty self explanatory, that's the end of Scene_Menu, make sure there are enough ends at the end, you will get a syntax error if there aren't the right number of ends at the end

Showing Icons

What I do here, is make myself a brand spanking new window with the same co-ordinates as my at the top of my menu, before class Scene_Menu
Code: [Select]
class Window_Icons < Window_Base
  def initialize
    super(x position of your command window, y position of you command window, x of your command window, y of you command window)
    self.contents = Bitmap.new(width - 32, height - 32)
    refresh
  end
Now, like in the Making a Window section, you need to place the icons, like this
Code: [Select]
  def refresh
    self.contents.clear
    bitmap = RPG::Cache.icon("034-Item03")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
    bitmap = RPG::Cache.icon("044-Skill01")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
    bitmap = RPG::Cache.icon("013-Body01")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
    bitmap = RPG::Cache.icon("Status")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
    bitmap = RPG::Cache.icon("037-Item06")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
    bitmap = RPG::Cache.icon("039-Item08")
    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), 160)
  end
end
Where x and y are the x and y of where you want the icons to appear, if you want you can add a number at the end like I have, to set the opacity (transparency) of the icon
Then, you need to add it into your menu
Before the line that says
Code: [Select]
@command_window = Window_Command.new
Paste this:
Code: [Select]
@icon_window = Window_Icon.new
@icon_window.x = !!!
@icon_window.y = !!!!
Change the !!! to the x co-ordinates of your command windowand change !!!! to the y co-ordinates of it

Then where it says all the crap like:
Code: [Select]
@command_window.dispose
Insert:
Code: [Select]
@icon_window.dispose
Then find:
Code: [Select]
@command_window.update
And add:
Code: [Select]
@icon_window.update

That should be it, enjoy :)

Spoiler for Using Variables:
Ingame Variables

You can use ingame variables in scripting, for example
Code: [Select]
$var = $game_variables[x]
Where x is the id of the variable, starting from 1
If you are making a window that uses an ingame variable, you can display it by using that syntax in def initialize above refresh and under the line that says
Code: [Select]
self.contents = Bitmap.new(width - 32, height - 32)
And using this line
Code: [Select]
self.contents.draw_text(0, 0, 96, 32, $var.to_s, 1)
The numbers have already been explained in the Making a Window section of this tut
The 1 centers the number, I think if you put a 2 there, I think it aligns it to the right, and if you don't put a number then it aligns to the left

Scripting Variables and Game class

The way I make scripting variables may be different to the way other scripters do it, if any scripters out there know any other ways, then post it ;)

Code: [Select]
class Game_Var
  attr_accessor :var
  def initialize
    $var = 0
  end
end
That seems pretty self explanatory, the $ makes var a global variable and the fourth line makes $var preset to 0
In the def initialize of the window you want the variable displayed in, put
Code: [Select]
@game_var = Game_Var
Change game_var and Game_Var to whatever you have called your game class
You can now display the variable the same way you would display ingame variables, but changing the values is different, you need to use a call script that I don't know yet, if I figure it out i'll post it here ;)

More to come ;) if you have any problems with anything here, just post it and i'll try and fix it ;)


By the way, I locked the other topic
Sincerely,
Your conscience.