/* Project: 3x3x3 Mono LED Cube (r3).
 * File: MVEdgeChase.cpp
 * Description:
 *     Movie -- mv_EdgeChase
 *         LEDs are lit along an edge from one corner to another
 *         at a random speed. After a random delay another edge
 *         is lit. If the lighting of an edge runs in to an already
 *         lit LED, then the display is cleared and it starts again.
 *
 *     Movie -- mv_EdgeChase2
 *         LEDs are lit along an edge from one corner to another,
 *         but as it moves along, each previous LED is dimmed
 *         until it goes out.
 *
 * Copyright (C) 2014 Marc Symonds
 * All rights reserved.
 *
 * This software may be used and redistributed, with or without
 * modification, as long as it is understood that this software
 * is provided as-is without any explicit or implied warranties
 * of merchantablity or fitness of purpose.
 */

#include "Arduino.h"
#include "Movies.h"
#include "DisplayFrame.h"

void mv_EdgeChase()
{
  unsigned long ts, t;
  byte a, b, x, y, z;
  int nx, ny, nz;
  boolean r = false;
  int d1, d2;
  
  ts = millis() + DEF_MOVIE_TIME;

  d1 = random(40, 120);
  d2 = random(20, 60);
  
  a = random(0, 8);
  
  x = (a & 1) * 2;
  y = (a & 2);
  z = (a & 4) / 2;
  
  a = 3;
  
  displayFrame[POS(x, y, z)] = MAXBRIGHTNESSLEVEL;
  
  while (millis() < ts)
  {
    t = millis() + d1;
        
    nx = 0;
    ny = 0;
    nz = 0;
    
    do
    {
      b = random(0, 3);
    } while (a == b);

    a = b;
    
    switch(a)
    {
      case 0:
        nx = (x == 0) ? 1 : -1;
        break;
        
      case 1:
        ny = (y == 0) ? 1 : -1;
        break;
        
      case 2:
        nz = (z == 0) ? 1 : -1;
        break;
    }
    
    while (millis() < t)
      ;
    
    if (r)
      df_clear();
    
    displayFrame[POS(x, y, z)] = 4;
    displayFrame[POS(x+nx,y+ny,z+nz)] = MAXBRIGHTNESSLEVEL;
    
    delay(d2);
    
    displayFrame[POS(x+nx,y+ny,z+nz)] = 4;
    r = (displayFrame[POS(x+nx+nx,y+ny+ny,z+nz+nz)] != 0);
    displayFrame[POS(x+nx+nx,y+ny+ny,z+nz+nz)] = MAXBRIGHTNESSLEVEL;
    
    delay(d2);
    
    displayFrame[POS(x+nx,y+ny,z+nz)] = 1;
    
    x = x + nx + nx;
    y = y + ny + ny;
    z = z + nz + nz;
  }

  df_clear();
}

void mv_EdgeChase2()
{
  unsigned long ts, t;
  byte a, b, d, i, j, k, x, y, z;
  int nx, ny, nz;
  byte ss, sl;
  
  ts = millis() + DEF_MOVIE_TIME;

  d = random(50, 200);
  
  a = random(0, 8);
  
  x = (a & 1) * 2;
  y = (a & 2);
  z = (a & 4) / 2;
  points[0].Set(x, y, z);
  ss = 0;
  sl = 1;
  
  a = 3;
  
  displayFrame[points[0].Pos()] = MAXBRIGHTNESSLEVEL;

  t = millis() + d;
          
  while (millis() < ts)
  {
    nx = 0;
    ny = 0;
    nz = 0;
    
    do
    {
      b = random(0, 3);
    } while (a == b);

    a = b;
    
    switch(a)
    {
      case 0:
        nx = (x == 0) ? 1 : -1;
        break;
        
      case 1:
        ny = (y == 0) ? 1 : -1;
        break;
        
      case 2:
        nz = (z == 0) ? 1 : -1;
        break;
    }
    
    for (i = 0 ; i < 2 ; i++)
    {
      while (millis() < t)
        ;
        
      j = ss;
      for (k = 0 ; k < sl ; k++)
      {
        if (displayFrame[points[j].Pos()] > 0)
          --displayFrame[points[j].Pos()];
          
        if (j == 0)
          j = 7;
        else
          --j;
      }
      
      if (++ss > 7)
        ss = 0;
      
      if (sl < 8)
        ++sl;
  
      x = x + nx;
      y = y + ny;
      z = z + nz;
  
      points[ss].Set(x, y, z);
      displayFrame[points[ss].Pos()] = MAXBRIGHTNESSLEVEL;
      
      t = millis() + d;
    }
  }

  df_clear();
}

Leave a Reply

Your e-mail address will not be published. Required fields are marked *

Comments Protected by WP-SpamShield Spam Blocker