Skip to content

Bricks and Walls

noooway edited this page Jul 31, 2018 · 19 revisions

In Arkanoid bricks are arranged in a 2d-pattern. The next step is to add an array of bricks on the screen and walls to the borders.

The simplest way to create a 2d-pattern is to define several rows and columns of bricks:

bricks.rows = 8
bricks.columns = 11

For each brick we have to provide it's top-left corner position. It can be calculated using it's row and column indices, individual brick's width and height, vertical and horizontal distances between the bricks, and position of the top-left brick relative to the top-left corner of the screen:

local new_brick_position_x = bricks.top_left_position_x + 
   ( col - 1 ) *                                           --(*1)
   ( bricks.brick_width + bricks.horizontal_distance )
local new_brick_position_y = bricks.top_left_position_y + 
   ( row - 1 ) *                                           --(*1)
   ( bricks.brick_height + bricks.vertical_distance )     

(*1): indexing in Lua starts from 1 instead of 0.

When actual values for the parameters are provided, it is possible to populate bricks.current_level_bricks by looping over possible values of the row and column indices:

local bricks = {}
bricks.rows = 8                    --(*1a)
bricks.columns = 11
bricks.top_left_position_x = 70
bricks.top_left_position_y = 50
bricks.brick_width = 50
bricks.brick_height = 30
bricks.horizontal_distance = 10
bricks.vertical_distance = 15      --(*1b)
bricks.current_level_bricks = {}
.....
function bricks.construct_level()
   for row = 1, bricks.rows do
      for col = 1, bricks.columns do
         local new_brick_position_x = bricks.top_left_position_x +   --(*2)
            ( col - 1 ) *
            ( bricks.brick_width + bricks.horizontal_distance )
         local new_brick_position_y = bricks.top_left_position_y +   --(*2)
            ( row - 1 ) *
            ( bricks.brick_height + bricks.vertical_distance )     
         local new_brick = bricks.new_brick( new_brick_position_x,   --(*3)
                                             new_brick_position_y )
         bricks.add_to_current_level_bricks( new_brick )             --(*4)
      end      
   end   
end

(*1a)-(*1b): definition of the properties necessary to compute top left corner position for each brick.
(*2): top left position is computed.
(*3): a new brick is created.
(*4): the new brick is inserted into the bricks table.

In this part, I also want to add the walls on the borders of the screen. A wall is a rectangle, just like a brick is, so I use a walls table which is similar to bricks in it's structure.

There is a minor difference in walls.new_wall constructor: I do not provide a default width and height for the wall:

function walls.new_wall( position_x, position_y, width, height )
   return( { position_x = position_x,
             position_y = position_y,
             width = width,
             height = height } )
end

In walls.construct_walls, the left, right, top and bottom walls are constructed and then manually inserted into the walls.current_level_walls table:

function walls.construct_walls()
   local left_wall = walls.new_wall(
      0,
      0,
      walls.wall_thickness,
      love.graphics.getHeight()
   )
   local right_wall = walls.new_wall(
      love.graphics.getWidth() - walls.wall_thickness,
      0,
      walls.wall_thickness,
      love.graphics.getHeight()
   )
   local top_wall = walls.new_wall(
      0,
      0,
      love.graphics.getWidth(),
      walls.wall_thickness
   )
   local bottom_wall = walls.new_wall(
      0,
      love.graphics.getHeight() - walls.wall_thickness,
      love.graphics.getWidth(),
      walls.wall_thickness
   ) 
   walls.current_level_walls["left"] = left_wall
   walls.current_level_walls["right"] = right_wall
   walls.current_level_walls["top"] = top_wall
   walls.current_level_walls["bottom"] = bottom_wall
end

Constructors for the walls and the bricks have to be placed in love.load, so the walls and the bricks are created on the start of the game:

function love.load()
   bricks.construct_level()
   walls.construct_walls()
end

Finally, the love.update and love.draw functions now look like:

function love.update( dt )
   ball.update( dt )
   platform.update( dt )
   bricks.update( dt )
   walls.update( dt )
end
 
function love.draw()
   ball.draw()
   platform.draw()
   bricks.draw()
   walls.draw()
end



← 1.2 - Game Objects as Lua Tables     ↑ To the top     Next section: 1.4 - Detecting Collisions→

    Home
    Acknowledgements
    Todo

Chapter 1: Prototype

  1. The Ball, The Brick, The Platform
  2. Game Objects as Lua Tables
  3. Bricks and Walls
  4. Detecting Collisions
  5. Resolving Collisions
  6. Levels

    Appendix A: Storing Levels as Strings
    Appendix B: Optimized Collision Detection (draft)

Chapter 2: General Code Structure

  1. Splitting Code into Several Files
  2. Loading Levels from Files
  3. Straightforward Gamestates
  4. Advanced Gamestates
  5. Basic Tiles
  6. Different Brick Types
  7. Basic Sound
  8. Game Over

    Appendix C: Stricter Modules (draft)
    Appendix D-1: Intro to Classes (draft)
    Appendix D-2: Chapter 2 Using Classes.

Chapter 3 (deprecated): Details

  1. Improved Ball Rebounds
  2. Ball Launch From Platform (Two Objects Moving Together)
  3. Mouse Controls
  4. Spawning Bonuses
  5. Bonus Effects
  6. Glue Bonus
  7. Add New Ball Bonus
  8. Life and Next Level Bonuses
  9. Random Bonuses
  10. Menu Buttons
  11. Wall Tiles
  12. Side Panel
  13. Score
  14. Fonts
  15. More Sounds
  16. Final Screen
  17. Packaging

    Appendix D: GUI Layouts
    Appendix E: Love-release and Love.js

Beyond Programming:

  1. Game Design
  2. Minimal Marketing (draft)
  3. Finding a Team (draft)

Archive

Clone this wiki locally