Montag, 21. September 2015

Interactive Art - Moon Phases


This application let's you put in a specific date and visualizes this moon phase itself.
I love the idea. It's pretty unique. Also the visual effect looks great. Its definitely really cool work.


http://www.creativeapplications.net/processing/making-moon-phases-tangible-and-poetic/

Interactive Art - Homework 3

This game uses a small physics engine I coded.

I seperated the main functions into an update() function for physics and a render() function for visual stuff.
If some performance issues would occur you simply could lower the rate of for example physics update each second.

I am happy with Bob's bouncing animation, but there is no real gameplay yet. Right now, there only is collission with the floor. If there were to add more objects, which would all be affected by phyisics and by collission with each other a good data structure would probably be a quadtree. 





class Object
{
  float   posX, posY, posZ, sizeX, sizeXInit, sizeYInit, sizeY, colorR, colorG, colorB;
  
  public Object(int posX, int posY, int posZ, float sizeX, int sizeY, int colorR, int colorG, int colorB)
  {
    this.posX    = posX;
    this.posY    = posY;
    this.posZ    = posZ;
    this.sizeX   = sizeX;
    sizeXInit    = sizeX;
    this.sizeY   = sizeY;
    sizeYInit    = sizeY;
    this.colorR  = colorR;
    this.colorG  = colorG;
    this.colorB  = colorB;
  }
}





Object   cubes[];
float    velocityY, velocityJumpEnd, velocityAdd, gravity;
float    easing, easingJump, jumpTargetX, jumpDistanceX, rotationTarget;
int      timeLastJump, timeJumpEnd, bubbleStart;
boolean  bubbleShow, isJump;




void setup()
{
  size(800, 500, P3D);

  //====================
  //Creating Font
  //==================== 
  
  PFont myFont = createFont("Arial", 36, false);
  textFont(myFont);


  //====================
  //Setting up cubes
  //==================== 
  
  cubes = new Object [2];

  for (int i = 0; i < cubes.length; i++)
  {
    cubes[i] = new Object(width/2, height/2, 250, 5, 20, 255, 255, 255);
  }
  cubes[0].colorG = 0;
  cubes[0].colorB = 0;
  cubes[0].sizeX = 2; 
  cubes[0].sizeY = 2;   
  cubes[1].sizeY = 19;
  

  cubes[1].colorR = random(100,255);
  cubes[1].colorG = random(100,255);
  cubes[1].colorB = random(100,255);
 
  
  //====================
  //Initialising other
  //====================  
  
  velocityY       = 0;
  velocityJumpEnd = 0;
  velocityAdd     = 0;
  gravity         = 0.00155;
  rotationTarget  = 0.5;  
  timeLastJump    = 0;
  easing          = 0.25;
  easingJump      = 0.025;
  timeJumpEnd     = 0;
  isJump          = true;
  jumpTargetX     = cubes[1].posX;
  bubbleStart     = 0;
  bubbleShow      = false;
}




void draw()
{
  update();
  render();
}



