Programming

Pi in The Sky… Stage 1 – The Build Up

The first  part of the Pi in the Sky project is to get your RPI ( Raspberry Pi ) up and running and usable.

Every one follow this tutorial and get the Pi up and running.

next steps will be to add camera and stream software

http://learn.adafruit.com/setting-up-a-raspberry-pi-with-noobs/overview

Adafruit is a really excellent site for everything so Adafruit and Google are your friends…

Advertisements

3D Camera Test – Processing


float camY = 200;
float camZ = (200) / tan(PI*30.0 / 180.0);
float centerX = 200;
float centerY = 200;
boolean left = false;
boolean right = false;
boolean up = false;
boolean down = false;
boolean left2 = false;
boolean right2 = false;
boolean up2 = false;
boolean down2 = false;
boolean back = false;
boolean forward = false;
 
 
 
PImage bg;
PImage texmap;

int sDetail = 35;  // Sphere detail setting
float rotationX = 0;
float rotationY = 0;
float velocityX = 0;
float velocityY = 0;
float globeRadius = 400;
float pushBack = 0;

float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5;
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);

 
void setup() {
  size(400, 400, P3D);
    texmap = loadImage("world32k.jpg");    
  initializeSphere(sDetail);
}
 
void draw() {
  
  camera(camX, camY, camZ, centerX, centerY, 0, 0, 1, 0);
 
  lights();
  background(255);
 
 /*
  pushMatrix();
  translate(200, 350, -80);
  box(400, 20, 200);
  popMatrix();
 
 
  pushMatrix();
  translate(200, 275, 35);
  box(240, 100, 30);
  popMatrix();
 
  pushMatrix();
  translate(30, 250, 15);
  box(20, 175, 20);
  popMatrix();
 
 
  pushMatrix();
  translate(370, 250, 15);
  box(20, 175, 20);
  popMatrix();
 
  pushMatrix();
  translate(30, 250, -100);
  box(20, 175, 20);
  popMatrix();
 
 
  pushMatrix();
  translate(370, 250, -100);
  box(20, 175, 20);
  popMatrix();
 
  pushMatrix();
  translate(30, 150, 15);
  noStroke();
  sphere(12);
  stroke(0);
  popMatrix();
 
 
  pushMatrix();
  translate(370, 150, 15);
  noStroke();
  sphere(12);
  stroke(0);
  popMatrix();
 
  pushMatrix();
  translate(30, 150, -100);
  noStroke();
  sphere(12);
  stroke(0);
  popMatrix();
 
 
  pushMatrix();
  translate(370, 150, -100);
  noStroke();
  sphere(12);
  stroke(0);
  popMatrix();
 
  pushMatrix();
  translate(130, 215, 35);
  box(20);
  popMatrix();
 
  pushMatrix();
  translate(130, 195, 35);
  noStroke();
  sphere(20);
  stroke(0);
  popMatrix();
 
  pushMatrix();
  translate(260, 215, 35);
  box(20);
  popMatrix();
 
  pushMatrix();
  translate(260, 195, 35);
  noStroke();
  sphere(20);
  stroke(0);
  popMatrix();
 
  pushMatrix();
  translate(200, 215, 15);
  box(40);
  popMatrix();
 
  pushMatrix();
  translate(200, 175, 25);
  noStroke();
  sphere(40);
  stroke(0);
  popMatrix();
*/

  movement();


  renderGlobe();
}
 
void keyPressed() {
  switch(key) {
  case'a':
    left = true;
    break;
  case 'd':
    right = true;
    break;
  case 'w':
    up = true;
    break;
  case 's':
    down = true;
    break;
  case'j':
    left2 = true;
    break;
  case 'l':
    right2 = true;
    break;
  case 'i':
    up2 = true;
    break;
  case 'k':
    down2 = true;
    break;
  case 't':
    back = true;
    break;
  case 'g':
    forward = true;
    break;
  }
}
 
void keyReleased() {
  switch(key) {
  case'a':
    left = false;
    break;
  case 'd':
    right = false;
    break;
  case 'w':
    up = false;
    break;
  case 's':
    down = false;
    break;
  case'j':
    left2 = false;
    break;
  case 'l':
    right2 = false;
    break;
  case 'i':
    up2 = false;
    break;
  case 'k':
    down2 = false;
    break;
  case 't':
    back = false;
    break;
  case 'g':
    forward = false;
    break;
  }
}
 
 
void movement() {
  if (up)camY -= 3;
  if (down)camY += 3;
  if (left)camX -= 3;
  if (right)camX += 3;
  if (up2)centerY -= 3;
  if (down2)centerY += 3;
  if (left2)centerX -= 3;
  if (right2)centerX += 3;
  if (back)camZ -= 3;
  if (forward) camZ += 3;
}



