DEV Community

loading...
Cover image for A Game of Blobs - Dead Or Alive

A Game of Blobs - Dead Or Alive

Alfredo Salzillo 🐺
🐺
・4 min read

One boring day, some month ago during the Covid Quarantine, stuck in my room in Italy, finding something to do I found an article about Generative Art and it blow my mind.

What the hell is the "Generative Art"?

“Generative art is art made using a predetermined system that often includes an element of chance – is usually applied to computer based art”

The Article

The article summarize what "Generative Art" means and explain how to generate using javascript Blobs. Yes, BLOBS! And you know what? I love blobs.

What to do with infinite Blobs

I lost hours thinking about them to find out something to do with them. And, when i was in the bathroom I had an idea.
What is the better think you can using randomly infinite cute blobs with cute eyes that will make everyone fall in love?
A skill game in which the user must find the "Wanted" blob before the time end. Each time a blob is found the user receive earn point and receive a new blob to find, dead or alive.

How to make cute Blobs

In the original article a library to generate svg is used to make blobs, but, I decided to use React.
I will not explain how the shape of the blob is made because the [source article](https://dev.to/georgedoescode/tutorial-generative-blob-characters-using-svg-1igg already explain it very well.

The recipe

Ingredients for cute and juicy Blobs

  • a random number of points
  • 1 eye for a cyclopic blob or 2 eyes for a normal blob
  • a random cute pastel color palette

Start collecting all the ingredients than get the point and spline them to get a blobby cute shape, add the eyes in the right position and at last put some color, and, puff you get the nicest blob ever!

Lilith

const SvgBlobEye = (props) => {
  const { x, y, size, colors } = props
  return (
    <g
      transform={`matrix(1,0,0,1,${x},${y})`}
      className="blob-eye"
    >
      <circle
        r={size}
        cx="0"
        cy="0"
        stroke-width="2"
        stroke={colors.dark}
        fill={colors.light}
        className="blob-eye-iris"
      />
      <circle
        r={size / 2}
        cx="0"
        cy="0"
        fill={colors.dark}
        className="blob-eye-pupil"
        style={{
          '--radius': `${size / 2}px`,
        }}
      />
    </g>
  )
}
const SvgBlob = ({
   width,
   height,
   body,
   eyes,
   colors,
 }) => {
  return (
    <svg
      viewBox={`0 0 ${width} ${height}`}
      className="blob"
    >
      <path
        d={spline(body as any[], 1, true)}
        stroke-width={2}
        stroke={colors.dark}
        fill={colors.primary}
      />
      <g>
        {eyes.map((eye) => <SvgBlobEye {...eye} colors={colors}/>)}
      </g>
    </svg>
  )
}
Enter fullscreen mode Exit fullscreen mode

The cutest blob is the one that move eyes in funny ways

But i wanted more from my blobs, i wanted them to seem alive and interact with the user.
So i decided to add some animations:

  • randomly the blobs must move their eyes
  • if clicked the blob will shake the eyes
const animations = ['eye-roll', 'eye-roll-reverse', 'eye-converge', 'eye-converge-reverse'];
const SvgBlob = ({
   width,
   height,
   body,
   eyes,
   colors,
   animated,
 }) => {
  const [animation, setAnimation] = useState('');
  useEffect(() => {
    if (!animated) return;
    if (!animation) {
      const timeout = setTimeout(() => setAnimation(randomItem(animations)), random(0, 20000))
      return () => clearTimeout(timeout)
    }
  }, [animation, setAnimation])
  return (
    <svg
      viewBox={`0 0 ${width} ${height}`}
      className={`blob ${animated && animation}`}
      onClick={() => setAnimation('eye-flock')}
      onAnimationEnd={() => setAnimation('')}
    >
      <path
        d={spline(body as any[], 1, true)}
        stroke-width={2}
        stroke={colors.dark}
        fill={colors.primary}
      />
      <g>
        ${eyes.map((eye) => <SvgBlobEye {...eye} colors={colors}/>)}
      </g>
    </svg>
  )
}
Enter fullscreen mode Exit fullscreen mode
@keyframes roll {
    0% {
        transform: translate(0, 0);
    }
    20% {
        transform: translate(5px, 5px);
    }
    40% {
        transform: translate(5px, 0px);
    }
    60% {
        transform: translate(5px, -5px);
    }
    60% {
        transform: translate(0, -5px);
    }
    100% {
        transform: translate(0, 0);
    }
}

@keyframes converge-left {
    0% {
        transform: translate(0, 0);
    }
    50% {
        transform: translate(5px, 0);
    }
    100% {
        transform: translate(0, 0);
    }
}

@keyframes converge-right {
    0% {
        transform: translate(0, 0);
    }
    50% {
        transform: translate(-5px, 0);
    }
    100% {
        transform: translate(0, 0);
    }
}

@keyframes flock {
    0% {
        transform: translate(0, 0);
    }
    20% {
        transform: translate(5px, 0px);
    }
    40% {
        transform: translate(calc(-5px), 0px);
    }
    60% {
        transform: translate(5px, 0px);
    }
    80% {
        transform: translate(-5px, 0px);
    }
    100% {
        transform: translate(0, 0);
    }
}

.eye-roll .blob-eye-pupil {
    transform: translate(0, 0);
    animation: roll linear 3s;
}

.eye-roll-reverse .blob-eye-pupil {
    transform: translate(0, 0);
    animation: roll linear 3s reverse;
}

.eye-converge .blob-eye:nth-child(1) .blob-eye-pupil {
    transform: translate(0, 0);
    animation: converge-left linear 0.5s;
}

.eye-converge .blob-eye:nth-child(2) .blob-eye-pupil {
    transform: translate(0, 0);
    animation: converge-right linear 0.5s;
}

.eye-converge-reverse .blob-eye:nth-child(1) .blob-eye-pupil {
    transform: translate(0, 0);
    animation: converge-right linear 0.5s;
}

.eye-converge-reverse .blob-eye:nth-child(2) .blob-eye-pupil {
    transform: translate(0, 0);
    animation: converge-left linear 0.5s;
}

.eye-flock .blob-eye-pupil {
    transform: translate(0, 0);
    animation: flock linear 1s;
}
Enter fullscreen mode Exit fullscreen mode

Now you can enjoy your juicy blob!

Last things

This is only a part of the process i used to make the game Blobs - Dead or Alive but if you want you can look at the full code in the github repository.

GitHub logo alfredosalzillo / blobs-dead-or-alive

A Blobs game made using React.

icon blobs-dead-or-alive

A Blobs game made using React and generative art.

Try it here.

preview

Develop

Install denoliver and bundler.

denoliver dist
bundler bundle --watch --config tsconfig.json --import-map import_map.json index.html=index.html
Enter fullscreen mode Exit fullscreen mode

Made with ❤️ and blobs.

Discussion (1)

Collapse
inhuofficial profile image
InHuOfficial

Silly game - I love it! ❤️🦄