19

Ich arbeite derzeit an einem JavaScript(pure js) basierten Spiel. Das Spiel enthält 5 große Sprite-Blätter (z.B. 2861 × 768 und 4096 × 4864). Wenn das Spiel startet, werden alle 5 Sprite-Blätter auf Canvas-Elemente geladen. Drei dieser 5 Sprites repräsentieren zusammen eine Animation, wobei jedes Sprite 75 Frames enthält. Wenn ein Sprite mit seiner Animation endet, verstecke ich es und zeige das nächste Sprite an. Wenn das zweite Sprite aufhört zu animieren, verstecke ich es und zeige das dritte/letzte an.NW/Node Webkit - Bild decodiert, auch wenn es bereits sichtbar ist

Wenn das zweite oder dritte Sprite angezeigt wird, tritt eine kleine Verzögerung von 0,5 s - 1 s auf. Das Bild wird dekodiert.

Es ist nicht etwas, das passiert nur das erste Mal, es ist etwas, das immer passiert. Und diese Animation wiederholt sich alle 5 Minuten und die kleine Verzögerung passiert immer. Der Grund, warum ich Canvas-Elemente zum Vorladen verwende, ist der, dass ich dachte, dass WebKit decodierte Bilder für einige Zeit einfach wegwerfen würde und dass das Canvas-Element verhindern würde, dass WebKit es aus dem Speicher löscht. Aber das funktioniert nicht.

Ich habe fast jede Optimierung ausprobiert, die mir bekannt ist. Ich habe sogar alle meine CSS umgestaltet, indem ich Nachfahren-Selektoren usw. entfernt habe.

Der Renderer, den ich benutze, um diese Animationen zu zeichnen, ist von mir selbst gebaut und es funktioniert perfekt, so dass das Problem nicht sein konnte, da es sehr funktioniert gut in Firefox.

EDIT [2016/03/04]: Ich habe einen Modus mit Leinwand und das Ergebnis ist noch schlimmer. Es ist viel zu spät. Und die Verzögerung bleibt gleich. Nur in NW bleibt das Problem weder in Chrome noch in Firefox bestehen.

Canvas-Modus - Lags: enter image description here

Standard (HTML) Modus - Arbeitet perfekt: enter image description here

Codepen: Mein Renderer http://codepen.io/anon/pen/JXPWXX

Hinweis: Wenn ich die anderen verstecken Elemente mit opacity:0.2 anstatt opacity:0, das Problem tritt nicht auf. Aber ich kann sie nicht so verstecken, weil sie immer noch sichtbar sind. Sie sollten nicht sichtbar sein. Wenn ich opacity:0.01 hinzufüge ist es nicht sichtbar und das Problem tritt nicht in Chrome auf, aber bleibt in NW bestehen.

In NW, wenn ich von Opazität: 0,2 bis Opazität: 1, eine Bilddekodierung wird verarbeitet. Das Gleiche passiert nicht im Chrome-Browser. enter image description here

Ich verwende die folgende Version:

nw.js v0.12.3 
io.js v1.2.0 
Chromium 41.0.2272.76 
commit hash: 591068b-b48a69e-27b6800-459755a-2bdc251-1764a45 

Die drei Bilder Sprites sind 14.4MB, 14.9MB und 15.5MB Größe. Jedes Sprite enthält 75 Frames.

Warum könnte das passieren und wie kann ich das verhindern?

+1

Beachten Sie, dass dies nur in Node Webkit geschieht. Es funktioniert in Chrome gut. –

+1

Haben Sie sich den Müllsammler angesehen? Klingt wie der Garbage Collector, der die Pause verursacht. Entweder die Art, wie Sie mit den Canvases umgehen, oder vielleicht Ihr Renderer erstellt mehr Müll als Sie denken. – Bill

+3

Könnten Sie Code freigeben oder auf [JsFiddle] (https://jsfiddle.net/) setzen? –

Antwort

1

Versuchen Sie, direkt zu google-chrome zu wechseln, da die neue nw-Version wahrscheinlich am 19.04.2016 veröffentlicht wurde. Danach wird NW hoffentlich mit jedem Chromium-Release mithalten.

Sie sollten nicht die gleichen Probleme in Chrome haben.

0

Ich würde empfehlen, idata = ctx.getImageData(0, 0, canvas.width, canvas.height) zu verwenden, um das Datenarray von den Canvases abzurufen, dann ctx.putImageData(idata, 0, 0), um zwischen Sprites zu wechseln, anstatt die Canvases zu verstecken.

+0

Ich verwende Canvas-Elemente nur zum Vorladen. Aber ich werde Unterstützung für Canvas machen, und der "HTML" -Weg wird ein Fallback sein. Danke für die Empfehlung :) –

1

Da Webkit denkt, dass das Bild immer noch angezeigt wird, verschwindet das Problem (wie Ihr Opazitäts-Experiment zeigt), ich würde es fast vollständig aus dem sichtbaren Bereich herausbewegen, wobei nur eine einzige transparente Zeile das Ansichtsfenster überlappt (Überlauf ausgeblendet).

Beachten Sie, dass ein entpacktes 4000x4000 Sprite-Blatt 64 Megabyte RAM (4 Byte (= RGBA) pro Pixel) verwendet. Vielleicht ist es also besser, das nächste Bild ein wenig früher aufzuwärmen , ohne sie alle ständig ausgepackt zu halten?

+1

Obwohl ich schon etwas ähnliches versucht habe, werde ich das nochmal probieren und euch wissen lassen, ob es funktioniert. Danke für den Vorschlag :) Aber anstatt diesen Hack zu machen, wäre es besser für mich, zu Electron statt zu NW zu wechseln. Vorausgesetzt, dass Electron würde gut funktionieren. Ich werde nicht zu Electron wechseln und dieses Problem ungelöst lösen! : D –