Main Menu
  • Welcome to The RPG Maker Resource Kit.

Character Hover Graphics

Started by modern algebra, January 25, 2009, 05:15:53 AM

0 Members and 1 Guest are viewing this topic.

modern algebra

Character Hover Graphics
Version: 1.3
Author: modern algebra
Date: March 10, 2009

Version History




  • <Version 1.3> 03.10.2009 - You can now use animated pictures and set them above the characters
  • <Version 1.2> 03.10.2009 - Allowed the option to set font colour and size when setting text to float
  • <Version 1.1> 01.27.2009 - Fixed Bug with map scrolling
  • <Version 1.0b> 01.26.2009 - Fixed Bounce
  • <Version 1.0> 01.25.2009 - Original Release

Description



This script allows you to place a graphic to hover over any characters in the map. Like in Diablo, when an NPC has something important to say, you can place an exclamation mark or any other thing else over his/her head.

Features


  • Can show either a picture or text over any event or the player
  • Allows for showing animated pictures
  • Can set colour and size of text if drawing it
  • Option to have the graphic bounce up and down or not.
  • easy call script functionality

Screenshots



Instructions

Please see the header of the script.

Script




#==============================================================================
#  Character Hover Graphics
#  Version: 1.3
#  Author: modern algebra
#  Date: March 10, 2009
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Instructions:
#    Place this script above Main and below Materials.
#
#   To have a graphic hover, first you need to import the picture that you want
#  to have hovering in the Pictures folder. Then, you can place it over any
#  event with this in a call script:
#
#      set_hover_graphic (char_index, picture, bouncing_boolean, colour, size)
#
#    Where:
#      *char_index is the index of the event that you want it to hover over. If
#         this is set to -1, it will be over the player. If it is set to 0, it
#         will be over the current event. If it is set to any other ID, then it
#         will be over the event with that ID. If this is not set, it is
#         assumed to be 0
#      *picture is the name of the picture that you want to have hovering in
#         quotation marks. So, if your picture is named Exclamation! then
#         you would put: "Exclamation!" here. Remember, these graphics must be
#         in your Pictures folder. If the picture you denote is not in the
#         Picture file, then it will instead draw the actual word you send
#         through. If you set this to nil, then it will turn off any graphic
#         currently hovering over the specified event. If you leave this space
#         blank, it will default to nil.
#           If the name of the picture is prefaced by %[x], then the picture
#         will animate, with x being the number of frames. SO, a picture that
#         is named %[6]Teardrop and is 192 x 32, will consist of 6 frames, each
#         32 x 32 cutouts of the file. If you do not specify a number of frames
#         and merely preface the file with %, then it will default to 4 frames.
#      *bouncing boolean is either true or false, where true means that the
#         graphic will bounce up and down and false meaning it will be
#         stationary. If it is not set, then it defaults to false
#      *colour is the color you want the text drawn in, and this will only work
#         if it is writing text, not using a picture. If you set this as an
#         integer, it will take the colour of the corresponding index from the
#         windowskin palette. If you put an array, it will take that as the
#         RGB values. So, [255, 0, 0] would be RED, etc... If you leave this
#         blank, it defaults to 0, so the normal color on the windowskin palette.
#      *size is the size of the text. Again, this matters only if it is text
#         being drawn and not a picture. This determines the size of the text
#         drawn. If left blank, it will default to 20.
#
#   EXAMPLES:
#
#     set_hover_graphic (0, "Exclamation!")
#         - Assuming there is a picture in your Pictures folder named
#       "Exclamation!", it will set that picture to hover over the event that
#       calls it. If no such picture exists, it will print the text:
#       "Exclamation!" over the character
#  
#     set_hover_graphic (5, "?", true)
#         - Assuming there is a picture in your Pictures folder named "?", it
#       will set that picture to hover over the event with ID 5. If
#       no such picture exists, it will print a question mark over Event 5. It
#       will be bouncing.
#
#     set_hover_graphic (-1, "Player Name", false, 8, 28)
#         - This will print "Player Name" over the player. It will not be
#       bouncing. It will be drawn in the colour with index 8 on the windowskin
#       pallette. It will be size 28.
#
#     set_hover_graphic (-1)
#         - Will delete any hover graphic that is over the player.
#==============================================================================
# ** Game_Character
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new instance variable - ma_hover_graphic, ma_hgfloat
#==============================================================================

