Created
          June 28, 2020 17:10 
        
      - 
      
 - 
        
Save KrabCode/3009f2cd4404231bc719fd097a25743d to your computer and use it in GitHub Desktop.  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | private float imageScale = 2; | |
| private final int maxCatCount = 12; | |
| private final int maxChunkCount = 1000; | |
| private float time; | |
| private final ArrayList<Cat> cats = new ArrayList<Cat>(); | |
| private final ArrayList<Cat> catsToRemove = new ArrayList<Cat>(); | |
| private final ArrayList<Chunk> chunks = new ArrayList<Chunk>(); | |
| private final ArrayList<Chunk> chunksToRemove = new ArrayList<Chunk>(); | |
| private Cat held = null; | |
| private PImage sticksIdle, sticksHeld, catHeld; | |
| private PImage[] catDown, catRight, catUp; | |
| int sticksFadeoutDelay = 60; | |
| int sticksFadeoutDuration = 60; | |
| boolean fadeSticks = true; | |
| int sticksLastReleasedFrame = -sticksFadeoutDuration * 3; | |
| private PGraphics pg; | |
| public void settings() { | |
| // size(floor(1080 * .7f), floor(1920 * .7f), P2D); | |
| fullScreen(P2D); | |
| smooth(16); | |
| } | |
| public void setup() { | |
| loadImages(); | |
| pg = createGraphics(width, height, P2D); | |
| updateCatCount(); | |
| pg.beginDraw(); | |
| pg.colorMode(HSB, 1, 1, 1, 1); | |
| pg.background(0); | |
| pg.endDraw(); | |
| } | |
| public void draw() { | |
| if (held != null && !mousePressed) { | |
| drop(); | |
| } | |
| time = radians(frameCount); | |
| pg.beginDraw(); | |
| pg.background(0); | |
| pg.imageMode(CENTER); | |
| updateChunkCount(); | |
| updateChunks(); | |
| updateCatCount(); | |
| updateWalkingCats(); | |
| drawCursor(); | |
| updateHeldCat(); | |
| pg.endDraw(); | |
| image(pg, 0, 0); | |
| } | |
| private void updateChunks() { | |
| for (Chunk c : chunks) { | |
| c.update(); | |
| } | |
| chunks.removeAll(chunksToRemove); | |
| chunksToRemove.clear(); | |
| } | |
| public void mouseReleased() { | |
| drop(); | |
| } | |
| private void drop() { | |
| if(held != null && random(1) < 0.5){ | |
| held.explode(); | |
| catsToRemove.add(held); | |
| } | |
| held = null; | |
| sticksLastReleasedFrame = frameCount; | |
| } | |
| private void loadImages() { | |
| sticksIdle = loadImage("hulky-idle.png"); | |
| sticksHeld = loadImage("hulky-hold.png"); | |
| catHeld = loadImage("kitt-held.png"); | |
| catDown = new PImage[]{loadImage("kitt-down-1.png"), loadImage("kitt-down-2.png")}; | |
| catRight = new PImage[]{loadImage("kitt-side-1.png"), loadImage("kitt-side-2.png")}; | |
| catUp = new PImage[]{loadImage("kitt-up-1.png"), loadImage("kitt-up-2.png")}; | |
| } | |
| private void updateHeldCat() { | |
| if (held == null) { | |
| return; | |
| } | |
| held.update(); | |
| } | |
| private void drawCursor() { | |
| //noCursor(); | |
| pg.pushStyle(); | |
| float w = sticksHeld.width * imageScale; | |
| float h = sticksHeld.height * imageScale; | |
| pg.imageMode(CENTER); | |
| float x = mouseX + w * 0.37f; | |
| float y = mouseY + h * -0.37f; | |
| if (held == null && !mousePressed) { | |
| if (fadeSticks) { | |
| float sticksFadeout = constrain(norm(frameCount - sticksFadeoutDelay, sticksLastReleasedFrame, | |
| sticksLastReleasedFrame + sticksFadeoutDelay), 0, 1); | |
| pg.tint(1, 1 - sticksFadeout); | |
| } | |
| pg.image(sticksIdle, x, y, w, h); | |
| } else { | |
| pg.image(sticksHeld, x, y, w, h); | |
| } | |
| pg.popStyle(); | |
| } | |
| void updateCatCount() { | |
| while (maxCatCount > cats.size()) { | |
| cats.add(new Cat()); | |
| } | |
| } | |
| void updateChunkCount() { | |
| if (chunks.size() > maxChunkCount) { | |
| for (int i = 0; i < chunks.size()-maxChunkCount; i++) { | |
| if (chunks.get(i).fadeOutStarted == -1) { | |
| chunks.get(i).fadeOutStarted = frameCount; | |
| } | |
| } | |
| } | |
| } | |
| void updateWalkingCats() { | |
| for (Cat c : cats) { | |
| if (held == null || !held.equals(c)) { | |
| c.update(); | |
| } | |
| } | |
| cats.removeAll(catsToRemove); | |
| catsToRemove.clear(); | |
| } | |
| class Cat { | |
| private int frameBorn = frameCount; | |
| private int fadeInDuration = 60; | |
| private PVector pos = new PVector(width / 2f + random(-10, 10), height / 2f + random(-10, 10)); | |
| private int direction = floor(random(4)); | |
| private float size = 62 * imageScale; | |
| private float hue = (.7f + random(.4f)) % 1; | |
| private float sat = random(.15f, .4f); | |
| private float br = random(.8f, 1); | |
| private float timeOffset = random(TAU); | |
| float speedMagnitude = random(.25f, .75f); | |
| void update() { | |
| mouseInteract(); | |
| if (!thisHeld()) { | |
| updateDirection(); | |
| move(); | |
| checkCollisions(); | |
| } | |
| draw(); | |
| } | |
| private void move() { | |
| PVector speed = new PVector(); | |
| if (direction == 0) { | |
| speed.x = 1; | |
| } else if (direction == 1) { | |
| speed.y = 1; | |
| } else if (direction == 2) { | |
| speed.x = -1; | |
| } else if (direction == 3) { | |
| speed.y = -1; | |
| } | |
| speed.mult(speedMagnitude); | |
| pos.add(speed); | |
| if (pos.x < size / 2f) { | |
| pos.x += width; | |
| } | |
| if (pos.x > width + size / 2f) { | |
| pos.x -= width; | |
| } | |
| if (pos.y < size / 2f) { | |
| pos.y += height; | |
| } | |
| if (pos.y > height + size / 2f) { | |
| pos.y -= height; | |
| } | |
| } | |
| private void updateDirection() { | |
| if (random(1) < 0.01f) { | |
| changeDirection(); | |
| } | |
| } | |
| private void changeDirection() { | |
| if (random(1) > 0.5f) { | |
| direction++; | |
| } else { | |
| direction--; | |
| } | |
| while (direction < 0) { | |
| direction += 4; | |
| } | |
| direction %= 4; | |
| } | |
| private void draw() { | |
| pg.pushStyle(); | |
| int frame = sin(time * 8 + timeOffset) > 0 ? 0 : 1; | |
| boolean flipHorizontally = direction == 2 && !thisHeld(); | |
| float alpha = constrain(map(frameCount, frameBorn, frameBorn+fadeInDuration, 0, 1), 0, 1); | |
| PImage img = getImageByState(frame); | |
| pg.tint(hue, sat, br, alpha); | |
| drawCatAtPos(img, flipHorizontally); | |
| drawCatWrapAround(img, flipHorizontally); | |
| pg.popStyle(); | |
| } | |
| private void drawCatAtPos(PImage img, boolean flipHorizontally) { | |
| pg.pushMatrix(); | |
| pg.pushStyle(); | |
| pg.translate(pos.x, pos.y); | |
| flipIfNeeded(flipHorizontally); | |
| pg.image(img, 0, 0, size, size); | |
| pg.popStyle(); | |
| pg.popMatrix(); | |
| } | |
| private void drawCatWrapAround(PImage img, boolean flipHorizontally) { | |
| pg.pushMatrix(); | |
| pg.translate(pos.x, pos.y); | |
| if (pos.x < size / 2f) { | |
| pg.translate(width, 0); | |
| } | |
| if (pos.x > width - size / 2f) { | |
| pg.translate(-width, 0); | |
| } | |
| if (pos.y < size / 2f) { | |
| pg.translate(0, height); | |
| } | |
| if (pos.y > height - size / 2f) { | |
| pg.translate(0, -height); | |
| } | |
| flipIfNeeded(flipHorizontally); | |
| pg.image(img, 0, 0, size, size); | |
| pg.popMatrix(); | |
| } | |
| private PImage getImageByState(int frame) { | |
| if (thisHeld()) { | |
| return catHeld; | |
| } | |
| if (direction == 0 || direction == 2) { | |
| return catRight[frame]; | |
| } else if (direction == 1) { | |
| return catDown[frame]; | |
| } else if (direction == 3) { | |
| return catUp[frame]; | |
| } | |
| return catHeld; | |
| } | |
| private void flipIfNeeded(boolean flipX) { | |
| if (flipX) { | |
| pg.scale(-1, 1); | |
| } else { | |
| pg.scale(1, 1); | |
| } | |
| } | |
| private boolean thisHeld() { | |
| if (held == null) { | |
| return false; | |
| } | |
| return held.equals(this); | |
| } | |
| void mouseInteract() { | |
| float interactionDist = size / 2; | |
| boolean d = dist(mouseX, mouseY, pos.x, pos.y) < interactionDist; | |
| boolean d0 = dist(mouseX + width, mouseY, pos.x, pos.y) < interactionDist; | |
| boolean d1 = dist(mouseX, mouseY + height, pos.x, pos.y) < interactionDist; | |
| boolean d2 = dist(mouseX - width, mouseY, pos.x, pos.y) < interactionDist; | |
| boolean d3 = dist(mouseX, mouseY - height, pos.x, pos.y) < interactionDist; | |
| boolean mouseInInteractionDist = d || d0 || d1 || d2 || d3; | |
| if (true) { | |
| if (held == null && mousePressed && mouseInInteractionDist) { | |
| held = this; | |
| } | |
| if (held != null && held.equals(this)) { | |
| if (d0) { | |
| pos.x -= width; | |
| } | |
| if (d1) { | |
| pos.y -= height; | |
| } | |
| if (d2) { | |
| pos.x += width; | |
| } | |
| if (d3) { | |
| pos.y += height; | |
| } | |
| pos.x = lerp(pos.x, mouseX, .5f); | |
| pos.y = lerp(pos.y, mouseY, .5f); | |
| } | |
| } | |
| } | |
| private void explode() { | |
| int chunkCount = 30; | |
| for (int i = 0; i < chunkCount; i++) { | |
| chunks.add(new Chunk(pos)); | |
| } | |
| } | |
| void checkCollisions() { | |
| for (Cat otherCard : cats) { | |
| if (otherCard.equals(this)) { | |
| continue; | |
| } | |
| float distanceToOther = dist(pos.x, pos.y, otherCard.pos.x, otherCard.pos.y); | |
| if (distanceToOther < size) { | |
| PVector fromOtherToThis = PVector.sub(pos, otherCard.pos); | |
| float repulsion = (1 / norm(distanceToOther, 0, size)) * .5f; | |
| pos.add(fromOtherToThis.normalize().mult(repulsion)); | |
| } | |
| } | |
| } | |
| } | |
| class Chunk { | |
| PVector pos, spd; | |
| float size = random(2, 30); | |
| int shape = floor(random(2)); | |
| float sat = random(-.2f, .2f); | |
| int fadeOutStarted = -1; | |
| int fadeOutDuration = 60; | |
| public Chunk(PVector pos) { | |
| this.pos = pos.copy(); | |
| spd = PVector.fromAngle(random(TAU*2)).mult(randomGaussian()*2); | |
| } | |
| public void update() { | |
| float fadeOut = constrain(norm(frameCount, fadeOutStarted, fadeOutStarted + fadeOutDuration), 0, 1); | |
| if (fadeOutStarted == -1) { | |
| fadeOut = 0; | |
| } else if (fadeOut == 1) { | |
| chunksToRemove.add(this); | |
| } | |
| float drag = .975; // slider("drag", .95f); | |
| pg.pushMatrix(); | |
| pos.add(spd); | |
| spd.mult(drag); | |
| pg.noStroke(); | |
| pg.fill(0, .8f+sat, .6f, 1 - fadeOut); | |
| if (shape == 0) { | |
| pg.ellipse(pos.x, pos.y, size, size); | |
| } | |
| if (shape == 1) { | |
| pg.translate(pos.x, pos.y); | |
| pg.rotate(spd.heading()); | |
| pg.rect(0, 0, size, size); | |
| } | |
| pg.popMatrix(); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment