User Tools

Site Tools


haas:fall2021:c4eng:projects:brickify

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
haas:fall2021:c4eng:projects:brickify [2021/10/05 19:03] – [The paddle struct] wedgehaas:fall2021:c4eng:projects:brickify [2021/10/07 18:34] (current) – [Block processing code] wedge
Line 15: Line 15:
  
   * open up TIC-80   * open up TIC-80
-  * clear out the sample/demo code (CTRL-a then backspace or delete) +  * go into the code editor (hit ESCAPE from the command-line/rainbow screen) 
-  * go into the sprite editor:+    * clear out the sample/demo code (CTRL-a then backspace or delete) 
 +  * go into the sprite editor (click the PACMAN GHOST in the upper left):
     * select foreground sprites     * select foreground sprites
 +
 +{{ :haas:fall2021:c4eng:projects:spritenav.png?200 |}}
 +
       * in #257: draw an 8x4 paddle tile, going from edge to edge, and only using the top 4 rows of the tile       * in #257: draw an 8x4 paddle tile, going from edge to edge, and only using the top 4 rows of the tile
 +
 +{{ :haas:fall2021:c4eng:projects:sprite257.png?200 |}}
 +
       * in #258: in the top left of the tile, draw a 2x2 ball tile       * in #258: in the top left of the tile, draw a 2x2 ball tile
 +
 +{{ :haas:fall2021:c4eng:projects:sprite258.png?200 |}}
 +
       * in #259: from the top left of the tile, draw a 7x4 brick tile (using only the first 4 rows)       * in #259: from the top left of the tile, draw a 7x4 brick tile (using only the first 4 rows)
-  * proceed back to the code editor to input the code+ 
 +{{ :haas:fall2021:c4eng:projects:sprite259.png?200 |}} 
 +  
 +  * proceed back to the code editor to input the code (click the open/close square brackets in top left)
  
 =====Header and support function===== =====Header and support function=====
Line 147: Line 160:
 // data for the on-screen blocks the missile (ball) can hit // data for the on-screen blocks the missile (ball) can hit
 // //
