“Wiggly Worm” by Cooper Thomas
https://openprocessing.org/sketch/135637
License CreativeCommons Attribution ShareAlike
https://creativecommons.org/licenses/by-sa/3.0
{{filePath}}
{{width}} x {{height}}
Report Sketch
Oh, that naughty sketch! Please let us know what the issue is below.
Apply Template
Applying this template will reset your sketch and remove all your changes. Are you sure you would like to continue?
Report Sketch
Report Comment
Please confirm that you would like to report the comment below.
We will review your submission and take any actions necessary per our Community Guidelines. In addition to reporting this comment, you can also block the user to prevent any future interactions.
Please report comments only when necessary. Unnecessary or abusive use of this tool may result in your own account being suspended.
Are you sure you want to delete your sketch?
Any files uploaded will be deleted as well.
Delete Comment?
This will also delete all the replies to this comment.
Delete this tab? Any code in it will be deleted as well.
Select a collection to submit your sketch
We Need Your Support
Since 2008, OpenProcessing has provided tools for creative coders to learn, create, and share over a million open source projects in a friendly environment.
Niche websites like ours need your continued support for future development and maintenance, while keeping it an ad-free platform that respects your data and privacy!
Please consider subscribing below to show your support with a "Plus" badge on your profile and get access to many other features!
CC Attribution ShareAlike
Wiggly Worm
Thomas
xxxxxxxxxx
//WIGGLY WORM
//By Cooper Thomas
//Professor Casey
//Computer Science 2, Homework #3
//February 21, 2014
//In this groundbreaking game, the player controls Timmy the tapeworm,
//a lamentably misunderstood invertebrate battling for survival
//against an army of pesky antibiotics. Players control Timmy
//with the mouse. The longer that Timmy evades the antibiotics,
//the more points he will accrue...however, the antibiotics gradually
//move faster and faster, making survival for Timmy progressively more difficult!
//Timmy can also snack on green nutrients to gain bonus points.
//See CThomas_HW3_Info.txt (in sketch folder) for more information.
//GLOBAL VARAIBLES
//the three game states
int menu = 1;
int playing = 2;
int lost = 3;
//game state constant
int gameState;
//scoring variables
int score;
int hiScore;
int scoreUpdate;
//create font for menus and score
PFont font;
PFont fontTitle;
color fontColor;
//starting number of balls
int nBalls = 16;
//Timmy can have up to 15 total joints, but he starts with just 6
WormJoint[] joints = new WormJoint[6];
//the 10 antibiotics automatically regenerate once they leave the screen
Ball[] balls = new Ball[100];
Square[] squares = new Square[8];
void setup()
{
//canvas and project setup
size(800, 450);
smooth();
frameRate(30);
noStroke();
//font initialization
font = createFont("ArialRoundedMTBold.vlw", 20);
fontTitle = createFont("BirchStd.vlw", 20);
fontColor = color(0, random(100, 255), random(100, 240));
textFont(font);
textAlign(CENTER);
//initialize the game (function follows)
gameInit();
}
//global function that initializes the game
void gameInit()
{
//game begins on menu screen with score of 0
gameState = menu;
score = 0;
nBalls = 10;
// Construct joints at center of canvas.
for (int i=0; i<joints.length; i++)
{
joints[i] = new WormJoint(i*width/joints.length, height/2, 4);
}
// Create the antibiotic balls
for (int i=0; i<nBalls; i++) {
balls[i] = new Ball();
}
// Create the tasty nutritional squares
for (int i=0; i<squares.length; i++) {
squares[i] = new Square();
}
}
//create an additional ball every 1000 points
void addBall() {
balls[nBalls] = new Ball();
nBalls++;
//println(nBalls);
}
void draw()
{
//very slight motion blur
rectMode(CORNER);
fill(0);
rect(0, 0, width, height);
//conditionally draw game modes
switch(gameState)
{
//THIS IS THE IN-GAME STATE
case 2:
noCursor();
// Draw and update balls
for (int i=0; i<nBalls; i++) balls[i].draw();
for (int i=0; i<nBalls; i++) balls[i].update();
for (int i=0; i<nBalls; i++) balls[i].bounce();
//Draw and update squares
for (int i=0; i<squares.length; i++) squares[i].draw();
for (int i=0; i<squares.length; i++) squares[i].update();
for (int i=0; i<squares.length; i++) squares[i].bounce();
//Draw and update wiggly worm
for (int i=0; i<joints.length; i++) joints[i].draw();
// Recenter first joint at the mouse
joints[0].update(mouseX, mouseY);
// Recenter each following joint at preceding joint
for (int i=1; i<joints.length; i++)
joints[i].update(joints[i-1].x, joints[i-1].y);
//update score each frame
score++;
//update, set high score if current score is greater than previous high score
hiScore = score > hiScore ? score : hiScore;
//check for collisions between worm head and bonus squares
for (int j=0; j<squares.length; j++)
{
if (dist(mouseX, mouseY, squares[j].x, squares[j].y) <= 20)
{
if (squares[j].timer > 0)
{
//if there are any collisions, add 100 bonus points, extinguish+reinitialize square, show bonus text
score += 100;
squares[j].timer = 100;
squares[j].dt = 30;
squares[j].w += 20;
squares[j].timerBonus = 100;
squares[j].dtBonus = 0.5;
fill(squares[j].c, (squares[j].timerBonus));
textAlign(CENTER);
textFont(font, 45);
text("+100", (mouseX), (mouseY));
}
}
}
//increase level and number of balls every 2000 points
if (score / 1000 > scoreUpdate)
{
addBall();
scoreUpdate++;
}
//check for collisions between worm and balls
//if there are any collisions, game over!
for (int j=0; j<nBalls; j++)
for (int i=0; i<joints.length; i++)
{
if (dist(joints[i].x, joints[i].y, balls[j].x, balls[j].y) <= joints[i].r + balls[j].r)
{
gameState = lost;
}
}
//display score in left corner
textAlign(LEFT);
fill(255);
textFont(font);
text("SCORE: " + score, 20, (height - 30));
//display high score in right corner
textAlign(RIGHT);
text("HIGH SCORE: " + hiScore, (width - 20), (height - 30));
break;
//END GAME STATE
case 3:
noCursor();
//display "GAME OVER" messages
textAlign(CENTER);
fill(0, 200, joints[0].blue);
textFont(font, 40);
text("You killed Timmy, you asshole!", (width/2), (height/2) - 40);
fill(255);
textFont(font, 20);
text("Click to restart game", width/2, height/2);
textFont(font, 10);
text("(Hint: Timmy doesn't like sudden movements)", width/2, height/2 + 100);
//display score in left corner
textAlign(LEFT);
textFont(font, 20);
text("SCORE: " + score, 20, (height - 30));
//display high score in corner
textAlign(RIGHT);
text("HIGH SCORE: " + hiScore, (width - 20), (height - 30));
break;
//MENU STATE
case 1:
noCursor();
//Draw and update wiggly worm
for (int i=0; i<joints.length; i++) joints[i].draw();
// Recenter first joint at mouse position
joints[0].update(mouseX, mouseY);
// Recenter each following joint at preceding joint
for (int i=1; i<joints.length; i++)
joints[i].update(joints[i-1].x, joints[i-1].y);
//display start messages
textAlign(CENTER);
fill(fontColor);
textFont(fontTitle, 60);
text("WIGGLY WORM", width/2, height/2 - 80);
textFont(font, 16);
fill(255);
text("Use the mouse to help Timmy the misunderstood tapeworm evade the evil antibiotics!",
width/2, height/2);
text("Snack on delicious green nutrients for bonus points.",
width/2, height/2 + 20);
textFont(font, 10);
text("Click anywhere to begin", width/2, height/2 + 80);
//display high score in corner
textFont(font, 20);
textAlign(RIGHT);
text("HIGH SCORE: " + hiScore, (width - 20), (height - 30));
break;
}
}
//if in menu state, mouse click begins game
//if in end game state, mouse click restarts game
void mousePressed()
{
if (gameState == menu)
{
gameState = playing;
}
else if (gameState == lost)
{
gameInit();
}
}
class Ball {
float x, y; // current position
float vx, vy; // velocity
float vr; //ball radius multiplier (increases over time)
float r; //radius
float vMin;
float vMax;
color c; //ball color
float spring = 0.2; //ball springiness (for collisions)
boolean on = false;
Ball() {
}
// Initialize ball offscreen (right of canvas)
void initialize()
{
on = true;
vMin = -5;
vMax = -2;
x = random(width+200, width+600);
y = random(0, height);
vx = random(vMin, vMax);
vy = random(-2, 2);
vr = 1;
r = vr * random(10, 30);
c = color(random(100, 255), 0, random(0, 100));
}
void draw()
{
if (!on) return;
noStroke();
fill(c, 200);
ellipse(x, y, 2*r, 2*r);
}
void update()
{
// initialize if necessary
if (!on) {
if (random(0, 1) < 0.5) initialize();
return;
}
//move ball
x += vx;
y += vy;
//increase ball velocity multiplier
//increase ball radius multiplier
//reverse ball vy when it hits floor/ceiling
if (y > height-r || y < r)
{
vy = -vy;
}
// When ball exits screen, re-initialize
if (x < 0 ) {
on = false;
}
vMin += -0.1;
}
//check for ball collisions
void bounce() {
for (int i = 0; i < nBalls; i ++) {
// if this is myself, continue
if (this == balls[i]) continue;
// distance between two balls
float d = dist(x, y, balls[i].x, balls[i].y);
// minimum distance between two balls
float md = r+balls[i].r;
// if I collide with one of them
if (d < md) {
// push back in the opposite direction
float dx = (x - balls[i].x)/d;
float dy = (y - balls[i].y)/d;
// check if perfectly overlapping
if (dx == 0 && dy == 0) {
dx = random(-1, 1);
dy = random(-1, 1);
}
// compute the speed to add
float s = min(10, spring*(md-d));
vx += dx*s;
vy += dy*s;
}
}
}
}
class Square {
float x, y; // current position
float vxx; //velocity multiplier (increases over time)
float vx, vy; // velocity
float w; //witdh
color c; //color
float timer; // time left before square disappears
float timerBonus; //time left before "BONUS!" message disappears
float dt; // extinguishing speed
float dtBonus; //text extinguishing speed
float spring = 0.05; //ball springiness (for collisions)
boolean on = false;
Square() {
}
// Initialize squares offscreen (right of canvas)
void initialize()
{
on = true;
x = random(width+400, width+800);
y = random(0, height);
vx = random(-10, -4);
vy = random(-2, 2);
w = random(10, 15);
c = color(0, random(100, 200), random(100));
timer = 255;
timerBonus = 0.5;
dt = random(0.1, 5);
}
void draw()
{
if (!on) return;
fill(c, timer);
noStroke();
rectMode(CENTER);
rect(x, y, w, w);
}
void update()
{
// initialize if necessary
if (!on) {
if (random(0, 1) < 0.5) initialize();
return;
}
//move squares
x += vx;
y += vy;
//decay transparency
timer -= dt;
timerBonus -= dtBonus;
//reverse square vy when it hits floor/ceiling
if (y > height-w || y < w)
{
vy = -vy;
}
// When square exits screen, re-initialize
if (x < 0 || x > width+601 || timer < 0) {
on = false;
}
}
//check for square collisions
void bounce() {
for (int i = 0; i < squares.length; i ++) {
// if this is myself, continue
if (this == squares[i]) continue;
// distance between two squares
float d = dist(x, y, squares[i].x, squares[i].y);
// minimum distance between two squares
float md = w+squares[i].w;
// if I collide with one of them
if (d < md) {
// push back in the opposite direction
float dx = (x - squares[i].x)/d;
float dy = (y - squares[i].y)/d;
// check if perfectly overlapping
if (dx == 0 && dy == 0) {
dx = random(-1, 1);
dy = random(-1, 1);
}
// compute the speed to add
float s = min(10, spring*(md-d));
vx += dx*s;
vy += dy*s;
}
}
}
}
//this class defines Timmy's body, which is comprised of joints, links, and his head
class WormJoint {
float cx, cy; // rest position
float x, y;
float vx=0, vy=0; // velocity in the two directions
float r; // joint radius
float k = 0.06; // spring constant
float d = 0.75; // damping
float hg = 0.5; // horizontal gravity
float red = 50; //color channels
float green = 200;
float blue = 200;
float a;
float da;
// Initialize a worm joint at rest position (x0,y0)
WormJoint(float x0, float y0, float r0)
{
x = x0;
y = y0;
r = r0;
a = random(TWO_PI);
da = radians(2);
}
void draw()
{
blue = 140 * (1+sin(a));
//draw worm joints
stroke(red, green, blue);
strokeWeight(4);
line(cx, cy, x, y);
fill(red, green, blue);
//draw worm eye connectors
strokeWeight(2);
line(mouseX, mouseY, mouseX+4, mouseY-12);
line(mouseX, mouseY, mouseX-4, mouseY-12);
//draw worm head
noStroke();
ellipse(mouseX, mouseY+2, 3*r, 3.5*r);
ellipse(x, y, 2*r, 2*r);
//draw worm eyes
fill(255);
ellipse(mouseX+4, mouseY-12, 1.5*r, 1.5*r);
ellipse(mouseX-4, mouseY-12, 1.5*r, 1.5*r);
fill(0);
ellipse(mouseX+4, mouseY-12, r-2, r-2);
ellipse(mouseX-4, mouseY-12, r-2, r-2);
//draw worm mouth
stroke(0);
line(mouseX-2, mouseY+4, mouseX+2, mouseY+4);
}
// Update the spring, with a new center
void update(float ncx, float ncy)
{
// set the new center
cx = ncx;
cy = ncy;
// usual spring stuff
vx -= k * (x-cx);
vy -= k * (y-cy);
vx -= hg;
vx *= d;
vy *= d;
x += vx;
y += vy;
a += da;
// green += random(-8, 8);
// blue += random(-8, 8);
green = constrain(green, 100, 240);
blue = constrain(blue, 100, 240);
}
}
See More Shortcuts