diff options
| author | Amir Rajan <[email protected]> | 2021-04-10 03:51:14 -0500 |
|---|---|---|
| committer | Amir Rajan <[email protected]> | 2021-04-10 03:51:14 -0500 |
| commit | 00e85147c9a1dd35a0857f361e5833a1c25f4a0a (patch) | |
| tree | 52534d292ca3fa5733584eb926116228cb3551af /samples/99_genre_lowrez/nokia_3310/app/main.rb | |
| parent | a2d92c2bf09bcdc494f1391af69b707cca281a16 (diff) | |
| download | dragonruby-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.rb | 625 |
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 |
