Skip to content

Final Screen

noooway edited this page Jun 18, 2017 · 46 revisions

In this part I want to add credits screen at the end of the game.

On the credits screen it is customary to mention people who have been involved in the project and resources that have been used. I'm going to use simple text buttons and attach a URL to each one. When cursor hovers over a button, the text changes color; the URL is opened on mouse click.

Most of the required functionality has already been implemented for the buttons class. It is possible to reuse certain parts of the code.

There are different approaches to reusing the code. Lua provides metatables; it is also possible to implement some kind of an OOP system. However, I'll deliberately ignore them and stick to a simpler approach.

To construct a button with URL, it is possible to use a constructor from the old buttons class and insert a URL manually. To achieve a better control over the text appearance, it is also convenient to specify font and text alignment on button construction.

local buttons = require "buttons"

local buttons_with_url = {}

function buttons_with_url.new_button( o )
   btn = buttons.new_button( o )
   btn.url = o.url or nil
   btn.font = o.font or love.graphics.getFont()
   btn.text_align = o.text_align or "center"
   .....
   return( btn )
end

The functionality of the update, and inside callbacks of the buttons_with_url is identical to the similar callbacks of the buttons. In fact, it is possible to simply use an assignment such as buttons_with_url.update_button = buttons.update_button. However, I redirect them explicitly.

function buttons_with_url.update_button( single_button, dt )
   buttons.update_button( single_button, dt )
end

function buttons_with_url.inside( single_button, pos )
   buttons.inside( single_button, pos )
end

The draw callback is redefined to use fonts and text alignment specified on construction.

function buttons_with_url.draw_button( single_button )
   local oldfont = love.graphics.getFont()
   love.graphics.setFont( single_button.font )
   if single_button.selected then
      local r, g, b, a = love.graphics.getColor()
      love.graphics.setColor( 255, 0, 0, 100 )
      love.graphics.printf( single_button.text,
                            single_button.position.x,
                            single_button.position.y,
                            single_button.width,
                            single_button.text_align )
      love.graphics.setColor( r, g, b, a )
   else
      love.graphics.printf( single_button.text,
                            single_button.position.x,
                            single_button.position.y,
                            single_button.width,
                            single_button.text_align )   
   end
   love.graphics.setFont( oldfont )
end

To open a URL on a mouse click, love.system.openURL can be used. The mousereleased callback is redefined instead of being redirected to the buttons.mousereleased.

function buttons_with_url.mousereleased( single_button, x, y, button )
   if single_button.selected then
      local status = love.system.openURL( single_button.url )
   end
   return single_button.selected 
end

These definitions are sufficient to create the necessary buttons on the final screen (at least, that is how I've implemented it initially). The problem is, there are 13 of them; together with non-clickable text there are 20 elements, and each one has to be positioned manually. This is cumbersome to maintain: for example, to shift the 'Sound' column 5 pixels right it is necessary to update positions of the 9 elements.

  1. Final screen: define and draw buttons.
local buttons_with_url = require "buttons_with_url"
local vector = require "vector"

local gamefinished = {}

.....

function gamefinished.load( prev_state, ... )
   gamecode_button = buttons_with_url.new_button{
      text = "Game code by noway",
      url = "https://github.com/noooway/love2d_arkanoid_tutorial",
      position = vector( 10, 310 ),
      width = 260,
      height = 30      
   }
   love_button = buttons_with_url.new_button{
      text = "Love2d framework by the Love Team",
      url = "http://love2d.org/",
      position = vector( 10, 350 ),
      width = 260,
      height = 50      
   }
   vector_button = buttons_with_url.new_button{
      text = "Vector library from HUMP by vrld",
      url = "https://github.com/vrld/hump",
      position = vector( 10, 410 ),
      width = 260,
      height = 80
   }
   .....
end

Along with buttons, some additional text is also printed.

function gamefinished.draw()
   local oldfont = love.graphics.getFont()
   love.graphics.setFont( bungee_font )
   love.graphics.printf( "Congratulations!",
                         235, 70, 350, "center" )
   love.graphics.printf( "You have finished the game!",
                         100, 110, 600, "center" )
   love.graphics.printf( "---Credits---",
                         276, 220, 250, "center" )
   love.graphics.printf( "Code",
                         10, 265, 260, "center" )
   love.graphics.setFont( bungee_font_links )
   buttons_with_url.draw_button( gamecode_button )
   buttons_with_url.draw_button( love_button )
   buttons_with_url.draw_button( vector_button )

   love.graphics.setFont( bungee_font )
   love.graphics.printf( "Visuals",
                         270, 265, 260, "center" )
   love.graphics.setFont( bungee_font_links )
   buttons_with_url.draw_button( tileset_button )
   buttons_with_url.draw_button( bungeefont_button )

   love.graphics.setFont( bungee_font )
   love.graphics.printf( "Sound",
                         530, 265, 260, "center" )
   love.graphics.setFont( bungee_font_links )
   love.graphics.printf( "Samples derived from works by",
                         570, 315, 200, "center" )

   love.graphics.setFont( bungee_font_soundeffects )
   buttons_with_url.draw_button( cmusounddesign_button )
   buttons_with_url.draw_button( ngruber_button )
   buttons_with_url.draw_button( bart_button )
   buttons_with_url.draw_button( qubodup_button )
   buttons_with_url.draw_button( tinyworlds_button )
   buttons_with_url.draw_button( edgardedition_button )

   love.graphics.setFont( bungee_font_links )
   buttons_with_url.draw_button( music_button )
   
   love.graphics.setFont( oldfont )
end
  1. Make buttons react on mouse
function gamefinished.update( dt )
   buttons_with_url.update_button( gamecode_button, dt )
   buttons_with_url.update_button( love_button, dt )
   buttons_with_url.update_button( vector_button, dt )
   buttons_with_url.update_button( tileset_button, dt )
   buttons_with_url.update_button( bungeefont_button, dt )
   buttons_with_url.update_button( cmusounddesign_button, dt )
   buttons_with_url.update_button( ngruber_button, dt )
   buttons_with_url.update_button( bart_button, dt )
   buttons_with_url.update_button( qubodup_button, dt )
   buttons_with_url.update_button( tinyworlds_button, dt )
   buttons_with_url.update_button( edgardedition_button, dt )
   buttons_with_url.update_button( music_button, dt )
end

function gamefinished.mousereleased( x, y, button, istouch )
   if button == 'r' or button == 2 then
      love.event.quit()
   end
   buttons_with_url.mousereleased( gamecode_button, x, y, button )
   buttons_with_url.mousereleased( love_button, x, y, button )
   buttons_with_url.mousereleased( vector_button, x, y, button )
   buttons_with_url.mousereleased( tileset_button, x, y, button )
   buttons_with_url.mousereleased( bungeefont_button, x, y, button )
   buttons_with_url.mousereleased( cmusounddesign_button, x, y, button )
   buttons_with_url.mousereleased( ngruber_button, x, y, button )
   buttons_with_url.mousereleased( bart_button, x, y, button )
   buttons_with_url.mousereleased( qubodup_button, x, y, button )
   buttons_with_url.mousereleased( tinyworlds_button, x, y, button )
   buttons_with_url.mousereleased( edgardedition_button, x, y, button )
   buttons_with_url.mousereleased( music_button, x, y, button )
end

    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