void renderGlobe() {
  pushMatrix();
  translate(width * 0.33, height * 0.5, pushBack);
  pushMatrix();
  noFill();
  stroke(255,200);
  strokeWeight(2);
  smooth();
  popMatrix();
  lights();    
  pushMatrix();
  rotateX( radians(-rotationX) );  
  rotateY( radians(270 - rotationY) );
  fill(200);
  noStroke();
  textureMode(IMAGE);  
  texturedSphere(globeRadius, texmap);
  popMatrix();  
  popMatrix();
  rotationX += velocityX;
  rotationY += velocityY;
  velocityX *= 0.95;
  velocityY *= 0.95;
  
  // Implements mouse control (interaction will be inverse when sphere is  upside down)
  if(mousePressed){
    //velocityX += (mouseY-pmouseY) * 0.01;
    //velocityY -= (mouseX-pmouseX) * 0.01;
   // camera(mouseX, mouseY, (height/2) / tan(PI/6), mouseX, height/2, 0, 0, 1, 0);
  }
}

void initializeSphere(int res)
{
  sinLUT = new float[SINCOS_LENGTH];
  cosLUT = new float[SINCOS_LENGTH];

  for (int i = 0; i < SINCOS_LENGTH; i++) {
    sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
    cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
  }

  float delta = (float)SINCOS_LENGTH/res;
  float[] cx = new float[res];
  float[] cz = new float[res];
  
  // Calc unit circle in XZ plane
  for (int i = 0; i < res; i++) {
    cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
    cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
  }
  
  // Computing vertexlist vertexlist starts at south pole
  int vertCount = res * (res-1) + 2;
  int currVert = 0;
  
  // Re-init arrays to store vertices
  sphereX = new float[vertCount];
  sphereY = new float[vertCount];
  sphereZ = new float[vertCount];
  float angle_step = (SINCOS_LENGTH*0.5f)/res;
  float angle = angle_step;
  
  // Step along Y axis
  for (int i = 1; i < res; i++) {
    float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
    float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
    for (int j = 0; j < res; j++) {
      sphereX[currVert] = cx[j] * curradius;
      sphereY[currVert] = currY;
      sphereZ[currVert++] = cz[j] * curradius;
    }
    angle += angle_step;
  }
  sDetail = res;
}

// Generic routine to draw textured sphere
void texturedSphere(float r, PImage t) {
  int v1,v11,v2;
  r = (r + 240 ) * 0.33;
  beginShape(TRIANGLE_STRIP);
  texture(t);
  float iu=(float)(t.width-1)/(sDetail);
  float iv=(float)(t.height-1)/(sDetail);
  float u=0,v=iv;
  for (int i = 0; i < sDetail; i++) {
    vertex(0, -r, 0,u,0);
    vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
    u+=iu;
  }
  vertex(0, -r, 0,u,0);
  vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
  endShape();   
  
  // Middle rings
  int voff = 0;
  for(int i = 2; i < sDetail; i++) {
    v1=v11=voff;
    voff += sDetail;
    v2=voff;
    u=0;
    beginShape(TRIANGLE_STRIP);
    texture(t);
    for (int j = 0; j < sDetail; j++) {
      vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
      vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
      u+=iu;
    }
  
    // Close each ring
    v1=v11;
    v2=voff;
    vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
    vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
    endShape();
    v+=iv;
  }
  u=0;
  
  // Add the northern cap
  beginShape(TRIANGLE_STRIP);
  texture(t);
  for (int i = 0; i < sDetail; i++) {
    v2 = voff + i;
    vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
    vertex(0, r, 0,u,v+iv);    
    u+=iu;
  }
  vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
  endShape();
  
}

Pixel Detection Code

Cracking game idea this week. A maze.  Draw up a complex maze – then work your way through it.  Winner is best time.

Two ways to implement it.  First is to say create a bunch of objects.  Then use collision detection on those objects. Thats a lot of work.  Second way it to draw the matrix – then use pixel collision detection to determine if the player can move – a bit easier.  Here is an example app with a simple matrix.

 

maze

 

