Correct Character Sprite Display
#1
Correct Character Sprite Display

Version: 1.1



Introduction

VXAce thinks you only want to use baby-chibi sprites, and does not properly handle cases when character sprites are taller than a tile.


Script

Code:
#==============================================================================
#
# ▼ Moby's Script System - Correct Sprite Display V1.0
# -- Last Updated: 2013.01.26
#
#==============================================================================

$imported = {} if $imported.nil?
$imported["MSS-Correct_Sprite_Display"] = 1.0

#==============================================================================
# ▼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# (by brushfe) Tall events interact better with other tall events
#
#==============================================================================
# ▼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script corrects how sprites will be displayed, to prevent errors
# happening when the sprite is higher than 32px and the tile above it is set
# to star passability.
#
#==============================================================================
# ▼ Instructions
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# To install this script, open up your script editor and copy/paste this script
# to an open slot below ▼ Materials/素材 but above ▼ Main. Remember to save.
#
#
# If you have any questions, bugs you want to report or anything else,
# please contact me at mobychan@gmx.de or via my profile on
# http://forums.rpgmakerweb.com (mobychan).
#
#
# This script is Plug and Play.
# It automatically checks if the Sprite is bigger then 32px and adjust the
# tiles around that sprite accordingly.
# If you're using Anaryu's Particle Engine (ported by Yami)
# there won't be any issues.
#
#==============================================================================
# ▼ Compatibility
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# This script is made strictly for RPG Maker VX Ace. It is highly unlikely that
# it will run with RPG Maker VX without adjusting.
#
#==============================================================================
#
#==============================================================================
# ▼ Known Issues
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Really wide character sprites still are sometimes drawn behind tiles they
# should be in front of.
#==============================================================================



#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# This class brings together map screen sprites, tilemaps, etc. It's used
# within the Scene_Map class.
#==============================================================================

class Spriteset_Map
#--------------------------------------------------------------------------
# * Update Character Sprite
#--------------------------------------------------------------------------
alias msscsd_update_characters update_characters unless $@
def update_characters
msscsd_update_characters

@character_sprites.each do |curr_sprite|
if curr_sprite.character.class.name == "Game_Event" ||
curr_sprite.character.class.name == "Game_Player" ||
curr_sprite.character.class.name == "Game_Follower"
height = get_height(curr_sprite)

if height > 1
x = curr_sprite.character.x
curr_sprite.z = 100

id = $game_map.data[x, curr_sprite.character.y, 2]
flag_pos = $game_map.tileset.flags[id]

if (!(flag_pos & 0x10 != 0) || id == 0)
for i in 2..height
y = curr_sprite.character.y - (i - 1)

if !$game_map.data[x, y, 2].nil?
flag = $game_map.tileset.flags[$game_map.data[x, y, 2]]

if flag & 0x10 != 0 && # [☆]: No effect on passage
$game_map.data[x, y, 2] != 0
curr_sprite.z = 300
break
else
curr_sprite.z = 100
end
loc = [curr_sprite.character.x, curr_sprite.character.y - 1]
$game_map.events_xy(*loc).each do |event|
if curr_sprite.character.class.name == "Game_Player" ||
curr_sprite.character.class.name == "Game_Follower" ||
curr_sprite.character.class.name == "Game_Event"
curr_sprite.z = 300
break
end
end
end
end
end
end
end
end
end
#--------------------------------------------------------------------------
# * Gets the given Sprites height
#--------------------------------------------------------------------------
def get_height(curr_sprite)
height = 0

if curr_sprite.character.character_name.scan(/$/)
height = (curr_sprite.bitmap.height / 4) / 32
height += 1 if (curr_sprite.bitmap.height / 4) % 32 > 0
else
height = (curr_sprite.bitmap.height / 8) / 32
height += 1 if (curr_sprite.bitmap.height / 8) % 32 > 0
end
return height
end
#--------------------------------------------------------------------------
# * Add Particle
#--------------------------------------------------------------------------
def add_particle(target, name, blend, setting, offset, v = nil, a = nil)
particle = Particle.new(@viewport2, target, name, blend, setting, offset, v, a)
@particles.push(particle)
end
end


Instructions

Paste in Materials section. Weep at how 138 lines of code were needed to fix something Enterbrain could have done in 1.


Credits and Thanks

Script is by Moby, with changes made by brushfe to make character sprites overlap with other character sprites correctly


Author's Notes

