» ,

Chedd Off!

CheddOff gameplay

CheddOff gameplay

A branded game for the short lived Monty the mouse campaign for Cathedral City’s Chedds (Did someone say Didymus?). It was on Cartoon Network where it racked up a sizable number of impressions.

CheddOff title screen

CheddOff title screen

Illustration duties went to the talented John Gore who repurposed Monty the mouse into a cavalier and drew the game assets and scenery. While I embellished ‘Chedds’ to create the Chedd Off logo. Then laid out the title, how to play, pause and final score screens before moving onto Flash development. I’m particularly happy with how my cheese scroll turned out!

How to play Chedd Off

How to play Chedd Off


CheddOff final score, featuring Monty and John Gore’s bendy arrow

CheddOff final score, featuring Monty and John Gore’s bendy arrow

 

Flash development

Before opening FDT I mapped out the classes in OmniGraffle using a simplified version of MVC. Greensock’s LoaderMax is used to import XML, fonts and CSS for text in Flash. All graphics were put in a separate Assets SWC to improve workflow.

 

Collision detection & describeType

Collision detection is done with the handy bitmapData.hitTest. When the coordinates for the arrow position are detected the main game area loops through its children. looking for targets and furniture the arrow can hit. Here’s the loop:

private function startCollisionTests(event:ArrowEvent):void
{
  var collision:Boolean = false;
  
  for (var i:int = numChildren-1; i>=0; i--)
  {
    var typeXML:XML = describeType(getChildAt(i));
    var furniture:String = 'uk.cathedralcity.cheddoff.view.gamearea::Furniture';
    var targetLayer:String = 'uk.cathedralcity.cheddoff.view.gamearea::TargetLayer';
    
    if(typeXML.extendsClass.(@type==furniture).length() > 0)
    {
      //trace('Furniture found');
      collision = Furniture(getChildAt(i)).collisionTest(event.xy);
      if (collision) 
      {
        _targetController.firedAndMissed();
        break;
      }
    }
    else if (typeXML.(@name==targetLayer).length() > 0)
    {
      //trace('TargetLayer found');
      collision = TargetLayer(getChildAt(i)).collisionTest(event.xy);
      if (collision) break;
    }
  }
  
  // missed?
  if (!collision) _targetController.firedAndMissed();
}

Potential targets do a quick bounding box test first. Only when the arrow coordinates are within the targets bounding box will a more accurate, and more demanding bitmap data test be done.

public function collisionTest(xy:Point):Boolean
{
  var collision:Boolean = false;
  
  // test x, y, width height
  if (xy.x > _t1 && xy.x < _t2 && xy.y > _t3 && xy.y < _t4)
  {
    collision = _bitmapCollision.testPixel(xy, _graphics);
    if (collision) arrowStruck(xy);
  }
  
  return collision;
}

The BitmapCollision class is a singleton, reusing the same two BitmapData objects over and over again.

package uk.cathedralcity.cheddoff.view.gamearea
{
  import …

  /**
   * @author ajbis
   */
  public class BitmapCollision
  {
    private static var _inst:BitmapCollision;
    
    private var _sizeModel:SizeModel;
    private var _bmd1:BitmapData;
    private var _bmd2:BitmapData;
    private var _pixel:Shape;
    
    
    public function BitmapCollision(enforcer:Singleton)
    {
      _sizeModel = SizeModel.getModel();
      _bmd1 = new BitmapData(_sizeModel.width, _sizeModel.height, true, 0);
      _bmd2 = _bmd1.clone();
      
      _pixel = Block.getBlock(1, 1);
      
    }
    
    public static function getInst():BitmapCollision
    {
      if (_inst==null) _inst = new BitmapCollision(new Singleton());
      return _inst;
    }
    
    ///////////// actions //////////////
    
    public function test(a:DisplayObject, b:DisplayObject):Boolean
    {
      var boo:Boolean = false;
      
      // clear the bitmaps
      _bmd1.fillRect(_bmd1.rect, 0);
      _bmd2.fillRect(_bmd2.rect, 0);
      
      _bmd1.draw(a, new Matrix(1, 0, 0, 1, a.x, a.y));
      _bmd2.draw(b, new Matrix(1, 0, 0, 1, b.x, b.y));
      
      // the hit test itself
      if (_bmd1.hitTest(new Point(), 1, _bmd2, new Point(), 1))
        boo = true;
      
      return boo;
    }
    
    public function testPixel(xy:Point, dObj:DisplayObject):Boolean
    {
      _pixel.x = Math.floor(xy.x);
      _pixel.y = Math.floor(xy.y);
      
      return test(_pixel, dObj);
    }
  }
}
class Singleton {}

There’s a bunch of other interesing things going on in the code like the modifiers for speed, points, wind and targets. I might go into these in another post later. For those of you with Flash Player installed you can play the game here.

Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>