PImage maze;
boolean collision;
PrintWriter output;

int px,py,pw,ph;

void setup()

{

    size(200,200);
    
    output = createWriter("positions.txt"); 
    
    maze = loadImage("maze.png");
    image(maze, 0, 0); // Displays the image from point (0,0) 
    maze.loadPixels();
    
    for (int y = 0; y < maze.height-1; y++) { // Skip top and bottom edges
    for (int x = 0; x < maze.width-1; x++) { // Skip left and right edges
          // Calculate the adjacent pixel for this kernel point
          
          
          int pos =  y *maze.width + x;
          color c = maze.pixels[pos];
          output.println("Pixel: " + x + " y: " +  c);
          int alpha = (c >> 24) & 0xFF;
          int red   = (c >> 16) & 0xFF;
          int green = (c >> 8)  & 0xFF;
          int blue  =  c        & 0xFF;
          output.println("Color Map: " + alpha + " " + red + " " + green + " " + blue);
                   
          
        }
  }
  
  output.flush(); // Writes the remaining data to the file
  output.close(); // Finishes the file
  
  
}



void draw()
{

 background(255);
 fill(255,0,0);
 
 
  image(maze, 0, 0); // Displays the image from point (0,0) 
  maze.loadPixels();
  // Create an opaque image of the same size as the original
 //PImage edgeImg = createImage(maze.width, maze.height, RGB);
  // Loop through every pixel in the image.
  for (int y = 0; y < maze.height-1; y++) { // Skip top and bottom edges
    for (int x = 0; x < maze.width-1; x++) { // Skip left and right edges
          // Calculate the adjacent pixel for this kernel point
          
           int pos =  y *maze.width + x;
          color c = maze.pixels[pos];
          
          int alpha = (c >> 24) & 0xFF;
          int red   = (c >> 16) & 0xFF;
          int green = (c >> 8)  & 0xFF;
          int blue  =  c        & 0xFF;
          
          if ( alpha != 0 ) // is this a non transparent pixel ?
          {
              collision = insideBox(x, y, mouseX-4, mouseY-4,8,8);
              
              if ( collision ) 
              {
                fill(0,255,0);              
                
              }
            
          }
          
          
        }
  }
        
   rect(mouseX-4, mouseY-4, 8,8);
  
}


boolean insideBox(int x, int y, int p1x, int p1y, int w, int h)
// This code checks the cursor is inside the window... 
{
  // This code will return a false if the cursor is not in the button
  if (x > p1x  && x < p1x + w && y > p1y  &&  y  < p1y + h  ) {
       // the cursor is in the box
       return true;
  }
  else {
       // the cursor is not in the box
       return false;
  }
}

Helicopter Game

The helicopter game should be dodging missiles not clouds 🙂

So…

C-802

This is also in DropBox – in sketches\images

This is a PNG image – it has a transparent background.

The best way is to find an image that already is PNG and has a transparent background.

If you find a JPEG – you can down an application call Paint.NET – its free.  http://www.getpaint.net/

Load up your jpeg and then use the magic want to select the background you want to remove.  Then just delete it and save as a PNG – Magic!

 

 

 

Rectangle Collision Detection

This is a simple article on how we can detect if two rectangles are in collision.

You must check this with every frame that is drawn – so it will be part of your main loop.

The based approach is say to have  a rectangular player shape and a rectangular object.

You could take each point of the player rectangle and simply check if it inside the object rectangle.  That will work.

If you remember your coordinate space

These are the rectangles we want to detect.

So you can use a single call to determine if they are in collision:

/**
 * Check if two rectangles collide
 * x_1, y_1, width_1, and height_1 define the boundaries of the first rectangle
 * x_2, y_2, width_2, and height_2 define the boundaries of the second rectangle
 */
boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1, float x_2, float y_2, float width_2, float height_2)
{
  return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
}

Player Class

This is only the player class. It allows you to define a player then move it around the screen. Note the calls in the main loop are very few

 
class Player
{
  
  static final float gravity = 0.14;
  static final float friction = 0.03;
  static final float bounceVel = 6.1;
  
  PImage pimage=null;  // The player image
  public int pWidth=20;
  public int pHeight=20;
  public float maxYVel = 2;
  public float maxXVel = 2;
  public float acceleration=2;
  public boolean useGravity=false; 
  public boolean deadStop=false;
  public boolean edgeStop=false;
  