class Game_Character
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Public Instance Variable
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 attr_accessor :ma_hover_graphic # The picture name of hover graphic
 attr_accessor :ma_hgfloat       # Boolean on bouncing
 attr_accessor :ma_hgcolour      # Colour of text
 attr_accessor :ma_hgsize        # Size of text
end

#==============================================================================
# ** Game Interpreter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new method - set_hover_graphic
#==============================================================================

class Game_Interpreter
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Set Hover Graphic
 #    char_index   : the index of the character
 #    picture_name : the picture to show over the character
 #    float        : boolean with whether or not you want graphic to bounce
 #    colour       : integer -> windowskin palette; array -> RGB
 #    size         : the size of the text
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def set_hover_graphic (char_index = 0, picture_name = nil, float = false, colour = 0, size = 20)
   # Get Character
   char_index = @event_id if char_index == 0
   target = char_index == -1 ? $game_player : $game_map.events[char_index]
   return if target == nil
   target.ma_hover_graphic = picture_name
   target.ma_hgfloat = picture_name == nil ? nil : float
   if colour.is_a? (Array)
     colour.push (255) while colour.size < 4
   else
     windowskin = Cache.system ("Window")
     clr = windowskin.get_pixel(64 + (size % 8) * 8, 96 + (size / 8) * 8)
     colour = clr.alpha == 0 ? [255, 255, 255, 255] : [clr.red, clr.green, clr.blue, clr.alpha]
   end
   target.ma_hgcolour = colour
   target.ma_hgsize = size.is_a? (Integer) ? size : 20
 end
end
 
#==============================================================================
# ** Sprite Character
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Chages:
#    aliased methods - dispose, update
#    new method - ma_start_hover_graphic, ma_update_hover_graphic,
#           ma_dispose_hover_graphic
#==============================================================================