Overly wide character sprites still have issues. If I ever try to make something with VXAce I'll see what I can do about fixing it.
TODO:
  • Check left and right of over-wide characters, and adjust those tiles/characters too.
  • Use multiple Z levels (not just 100 and 300) to make tall characters stack more correctly.

Terms and Conditions

Not my script, found on pastebin and http://www.rpgmakervxace.net using google. I just mixed the two edits together. Don't credit me credit these nice smart people instead,
Reply }
#2
I'm really screwing things up repeatedly with editing this script to try and improve perceived issues, ahaha.
  • This script does not take in account shift_y that makes sprites offset. If a game creator alters this, sprites extend further into other tiles. Editing the code to compensate for this, I then find that tall events standing under * tiles and the hero walking away from them there's momentary feet appearing over the hero.
  • I'm not sure why x-axis tiles are being a bother. I was unable to be successful with having a loop to check tiles either side of an event. Sometimes walking away from a * tile there's a moment where the tile will reappear over the hero. This is a problem with tiles like fences or reception desks. Other times it's the opposite, which might be caused by my edits. Reverting those avoids that.
  • It appears that even with the default offset of 4px, my sprites will cover three tiles. Their location, their upper body, and the smidgen of pixels they phase into. This is probably a cause of a large number of issues, as I edit things to consider their height and run into those issues.
I think the thing is, every tile and event needs to have a z value influenced by their y axis or height. This z value would only come into play if [*] passability for tiles, or if normal priority for events. The cause of these visual errors is because what we're getting basically are "sheets" of sprites, that are associated with z-axies, and the z-axies are associated with what's above (y) the sprite. Because this is checked as a sprite moves onto a tile and is based only on what's above them, weirdness occurs because an event that's not next to a [*] or similar will be on a lower (z) "sheet".

Except I think this would cause a lot of lag? Maybe it's part of the lag that plagued RMXP. RMXP had different levels of priority for [*] tiles, what maybe needs to be done is altering the priority of those tiles, not the event sprites.

This is what my experimentation resulted in anyway, I don't think it's much better. The only thing that's really that great is the terrain tag 7 check to make a tile always appear over the hero, which works for the likes of doorways.

PHP Code:
<?php 
#==============================================================================
# ▼ Moby's Script System - Correct Sprite Display V1.0
# -- Last Updated: 2014.02.05
# Edit by Taylor and brushfe
#==============================================================================

#==============================================================================
# ** Spriteset_Map
#==============================================================================

class Spriteset_Map
#--------------------------------------------------------------------------
# * Update Character Sprite
#--------------------------------------------------------------------------
alias :msscsd_update_characters :update_characters unless $@
def update_characters
# Original method
msscsd_update_characters
# On every sprite
@character_sprites.each do |curr_sprite|
# Determine if sprite has hero priority and visible
if curr_sprite.character.normal_priority? &&
curr_sprite.visible && curr_sprite.character.character_name != ""
# Get height in tiles
height = get_height(curr_sprite)
if
height > 1
x
= curr_sprite.character.x
#curr_sprite.z = 100
# Get tile data
id = $game_map.data[x, curr_sprite.character.y, 2]
flag_pos = $game_map.tileset.flags[id]
# Return if invalid tile
if (!(flag_pos & 0x10 != 0) || id == 0) # I HATE THIS LINE WITH A PASSION FOR NOT LETTING ME REPLACE IT WITH 'RETURN', FUCK
# Go through every tile the sprite may appear over
for i in 2..height
y
= curr_sprite.character.y - (i - 1)
# Return if invalid tile
return if $game_map.data[x, y, 2].nil?
flag = $game_map.tileset.flags[$game_map.data[x, y, 2]]
# If valid and not terrian ID 7
if flag & 0x10 != 0 && $game_map.data[x, y, 2] != 0 && $game_map.terrain_tag(x, y) != 7
curr_sprite
.z = 300 #+ curr_sprite.character.y
break
else
curr_sprite.z = 100
end
loc
= [curr_sprite.character.x, curr_sprite.character.y - 1]
$game_map.events_xy(*loc).each do |event|
if
event.normal_priority?
curr_sprite.z = 300 #+ curr_sprite.character.y
break
end
end
end
end
# (!(flag_pos & 0x10 != 0) || id == 0)
end
end
end
end
#--------------------------------------------------------------------------
# * Gets the given Sprites height
#--------------------------------------------------------------------------
def get_height(curr_sprite)
height = 0
height
= (curr_sprite.src_rect.height + curr_sprite.character.shift_y).to_f / 32
height
+= 1 if curr_sprite.src_rect.height % 32 > 0
return height.round + 1
end
end