public void render()
{
  //====================
  //Basic Lightning, Background, etc.
  //====================

  background(45);
  directionalLight(255, 255, 255, 25, 20, -100);
  ambientLight(50, 50, 50);

  //====================
  //Draw Name
  //====================
  
  pushStyle();
    textAlign(CENTER);
    textSize(6);
    textLeading(6);
    fill(cubes[1].colorR, cubes[1].colorG, cubes[1].colorB, 255);
    text("<Ultra>\nBob", cubes[1].posX, cubes[1].posY-cubes[1].sizeY*2 - 14, cubes[1].posZ);
  popStyle();
  
 
  //====================
  //Draw Shadow
  //====================  

    pushStyle();
    fill(0,0,0,255);
      pushMatrix();
        noStroke();
        beginShape();
        vertex(cubes[1].posX-cubes[1].sizeX*1.2, 331, cubes[1].posZ-cubes[1].sizeX*1.8-5);
        vertex(cubes[1].posX+cubes[1].sizeX*1.2, 331, cubes[1].posZ-cubes[1].sizeX*1.8-5);
        vertex(cubes[1].posX+cubes[1].sizeX*1.2, 331, cubes[1].posZ+cubes[1].sizeX*1.8-5);
        vertex(cubes[1].posX-cubes[1].sizeX*1.2, 331, cubes[1].posZ+cubes[1].sizeX*1.8-5);
        endShape();    
      popMatrix();
    popStyle();
  
  
  //====================
  //Draw Bubble
  //====================
  
  if(bubbleShow)
  {
    pushStyle();
      pushMatrix();
        fill(0);
        beginShape();
          vertex(floor(cubes[1].posX)+10, cubes[1].posY-27+20-cubes[1].sizeY,  floor(cubes[1].posZ)-5); 
          vertex(floor(cubes[1].posX)+15, cubes[1].posY-30+20-cubes[1].sizeY, floor(cubes[1].posZ)-5);
          vertex(floor(cubes[1].posX)+15, cubes[1].posY-24+20-cubes[1].sizeY, floor(cubes[1].posZ)-5);   
        endShape();
        beginShape();
          vertex(floor(cubes[1].posX)+15, cubes[1].posY-36+20-cubes[1].sizeY, floor(cubes[1].posZ)-5); 
          vertex(floor(cubes[1].posX)+55, cubes[1].posY-36+20-cubes[1].sizeY, floor(cubes[1].posZ)-5);
          vertex(floor(cubes[1].posX)+55, cubes[1].posY-18+20-cubes[1].sizeY, floor(cubes[1].posZ)-5);
          vertex(floor(cubes[1].posX)+15, cubes[1].posY-18+20-cubes[1].sizeY, floor(cubes[1].posZ)-5);    
        endShape();
        fill(255, 255, 255);
        textAlign(CENTER);
        textSize(6);
        text("123", cubes[1].posX+35,cubes[1].posY-25+20-cubes[1].sizeY,cubes[1].posZ-4 );
      popMatrix();
    popStyle();  
  }
  
  //====================
  //Draw Cubes
  //====================
  
  for (int i = 0; i < cubes.length; i++)
  {
    pushStyle();
      noStroke();
        pushMatrix();  
        if(i == 0)
        {
          translate(cubes[i].posX,cubes[i].posY+cubes[i].sizeY,cubes[i].posZ);
            rotateX(rotationTarget);
            rotateY(rotationTarget);
          translate(-cubes[i].posX,-cubes[i].posY+cubes[i].sizeY,-cubes[i].posZ);
        }   
        fill(cubes[i].colorR, cubes[i].colorG, cubes[i].colorB);
        //TOP
        beginShape();
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
        endShape();
        //BOTTOM
        beginShape();
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
        endShape();    
        //LEFT
        beginShape();
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);
        endShape();    
        //RIGHT
        beginShape();
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);
        endShape();   
        //FRONT
        beginShape();
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ+cubes[i].sizeX);
        endShape(); 
        //BACK
        beginShape();
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY-cubes[i].sizeY*2, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX+cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);
          vertex(cubes[i].posX-cubes[i].sizeX, cubes[i].posY, cubes[i].posZ-cubes[i].sizeX);    
        endShape();
      popMatrix();
    popStyle();
  }
}