-var brick = { 
-  tile: 259, 
-  wide: 8, 
-  x: 0, 
-  y: 0, 
-  visible: true, 
-}; 
 </code> </code>
 +
 +{{:haas:fall2021:c4eng:projects:tic80brickstruct.png?200|}}
 +
 +The actual definition of the brick will be part of class interactions.
 +
 +=====Iterate ourselves to a wall of blocks=====
 +The previous snippet hints at the foundation being laid for the creation of a brick struct, indicating we'd be replicating them, to have many bricks. We accomplish that here:
 +
 +<code javascript>
 +//////////////////////////////////////////////////////////////////////////////
 +//
 +// Create an array of blocks (30 blocks per row, 12 total rows)
 +//
 +</code>
 +
 +{{:haas:fall2021:c4eng:projects:tic80blockarrayfill.png?200|}}
 +
 +This actual process will be part of class interactions.
 +
 +=====The TIC() function=====
 +All of this code so far is taking place before the TIC() function, which means it will be run exactly once, and at the very beginning of running. The reason being we often want to perform one-time initialization steps and defining things, which we only need or want to do once.
 +
 +Now, though, we enter into the main section of the code responsible for the interactive game experience, and hence we place that in the TIC() function. We start with the bulk of paddle code, checking for controller presses, edge detection, and display (this should be among the most familiar of the code we've dealt with):
 +
 +<code javascript>
 +function TIC()
 +{
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // declare local variables
 +  //
 +  var index = 0;
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Clear the screen
 +  //
 +  cls(0);
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Check to see if the left arrow is being pressed
 +  //
 +  if (btn (left) == true)
 +  {
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Adjust the x position of the paddle by decrementing it
 +    //
 +    paddle.x = paddle.x - 1;
 +
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Bounds check: see if that recent movement moved us off the
 +    // left side of the screen (x-axis position of 0). If we have,
 +    // reset the x coordinate of the paddle to 0.
 +    //
 +    if (paddle.x <  0)
 +    {
 +      paddle.x  = 0;
 +    }
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Check to see if the left right arrow is being pressed
 +  //
 +  if (btn (right) == true)
 +  {
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Adjust the x position of the paddle by incrementing it
 +    //
 +    paddle.x = paddle.x + 1;
 +
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Bounds check: see if that recent movement moved us off the
 +    // right side of the screen (x-axis position of 240). If we have,
 +    // reset the x coordinate of the paddle to a position such that it
 +    // is bumping against the right side of the screen.
 +    //
 +    // This requires some calculations, since tiles are 8 pixels wide,
 +    // and we are doubling up our display of the paddle tiles (so 16);
 +    // that means, since coordinates of sprites are referenced from a
 +    // top-left perspective, we take the screen width (240) and then
 +    // subtract our total sprite width (16 for a double wide)
 +    //
 +    if (paddle.x >  (screenwidth - (paddle.wide / 2)))
 +    {
 +      paddle.x  = screenwidth - (paddle.wide / 2);
 +    }
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Display the paddle, compensating for width of desired sprite
 +  //
 +  for (index = 0; index < paddle.wide / 8; index=index+1)
 +  {
 +    spr (paddle.tile, paddle.x+(index*8), paddle.y, 0);
 +  }
 +
 +</code>
 +
 +=====ball processing in TIC()=====
 +The next part of TIC() will deal with the processing of the ball, its edge detection, and checking for collisions between the ball and paddle. This code should also be quite familiar:
 +
 +<code javascript>
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Move ball along its current path (determined by xdir
 +  // and ydir current states)
 +  //
 +  ball.x = ball.x + (1 * ball.xdir);
 +  ball.y = ball.y + (1 * ball.ydir);
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Bounds checking for the ball: left side of screen: reflect
 +  // it and send it in the opposite direction.
 +  //
 +  if (ball.x < 0)
 +  {
 +    ball.xdir = 1;
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Bounds checking for the ball: right side of screen: reflect
 +  // it and send it in the opposite direction.
 +  //
 +  if (ball.x + ball.wide > screenwidth)
 +  {
 +    ball.xdir = -1;
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Bounds checking for the ball: top of screen: reflect
 +  // it and send it in the opposite direction.
 +  //
 +  if (ball.y < 0)
 +  {
 +    ball.ydir = 1;
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Loss for player: paddle misses ball and ball leaves the
 +  // bottom of the screen. Reset ball to starting position.
 +  //
 +  if (ball.y + ball.wide > screenheight)
 +  {
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Same code as above: reset ball to its starting point
 +    //
 +    ball.x = (screenwidth / 2) - (ball.wide) / 2;
 +    ball.y = screenheight - (screenheight / 3);
 +
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Same code for initializing xdir and ydir above: obtain
 +    // a random choice of -1 or 1
 +    //
 +    ball.xdir = getRandomDirection();
 +    ball.ydir = getRandomDirection();
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Collision detection: is the top of the paddle coming into
 +  // contact with the ball? Check and react accordingly (reflect
 +  // the ball away).
 +  //
 +  // This requires the use of a compound condition in our if(),
 +  // as we need to check both x and y axis within the range of
 +  // the paddle to determine if we have a hit.
 +  //
 +  if ((ball.y+ball.wide >= paddle.y)     && // ball on y-plane
 +    (ball.x >= (paddle.x - ball.wide))   && // left side
 +    (ball.x <= (paddle.x + paddle.wide)) && // right side
 +    (ball.y <= (paddle.y + 8)))             // bottom
 +  {
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Place ball above the paddle
 +    //
 +    ball.y = paddle.y - 8;
 +
 +    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Reflect the ball away
 +    //
 +    ball.ydir = -1;
 +  }
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Display the ball sprite
 +  //
 +  spr (ball.tile, ball.x, ball.y, 0);
 +</code>
 +
 +With this, we'd technically have our functional pong game (which could be tested- we'd merely have to add one closing curly brace and run it). 
 +
 +But, the aim here is to add in brick blocks, so we continue on...
 +
 +=====Block processing code=====
 +The last part of our program, also to be done via classroom interaction, will handle the ball/brick collision detection. We lay down important comment blocks so that we can place the needed code:
 +
 +<code javascript>
 + 
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Ball-block collision detection - we have to check the ball against
 +  // each and every visible brick to determine if a collision has taken
 +  // place
 +  //
 +
 +</code>
 +
 +{{:haas:fall2021:c4eng:projects:tic80ballbrickcollision1.png?200|}}
 +
 +<code javascript>    //////////////////////////////////////////////////////////////////////////
 +    //
 +    // Only check if the asset is considered active
 +    //
 +
 +</code>
 +
 +{{:haas:fall2021:c4eng:projects:tic80ballblockcollision2.png?200|}}
 +
 +<code javascript>
 +      ////////////////////////////////////////////////////////////////////////
 +      //
 +      // Check for collision based on the four possible sides of impact
 +      //
 +
 +        //////////////////////////////////////////////////////////////////////
 +        //
 +        // If a brick, it is now considered inactive
 +        //
 +
 +        //////////////////////////////////////////////////////////////////////
 +        //
 +        // Determine if collision is occurring at the top or bottom of the
 +        // asset, and reflect y if so
 +        //
 +
 +        //////////////////////////////////////////////////////////////////////
 +        //
 +        // Determine if collision is occuring at the left or right of the
 +        // brick, and reflect x if so
 +        //
 +
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Display the block sprites, if visible
 +  //
 +  
 +  ////////////////////////////////////////////////////////////////////////////
 +  //
 +  // Draw borders around the playfield
 +  //
 +
 +}
 +</code>
 +
 +Also take note: that final closing curly brace, which completes our program.
 +
 +Once everything is typed in, and tiles are created in their appropriate slots, we can give the program a run and see it in action.
 +
haas/fall2021/c4eng/projects/brickify.1633460586.txt.gz · Last modified: 2021/10/05 19:03 by wedge