(we could really do with a ruby tag with ruby syntax highlighting, 'cause this aint php)
Reply }
#3
Walking away (down I'm guessing) from a tile immediately sets your y one less, even though you are still MOSTLY on the previous tile. Running the loop for height+1 might help solve this. And is there some way to get a sprite's screen position? Because I see you tried to "300 + curr_sprite.character.y" which you probably discovered goes wrong when curr_sprite.character.y is large. Using a sprite's screen Y (if such a thing exists) could help fix that.
Reply }
#4
Screen-relative y is supposed to be a thing, but I I'm not sure what it's defined as. I want to say .y is it, but I'm not so sure.
Reply }
#5
Addendum: This is another script that performs the same function. It has some similar functions to my edit above, maybe improved.

Appearing over tiles is dependant on a terrain tag being visible instead of not, and events require a comment instead of being based on priority setting (normal_priority?). I want to edit this because it makes more sense to me to mark tiles that you want to appear over everything (high objects) than to mark tiles you want to appear in front of (a whole lot of ground level tiles).
Replacing terrain references with $game_map.terrain_tag(last_x, last_y) == UpperTerrain && $game_map.tile_id(last_x, last_y, 2) != 0 seems to do it, but I'm not why it still draws the upper dummy even on blank tiles. (Which may cause unnecessary lag?) I believe there are things I'm still misunderstanding about the conditions to draw the dummy area, this isn't the way to do it.
Events are a pain. Laggy. Better to set them <large sprite> on a case-by-case basis. Even then something is up somewhere. Hrmmm.

It also appears to not work on Victor Slant-script-altered followers in general??
Replacing an early line with return false unless @character.is_a?(Game_Player) || @character.is_a?(Game_Follower) seems to do it...
Reply }
#6
You misunderstand how to use that script. You use terrain tiles to mark which tiles you want to be in front of the character when its Y is the same as the sprite, and behind if the character is lower than the tile. The author did this so that you could use star tiles for ceilings as well.

If you want to make it so that all star tiles are treated as trees, just replace the check for a terrain tile with THIS script's check for a star tile.

( "## Creates the upper sprite that's a copy of the current sprite." That was the first way I tried to solve this problem! Unfortunately doing this way, correctly, means a sprite for every 32px you are tall, and that is a lot of sprites. Since this script doesn't do that, they'll be situations where you are in front of tiles that you should be behind.)
Reply }
#7
Hrm, yeah I'm not sure what it is, but it seems that the script I posted just works better by marking the "lower" star tiles, even "(flag & 0x10 != 0)", which I think is the priority check, doesn't seem to work the same. (And yes, I defined 'flag'.) Weird.

I tested this with tiles formatted as doorways and counters, and it seems that it only consistently worked with the script's default behaviour. Even though I was just swapping out the terrain tag check for the * check. It may also have something to do with X/O passability and proximity to tiles like that. I dunno.

But there's two scripts for this now, so hopefully either one of them is useful and functional for people.
Reply }


Possibly Related Threads…
Thread Author Replies Views Last Post
   Character's Dash Animation kyonides 0 767 04-08-2024, 03:50 AM
Last Post: kyonides
   Set Map's Display Name ACE kyonides 0 1,193 12-16-2022, 09:44 PM
Last Post: kyonides
   New Character Properties with Calls 2.2 PK8 9 21,974 06-11-2012, 10:46 PM
Last Post: PK8
   Victor Engine - Character Control Victor Sant 0 5,112 01-04-2012, 09:54 AM
Last Post: Victor Sant
   Victor Engine - Character Effects Victor Sant 0 4,683 01-01-2012, 02:08 PM
Last Post: Victor Sant
   Sprite Mover woratana 0 4,813 01-22-2009, 01:19 PM
Last Post: woratana
   Sprite Sun syvkal 0 5,440 03-08-2008, 04:36 AM
Last Post: syvkal
   Sprite Shadow syvkal 0 6,054 03-08-2008, 04:31 AM
Last Post: syvkal
   8-Directional Movement with Sprite Support Kylock 0 8,908 03-07-2008, 07:06 PM
Last Post: Kylock



Users browsing this thread: 2 Guest(s)