  float x, y, xVel, yVel;
  int w, h;
  Player(int x, int y)
  {
    this.x = x;
    this.y = y;
    w = h = 20;
    this.useGravity=false;
  }
  
  void display()
  {
    fill(204,0,0);
    rect(x,y,pWidth,pHeight);
  }
  
  void move()
  {
    x += xVel;
    y += yVel;
  
    
    // horizontal
    if (gameOver)
    {
       println("GAME OVER");
       exit();
    }
   
    if (aPressed) 
    {
      xVel -= acceleration;
    }
    else if (sPressed) 
    {
      xVel += acceleration;
    }
    else if (wPressed) 
    {
      yVel -= acceleration;
    }
    else if (zPressed) 
    {
      yVel += acceleration;
    }
    else if (jPressed) 
    {
      yVel = -5;
      deadStop=false;
      useGravity=true;
    }

    else 
    {
      if (deadStop) {
        xVel=0;
        yVel=0;
      }
      
      
    }
    
    
    // X Friction
    if (xVel > 0)
    {
      xVel -= friction;
    }
    else
    {
      xVel += friction;
    }
    
    // Y Friction
    if (yVel > 0)
    {
      yVel -= friction;
    }
    else
    {
      yVel += friction;
    }
    
    // check wrap around before a move
    if (edgeStop)
    {
      if (x > width-w) x = width-w;
      if (x < 0) x = 0;
    
      if (y> height-h) y=height-h;
      if (y<0) y = 0;
    }
    else
    {
      if (x > width-w) x = 0;
      if (x < 0) x = width-w;
    
      if (y> height-h) y=0;
      if (y<0) y = height-h;
      
    }
  
    
    // Check limits on all movement of the player
    if (abs(xVel) <= friction) 
    {
      xVel = 0;
    }
    if (abs(yVel) <= friction) 
    {
      yVel = 0;
    }
    // vertical - always overide - can stop Gravity
    if (useGravity)
    {
      yVel += gravity;
    }
      
    // Limit max velocity
    xVel = min(maxXVel, xVel);
    xVel = max(-maxXVel, xVel);
    // Limit max velocity
    yVel = min(maxYVel, yVel);
    yVel = max(-maxYVel, yVel);
    
    println(xVel);
    println(yVel);
  
    
  }
}


// This is where the sketch starts 
Player p;
boolean wPressed, aPressed, sPressed, zPressed, jPressed;
int score, fallCount;
boolean gameOver;
  
void setup()
{
  size(320, 480);
  frameRate(60);
  initialize();
}
  
void initialize()
{
  score = 0;
  fallCount = 0;
  gameOver = false;
  
  // Create a new player
  p = new Player(width/2, height/2);
  //p.deadStop = true;
  //p.edgeStop=true;

}
  
void draw()
{
  //println(score);
  background(204);
  p.display();
  p.move();
  
//  if (fallCount > 90 ) initialize();
}
  
  
  
void keyPressed()
{
  if (key == 'w') wPressed = true;
  if (key == 'a') aPressed = true;
  if (key == 's') sPressed = true;
  if (key == 'z') zPressed = true;
  if (key == 'j') jPressed = true;
}
  
void keyReleased()
{
  if (key == 'w') wPressed = false;
  if (key == 'a') aPressed = false;
  if (key == 's') sPressed = false;
  if (key == 'z') zPressed = false;
  if (key == 'j') jPressed = false;
}

Doodle Jump Test App

This sketch is complete and can be downloaded. its a version of doodle jump but it shows the way that you can use objects to create a simple game.


class Platform
{
 float x,y,w,h;
 float xvel, yvel;

 Platform(int x, int y, int w, int h)
 {
 this.x = x;
 this.y = y;
 this.w = w;
 this.h = h;
 }

 void display()
 {
 fill(0);
 rect(x,y,w,h);
 }

 void move()
 {
 x += xvel;
 y += yvel;
 }

}

class HorizontalMovingPlatform extends Platform
{
 static final float speed = 0.9;

 HorizontalMovingPlatform(int x, int y, int w, int h)
 {
 super(x, y, w, h);
 this.xvel = speed;
 }

 void move()
 {
 super.move();
 if( (x+w > width - 10) || (x < 10) )
 {
 xvel *= -1;
 }
 }
}

class Player
{

 static final float gravity = 0.14;
 static final float bounceVel = 6.1;
 static final float maxYVel = 12;
 static final float maxXVel = 2;

