Переверніть справа в полотні

Я використовую полотно для відображення деяких спрацьовувань, і мені потрібно перевернути горизонтально (так що це обличчя вліво або вправо). Однак я не бачу жодного способу це зробити за допомогою drawImage .

Ось мій відповідний код:

this.idleSprite = new Image();
this.idleSprite.src = "/game/images/idleSprite.png";
this.idleSprite.frameWidth = 28;
this.idleSprite.frameHeight = 40;
this.idleSprite.frames = 12;
this.idleSprite.frameCount = 0;

this.draw = function() {
        if(this.state == "idle") {
            c.drawImage(this.idleSprite, this.idleSprite.frameWidth * this.idleSprite.frameCount, 0, this.idleSprite.frameWidth, this.idleSprite.frameHeight, this.xpos, this.ypos, this.idleSprite.frameWidth, this.idleSprite.frameHeight);
            if(this.idleSprite.frameCount < this.idleSprite.frames - 1) { this.idleSprite.frameCount++; } else { this.idleSprite.frameCount = 0; }
        } else if(this.state == "running") {
            c.drawImage(this.runningSprite, this.runningSprite.frameWidth * this.runningSprite.frameCount, 0, this.runningSprite.frameWidth, this.runningSprite.frameHeight, this.xpos, this.ypos, this.runningSprite.frameWidth, this.runningSprite.frameHeight);
            if(this.runningSprite.frameCount < this.runningSprite.frames - 1) { this.runningSprite.frameCount++; } else { this.runningSprite.frameCount = 0; }
        }
    }

Як ви можете бачити, я використовую метод drawImage , щоб намалювати мої справи на полотно. Єдиний спосіб перевернути спрайт, який я бачу, це перевернути/повернути весь полотно, що я не хочу робити.

Чи є спосіб зробити це? Або мені доведеться зробити новий спрайт обличчям в інший бік і використовувати це?

20

3 Відповіді

Хоча Gaurav показав технічний спосіб перевернути справа в полотно ...

Не робіть цього для вашої гри.

Замість того, щоб зробити друге зображення (або збільшити поточне зображення), це перевернута версія зображень. Різниця в продуктивності між "перевертанням контексту та нанесенням зображення" проти "просто нанесення зображення" може бути масовою. У Opera і Safari перевертання полотно призводить до малюнка, що в десять разів повільніше, а в Chrome - в два рази повільніше. Див. цей jsPerf на прикладі.

Попереднє обчислення ваших перевернутих спрайтів завжди буде швидше, і в іграх холстину дійсно важливо.

33
додано
Дякую. Що я в кінцевому підсумку робив, додав ще один спрайт до мого існуючого (нижче), коли мій персонаж виконував інший спосіб, і додав якийсь код, щоб використовувати цей набір спрацьов в залежності від напрямку. Подібно до цього: i.imgur.com/uIPvF.png
додано Автор James Dawson, джерело
Виглядає добре! Незважаючи на те, що я буду переставляти новий рядок: вирівняйте перевернуту версію кожного вертикально, тому єдине, що потрібно змінювати при перегоні, - це координата y.
додано Автор Simon Sarris, джерело
Джефф ви підкреслюєте, що save і restore не потрібні, але ваш результат виявився потрясінням, перегляньте результати зараз. Можливо, ви почали тест, перш ніж браузер закінчив завантаження сторінки або Java (використовується в таймері). Я б стверджував, що тест не є точним при /4 , тому що робота, необхідна для перевертання, також повинна включати роботу, щоб повернути перетворення в його звичайний стан. Це означає щонайменше один другий виклик до ctx.scale (-1,1) . Ось "чесний" тест, і перевертання відбувається повільніше в кожному браузері та на мобільному пристрої, проте це дуже часто: jsperf.com/ctx-flip-performance/5
додано Автор Simon Sarris, джерело
Вауа! Ви просто показали щось дуже важливе. Функція налаштування Jsperf розбита і не очищує полотно! Див. jsperf.com/ctx-flip-performance/10 для того, що відбудеться, якщо я явно ясно усередині тесту, і див. у розділі jsfiddle.net/sX2jT за те, що дійсно відбувається. scale завжди множить, його помилка з jsperf ми бачимо :(
додано Автор Simon Sarris, джерело
Відповідь Гаура - це дійсно дорога робота через ctx.save/restore. Насправді, якщо ви просто називаєте ctx.scale (...) кожен раз, весело перетворюється версія швидше: jsperf.com/ctx-flip-performance/3 . (це ще швидше, якщо ви називаєте ctx.scale (-1) для перевернутого і нічого для неперевернутого випадку: jsperf.com/ctx-flip-performance/4 ).
додано Автор Jeff Gates, джерело
Я думав, що .scale() встановлює масштаб перетворень, а не збільшує його. Множий - це те, що мається на увазі у документах w3.org ( dev. w3.org/html5/2dcontext/#dom-context-2d-scale ), що дійсно недійсне тест/4. (Він використовує термін "add", який трохи неоднозначний). Проте це не те, що, здається, робить, принаймні на chrome: jsperf.com/ctx- фліп-шоу/8 .
додано Автор Jeff Gates, джерело

Ви можете перетворити контекст малюнка полотна, не перегортаючи весь полотно.

c.save();
c.scale(-1, 1);

буде відображати контекст. Потім малюйте своє зображення

c.restore();

and you can draw normally again. For more information, see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations

11
додано
Дякую! Але завдяки відповіді Саймона я буду використовувати свою техніку. Я позначу вас як прийняту відповідь, хоча це відповідає на моє запитання :)
додано Автор James Dawson, джерело

Use this to flip your sprite sheet http://flipapicture.com/

3
додано
На жаль, це не підтримує PNG :(
додано Автор Scott, джерело
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram