summaryrefslogtreecommitdiffhomepage
path: root/samples/99_genre_lowrez/nokia_3310/app/main.rb
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2021-04-10 03:51:14 -0500
committerAmir Rajan <[email protected]>2021-04-10 03:51:14 -0500
commit00e85147c9a1dd35a0857f361e5833a1c25f4a0a (patch)
tree52534d292ca3fa5733584eb926116228cb3551af /samples/99_genre_lowrez/nokia_3310/app/main.rb
parenta2d92c2bf09bcdc494f1391af69b707cca281a16 (diff)
downloaddragonruby-game-toolkit-contrib-00e85147c9a1dd35a0857f361e5833a1c25f4a0a.tar.gz
dragonruby-game-toolkit-contrib-00e85147c9a1dd35a0857f361e5833a1c25f4a0a.zip
Synced from DRGTK 2.10.
Diffstat (limited to 'samples/99_genre_lowrez/nokia_3310/app/main.rb')
-rw-r--r--samples/99_genre_lowrez/nokia_3310/app/main.rb625
1 files changed, 625 insertions, 0 deletions
diff --git a/samples/99_genre_lowrez/nokia_3310/app/main.rb b/samples/99_genre_lowrez/nokia_3310/app/main.rb
new file mode 100644
index 0000000..d275ada
--- /dev/null
+++ b/samples/99_genre_lowrez/nokia_3310/app/main.rb
@@ -0,0 +1,625 @@
+require 'app/nokia.rb'
+
+def tick args
+ # =======================================================================
+ # ==== HELLO WORLD ======================================================
+ # =======================================================================
+ # Steps to get started:
+ # 1. ~def tick args~ is the entry point for your game.
+ # 2. There are quite a few code samples below, remove the "##"
+ # before each line and save the file to see the changes.
+ # 3. 0, 0 is in bottom left and 83, 47 is in top right corner.
+ # 4. Be sure to come to the discord channel if you need
+ # more help: [[http://discord.dragonruby.org]].
+
+ # Commenting and uncommenting code:
+ # - Add a "#" infront of lines to comment out code
+ # - Remove the "#" infront of lines to comment out code
+
+ # Invoke the hello_world subroutine/method
+ hello_world args # <---- add a "#" to the beginning of the line to stop running this subroutine/method.
+
+ # =======================================================================
+ # ==== HOW TO RENDER A LABEL ============================================
+ # =======================================================================
+
+ # Uncomment the line below to invoke the how_to_render_a_label subroutine/method.
+ # Note: The method is defined in this file with the signature ~def how_to_render_a_label args~
+ # Scroll down to the method to see the details.
+
+ # Remove the "#" at the beginning of the line below
+ # how_to_render_a_label args # <---- remove the "#" at the beginning of this line to run the method
+
+
+ # =======================================================================
+ # ==== HOW TO RENDER A FILLED SQUARE (SOLID) ============================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_render_solids args
+
+
+ # =======================================================================
+ # ==== HOW TO RENDER AN UNFILLED SQUARE (BORDER) ========================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_render_borders args
+
+
+ # =======================================================================
+ # ==== HOW TO RENDER A LINE =============================================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_render_lines args
+
+
+ # =======================================================================
+ # == HOW TO RENDER A SPRITE =============================================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_render_sprites args
+
+
+ # =======================================================================
+ # ==== HOW TO MOVE A SPRITE BASED OFF OF USER INPUT =====================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_move_a_sprite args
+
+
+ # =======================================================================
+ # ==== HOW TO ANIMATE A SPRITE (SEPERATE PNGS) ==========================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_animate_a_sprite args
+
+
+ # =======================================================================
+ # ==== HOW TO ANIMATE A SPRITE (SPRITE SHEET) ===========================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_animate_a_sprite_sheet args
+
+
+ # =======================================================================
+ # ==== HOW TO DETERMINE COLLISION =============================================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_determine_collision args
+
+
+ # =======================================================================
+ # ==== HOW TO CREATE BUTTONS ==================================================
+ # =======================================================================
+ # Remove the "#" at the beginning of the line below
+ # how_to_create_buttons args
+
+ # ==== The line below renders a debug grid, mouse information, and current tick
+ # render_debug args
+end
+
+# =======================================================================
+# ==== HELLO WORLD ======================================================
+# =======================================================================
+def hello_world args
+ args.nokia.solids << { x: 0, y: 64, w: 10, h: 10, r: 255 }
+
+ args.nokia.labels << {
+ x: 42,
+ y: 46,
+ text: "nokia 3310 jam 3",
+ size_enum: NOKIA_FONT_SM,
+ alignment_enum: 1,
+ r: 0,
+ g: 0,
+ b: 0,
+ a: 255,
+ font: NOKIA_FONT_PATH
+ }
+
+ args.nokia.sprites << {
+ x: 42 - 10,
+ y: 26 - 10,
+ w: 20,
+ h: 20,
+ path: 'sprites/monochrome-ship.png',
+ a: 255,
+ angle: args.state.tick_count % 360
+ }
+end
+
+# =======================================================================
+# ==== HOW TO RENDER A LABEL ============================================
+# =======================================================================
+def how_to_render_a_label args
+ # NOTE: Text is aligned from the TOP LEFT corner
+
+ # Render an EXTRA LARGE/XL label (remove the "#" in front of each line below)
+ args.nokia.labels << { x: 0, y: 46, text: "Hello World",
+ size_enum: NOKIA_FONT_XL,
+ r: 0, g: 0, b: 0, a: 255,
+ font: NOKIA_FONT_PATH }
+
+ # Render a LARGE/LG label (remove the "#" in front of each line below)
+ args.nokia.labels << { x: 0, y: 29, text: "Hello World",
+ size_enum: NOKIA_FONT_LG,
+ r: 0, g: 0, b: 0, a: 255,
+ font: NOKIA_FONT_PATH }
+
+ # Render a MEDIUM/MD label (remove the "#" in front of each line below)
+ args.nokia.labels << { x: 0, y: 16, text: "Hello World",
+ size_enum: NOKIA_FONT_MD,
+ r: 0, g: 0, b: 0, a: 255,
+ font: NOKIA_FONT_PATH }
+
+ # Render a SMALL/SM label (remove the "#" in front of each line below)
+ args.nokia.labels << { x: 0, y: 7, text: "Hello World",
+ size_enum: NOKIA_FONT_SM,
+ r: 0, g: 0, b: 0, a: 255,
+ font: NOKIA_FONT_PATH }
+
+ # You are provided args.nokia.default_label which returns a Hash that you
+ # can ~merge~ properties with
+ # Example 1
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(text: "Default")
+
+ # Example 2
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 31,
+ text: "Default")
+end
+
+# =============================================================================
+# ==== HOW TO RENDER FILLED SQUARES (SOLIDS) ==================================
+# =============================================================================
+def how_to_render_solids args
+ # Render a square at 0, 0 with a width and height of 1
+ args.nokia.solids << { x: 0, y: 0, w: 1, h: 1 }
+
+ # Render a square at 1, 1 with a width and height of 2
+ args.nokia.solids << { x: 1, y: 1, w: 2, h: 2 }
+
+ # Render a square at 3, 3 with a width and height of 3
+ args.nokia.solids << { x: 3, y: 3, w: 3, h: 3 }
+
+ # Render a square at 6, 6 with a width and height of 4
+ args.nokia.solids << { x: 6, y: 6, w: 4, h: 4 }
+end
+
+# =============================================================================
+# ==== HOW TO RENDER UNFILLED SQUARES (BORDERS) ===============================
+# =============================================================================
+def how_to_render_borders args
+ # Render a square at 0, 0 with a width and height of 3
+ args.nokia.borders << { x: 0, y: 0, w: 3, h: 3, a: 255 }
+
+ # Render a square at 3, 3 with a width and height of 3
+ args.nokia.borders << { x: 3, y: 3, w: 4, h: 4, a: 255 }
+
+ # Render a square at 5, 5 with a width and height of 4
+ args.nokia.borders << { x: 7, y: 7, w: 5, h: 5, a: 255 }
+end
+
+# =============================================================================
+# ==== HOW TO RENDER A LINE ===================================================
+# =============================================================================
+def how_to_render_lines args
+ # Render a horizontal line at the bottom
+ args.nokia.lines << { x: 0, y: 0, x2: 83, y2: 0 }
+
+ # Render a vertical line at the left
+ args.nokia.lines << { x: 0, y: 0, x2: 0, y2: 47 }
+
+ # Render a diagonal line starting from the bottom left and going to the top right
+ args.nokia.lines << { x: 0, y: 0, x2: 83, y2: 47 }
+end
+
+# =============================================================================
+# == HOW TO RENDER A SPRITE ===================================================
+# =============================================================================
+def how_to_render_sprites args
+ # Loop 10 times and create 10 sprites in 10 positions
+ # Render a sprite at the bottom left with a width and height of 5 and a path of 'sprites/monochrome-ship.png'
+ 10.times do |i|
+ args.nokia.sprites << {
+ x: i * 8.4,
+ y: i * 4.8,
+ w: 5,
+ h: 5,
+ path: 'sprites/monochrome-ship.png'
+ }
+ end
+
+ # Given an array of positions create sprites
+ positions = [
+ { x: 20, y: 32 },
+ { x: 45, y: 15 },
+ { x: 72, y: 23 },
+ ]
+
+ positions.each do |position|
+ # use Ruby's ~Hash#merge~ function to create a sprite
+ args.nokia.sprites << position.merge(path: 'sprites/monochrome-ship.png',
+ w: 5,
+ h: 5)
+ end
+end
+
+# =============================================================================
+# ==== HOW TO ANIMATE A SPRITE (SEPERATE PNGS) ==========================
+# =============================================================================
+def how_to_animate_a_sprite args
+ # STEP 1: Define when you want the animation to start. The animation in this case will start in 3 seconds
+ start_animation_on_tick = 180
+
+ # STEP 2: Get the frame_index given the start tick.
+ sprite_index = start_animation_on_tick.frame_index count: 7, # how many sprites?
+ hold_for: 8, # how long to hold each sprite?
+ repeat: true # should it repeat?
+
+ # STEP 3: frame_index will return nil if the frame hasn't arrived yet
+ if sprite_index
+ # if the sprite_index is populated, use it to determine the sprite path and render it
+ sprite_path = "sprites/explosion-#{sprite_index}.png"
+ args.nokia.sprites << { x: 42 - 16,
+ y: 47 - 32,
+ w: 32,
+ h: 32,
+ path: sprite_path }
+ else
+ # if the sprite_index is nil, render a countdown instead
+ countdown_in_seconds = ((start_animation_on_tick - args.state.tick_count) / 60).round(1)
+
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 18,
+ text: "Count Down: #{countdown_in_seconds.to_sf}",
+ alignment_enum: 0)
+ end
+
+ # render the current tick and the resolved sprite index
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 11,
+ text: "Tick: #{args.state.tick_count}")
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 5,
+ text: "sprite_index: #{sprite_index}")
+end
+
+# =============================================================================
+# ==== HOW TO ANIMATE A SPRITE (SPRITE SHEET) =================================
+# =============================================================================
+def how_to_animate_a_sprite_sheet args
+ # STEP 1: Define when you want the animation to start. The animation in this case will start in 3 seconds
+ start_animation_on_tick = 180
+
+ # STEP 2: Get the frame_index given the start tick.
+ sprite_index = start_animation_on_tick.frame_index count: 7, # how many sprites?
+ hold_for: 8, # how long to hold each sprite?
+ repeat: true # should it repeat?
+
+ # STEP 3: frame_index will return nil if the frame hasn't arrived yet
+ if sprite_index
+ # if the sprite_index is populated, use it to determine the source rectangle and render it
+ args.nokia.sprites << {
+ x: 42 - 16,
+ y: 47 - 32,
+ w: 32,
+ h: 32,
+ path: "sprites/explosion-sheet.png",
+ source_x: 32 * sprite_index,
+ source_y: 0,
+ source_w: 32,
+ source_h: 32
+ }
+ else
+ # if the sprite_index is nil, render a countdown instead
+ countdown_in_seconds = ((start_animation_on_tick - args.state.tick_count) / 60).round(1)
+
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 18,
+ text: "Count Down: #{countdown_in_seconds.to_sf}",
+ alignment_enum: 0)
+ end
+
+ # render the current tick and the resolved sprite index
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 11,
+ text: "tick: #{args.state.tick_count}")
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 0,
+ y: 5,
+ text: "sprite_index: #{sprite_index}")
+end
+
+# =============================================================================
+# ==== HOW TO STORE STATE, ACCEPT INPUT, AND RENDER SPRITE BASED OFF OF STATE =
+# =============================================================================
+def how_to_move_a_sprite args
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 46, text: "Use Arrow Keys",
+ alignment_enum: 1)
+
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 41, text: "Or WASD",
+ alignment_enum: 1)
+
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 36, text: "Or Click",
+ alignment_enum: 1)
+
+ # set the initial values for x and y using ||= ("or equal operator")
+ args.state.ship.x ||= 0
+ args.state.ship.y ||= 0
+
+ # if a mouse click occurs, update the ship's x and y to be the location of the click
+ if args.nokia.mouse_click
+ args.state.ship.x = args.nokia.mouse_click.x
+ args.state.ship.y = args.nokia.mouse_click.y
+ end
+
+ # if a or left arrow is pressed/held, decrement the ships x position
+ if args.nokia.keyboard.left
+ args.state.ship.x -= 1
+ end
+
+ # if d or right arrow is pressed/held, increment the ships x position
+ if args.nokia.keyboard.right
+ args.state.ship.x += 1
+ end
+
+ # if s or down arrow is pressed/held, decrement the ships y position
+ if args.nokia.keyboard.down
+ args.state.ship.y -= 1
+ end
+
+ # if w or up arrow is pressed/held, increment the ships y position
+ if args.nokia.keyboard.up
+ args.state.ship.y += 1
+ end
+
+ # render the sprite to the screen using the position stored in args.state.ship
+ args.nokia.sprites << {
+ x: args.state.ship.x,
+ y: args.state.ship.y,
+ w: 5,
+ h: 5,
+ path: 'sprites/monochrome-ship.png',
+ # parameters beyond this point are optional
+ angle: 0, # Note: rotation angle is denoted in degrees NOT radians
+ r: 255,
+ g: 255,
+ b: 255,
+ a: 255
+ }
+end
+
+# =======================================================================
+# ==== HOW TO DETERMINE COLLISION =======================================
+# =======================================================================
+def how_to_determine_collision args
+ # Render the instructions
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 46, text: "Click Anywhere",
+ alignment_enum: 1)
+
+ # if a mouse click occurs:
+ # - set ship_one if it isn't set
+ # - set ship_two if it isn't set
+ # - otherwise reset ship one and ship two
+ if args.nokia.mouse_click
+ # is ship_one set?
+ if !args.state.ship_one
+ args.state.ship_one = { x: args.nokia.mouse_click.x - 5,
+ y: args.nokia.mouse_click.y - 5,
+ w: 10,
+ h: 10 }
+ # is ship_one set?
+ elsif !args.state.ship_two
+ args.state.ship_two = { x: args.nokia.mouse_click.x - 5,
+ y: args.nokia.mouse_click.y - 5,
+ w: 10,
+ h: 10 }
+ # should we reset?
+ else
+ args.state.ship_one = nil
+ args.state.ship_two = nil
+ end
+ end
+
+ # render ship one if it's set
+ if args.state.ship_one
+ # use Ruby's .merge method which is available on ~Hash~ to set the sprite and alpha
+ # render ship one
+ args.nokia.sprites << args.state.ship_one.merge(path: 'sprites/monochrome-ship.png')
+ end
+
+ if args.state.ship_two
+ # use Ruby's .merge method which is available on ~Hash~ to set the sprite and alpha
+ # render ship two
+ args.nokia.sprites << args.state.ship_two.merge(path: 'sprites/monochrome-ship.png')
+ end
+
+ # if both ship one and ship two are set, then determine collision
+ if args.state.ship_one && args.state.ship_two
+ # collision is determined using the intersect_rect? method
+ if args.state.ship_one.intersect_rect? args.state.ship_two
+ # if collision occurred, render the words collision!
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 5,
+ text: "Collision!",
+ alignment_enum: 1)
+ else
+ # if collision occurred, render the words no collision.
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 5,
+ text: "No Collision.",
+ alignment_enum: 1)
+ end
+ else
+ # if both ship one and ship two aren't set, then render --
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 6,
+ text: "--",
+ alignment_enum: 1)
+ end
+end
+
+# =============================================================================
+# ==== HOW TO CREATE BUTTONS ==================================================
+# =============================================================================
+def how_to_create_buttons args
+ # Define a button style
+ args.state.button_style = { w: 82, h: 10, }
+
+ # Render instructions
+ args.state.button_message ||= "Press a Button!"
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 82,
+ text: args.state.button_message,
+ alignment_enum: 1)
+
+
+ # Creates button one using a border and a label
+ args.state.button_one_border = args.state.button_style.merge( x: 1, y: 32)
+ args.nokia.borders << args.state.button_one_border
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: args.state.button_one_border.x + 2,
+ y: args.state.button_one_border.y + NOKIA_FONT_SM_HEIGHT + 2,
+ text: "Button One")
+
+ # Creates button two using a border and a label
+ args.state.button_two_border = args.state.button_style.merge( x: 1, y: 20)
+
+ args.nokia.borders << args.state.button_two_border
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: args.state.button_two_border.x + 2,
+ y: args.state.button_two_border.y + NOKIA_FONT_SM_HEIGHT + 2,
+ text: "Button Two")
+
+ # Initialize the state variable that tracks which button was clicked to "" (empty stringI
+ args.state.last_button_clicked ||= "--"
+
+ # If a click occurs, check to see if either button one, or button two was clicked
+ # using the inside_rect? method of the mouse
+ # set args.state.last_button_clicked accordingly
+ if args.nokia.mouse_click
+ if args.nokia.mouse_click.inside_rect? args.state.button_one_border
+ args.state.last_button_clicked = "One Clicked!"
+ elsif args.nokia.mouse_click.inside_rect? args.state.button_two_border
+ args.state.last_button_clicked = "Two Clicked!"
+ else
+ args.state.last_button_clicked = "--"
+ end
+ end
+
+ # Render the current value of args.state.last_button_clicked
+ args.nokia.labels << args.nokia
+ .default_label
+ .merge(x: 42,
+ y: 5,
+ text: args.state.last_button_clicked,
+ alignment_enum: 1)
+end
+
+def render_debug args
+ if !args.state.grid_rendered
+ (NOKIA_HEIGHT + 1).map_with_index do |i|
+ args.outputs.static_debug << {
+ x: NOKIA_X_OFFSET,
+ y: NOKIA_Y_OFFSET + (i * NOKIA_ZOOM),
+ x2: NOKIA_X_OFFSET + NOKIA_ZOOMED_WIDTH,
+ y2: NOKIA_Y_OFFSET + (i * NOKIA_ZOOM),
+ r: 128,
+ g: 128,
+ b: 128,
+ a: 80
+ }.line
+ end
+
+ (NOKIA_WIDTH + 1).map_with_index do |i|
+ args.outputs.static_debug << {
+ x: NOKIA_X_OFFSET + (i * NOKIA_ZOOM),
+ y: NOKIA_Y_OFFSET,
+ x2: NOKIA_X_OFFSET + (i * NOKIA_ZOOM),
+ y2: NOKIA_Y_OFFSET + NOKIA_ZOOMED_HEIGHT,
+ r: 128,
+ g: 128,
+ b: 128,
+ a: 80
+ }.line
+ end
+ end
+
+ args.state.grid_rendered = true
+
+ args.state.last_click ||= 0
+ args.state.last_up ||= 0
+ args.state.last_click = args.state.tick_count if args.nokia.mouse_down # you can also use args.nokia.click
+ args.state.last_up = args.state.tick_count if args.nokia.mouse_up
+ args.state.label_style = { size_enum: -1.5 }
+
+ args.state.watch_list = [
+ "args.state.tick_count is: #{args.state.tick_count}",
+ "args.nokia.mouse_position is: #{args.nokia.mouse_position.x}, #{args.nokia.mouse_position.y}",
+ "args.nokia.mouse_down tick: #{args.state.last_click || "never"}",
+ "args.nokia.mouse_up tick: #{args.state.last_up || "false"}",
+ ]
+
+ args.outputs.debug << args.state
+ .watch_list
+ .map_with_index do |text, i|
+ {
+ x: 5,
+ y: 720 - (i * 18),
+ text: text,
+ size_enum: -1.5,
+ r: 255, g: 255, b: 255
+ }.label
+ end
+
+ args.outputs.debug << {
+ x: 640,
+ y: 25,
+ text: "INFO: dev mode is currently enabled. Comment out the invocation of ~render_debug~ within the ~tick~ method to hide the debug layer.",
+ size_enum: -0.5,
+ alignment_enum: 1,
+ r: 255, g: 255, b: 255
+ }.label
+end
+
+def snake_demo args
+
+end
+
+$gtk.reset