Adding New ImageManager Entries to Display Portaits in Windows

Kenen

Veteran
Veteran
Joined
Apr 3, 2012
Messages
256
Reaction score
153
First Language
English
Primarily Uses
RMMV
Preface: I'm a programming newbie. I am making some adjustments to Window_Status, which include loading a portrait image for actors instead of a face image. To do this, I piggybacked off of the existing drawActorFace methods, including adding a .loadPortrait entry to the ImageManager.

The issue that I am having is that the portrait does not load the first time that I open the status window, but it does load the second time that I do. I am adding a video that displays the problem as well as my plugin code. Any pointers would be tremendously appreciated.

Video:




Code:

Code:
//-----------------------------------------------------------------------------// ImageManager//// The static class that loads images, creates bitmap objects and retains them.ImageManager.loadPortrait = function(filename, hue) {    return this.loadBitmap('img/portraits/', filename, hue, true);};//-----------------------------------------------------------------------------// Window_Base//// The superclass of all windows within the game.Window_Base.prototype.drawActorClass = function(actor, x, y, width) {    width = width || 168;    this.changeTextColor(this.systemColor());    this.drawText(actor.currentClass().name, x, y, width);    this.resetTextColor();};Window_Base.prototype.drawActorLevel = function(actor, x, y) {    this.changeTextColor(this.systemColor());    this.drawText(TextManager.levelA, x, y, 48);    this.drawText(actor.level, x, y, 36, 'right');    this.resetTextColor();};Window_Base.prototype.drawPortrait = function(faceName, faceIndex, x, y, width, height) {    var portraitWidth = 500;    var portraitHeight = 500;    width = width || portraitWidth;    height = height || portraitHeight;    var bitmap = ImageManager.loadPortrait(faceName);    var pw = portraitWidth;    var ph = portraitHeight;    var sw = Math.min(width, pw);    var sh = Math.min(height, ph);    var dx = Math.floor(x + Math.max(width - pw, 0) / 2);    var dy = Math.floor(y + Math.max(height - ph, 0) / 2);    var sx = faceIndex % 4 * pw + (pw - sw) / 2;    var sy = Math.floor(faceIndex / 4) * ph + (ph - sh) / 2;    this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);};Window_Base.prototype.drawActorPortrait = function(actor, x, y, width, height) {    this.drawPortrait(actor.faceName(), actor.faceIndex(), x, y, width, height);};//-----------------------------------------------------------------------------// Window_Status//// The window for displaying full status on the status screen.Window_Status.prototype = Object.create(Window_Selectable.prototype);Window_Status.prototype.constructor = Window_Status;Window_Status.prototype.initialize = function() {    var width = Graphics.boxWidth;    var height = Graphics.boxHeight;    Window_Selectable.prototype.initialize.call(this, 0, 0, width, height);    this.refresh();    this.activate();};Window_Status.prototype.standardPadding = function() {    return 1;};Window_Status.prototype.setActor = function(actor) {    if (this._actor !== actor) {        this._actor = actor;        this.refresh();    }};Window_Status.prototype.refresh = function() {    this.contents.clear();    if (this._actor) {        var lineHeight = this.lineHeight();        var offset = 17;        // Name, class, and level        this.drawActorName(this._actor, 23, (lineHeight * 0) + offset);        this.drawActorLevel(this._actor, 117, (lineHeight * 0) + offset);        this.drawActorClass(this._actor, 187, (lineHeight * 0) + offset);        this.drawHorzLine((lineHeight * 1) + offset);        // Profile        this.drawProfile(23, (lineHeight * 2) + offset);        this.drawHorzLine((lineHeight * 4) + offset);        // Stats and equipment        this.drawActorHp(this._actor, 23, (lineHeight * 5) + offset, 520);        this.drawActorMp(this._actor, 23, (lineHeight * 6) + offset + 15, 520);        this.drawParameters(23, (lineHeight * 8) + offset);        this.drawEquipmentsHeader(297, (lineHeight * 8) + offset);        this.drawEquipments(297, (lineHeight * 9) + offset);        // Portrait        this.drawActorPortrait(this._actor, Graphics.boxWidth - 500, 100);    }};Window_Status.prototype.drawHorzLine = function(y) {    var lineY = y + this.lineHeight() / 2 - 1;    this.contents.paintOpacity = 48;    this.contents.fillRect(17, lineY, this.contentsWidth() - 36, 2, this.lineColor());    this.contents.paintOpacity = 255;};Window_Status.prototype.lineColor = function() {    return this.normalColor();};Window_Status.prototype.drawParameters = function(x, y) {    var lineHeight = this.lineHeight();    for (var i = 0; i < 6; i++) {        // start paramId at 0 to draw HP and MP        var paramId = i + 0;        var y2 = y + lineHeight * i;        this.changeTextColor(this.systemColor());        this.drawText(TextManager.param(paramId), x, y2, 160);        this.resetTextColor();        this.drawText(this._actor.param(paramId), x + 160, y2, 60, 'right');    }};Window_Status.prototype.drawEquipmentsHeader = function(x, y) {    this.changeTextColor(this.systemColor());    this.drawText('Equipment', x, y, 200, 'left');    this.resetTextColor();  }Window_Status.prototype.drawEquipments = function(x, y) {    var equips = this._actor.equips();    var count = Math.min(equips.length, this.maxEquipmentLines());    for (var i = 0; i < count; i++) {        this.drawItemName(equips[i], x, y + this.lineHeight() * i);    }};Window_Status.prototype.drawProfile = function(x, y) {    this.drawTextEx(this._actor.profile(), x, y);};Window_Status.prototype.maxEquipmentLines = function() {    return 6;};
 

