summaryrefslogtreecommitdiffhomepage
path: root/samples/99_genre_rpg_roguelike/roguelike_starting_point/app
diff options
context:
space:
mode:
author_Tradam <[email protected]>2021-12-16 19:22:26 -0500
committerGitHub <[email protected]>2021-12-16 19:22:26 -0500
commit5954b9beb4d4a3b4f248d72d1851195f030558a8 (patch)
treefecd8aa840a25afdb502915b0fdb4d03b7ed339a /samples/99_genre_rpg_roguelike/roguelike_starting_point/app
parent2f845281f133849256b57bb08fd3e9ae57600784 (diff)
parenteaa29e72939f5edf61735ccbb73c36ee89369f65 (diff)
downloaddragonruby-game-toolkit-contrib-5954b9beb4d4a3b4f248d72d1851195f030558a8.tar.gz
dragonruby-game-toolkit-contrib-5954b9beb4d4a3b4f248d72d1851195f030558a8.zip
Merge branch 'DragonRuby:master' into masterHEADmaster
Diffstat (limited to 'samples/99_genre_rpg_roguelike/roguelike_starting_point/app')
-rw-r--r--samples/99_genre_rpg_roguelike/roguelike_starting_point/app/main.rb438
1 files changed, 0 insertions, 438 deletions
diff --git a/samples/99_genre_rpg_roguelike/roguelike_starting_point/app/main.rb b/samples/99_genre_rpg_roguelike/roguelike_starting_point/app/main.rb
deleted file mode 100644
index 7ed8d60..0000000
--- a/samples/99_genre_rpg_roguelike/roguelike_starting_point/app/main.rb
+++ /dev/null
@@ -1,438 +0,0 @@
-=begin
-
- APIs listing that haven't been encountered in previous sample apps:
-
- - lambda: A way to define a block and its parameters with special syntax.
- For example, the syntax of lambda looks like this:
- my_lambda = -> { puts "This is my lambda" }
-
- Reminders:
- - args.outputs.labels: An array. The values generate a label.
- The parameters are [X, Y, TEXT, SIZE, ALIGNMENT, RED, GREEN, BLUE, ALPHA, FONT STYLE]
-
- - ARRAY#inside_rect?: Returns whether or not the point is inside a rect.
-
- - product: Returns an array of all combinations of elements from all arrays.
-
- - find: Finds all elements of a collection that meet requirements.
-
- - abs: Returns the absolute value.
-
-=end
-
-# This sample app allows the player to move around in the dungeon, which becomes more or less visible
-# depending on the player's location, and also has enemies.
-
-class Game
- attr_accessor :args, :state, :inputs, :outputs, :grid
-
- # Calls all the methods needed for the game to run properly.
- def tick
- defaults
- render_canvas
- render_dungeon
- render_player
- render_enemies
- print_cell_coordinates
- calc_canvas
- input_move
- input_click_map
- end
-
- # Sets default values and initializes variables
- def defaults
- outputs.background_color = [0, 0, 0] # black background
-
- # Initializes empty canvas, dungeon, and enemies collections.
- state.canvas ||= []
- state.dungeon ||= []
- state.enemies ||= []
-
- # If state.area doesn't have value, load_area_one and derive_dungeon_from_area methods are called
- if !state.area
- load_area_one
- derive_dungeon_from_area
-
- # Changing these values will change the position of player
- state.x = 7
- state.y = 5
-
- # Creates new enemies, sets their values, and adds them to the enemies collection.
- state.enemies << state.new_entity(:enemy) do |e| # declares each enemy as new entity
- e.x = 13 # position
- e.y = 5
- e.previous_hp = 3
- e.hp = 3
- e.max_hp = 3
- e.is_dead = false # the enemy is alive
- end
-
- update_line_of_sight # updates line of sight by adding newly visible cells
- end
- end
-
- # Adds elements into the state.area collection
- # The dungeon is derived using the coordinates of this collection
- def load_area_one
- state.area ||= []
- state.area << [8, 6]
- state.area << [7, 6]
- state.area << [7, 7]
- state.area << [8, 9]
- state.area << [7, 8]
- state.area << [7, 9]
- state.area << [6, 4]
- state.area << [7, 3]
- state.area << [7, 4]
- state.area << [6, 5]
- state.area << [7, 5]
- state.area << [8, 5]
- state.area << [8, 4]
- state.area << [1, 1]
- state.area << [0, 1]
- state.area << [0, 2]
- state.area << [1, 2]
- state.area << [2, 2]
- state.area << [2, 1]
- state.area << [2, 3]
- state.area << [1, 3]
- state.area << [1, 4]
- state.area << [2, 4]
- state.area << [2, 5]
- state.area << [1, 5]
- state.area << [2, 6]
- state.area << [3, 6]
- state.area << [4, 6]
- state.area << [4, 7]
- state.area << [4, 8]
- state.area << [5, 8]
- state.area << [5, 9]
- state.area << [6, 9]
- state.area << [7, 10]
- state.area << [7, 11]
- state.area << [7, 12]
- state.area << [7, 12]
- state.area << [7, 13]
- state.area << [8, 13]
- state.area << [9, 13]
- state.area << [10, 13]
- state.area << [11, 13]
- state.area << [12, 13]
- state.area << [12, 12]
- state.area << [8, 12]
- state.area << [9, 12]
- state.area << [10, 12]
- state.area << [11, 12]
- state.area << [12, 11]
- state.area << [13, 11]
- state.area << [13, 10]
- state.area << [13, 9]
- state.area << [13, 8]
- state.area << [13, 7]
- state.area << [13, 6]
- state.area << [12, 6]
- state.area << [14, 6]
- state.area << [14, 5]
- state.area << [13, 5]
- state.area << [12, 5]
- state.area << [12, 4]
- state.area << [13, 4]
- state.area << [14, 4]
- state.area << [1, 6]
- state.area << [6, 6]
- end
-
- # Starts with an empty dungeon collection, and adds dungeon cells into it.
- def derive_dungeon_from_area
- state.dungeon = [] # starts as empty collection
-
- state.area.each do |a| # for each element of the area collection
- state.dungeon << state.new_entity(:dungeon_cell) do |d| # declares each dungeon cell as new entity
- d.x = a.x # dungeon cell position using coordinates from area
- d.y = a.y
- d.is_visible = false # cell is not visible
- d.alpha = 0 # not transparent at all
- d.border = [left_margin + a.x * grid_size,
- bottom_margin + a.y * grid_size,
- grid_size,
- grid_size,
- *blue,
- 255] # sets border definition for dungeon cell
- d # returns dungeon cell
- end
- end
- end
-
- def left_margin
- 40 # sets left margin
- end
-
- def bottom_margin
- 60 # sets bottom margin
- end
-
- def grid_size
- 40 # sets size of grid square
- end
-
- # Updates the line of sight by calling the thick_line_of_sight method and
- # adding dungeon cells to the newly_visible collection
- def update_line_of_sight
- variations = [-1, 0, 1]
- # creates collection of newly visible dungeon cells
- newly_visible = variations.product(variations).flat_map do |rise, run| # combo of all elements
- thick_line_of_sight state.x, state.y, rise, run, 15, # calls thick_line_of_sight method
- lambda { |x, y| dungeon_cell_exists? x, y } # checks whether or not cell exists
- end.uniq# removes duplicates
-
- state.dungeon.each do |d| # perform action on each element of dungeons collection
- d.is_visible = newly_visible.find { |v| v.x == d.x && v.y == d.y } # finds match inside newly_visible collection
- end
- end
-
- #Returns a boolean value
- def dungeon_cell_exists? x, y
- # Finds cell coordinates inside dungeon collection to determine if dungeon cell exists
- state.dungeon.find { |d| d.x == x && d.y == y }
- end
-
- # Calls line_of_sight method to add elements to result collection
- def thick_line_of_sight start_x, start_y, rise, run, distance, cell_exists_lambda
- result = []
- result += line_of_sight start_x, start_y, rise, run, distance, cell_exists_lambda
- result += line_of_sight start_x - 1, start_y, rise, run, distance, cell_exists_lambda # one left
- result += line_of_sight start_x + 1, start_y, rise, run, distance, cell_exists_lambda # one right
- result
- end
-
- # Adds points to the result collection to create the player's line of sight
- def line_of_sight start_x, start_y, rise, run, distance, cell_exists_lambda
- result = [] # starts as empty collection
- points = points_on_line start_x, start_y, rise, run, distance # calls points_on_line method
- points.each do |p| # for each point in collection
- if cell_exists_lambda.call(p.x, p.y) # if the cell exists
- result << p # add it to result collection
- else # if cell does not exist
- return result # return result collection as it is
- end
- end
-
- result # return result collection
- end
-
- # Finds the coordinates of the points on the line by performing calculations
- def points_on_line start_x, start_y, rise, run, distance
- distance.times.map do |i| # perform an action
- [start_x + run * i, start_y + rise * i] # definition of point
- end
- end
-
- def render_canvas
- return
- outputs.borders << state.canvas.map do |c| # on each element of canvas collection
- c.border # outputs border
- end
- end
-
- # Outputs the dungeon cells.
- def render_dungeon
- outputs.solids << [0, 0, grid.w, grid.h] # outputs black background for grid
-
- # Sets the alpha value (opacity) for each dungeon cell and calls the cell_border method.
- outputs.borders << state.dungeon.map do |d| # for each element in dungeon collection
- d.alpha += if d.is_visible # if cell is visible
- 255.fdiv(30) # increment opacity (transparency)
- else # if cell is not visible
- 255.fdiv(600) * -1 # decrease opacity
- end
- d.alpha = d.alpha.cap_min_max(0, 255)
- cell_border d.x, d.y, [*blue, d.alpha] # sets blue border using alpha value
- end.reject_nil
- end
-
- # Sets definition of a cell border using the parameters
- def cell_border x, y, color = nil
- [left_margin + x * grid_size,
- bottom_margin + y * grid_size,
- grid_size,
- grid_size,
- *color]
- end
-
- # Sets the values for the player and outputs it as a label
- def render_player
- outputs.labels << [grid_x(state.x) + 20, # positions "@" text in center of grid square
- grid_y(state.y) + 35,
- "@", # player is represented by a white "@" character
- 1, 1, *white]
- end
-
- def grid_x x
- left_margin + x * grid_size # positions horizontally on grid
- end
-
- def grid_y y
- bottom_margin + y * grid_size # positions vertically on grid
- end
-
- # Outputs enemies onto the screen.
- def render_enemies
- state.enemies.map do |e| # for each enemy in the collection
- alpha = 255 # set opacity (full transparency)
-
- # Outputs an enemy using a label.
- outputs.labels << [
- left_margin + 20 + e.x * grid_size, # positions enemy's "r" text in center of grid square
- bottom_margin + 35 + e.y * grid_size,
- "r", # enemy's text
- 1, 1, *white, alpha]
-
- # Creates a red border around an enemy.
- outputs.borders << [grid_x(e.x), grid_y(e.y), grid_size, grid_size, *red]
- end
- end
-
- #White labels are output for the cell coordinates of each element in the dungeon collection.
- def print_cell_coordinates
- return unless state.debug
- state.dungeon.each do |d|
- outputs.labels << [grid_x(d.x) + 2,
- grid_y(d.y) - 2,
- "#{d.x},#{d.y}",
- -2, 0, *white]
- end
- end
-
- # Adds new elements into the canvas collection and sets their values.
- def calc_canvas
- return if state.canvas.length > 0 # return if canvas collection has at least one element
- 15.times do |x| # 15 times perform an action
- 15.times do |y|
- state.canvas << state.new_entity(:canvas) do |c| # declare canvas element as new entity
- c.x = x # set position
- c.y = y
- c.border = [left_margin + x * grid_size,
- bottom_margin + y * grid_size,
- grid_size,
- grid_size,
- *white, 30] # sets border definition
- end
- end
- end
- end
-
- # Updates x and y values of the player, and updates player's line of sight
- def input_move
- x, y, x_diff, y_diff = input_target_cell
-
- return unless dungeon_cell_exists? x, y # player can't move there if a dungeon cell doesn't exist in that location
- return if enemy_at x, y # player can't move there if there is an enemy in that location
-
- state.x += x_diff # increments x by x_diff (so player moves left or right)
- state.y += y_diff # same with y and y_diff ( so player moves up or down)
- update_line_of_sight # updates visible cells
- end
-
- def enemy_at x, y
- # Finds if coordinates exist in enemies collection and enemy is not dead
- state.enemies.find { |e| e.x == x && e.y == y && !e.is_dead }
- end
-
- #M oves the user based on their keyboard input and sets values for target cell
- def input_target_cell
- if inputs.keyboard.key_down.up # if "up" key is in "down" state
- [state.x, state.y + 1, 0, 1] # user moves up
- elsif inputs.keyboard.key_down.down # if "down" key is pressed
- [state.x, state.y - 1, 0, -1] # user moves down
- elsif inputs.keyboard.key_down.left # if "left" key is pressed
- [state.x - 1, state.y, -1, 0] # user moves left
- elsif inputs.keyboard.key_down.right # if "right" key is pressed
- [state.x + 1, state.y, 1, 0] # user moves right
- else
- nil # otherwise, empty
- end
- end
-
- # Goes through the canvas collection to find if the mouse was clicked inside of the borders of an element.
- def input_click_map
- return unless inputs.mouse.click # return unless the mouse is clicked
- canvas_entry = state.canvas.find do |c| # find element from canvas collection that meets requirements
- inputs.mouse.click.inside_rect? c.border # find border that mouse was clicked inside of
- end
- puts canvas_entry # prints canvas_entry value
- end
-
- # Sets the definition of a label using the parameters.
- def label text, x, y, color = nil
- color ||= white # color is initialized to white
- [x, y, text, 1, 1, *color] # sets label definition
- end
-
- def green
- [60, 200, 100] # sets color saturation to shade of green
- end
-
- def blue
- [50, 50, 210] # sets color saturation to shade of blue
- end
-
- def white
- [255, 255, 255] # sets color saturation to white
- end
-
- def red
- [230, 80, 80] # sets color saturation to shade of red
- end
-
- def orange
- [255, 80, 60] # sets color saturation to shade of orange
- end
-
- def pink
- [255, 0, 200] # sets color saturation to shade of pink
- end
-
- def gray
- [75, 75, 75] # sets color saturation to shade of gray
- end
-
- # Recolors the border using the parameters.
- def recolor_border border, r, g, b
- border[4] = r
- border[5] = g
- border[6] = b
- border
- end
-
- # Returns a boolean value.
- def visible? cell
- # finds cell's coordinates inside visible_cells collections to determine if cell is visible
- state.visible_cells.find { |c| c.x == cell.x && c.y == cell.y}
- end
-
- # Exports dungeon by printing dungeon cell coordinates
- def export_dungeon
- state.dungeon.each do |d| # on each element of dungeon collection
- puts "state.dungeon << [#{d.x}, #{d.y}]" # prints cell coordinates
- end
- end
-
- def distance_to_cell cell
- distance_to state.x, cell.x, state.y, cell.y # calls distance_to method
- end
-
- def distance_to from_x, x, from_y, y
- (from_x - x).abs + (from_y - y).abs # finds distance between two cells using coordinates
- end
-end
-
-$game = Game.new
-
-def tick args
- $game.args = args
- $game.state = args.state
- $game.inputs = args.inputs
- $game.outputs = args.outputs
- $game.grid = args.grid
- $game.tick
-end