public void update()
{
  
  //====================
  //Bounding to Screen
  //==================== 
  
  rotationTarget+= 0.05;
  
  cubes[0].posX = mouseX;
  if(cubes[0].posX > 550)
  {
    cubes[0].posX = 550;
  }
  else if(cubes[0].posX < 245)
  {
    cubes[0].posX = 245;
  }
  
  cubes[0].posY = 315; 


  //====================
  //Jump Movement Left Right
  //====================
  
  jumpDistanceX  = jumpTargetX - cubes[1].posX; 
  cubes[1].posX  += jumpDistanceX * easingJump;  

  
  //====================
  //Physics and Stuff
  //====================
  int time             = millis() - timeLastJump;  
       
  if (cubes[1].posY < 330)
  {
    isJump             = true;
    cubes[1].posY      += velocityY;
    velocityY          += gravity * time;
  } 
  else
  {
    if(isJump)
    {  
      timeJumpEnd      = millis();
      velocityJumpEnd  = velocityY;
    }
    isJump             = false;
    cubes[1].posY      = 330;
    jumpTargetX        = cubes[1].posX;
    timeLastJump       = millis();
  }
  if (!isJump && velocityY > 0)
  {
    velocityY          -= (velocityJumpEnd/20);

    if (velocityY < 0)
    {
      velocityY        = 0;
    }
  }

    
  //====================
  //Bump Effect
  //====================
  
  if (!isJump && cubes[1].sizeY > 7 && velocityY > velocityJumpEnd / 3)
  {
    float targetSize   = 7;
    float dx           = targetSize - cubes[1].sizeY; 
    cubes[1].sizeY     += dx * easing;
    cubes[1].sizeX     -= dx / 3 * easing;
    
    velocityAdd        += (velocityJumpEnd/20);
    if(velocityAdd > 6.2)
    {
      velocityAdd = 6.2;
    }
    
  } 
  if (velocityY <= velocityJumpEnd / 3 && cubes[1].sizeY < cubes[1].sizeYInit )
  {
    float targetSize   = cubes[1].sizeYInit;
    float dx           = targetSize - cubes[1].sizeY; 
    cubes[1].sizeY     += dx * easing;
    cubes[1].sizeX     -= dx / 3 * easing;
    
    velocityAdd        -= (velocityJumpEnd/20);
    if(velocityAdd < 0)
    {
      velocityAdd = 0;
    }
    
    if (cubes[1].sizeY > cubes[1].sizeYInit-0.5)
    {
      cubes[1].sizeY   = cubes[1].sizeYInit;
      cubes[1].sizeX   = cubes[1].sizeXInit;
    }
  }
}


void mouseReleased()
{
  if (!isJump)
  {
    //====================
    //Jump Velocity
    //====================  
    cubes[1].posY = 329;
    //velocityY = - 2.0 - (velocityY / 4);
    velocityY = - 2.0 - velocityAdd;
    
    //====================
    //Jump Target X
    //====================
    
    jumpTargetX = cubes[0].posX;
    
    if(abs(cubes[0].posX - cubes[1].posX) > 65)
    {
      if(cubes[0].posX < cubes[1].posX)
      {
        jumpTargetX = cubes[0].posX - 65;
      }
      else
      {
        jumpTargetX = cubes[0].posX + 65;
      }      
    }
  }
}












Montag, 14. September 2015

Interactive Art - Homework 2

A small animation as Homework for Interactive Art
Download zip: click here

Initially I wanted to to animate a sequence from The Matrix but then decided for Naruto.

The scene uses animated Sprites.
























class Animation
{
  int     tick, frame, fps;
  int     repeated, repeatCount;
  int     posX, posY;  
  boolean sequenceFinished;
  PImage  sequenceRAW = new PImage();
  PImage  []sequence;

  public Animation(String name, int numFrames, int offsetX, int addX, int sizeX, int sizeY, int fps, int repeatCount, int posX, int posY)
  {
    tick              = 0;
    frame             = 0;
    repeated          = 0;
    sequenceFinished  = false;
    this.fps          = fps;
    this.repeatCount  = repeatCount;
    this.posX         = posX;
    this.posY         = posY;    
    sequence          = new PImage[numFrames]; 
    sequenceRAW       = loadImage(name+".png");
    
    for(int i=0; i<sequence.length; i++)
    {
      sequence[i] = sequenceRAW.get(i*offsetX+addX,  0, sizeX, sizeY);
    }
  }
  
  
  
  public void animate()
  {
    pushStyle(); 
    image(sequence[frame], posX,posY);   
    if( !sequenceFinished )
    {  
      if (millis() - tick >= 1000/fps)
      {  
        frame++;
        if( frame == sequence.length-1 )
        {
          frame = 0;
          repeated++;
        } 
        if( repeatCount == repeated )
        {
          sequenceFinished = true;
          frame = sequence.length-2;
        }
        tick = millis();
      }
    }
    popStyle();  
  }
}



float     scale, circleSize, circleAlpha, shadowAlpha;
int       anim001X, anim001Y;
Animation anim001;
Animation anim002;  

int       anim003X, anim003Y;
Animation anim003;
Animation anim004;

PImage    bg, shadow, charShadow;
boolean   locked;