Evgenij

Veteran
Veteran
Joined
Aug 28, 2013
Messages
349
Reaction score
100
First Language
German
Primarily Uses
N/A
I had the same problem: http://forums.rpgmakerweb.com/index.php?/topic/48266-need-some-help-understanding-drawing-in-windows/

Nobody has answered my questions, but I figured it out by myself. The graphics are loaded asynchron.

Look at the Bitmap class. You can see that the class has an isReady function which returns true when the bitmap has finished loading.

I dont know if there are any simpler solutions but for the time being I have solved it by adding all the bitmaps I wanted to draw into an array after I have loaded them through the ImageManager:

Window_SimpleHud.prototype.loadImages = function () { var max = this.maxActors(); for (var i = 0; i < max; i++) { this._bitmaps.push(ImageManager.loadFace($gameParty.members().faceName())); };};Then I added a flag variable called _finishedLoading to my window class.

In the update method of my window I do this:

Window_SimpleHud.prototype.update = function () { Window_Base.prototype.update.call(this); // only do this as long as the bitmaps have not finished loading if (!this._finishedLoading) { // assume that everything loaded fine this._finishedLoading = true; // iterate over all bitmaps for (var i = 0; i < this._bitmaps.length; i++) { // if any bitmap has not finished set the flag to false and retry next frame if (!this._bitmaps.isReady()) { this._finishedLoading = false; break; }; }; // if everything loaded fine call the refresh method and redraw the pictures if (this._finishedLoading) this.refresh(); };};I haven't figured out how the maker handles this, so like I said there might be better solutions. If somebody has any info on this I would be glad to hear it. If I find out something more I will post it.
 
Last edited by a moderator:

Iavra

Veteran
Veteran
Joined
Apr 9, 2015
Messages
1,797
Reaction score
859
First Language
German
Primarily Uses
If you work with Sprites, the whole image loading will be handled for you. Like this:

Code:
new Sprite(Bitmap.load(...));
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

My first Video Scene - Kraken Art By @whtdragon -

Still needs work but its a start.
Considering a side project of making a Choose Your Own Adventure in MV but letting people play it as YouTube videos with the choices at the end leading to other videos. Thoughts?
I've made a rudimentary prototype map for the first game with the MV RTP overworld tiling. I'm probably going to photoshop the crap out of it for parallax, but the prototype has given me new ideas about how I want to place dungeons in the game.
I got tired of not having an avatar image. Couldn't think of anything cool. So I'm just using my game's antagonist instead... How original. At least both of our names start with C?
Expectation: Design/dev a game for the game jam | Reality: "These codes suck, why did I do it this way? lemme fix this. Also what if I add feature xyz because... well, I can."

Forum statistics

Threads
95,635
Messages
930,612
Members
125,950
Latest member
Tocilux
Top