 float x, y, xVel, yVel;
 int w, h;
 Player(int x, int y)
 {
 this.x = x;
 this.y = y;
 w = h = 20;
 }

 void display()
 {
 fill(204,0,0);
 rect(x,y,w,h);
 }

 void move()
 {
 x += xVel;
 y += yVel;

 // wrap around
 if (x > width-w) x = 0;
 if (x < 0) x = width-w;

 // horizontal
 if (!gameOver)
 {
 if (aPressed) xVel -= 0.05;
 else if (dPressed) xVel += 0.05;
 else
 {
 if (xVel > 0) xVel -= 0.03;
 else xVel += 0.03;
 }
 }
 if (abs(xVel) < 0.01) xVel = 0;
 xVel = min(maxXVel, xVel);
 xVel = max(-maxXVel, xVel);

 // vertical
 yVel += gravity;
 yVel = min(maxYVel, yVel);
 yVel = max(-maxYVel, yVel);
 }

 void collide(Platform p)
 {
 // standard rectangle intersections, but only for our lowest quarter
 if(x < p.x + p.w &&
 x + w > p.x &&
 y+h/2+h/4 < p.y + p.h &&
 y + h > p.y)
 {
 // but we only care about platforms when falling
 if (yVel > 0) {
 // for bouncing
 yVel = -bounceVel;
 }
 }
 }

}

Player p;
ArrayList platforms;
boolean wPressed, aPressed, sPressed, dPressed;
int score, fallCount;
boolean gameOver;

void setup()
{
 size(320, 480);
 frameRate(60);
 initialize();
}

void initialize()
{
 score = 0;
 fallCount = 0;
 gameOver = false;
 p = new Player(width/2, height/2);
 platforms = new ArrayList();
 platforms.add(new HorizontalMovingPlatform(20,80,70,8));
 platforms.add(new Platform(100,420,100,8));
 platforms.add(new Platform((int)random(40,180),320,100,8));
 platforms.add(new Platform((int)random(40,180),220,100,8));
 platforms.add(new Platform((int)random(40,180),120,100,8));
 platforms.add(new Platform((int)random(40,180),20,100,8));
}

void draw()
{
 //println(score);
 background(204);
 for(int i=0; i<platforms.size(); i++)
 {
 // le sigh... i wish processing supported generics.
 // http://dev.processing.org/bugs/show_bug.cgi?id=598
 p.collide((Platform)platforms.get(i));
 ((Platform)platforms.get(i)).display();
 ((Platform)platforms.get(i)).move();
 }
 p.display();
 p.move();

 adjustViewport();
 cleanUp();
 seedNewPlatforms();
 if (platformsBelow() == 0) gameOver = true;
 if (gameOver) fallCount++;
 if (fallCount > 90 ) initialize();
}

int platformsBelow()
{
 int count = 0;
 for(int i=0; i<platforms.size(); i++)
 {
 if (((Platform)platforms.get(i)).y >= p.y) count++;
 }
 return count;
}

void adjustViewport()
{
 // above midpoint
 float overHeight = height * 0.5 - p.y;
 if(overHeight > 0)
 {
 p.y += overHeight;
 for(int i=0; i<platforms.size(); i++)
 {
 ((Platform)platforms.get(i)).y += overHeight;
 }
 score += overHeight;
 }
 // falling
 float underHeight = p.y - (height-p.h-4);
 if(underHeight > 0)
 {
 p.y -= underHeight;
 for(int i=0; i<platforms.size(); i++)
 {
 ((Platform)platforms.get(i)).y -= underHeight;
 }
 }
}

void cleanUp()
{
 for(int i=platforms.size()-1; i>=0; i--)
 {
 // scrolled off the bottom
 if(((Platform)platforms.get(i)).y > height)
 {
 platforms.remove(i);
 }
 }
}

void seedNewPlatforms()
{
 if(platforms.size() < 7)
 {
 if(random(0,10) < 2) platforms.add(new HorizontalMovingPlatform((int)random(10,width-80),-10,70,8));
 else platforms.add(new Platform((int)random(20,200),-10,70,8));
 }
}

void keyPressed()
{
 if (key == 'w') wPressed = true;
 if (key == 'a') aPressed = true;
 if (key == 's') sPressed = true;
 if (key == 'd') dPressed = true;
}

void keyReleased()
{
 if (key == 'w') wPressed = false;
 if (key == 'a') aPressed = false;
 if (key == 's') sPressed = false;
 if (key == 'd') dPressed = false;
}