void setup()
{
  size(500,250);
  scale        = 1;
  circleSize   = 10;
  circleAlpha  = 10;
  shadowAlpha  = 180;
  anim001X     = 50;
  anim001Y     = 100;
  anim003X     = 450;
  anim003Y     = 93;
  locked       = true;
  //name, numFrames, offsetX, addX,  sizeX, sizeY,  fps,  repeatCount,   posX, posY
  anim001      = new Animation("sequenz001",4,   104,14,    100,72,   10,3,   0,0);
  anim002      = new Animation("sequenz001",3,   104,470,   100,72,   5,1,    0,0);  
  anim003      = new Animation("sequenz002",4,   104,14,    100,72,   10,3,   0,0);  
  anim004      = new Animation("sequenz002",3,   104,556,   100,72,   5,1,    0,0);    
  
  bg           = loadImage("background.png");
  shadow       = loadImage("shadow.png");
  charShadow   = loadImage("charShadow.png");
}



void draw()
{ 
  background(121);
  
  if(millis() > 1400)
  {
    locked = false;
  }
  
  if (!locked)
  {
    image(bg,0,-110);
    
    pushStyle();
    tint(255, 190);
    image(charShadow,anim001X+30,anim001Y+46);
    image(charShadow,anim003X-90,anim003Y+53);
    popStyle();
    
    
    
    //Draw Sasuke 
    pushMatrix();
    translate( anim001X,anim001Y );
    
    if( !anim001.sequenceFinished )
    {  
      anim001X += 2;
      anim001.animate();
    }
  
    if( anim001.sequenceFinished )
    {
      anim002.animate();
    }  
    popMatrix();
    
    
    
   //Draw Naruto
    pushMatrix();
    translate( anim003X,anim003Y );
    scale(-1,1);
    if( !anim003.sequenceFinished )
    {  
      anim003X -= 2;
      anim003.animate();
    }
    if( anim003.sequenceFinished )
    {
      anim004.animate();
    }   
    popMatrix(); 
    
    
    //Draw Explosion
    if( anim001.sequenceFinished )
    {
      pushStyle();
      fill(255,255,255,circleAlpha);
      noStroke();
      circleSize+=5;
      circleAlpha+= 2;
      ellipse(width/2, height/2, circleSize, circleSize);
      popStyle();
      pushStyle();
      tint(255, shadowAlpha); 
      shadowAlpha -= 3;
      image(shadow,0,0);
      popStyle();
    }   
    if( circleAlpha > 270 ) 
    {
      pushMatrix();
      pushStyle();
      fill(0);
      textAlign(CENTER);
      text("Martin Hanusch \n-\n Interactive Art Homework 2",250,height/2-20);
      popStyle();
      popMatrix();
    }
  }
}







Montag, 7. September 2015

Interactive Art: Homework 1


A simple program in processing creating a face. 
There are two functions called in mainloop every 1/60 sec. 
-One function creates a background patern with a for loop. Colors a generated random with every tick of the program.
-The other function creates a rotating creeper face.











Processing Code:

int colorR, colorG, colorB, varianz;
float counter;

public void setup()
{
  size(400,400);
  background(90,90,90,255);
  counter = 0;
}

public void draw()
{
  drawBackground();
  drawFace();
  
  pushStyle();
  fill(0);
  text("Interactive Art - Homework 1 (Martin Hanusch): \nFace (Creeper Face, Minecraft)",20,20);
  popStyle();
  
  println (frameRate); //just to check the performance
}

/*
DRAW THE Background
*/
public void drawBackground()
{
  for(int i = 0; i < 10; i++)
  {
    for(int j = 0; j < 10; j++)
    { 
      colorR = floor(random(0,100));
      colorG = floor(random(150,255));   
      colorB = floor(random(0,100));       
      pushStyle();
      noStroke();  
      fill(colorR,colorG,colorB,255);
      rect(i*40,j*40,40,40);
      popStyle(); 
    }  
  }
}

/*
DRAW THE FACE
*/
public void drawFace()
{
  counter+=0.01;
  pushMatrix();
  pushStyle();
  translate(width/2, height/2);
  rotate(counter);
  translate(-width/2, -height/2);  
  scale(1.05);
  noStroke();
  fill(0);
  rect(110,90,60,60);
  rect(230,90,60,60);
  rect(170,150,60,30);
  rect(140,180,120,60);
  rect(140,240,30,30);  
  rect(230,240,30,30);  
  popStyle();
  popMatrix();
}