#==============================================================================
#==============================================================================
#Berans' "Interactive Piano" script v1.12
#Last edited: 24 August 2008
#
#
#What's new in v1.12
# - Improved parsing so that codes longer than 1 line will no longer give
# problems
#
#
#
#What's new in v1.11
# - Script now features support for "input codes"
# - Raises an error when Tons of Add-ons is not installed
#
#
#
#
#This script creates an interactive piano to play with. It makes use of
#Blizzard's Custom Game Controls from his "Tons of Add-ons" script, to allow
#for all different keyboard inputs.
#
#Credits: Berans - Creating the script, graphics and sounds
# Blizzard - For use of his Custom Game Controls from "Tons of Add-ons"
#
#Features
#
# - 4-octave keyboard (48 keys)
# - Graphics and sound samples included
# - Uses Custom Game Controls from "Tons of Add-ons" by Blizzard
# - Virtually lagfree
# - Loads of fun
# - NEW: You can now use the piano to input codes
#
#Compatibility
#
#This script should not have incompatibility issues with other scripts,
#including the SDK.
#This script requires the Custom Game Controls from Tons of Add-ons to operate
#properly. Unless the script is changed, the Custom Game Controls must be set up
#as in the demo.
#
#==============================================================================
#Instructions
#==============================================================================
#
#
#Set up
#
# - Download the demo of script was obtained separately
# - Copy Audio files from the "Audio/BGM" folder to your own project
# - Feel free to provide your own Audiofiles, provided they use the same names
# - Copy the picture files from "Graphics/Pictures" folder to your own project
# - Use the import feature to set the piano's transparant color to white
# - Use the import feature to set the "Piano Lights" transparant color to white
# and the semi-transparant color to the other color used
# - Feel free to play around with the color used for the lights to create your
# own feel
# - Insert this script into your own project if you haven't already done so
# - Insert the demo's "Tons of Add-ons" script into your project (all 3 parts)
# if you don't have Tons of Add-ons yet. Otherwise, just replace your Custom
# Game Controls with the one in the demo.
# - To customize the keys, just change the set-up in Tons of Add-ons.
# It is recommended to leave the key's names the same
# example: Instead of FS = [Key] you could make it FS = [Key]
#
#
#Using the script
#
# - Call the scene from an event using a script call
# - Put the following in the script call "$scene = Scene_Piano.new"
# (leave out the quotes)
# - You can change the script call as follows to create a "musical code" that
# turns on a game switch when entered correctly
# $scene = Scene_Piano.new(switch,code,mode) see "further instruction" below
# for how to use this feature
#
#
#Further instructions
#
#
# Using the "Code input" feature:
# call the script with the format $scene = Scene_Piano.new(switch,code,mode)
# replace switch with the switch number you want to have turned on by a
# correct input. Replace code by a "musical code" of the following format:
# 'C1B1As1D1'
# The format must include the single quotes. Everything up to the numer
# represents a note. i.e C1 is the first C on the keyboard. Notes with an s in
# the name represent sharps. The sharp notes include Cs,Ds,Fs,Gs and As
# and the non-sharp notes include C-G
# Finally, you can replace mode by either 0, 1 or 2 to have a different style
# of inputting the code
# mode 0 means that, if you get the code wrong, nothing happens
# mode 1 means that, if you get the code wrong, a sound plays notifying you
# of the wrong input, and the input starts over
# mode 2 means that, if you get the code wrong, a sound plays and the scene
# is quit to map
# leaving mode out automatically uses mode 0
#==============================================================================
#==============================================================================
#==============================================================================
#**Scene_Piano
#
#This class handles processing for the piano screen
#==============================================================================
class Scene_Piano
#
#*Object initializations
#
def initialize(switch = nil, string = nil, mode = 0)
if $tons_version == nil || $tons_version < 6.56
raise 'This script requires Custom Game Controls from Tons of add-ons.' +
'Please get Tons of Add-ons 6.56 or higher.'
end
@switch = switch
@string = ''
unless string == nil
@required = @string.gsub("\n"){nil}
end
@mode = mode
end
#
#*Main processing
#
def main
#Memorize Map/Menu BGM
$game_system.bgm_memorize
#Fade out BGM
$game_system.bgm_fade(2)
#Memorize Map/Menu BGS
$game_system.bgs_memorize
#Fade out BGS
$game_system.bgs_fade(2)
#This keeps track of the animation frames for the piano's lighting effects
@animation = []
#create a value for @animation for each key
for i in 0...48
@animation.push(-1)
end
#Create spritesets
@spriteset = Spriteset_Map.new
@piano = Spriteset_Piano.new
#Create windows
@piano_dummy = Piano_Dummy.new
@help_window = Window_PianoHelp.new
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
#Dispose windows and spriteset
@spriteset.dispose
@piano.dispose
@piano_dummy.dispose
@help_window.dispose
#Restore Map/Menu BGM
$game_system.bgm_restore
#Restore Map/Menu BGS
$game_system.bgs_restore
end
#
#*Frame update
#
def update
if Input.trigger?(Input::CTRL)
$scene = Scene_Map.new
end
#Check for inputs for every different key
if Input.trigger?(Input::ONE)
Audio.se_play("Audio/SE/C4",100,100)
@string += 'C4'
@animation[21] = 0
@piano_dummy.refresh(21)
end
if Input.trigger?(Input::TWO)
Audio.se_play('Audio/SE/Cs4',100,100)
@string += 'Cs4'
@animation[43] = 0
@piano_dummy.refresh(43)
end
if Input.trigger?(Input::THREE)
Audio.se_play("Audio/SE/D4",100,100)
@string += 'D4'
@animation[22] = 0
@piano_dummy.refresh(22)
end
if Input.trigger?(Input::FOUR)
Audio.se_play("Audio/SE/Ds4",100,100)
@string += 'Ds4'
@animation[44] = 0
@piano_dummy.refresh(44)
end
if Input.trigger?(Input::FIVE)
Audio.se_play("Audio/SE/E4",100,100)
@string += 'E4'
@animation[23] = 0
@piano_dummy.refresh(23)
end
if Input.trigger?(Input::SIX)
Audio.se_play("Audio/SE/F4",100,100)
@string += 'F4'
@animation[24] = 0
@piano_dummy.refresh(24)
end
if Input.trigger?(Input::SEVEN)
Audio.se_play("Audio/SE/Fs4",100,100)
@string += 'Fs4'
@animation[45] = 0
@piano_dummy.refresh(45)
end
if Input.trigger?(Input::EIGHT)
Audio.se_play("Audio/SE/G4",100,100)
@string += 'G4'
@animation[25] = 0
@piano_dummy.refresh(25)
end
if Input.trigger?(Input::NINE)
Audio.se_play('Audio/SE/Gs4',100,100)
@string += 'Gs4'
@animation[46] = 0
@piano_dummy.refresh(46)
end
if Input.trigger?(Input::ZERO)
Audio.se_play('Audio/SE/A4',100,100)
@string += 'A4'
@animation[26] = 0
@piano_dummy.refresh(26)
end
if Input.trigger?(Input::DASH)
Audio.se_play('Audio/SE/As4',100,100)
@string += 'As4'
@animation[47] = 0
@piano_dummy.refresh(47)
end
if Input.trigger?(Input::IS)
Audio.se_play('Audio/SE/B4',100,100)
@string += 'B4'
@animation[27] = 0
@piano_dummy.refresh(27)
end
if Input.trigger?(Input::QQ)
Audio.se_play('Audio/SE/C3',100,100)
@string += 'C3'
@animation[14] = 0
@piano_dummy.refresh(14)
end
if Input.trigger?(Input::WW)
Audio.se_play('Audio/SE/Cs3',100,100)
@string += 'Cs3'
@animation[38] = 0
@piano_dummy.refresh(38)
end
if Input.trigger?(Input::E)
Audio.se_play('Audio/SE/D3',100,100)
@string += 'D3'
@animation[15] = 0
@piano_dummy.refresh(15)
end
if Input.trigger?(Input::RR)
Audio.se_play('Audio/SE/Ds3',100,100)
@string += 'Ds3'
@animation[39] = 0
@piano_dummy.refresh(39)
end
if Input.trigger?(Input::T)
Audio.se_play('Audio/SE/E3',100,100)
@string += 'E3'
@animation[16] = 0
@piano_dummy.refresh(16)
end
if Input.trigger?(Input::YY)
Audio.se_play('Audio/SE/F3',100,100)
@string += 'F3'
@animation[17] = 0
@piano_dummy.refresh(17)
end
if Input.trigger?(Input::U)
Audio.se_play('Audio/SE/Fs3',100,100)
@string += 'Fs3'
@animation[40] = 0
@piano_dummy.refresh(40)
end
if Input.trigger?(Input::I)
Audio.se_play('Audio/SE/G3',100,100)
@string += 'G3'
@animation[18] = 0
@piano_dummy.refresh(18)
end
if Input.trigger?(Input::O)
Audio.se_play('Audio/SE/Gs3',100,100)
@string += 'Gs3'
@animation[41] = 0
@piano_dummy.refresh(41)
end
if Input.trigger?(Input:
)
Audio.se_play('Audio/SE/A3',100,100)
@string += 'A3'
@animation[19] = 0
@piano_dummy.refresh(19)
end
if Input.trigger?(Input::LBRACK)
Audio.se_play('Audio/SE/As3',100,100)
@string += 'As3'
@animation[42] = 0
@piano_dummy.refresh(42)
end
if Input.trigger?(Input::RBRACK)
Audio.se_play('Audio/SE/B3',100,100)
@string += 'B3'
@animation[20] = 0
@piano_dummy.refresh(20)
end
if Input.trigger?(Input:
)
Audio.se_play('Audio/SE/C2',100,100)
@string += 'C2'
@animation[7] = 0
@piano_dummy.refresh(7)
end
if Input.trigger?(Input::Y)
Audio.se_play('Audio/SE/CS2',100,100)
@string += 'Cs2'
@animation[33] = 0
@piano_dummy.refresh(33)
end
if Input.trigger?(Input::Z)
Audio.se_play('Audio/SE/D2',100,100)
@string += 'D2'
@animation[8] = 0
@piano_dummy.refresh(8)
end
if Input.trigger?(Input::F)
Audio.se_play('Audio/SE/Ds2',100,100)
@string += 'Ds2'
@animation[34] = 0
@piano_dummy.refresh(34)
end
if Input.trigger?(Input::G)
Audio.se_play('Audio/SE/E2',100,100)
@string += 'E2'
@animation[9] = 0
@piano_dummy.refresh(9)
end
if Input.trigger?(Input::H)
Audio.se_play('Audio/SE/F2',100,100)
@string += 'F2'
@animation[10] = 0
@piano_dummy.refresh(10)
end
if Input.trigger?(Input::J)
Audio.se_play('Audio/SE/Fs2',100,100)
@string += 'Fs2'
@animation[35] = 0
@piano_dummy.refresh(35)
end
if Input.trigger?(Input::K)
Audio.se_play('Audio/SE/G2',100,100)
@string += 'G2'
@animation[11] = 0
@piano_dummy.refresh(11)
end
if Input.trigger?(Input::L)
Audio.se_play('Audio/SE/Gs2',100,100)
@string += 'Gs2'
@animation[36] = 0
@piano_dummy.refresh(36)
end
if Input.trigger?(Input::COLON)
Audio.se_play('Audio/SE/A2',100,100)
@string += 'A2'
@animation[12] = 0
@piano_dummy.refresh(12)
end
if Input.trigger?(Input::QUOTE)
Audio.se_play('Audio/SE/As2',100,100)
@string += 'As2'
@animation[37] = 0
@piano_dummy.refresh(37)
end
if Input.trigger?(Input::C)
Audio.se_play('Audio/SE/B2',100,100)
@string += 'B2'
@animation[13] = 0
@piano_dummy.refresh(13)
end
if Input.trigger?(Input::LSHIFT)
Audio.se_play('Audio/SE/C1',100,100)
@string += 'C1'
@animation[0] = 0
@piano_dummy.refresh(0)
end
if Input.trigger?(Input::ZZ)
Audio.se_play('Audio/SE/Cs1',100,100)
@string += 'Cs1'
@animation[28] = 0
@piano_dummy.refresh(28)
end
if Input.trigger?(Input::XX)
Audio.se_play('Audio/SE/D1',100,100)
@string += 'D1'
@animation[1] = 0
@piano_dummy.refresh(1)
end
if Input.trigger?(Input::CC)
Audio.se_play('Audio/SE/Ds1',100,100)
@string += 'Ds1'
@animation[29] = 0
@piano_dummy.refresh(29)
end
if Input.trigger?(Input::V)
Audio.se_play('Audio/SE/E1',100,100)
@string += 'E1'
@animation[2] = 0
@piano_dummy.refresh(2)
end
if Input.trigger?(Input::BB)
Audio.se_play('Audio/SE/F1',100,100)
@string += 'F1'
@animation[3] = 0
@piano_dummy.refresh(3)
end
if Input.trigger?(Input::N)
Audio.se_play('Audio/SE/Fs1',100,100)
@string += 'Fs1'
@animation[30] = 0
@piano_dummy.refresh(30)
end
if Input.trigger?(Input::M)
Audio.se_play('Audio/SE/G1',100,100)
@string += 'G1'
@animation[4] = 0
@piano_dummy.refresh(4)
end
if Input.trigger?(Input::COMMA)
Audio.se_play('Audio/SE/Gs1',100,100)
@string += 'Gs1'
@animation[31] = 0
@piano_dummy.refresh(31)
end
if Input.trigger?(Input::DOT)
Audio.se_play('Audio/SE/A1',100,100)
@string += 'A1'
@animation[5] = 0
@piano_dummy.refresh(5)
end
if Input.trigger?(Input::FS)
Audio.se_play('Audio/SE/As1',100,100)
@string += 'As1'
@animation[32] = 0
@piano_dummy.refresh(32)
end
if Input.trigger?(Input::RSHIFT)
Audio.se_play('Audio/SE/B1',100,100)
@string += 'B1'
@animation[6] = 0
@piano_dummy.refresh(6)
end
#update lighting effects
animation
#Check for code input
if @required != nil
#If mode is free input
if @mode == 0
#If correct code was input
if @string == @required
Audio.se_play('Audio/SE/055-Right01',100,100)
$game_switches[@switch] = true
$scene = Scene_Map.new
end
#If mode is specific input length
elsif @mode == 1
#When string length is correct
if @string.gsub(/[1-4]/){nil}.gsub(/s/){nil}.length ==
@required.gsub(/[1-4]/){nil}.gsub(/s/){nil}.length
if @string == @required
Audio.se_play('Audio/SE/055-Right01',100,100)
$game_switches[@switch] = true
$scene = Scene_Map.new
else
Audio.se_play('Audio/SE/057-Wrong01',100,100)
$game_switches[@switch] = false
@string = ''
end
end
#If mode is quit after input length
elsif @mode == 2
#When string length is correct
if @string.gsub(/[1-4]/){nil}.gsub(/s/){nil}.length ==
@required.gsub(/[1-4]/){nil}.gsub(/s/){nil}.length
if @string == @required
Audio.se_play('Audio/SE/055-Right01',100,100)
$game_switches[@switch] = true
$scene = Scene_Map.new
else
Audio.se_play('Audio/SE/057-Wrong01',100,100)
$game_switches[@switch] = false
$scene = Scene_Map.new
end
end
end
end
end
#
#*animation
#
#Takes care of animating the keys' lighting effects
#
def animation
for i in
[email protected]
if @animation
== 0
#Create lighting effect for the key
@piano_dummy.refresh(i)
end
#Unless animation "i" is active
unless @animation == -1
#Progress a frame
@animation += 1
#If animation has been on for 8 frames
if @animation == 8
#Remove lighting effect
@piano_dummy.clear(i)
#Turn off the animation
@animation = -1
end
end
end
end
end
#==============================================================================
#**Spriteset_Piano
#
#This class takes care of drawing the piano's graphics onscreen
#==============================================================================
class Spriteset_Piano
#
#*Object initialization
#
def initialize
@viewport = Viewport.new(0,150,640,480)
@viewport.z = 5000
@sprite = Sprite.new(@viewport)
@piano = RPG::Cache.picture('Piano.png')
@sprite.bitmap = @piano
end
#
#*Dispose
#
def dispose
@viewport.dispose
@sprite.dispose
end
end
#==============================================================================
#**Piano_Dummy
#
#This class draws the piano's lighting effects
#==============================================================================
class Piano_Dummy
#
#*Object initialization
#
def initialize
@sprite = []
@lights = RPG::Cache.picture('Piano Lights')
#Create a rect for the different keys
@rect = Rect.new(0,0,22,93)
@rect2 = Rect.new(24,0,22,93)
@rect3 = Rect.new(48,0,22,93)
@rect4 = Rect.new(72,0,12,50)
end
#
#*Refresh
#
def refresh(key)
#create a new bitmap for the key's lighting effect
if @sprite[key] == nil
@sprite[key] = Sprite.new
@sprite[key].bitmap = Bitmap.new(640,480)
@sprite[key].z = 9999
@sprite[key].visible = false
end
#Clear lighting effect to avoid overlap
@sprite[key].bitmap.clear
#If key is a white key
if key < 28
x = key * 22 + 1*(key -1)
y = 150
if key > 17
x -= 1
end
#Create correct effect in the given bitmap
case key % 7
when 0
@sprite[key].bitmap.blt(x,y,@lights,@rect)
when 1
@sprite[key].bitmap.blt(x,y,@lights,@rect2)
when 2
@sprite[key].bitmap.blt(x,y,@lights,@rect3)
when 3
@sprite[key].bitmap.blt(x,y,@lights,@rect)
when 4
@sprite[key].bitmap.blt(x,y,@lights,@rect2)
when 5
@sprite[key].bitmap.blt(x,y,@lights,@rect2)
when 6
@sprite[key].bitmap.blt(x,y,@lights,@rect3)
end
#If key is a black key
else
x = 13 + (key - 28) * 28
y = 150
#Create x offsets for different key groups
if (key - 28) > 1
x += 12
if (key - 28) == 4
x -= 2
end
end
if (key - 28) > 4
x += 10
end
if (key - 28) > 6
x += 10
if (key - 28) == 9
x -= 2
end
end
if (key - 28) > 9
x += 10
end
if (key - 28) > 11
x += 10
if key - 28 == 12
x += 2
end
if key - 28 == 14
x -= 2
end
end
if (key - 28) > 14
x += 11
end
if (key - 28) > 16
x += 10
if key - 28 == 17
x+= 2
end
end
#Create correct effect in the given bitmap
@sprite[key].bitmap.blt(x,y,@lights,@rect4)
end
#Make lighting effect visible
@sprite[key].visible = true
end
#
#*Dispose
#
def dispose
for i in
[email protected]
unless @sprite
== nil
@sprite.dispose
end
end
end
#
#*clear
#
#Removes the specified key's lighting bitmap when called
#
def clear(key)
if @sprite[key] != nil
@sprite[key].dispose
@sprite[key] = nil
end
end
end
class Window_PianoHelp < Window_Base
def initialize
super(0,0,640,64)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.draw_text(0,0,640,32,"Press the 'Ctrl' button to exit")
end
end