github.com/df-mc/dragonfly@v0.9.13/server/player/skin/animation.go (about)

     1  package skin
     2  
     3  import (
     4  	"image"
     5  	"image/color"
     6  )
     7  
     8  const (
     9  	// AnimationHead is an animation that is played over the head part of the skin.
    10  	AnimationHead AnimationType = iota
    11  	// AnimationBody32x32 is an animation that is played over the body of a skin with a 32x32(/64) size. This
    12  	// is the usual animation type for body animations.
    13  	AnimationBody32x32
    14  	// AnimationBody128x128 is an animation that is played over a body of a skin with a 128x128 size. This is
    15  	// the animation type for body animations with high resolution.
    16  	AnimationBody128x128
    17  )
    18  
    19  // AnimationType represents a type of the animation. It is one of the constants above, and specifies to what
    20  // part of the body it is assigned.
    21  type AnimationType int
    22  
    23  // Animation represents an animation that plays over the skin every so often. It is assigned to a particular
    24  // part of the skin, which is represented by one of the constants above.
    25  type Animation struct {
    26  	w, h  int
    27  	aType AnimationType
    28  
    29  	// Pix holds skin data for every frame of the animation. This is an RGBA byte slice, meaning that every
    30  	// first byte is a Red value, the second a Green value, the third a Blue value and the fourth an Alpha
    31  	// value.
    32  	Pix []uint8
    33  
    34  	// FrameCount is the amount of frames that the animation plays for. Exactly this amount of frames should
    35  	// be present in the Pix animation data.
    36  	FrameCount int
    37  
    38  	// AnimationExpression is the player's animation expression.
    39  	AnimationExpression int
    40  }
    41  
    42  // NewAnimation returns a new animation using the width and height passed, with the type specifying what part
    43  // of the body to display it on.
    44  // NewAnimation fills out the Pix field adequately and sets FrameCount to 1 by default.
    45  func NewAnimation(width, height int, expression int, animationType AnimationType) Animation {
    46  	return Animation{
    47  		w:                   width,
    48  		h:                   height,
    49  		aType:               animationType,
    50  		Pix:                 make([]uint8, width*height*4),
    51  		FrameCount:          1,
    52  		AnimationExpression: expression,
    53  	}
    54  }
    55  
    56  // Type returns the type of the animation, which is one of the constants above.
    57  func (a Animation) Type() AnimationType {
    58  	return a.aType
    59  }
    60  
    61  // ColorModel ...
    62  func (a Animation) ColorModel() color.Model {
    63  	return color.RGBAModel
    64  }
    65  
    66  // Bounds ...
    67  func (a Animation) Bounds() image.Rectangle {
    68  	return image.Rectangle{
    69  		Max: image.Point{X: a.w, Y: a.h},
    70  	}
    71  }
    72  
    73  // At returns the colour at a given position in the animation data, provided the X and Y are within the bounds
    74  // of the animation passed during construction.
    75  // The concrete type returned by At is a color.RGBA value.
    76  func (a Animation) At(x, y int) color.Color {
    77  	if x < 0 || y < 0 || x >= a.w || y >= a.h {
    78  		panic("pixel coordinates out of bounds")
    79  	}
    80  	offset := x*4 + a.w*y*4
    81  	return color.RGBA{
    82  		R: a.Pix[offset],
    83  		G: a.Pix[offset+1],
    84  		B: a.Pix[offset+2],
    85  		A: a.Pix[offset+3],
    86  	}
    87  }