001package squidpony.squidgrid.gui.gdx; 002 003import com.badlogic.gdx.graphics.Color; 004import com.badlogic.gdx.graphics.Texture; 005import com.badlogic.gdx.graphics.g2d.TextureRegion; 006import com.badlogic.gdx.scenes.scene2d.ui.Image; 007import squidpony.squidgrid.Direction; 008 009import java.util.ArrayList; 010import java.util.Collections; 011import java.util.List; 012 013/** 014 * An Image that has multiple possible color tints that it cycles through over time. 015 * Created by Tommy Ettinger on 3/23/2016. 016 */ 017public class ColorChangeImage extends Image { 018 019 private List<Color> colors; 020 private float progress; 021 private float loopTime = 2f; 022 023 /** 024 * Creates an image stretched and aligned center, that will use the specified list of colors. 025 * 026 * @param texture the texture to use 027 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 028 */ 029 public ColorChangeImage(Texture texture, List<Color> colors) { 030 this(texture, 2f, colors); 031 } 032 033 /** 034 * Creates an image stretched and aligned center, that will use the specified list of colors. 035 * 036 * @param texture the texture to use 037 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 038 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 039 */ 040 public ColorChangeImage(Texture texture, float loopTime, List<Color> colors) { 041 this(texture, loopTime, false, colors); 042 } 043 044 /** 045 * Creates an image stretched and aligned center, that will use the specified list of colors. 046 * 047 * @param texture the texture to use 048 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 049 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 050 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 051 */ 052 public ColorChangeImage(Texture texture, float loopTime, boolean doubleWidth, List<Color> colors) { 053 054 super(texture); 055 056 if(colors == null || colors.isEmpty()) 057 this.colors = DefaultResources.getSCC().rainbow(12); 058 else 059 this.colors = colors; 060 this.loopTime = loopTime; 061 setSize(texture.getWidth(), texture.getHeight()); 062 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 063 } 064 065 /** 066 * Creates an image stretched and aligned center, that will use the specified list of colors. 067 * 068 * @param texture the texture to use 069 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 070 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 071 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 072 */ 073 public ColorChangeImage(Texture texture, float loopTime, boolean doubleWidth, float width, float height, List<Color> colors) { 074 075 super(texture); 076 077 if(colors == null || colors.isEmpty()) 078 this.colors = DefaultResources.getSCC().rainbow(12); 079 else 080 this.colors = colors; 081 this.loopTime = loopTime; 082 setSize(width, height); 083 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 084 } 085 086 /** 087 * Creates an image stretched and aligned center, that will use the specified list of colors. 088 * 089 * @param texture the texture to use 090 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 091 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 092 */ 093 public ColorChangeImage(Texture texture, float loopTime, Color... colors) { 094 this(texture, loopTime, false, colors); 095 } 096 097 /** 098 * Creates an image stretched and aligned center, that will use the specified list of colors. 099 * 100 * @param texture the texture to use 101 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 102 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 103 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 104 */ 105 public ColorChangeImage(Texture texture, float loopTime, boolean doubleWidth, Color... colors) { 106 super(texture); 107 108 if(colors == null || colors.length == 0) 109 this.colors = DefaultResources.getSCC().rainbow(12); 110 else { 111 this.colors = new ArrayList<>(colors.length); 112 Collections.addAll(this.colors, colors); 113 } 114 this.loopTime = loopTime; 115 setSize(texture.getWidth(), texture.getHeight()); 116 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 117 } 118 /** 119 * Creates an image stretched and aligned center, that will use the specified list of colors. 120 * 121 * @param texture the texture to use 122 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 123 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 124 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 125 */ 126 public ColorChangeImage(Texture texture, float loopTime, boolean doubleWidth, float width, float height, Color... colors) { 127 super(texture); 128 129 if(colors == null || colors.length == 0) 130 this.colors = DefaultResources.getSCC().rainbow(12); 131 else { 132 this.colors = new ArrayList<>(colors.length); 133 Collections.addAll(this.colors, colors); 134 } 135 this.loopTime = loopTime; 136 137 setSize(width, height); 138 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 139 } 140 141 /** 142 * Creates an image stretched and aligned center, that will use the specified list of colors. 143 * 144 * @param texture the texture to use 145 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 146 */ 147 public ColorChangeImage(TextureRegion texture, List<Color> colors) { 148 this(texture, 2f, colors); 149 } 150 151 /** 152 * Creates an image stretched and aligned center, that will use the specified list of colors. 153 * 154 * @param texture the texture to use 155 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 156 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 157 */ 158 public ColorChangeImage(TextureRegion texture, float loopTime, List<Color> colors) { 159 this(texture, loopTime, false, colors); 160 } 161 162 /** 163 * Creates an image stretched and aligned center, that will use the specified list of colors. 164 * 165 * @param texture the texture to use 166 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 167 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 168 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 169 */ 170 public ColorChangeImage(TextureRegion texture, float loopTime, boolean doubleWidth, List<Color> colors) { 171 172 super(texture); 173 174 if(colors == null || colors.isEmpty()) 175 this.colors = DefaultResources.getSCC().rainbow(12); 176 else 177 this.colors = colors; 178 this.loopTime = loopTime; 179 setSize(texture.getRegionWidth(), texture.getRegionHeight()); 180 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 181 } 182 /** 183 * Creates an image stretched and aligned center, that will use the specified list of colors. 184 * 185 * @param texture the texture to use 186 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 187 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 188 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 189 */ 190 public ColorChangeImage(TextureRegion texture, float loopTime, boolean doubleWidth, float width, float height, List<Color> colors) { 191 192 super(texture); 193 194 if(colors == null || colors.isEmpty()) 195 this.colors = DefaultResources.getSCC().rainbow(12); 196 else 197 this.colors = colors; 198 this.loopTime = loopTime; 199 setSize(width, height); 200 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 201 } 202 /** 203 * Creates an image stretched and aligned center, that will use the specified list of colors. 204 * 205 * @param texture the texture to use 206 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 207 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 208 */ 209 public ColorChangeImage(TextureRegion texture, float loopTime, Color... colors) { 210 this(texture, loopTime, false, colors); 211 } 212 213 /** 214 * Creates an image stretched and aligned center, that will use the specified list of colors. 215 * 216 * @param texture the texture to use 217 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 218 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 219 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 220 */ 221 public ColorChangeImage(TextureRegion texture, float loopTime, boolean doubleWidth, Color... colors) { 222 super(texture); 223 224 if(colors == null || colors.length == 0) 225 this.colors = DefaultResources.getSCC().rainbow(12); 226 else { 227 this.colors = new ArrayList<>(colors.length); 228 Collections.addAll(this.colors, colors); 229 } 230 this.loopTime = loopTime; 231 232 setSize(texture.getRegionWidth(), texture.getRegionHeight()); 233 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 234 } 235 /** 236 * Creates an image stretched and aligned center, that will use the specified list of colors. 237 * 238 * @param texture the texture to use 239 * @param loopTime the amount of time, in seconds, to spend transitioning through the colors before repeating 240 * @param doubleWidth true if this takes up two grid cells; only matters if you use {@link AnimatedEntity#setDirection(Direction)} 241 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 242 */ 243 public ColorChangeImage(TextureRegion texture, float loopTime, boolean doubleWidth, float width, float height, Color... colors) { 244 245 super(texture); 246 247 if(colors == null || colors.length == 0) 248 this.colors = DefaultResources.getSCC().rainbow(12); 249 else { 250 this.colors = new ArrayList<>(colors.length); 251 Collections.addAll(this.colors, colors); 252 } 253 this.loopTime = loopTime; 254 setSize(width, height); 255 setOrigin(doubleWidth ? 16 : 1); //Align.right or Align.center 256 } 257 /** 258 * Returns the color the actor will be tinted when drawn. Takes the Color from the List of Color this was constructed 259 * with or assigned with setColors, not the normal Actor color assigned with setColor. 260 * @return the Color this will be drawn with 261 */ 262 @Override 263 public Color getColor() { 264 return colors.get((int)(progress * colors.size() / loopTime)); 265 } 266 267 /** 268 * Sets the list of colors this uses to choose what color it draws with. 269 * @param colors a List of Color, such as one returned by SquidColorCenter's gradient or rainbow methods 270 */ 271 public void setColors(List<Color> colors) 272 { 273 if(colors == null || colors.isEmpty()) 274 this.colors = DefaultResources.getSCC().rainbow(12); 275 else 276 this.colors = colors; 277 } 278 279 /** 280 * Sets the list of colors this uses to choose what color it draws with. 281 * @param colors an array or vararg of Color 282 */ 283 public void setColors(Color... colors) 284 { 285 if (colors == null || colors.length == 0) 286 this.colors = DefaultResources.getSCC().rainbow(12); 287 else { 288 this.colors = new ArrayList<>(colors.length); 289 Collections.addAll(this.colors, colors); 290 } 291 } 292 /** 293 * Updates the actor based on time. Typically this is called each frame by 294 * {@link com.badlogic.gdx.scenes.scene2d.Stage#act(float)}. 295 * <p> 296 * The default implementation calls 297 * {@link com.badlogic.gdx.scenes.scene2d.Action#act(float)} on each action and removes actions that are complete. 298 * 299 * @param delta Time in seconds since the last frame. 300 */ 301 @Override 302 public void act(float delta) { 303 super.act(delta); 304 progress = (progress + delta) % (loopTime - 0.001f); 305 } 306 307 /** 308 * Changes the amount of time this takes to loop through all colors, and also resets the current loop to its start. 309 * @param loopTime the amount of time, in seconds, it takes to loop through all the colors in the list 310 */ 311 public void resetLoopTime(float loopTime) 312 { 313 this.loopTime = loopTime; 314 progress = 0f; 315 } 316}