class Sprite_Character
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Dispose
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 alias modlg_hvr_graphc_dispse_94nb5 dispose
 def dispose
   # Dispose hover graphic
   ma_dispose_hover_graphic
   # Run Original Method
   modlg_hvr_graphc_dispse_94nb5
 end
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Frame Update
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 alias malg_hover_grfx_upd_char_954bn update
 def update
   # Run Original Method
   malg_hover_grfx_upd_char_954bn
   # Update Hover Graphic
   if @hover_sprite == nil && @character.ma_hover_graphic != nil
     ma_start_hover_graphic (@character.ma_hover_graphic, @character.ma_hgfloat,
                               @character.ma_hgcolour, @character.ma_hgsize)
   end
   ma_update_hover_graphic
 end
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Start Hover Graphic
 #    picture_name : the name of the picture to float
 #    float        : boolean on whether picture should float
 #    colour       : the colour of the text
 #    size         : the size of the text
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def ma_start_hover_graphic (picture_name, float, colour, size)
   ma_dispose_hover_graphic
   @hover_sprite = ::Sprite.new(viewport)
   begin
     # Use picture if it exists
     bmp = Cache.picture (picture_name)
     if picture_name[/^%(\[(\d+)\])?/] != nil # If animated graphic
       # Split into an array of bitmaps
       @frame_bmp_array = []
       frames_n = $2 == nil ? 4 : $2.to_i
       width = bmp.width / frames_n
       for i in 0...frames_n
         frame_bmp = Bitmap.new (width, bmp.height)
         frame_bmp.blt (0, 0, bmp, Rect.new (i*width, 0, width, bmp.height))
         @frame_bmp_array.push (frame_bmp)
       end
       bmp.dispose
       @hover_sprite.bitmap = @frame_bmp_array[0]
       @gframe_count = 0
       @frame_index = 0
     else
       @hover_sprite.bitmap = bmp
     end
   rescue
     # Else draw the word
     @hover_sprite.bitmap = Bitmap.new (32, 32)
     # Retrieve actual string
     ts = @hover_sprite.bitmap.text_size (picture_name)
     # Resize bitmap if too long
     if ts.width + 4 > @hover_sprite.bitmap.width
       @hover_sprite.bitmap.dispose
       @hover_sprite.bitmap = Bitmap.new (ts.width + 4, [ts.height + 4, 32].max)
     end
     # Draw text
     @hover_sprite.bitmap.font.color = Color.new (colour[0], colour[1], colour[2], colour[3])
     @hover_sprite.bitmap.font.size = size
     @hover_sprite.bitmap.draw_text (0, 0, @hover_sprite.bitmap.width, 32, picture_name, 1)
   end
   @gframe_count = -1 if @gframe_count != 0
   @hover_sprite.x = self.x - (@hover_sprite.bitmap.width / 2)
   @hover_sprite.y = self.y - self.height - @hover_sprite.bitmap.height
   @hover_sprite.z = z + 200
   @float_count = float ? 0 : -1
   @float_y = 0
   @ma_last_xy = [self.x, self.y]
 end
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Update Hover Graphic
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def ma_update_hover_graphic
   ma_dispose_hover_graphic if @character.ma_hover_graphic == nil
   return if @hover_sprite == nil
   # Reset x, y if map has scrolled
   if @ma_last_xy != [self.x, self.y]
     @hover_sprite.x = self.x - (@hover_sprite.bitmap.width / 2)
     @hover_sprite.y = self.y - self.height - @hover_sprite.bitmap.height + @float_y
     @ma_last_xy = [self.x, self.y]
   end
   # If the bitmap is animated
   if @gframe_count != -1
     # Count up
     @gframe_count += 1
     # Change graphics ever 8 frames
     if @gframe_count == 12
       @gframe_count = 0
       @frame_index = (@frame_index + 1) % @frame_bmp_array.size
       @hover_sprite.bitmap = @frame_bmp_array[@frame_index]
     end
   end
   # If bouncing
   if @float_count != -1
     @float_count += 1
     # Modify y every 2 frames
     return if @float_count % 2 == 0
     # If not yet asceneded 8 pixels
     if @float_count <= 16
       @hover_sprite.y -= 1
       @float_y -= 1
     else # Return to original position
       @hover_sprite.y += 1
       @float_y += 1
       @float_count %= 28
     end
   end
 end
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # * Dispose Hover Graphic
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 def ma_dispose_hover_graphic
   if @hover_sprite != nil
     @hover_sprite.dispose
     @frame_bmp_array.each { |bmp| bmp.dispose unless bmp.disposed? } if @frame_bmp_array != nil
     @hover_sprite = nil
     @ma_last_xy = nil
     @gframe_count = nil
     @frame_index = nil
     @float_count = nil
     @float_y = nil
   end
 end
end


Credit




  • modern algebra

Thanks


  • lomastul, for requesting the script
  • sasofrass, for suggesting ading option to set colour and size
  • grafikal009, for suggesting animated icons

Support


Please post in this topic at RMRK for the swiftest support.

Known Compatibility Issues

No known compatibility issues. If you do encounter something, try placing this script below all of your other custom scripts and see if the problem persists.

Author's Notes



If you post this script elsewhere, please link to this topic at RMRK so that people know where to go for updates and support.




SouthWall

Looks good. I'll have to take a closer look at the bouncing graphic feature a bit later.

Aindra

When I set the bouncing flag to true, it does work...

However, the bouncing picture do not return back to its original place, precisely. It does bounce but slowly the picture is advancing down. It can even go down past the event it's supposed to be above.

My picture is 32x32 pixels, same as the tile.

The picture will reset back to its original place when I receive some item from different chest on same map.

modern algebra

Weird, I had thought I fixed that.

Anyway, I replaced the code in the first post with one that ought to work - try it now.

Aindra

It works as it intended now. Many thanks!

Heartofshadow

This definitely caught my eye and looked really nice. So I stuck it in a project to test it out.. and came up with what I call an error.

When I call the script, and it hovers an image or text over an event, should the player move and cause the screen to have to scroll.. the hovering image or text goes along with the screen.

Is this something that's fixable.. or just has to be dealt with?


-Heart of Shadow-

"How can I be expected to save the world, when I can't even save myself?" --Sysolos(Return of a Shadow Lord)

modern algebra

It is fixable. I will do so soon. Thank you for notifying me of the error.

modern algebra

OK, it should be fixed now. The first post has been updated with the corrected code.

Heartofshadow

Righteous. Just tried out the updated script and it works wonderfully.

No more "errors" that I could spot right off the bat. =P

Nicely done, MA.

