* draw this sprite (automatically called by melonJS) * @param {Renderer} renderer - a renderer instance * @param {Camera2d} [viewport] - the viewport to (re)draw
(renderer)
| 770 | * @param {Camera2d} [viewport] - the viewport to (re)draw |
| 771 | */ |
| 772 | draw(renderer) { |
| 773 | // do nothing if we are flickering (time-based, frame-rate independent) |
| 774 | if ( |
| 775 | this._flicker.isFlickering && |
| 776 | Math.floor(this._flicker.elapsed / FLICKER_INTERVAL_MS) % 2 !== 0 |
| 777 | ) { |
| 778 | return; |
| 779 | } |
| 780 | |
| 781 | // the frame to draw |
| 782 | const frame = this.current; |
| 783 | |
| 784 | // cache the current position and size |
| 785 | let xpos = this.pos.x; |
| 786 | let ypos = this.pos.y; |
| 787 | |
| 788 | let w = frame.width; |
| 789 | let h = frame.height; |
| 790 | |
| 791 | // frame offset in the texture/atlas |
| 792 | const frame_offset = frame.offset; |
| 793 | const g_offset = this.offset; |
| 794 | |
| 795 | // remove image's TexturePacker/ShoeBox rotation |
| 796 | if (frame.angle !== 0) { |
| 797 | renderer.translate(-xpos, -ypos); |
| 798 | renderer.rotate(frame.angle); |
| 799 | xpos -= h; |
| 800 | w = frame.height; |
| 801 | h = frame.width; |
| 802 | // apply trim in rotated space: (tx, ty) → (-ty, tx) for -π/2 |
| 803 | if (frame.trim) { |
| 804 | xpos -= frame.trim.y; |
| 805 | ypos += frame.trim.x; |
| 806 | } |
| 807 | } else if (frame.trim) { |
| 808 | // apply trim offset for non-rotated trimmed sprites |
| 809 | xpos += frame.trim.x; |
| 810 | ypos += frame.trim.y; |
| 811 | } |
| 812 | |
| 813 | renderer.drawImage( |
| 814 | this.image, |
| 815 | g_offset.x + frame_offset.x, // sx |
| 816 | g_offset.y + frame_offset.y, // sy |
| 817 | w, |
| 818 | h, // sw,sh |
| 819 | xpos, |
| 820 | ypos, // dx,dy |
| 821 | w, |
| 822 | h, // dw,dh |
| 823 | ); |
| 824 | } |
| 825 | |
| 826 | /** |
| 827 | * Destroy function<br> |