"How can I be expected to save the world, when I can't even save myself?" --Sysolos(Return of a Shadow Lord)

jick6

Sweet. 'Cuz I think I'm sick of placing an event above an NPC to display an icon of some sort that has to move with the NPC.
Might use this though I don't think I'll be finishing any games anytime soon, since I'm still experimenting and such.
You've just been obliteraped!

Currently Working On: One Day Salesman
http://rmrk.net/index.php/topic,33234.0.html

Craze

Heh. I really like this script. I'm using it so that the player can easily know which NPC out of the fifty billion in each pub or whatever is the vendor/innkeeper/mentor/etc.; basically, I'm using it to distinguish service NPCs from the commonfolk.

Good work. =D

Grafikal

Hey MA, do you think you will make it optional to have the icons be animated? (I mean besides bouncing) That'd be awesome

modern algebra

#12
Version 1.2 released

Not much different, but someone on another forum suggested that it would be a good idea to be able to set the colour and the size when drawing text, and I agreed. So that's that.

@grafikal: animated icons sounds cool. Do you have any specific format you would like that in?

Grafikal

Nothing specific, I think it'd be awesome to have something animate around like if a player were poisoned, it could visually show it, or an NPC rather.

Heartofshadow

An idea for the animated suggestion: It could use a "characterset" type thing, like the balloon emotes do.

I don't know how hard that would be to implement, but I think that'd be kinda cool. The Tankentai SBS has a feature similar to this in that when an actor is at critical HP, the sweatdrop emote will loop it's animation over their head until they die or get healed above that critical point. That is prolly the closest existing example to what my idea is.

Just throwing some thoughts out there. Lemme know if you'd like any clarification or something.


-Heart of Shadow-

"How can I be expected to save the world, when I can't even save myself?" --Sysolos(Return of a Shadow Lord)

modern algebra

#15
Yeah, that sounds like something of what I'll do. I think I will make it just so that there is a character that, if at the start of the name identifies it as animated, and you can set the number of frames in the filename, so like:

%[4]Exclamation

or something, and what that would do is make it so that it will cycle between 4 frames. I don't think I will make speed an option...

And the frames will go across, so if Exlamation is 84 x 32, each frame would be 21 x 32


EDIT::

OK, Version 1.3 is now up. Please inform me if you encounter any bugs.

junkofly

#16
Really good script Modern Algebra.  ;D :P

But I was wondering if there was somewhere i could get a yellow exclamation mark, a grey question mark and a yellow question mark images (32x32 pixels)that I could put over NPCs and which would be used to do available quest, unfinished quest and finished quests like the most RPG based-games uses. Thanks and like I said really good script :P I love it.

modern algebra

I'm sure it wouldn't be hard to make them. Do you have an image editing program? Because then you could make thin in whatever font and shade you want. I can make them for you if you don't.

The font I used is Black Rose

Ariost

Is there any way to make it only show for a few seconds at each map transition?

If you've ever played Final Fantasy IX, I'm referring to the way to HERE Icon works.

Every time you transition from map to map, a pointer shows over the character's head for a few seconds, then disappears, but can be called to show permanently at the press of the Select Button.

Any way to do that with this? I'm sure it's possible.

modern algebra

Well, the easiest way is just with a parallel process at the beginning of each map.

Something like:

Script: set_hover_graphic (-1, "Here Arrow")
Wait: 240 Frames
Script: set_hover_graphic (-1)
Erase Event

Ariost

#20
Well that definitely works, thank you!

EDIT: Okay so maybe not, I get a syntax error. But that's fine, I suppose I can work with the overhead view always being there.

modern algebra

It works for me. Can you screenshot the event that you do it in?


Ariost

Sure thing.

http://i25.tinypic.com/2nslxg9.jpg

But after five seconds of looking over at the screenshot I took, I figured out what the problem was. Sorry about that.

Once again, great script. I appreciate the time and effort you must've put into this.

modern algebra

yeah, well you shouldn't let the command go to two lines since it evaluates them separately.

instead, you could put:

n = "pointerdown"
set_hover_graphic (-1, n)


but yeah, you said you figured it out so that was probably unnecessary.

SuperMega

I hate to necropost, but I've got a script error I haven't figured out how to fix:



This is what I have for the event:

http://img191.imageshack.us/img191/2319/hovererror2.png