samples/99_genre_crafting/craft_game_starting_point/app/main.rb
def input args
  # if the mouse is clicked and not item is currently being held
  # args.state.held_item is nil when the game starts.
  # If the player clicks, the property args.inputs.mouse.click will
  # be a non nil value, we don't want to process any of the code here
  # if the mouse hasn't been clicked
  return if !args.inputs.mouse.click

  # if a click occurred, add a ripple to the ripple queue
  args.state.click_ripples << { x: args.inputs.mouse.x - 5, y: args.inputs.mouse.y - 5, w: 10, h: 10, path: 'sprites/circle-gray.png', a: 128 }

  # if the mouse has been clicked, and no item is currently held...
  if !args.state.held_item
    # see if any of the items intersect the pointer using the inside_rect? method
    # the find method will either return the first object that returns true
    # for the match clause, or it'll return nil if nothing matches the match clause
    found = args.state.items.find do |item|
      # for each item in args.state.items, run the following boolean check
      args.inputs.mouse.click.point.inside_rect?(item)
    end

    # if an item intersects the mouse pointer, then set the item's location to :held and
    # set args.state.held_item to the item for later reference
    if found
      args.state.held_item = found
      found[:location] = :held
    end

  # if the mouse is clicked and an item is currently beign held....
  elsif args.state.held_item
    # determine if a slot within the craft area was clicked
    craft_area = args.state.craft_area.find { |a| args.inputs.mouse.click.point.inside_rect? a }

    # also determine if a slot within the inventory area was clicked
    inventory_area = args.state.inventory_area.find { |a| args.inputs.mouse.click.point.inside_rect? a }

    # if the click was within a craft area
    if craft_area
      # check to see if an item is already there and ignore the click if an item is found
      # item_at_craft_slot is a helper method that returns an item or nil for a given oridinal
      # position
      item_already_there = item_at_craft_slot args, craft_area[:ordinal_x], craft_area[:ordinal_y]

      # if an item *doesn't* exist in the craft area
      if !item_already_there
        # if the quantity they are currently holding is greater than 1
        if args.state.held_item[:quantity] > 1
          # remove one item (creating a seperate item of the same type), and place it
          # at the oridinal position and location of the craft area
          # the .merge method on Hash creates a new Hash, but updates any values
          # passed as arguments to merge
          new_item = args.state.held_item.merge(quantity: 1,
                                                location: :craft,
                                                ordinal_x: craft_area[:ordinal_x],
                                                ordinal_y: craft_area[:ordinal_y])

          # after the item is crated, place it into the args.state.items collection
          args.state.items << new_item

          # then subtract one from the held item
          args.state.held_item[:quantity] -= 1

        # if the craft area is available and there is only one item being held
        elsif args.state.held_item[:quantity] == 1
          # instead of creating any new items just set the location of the held item
          # to the oridinal position of the craft area, and then nil out the
          # held item state so that a new item can be picked up
          args.state.held_item[:location] = :craft
          args.state.held_item[:ordinal_x] = craft_area[:ordinal_x]
          args.state.held_item[:ordinal_y] = craft_area[:ordinal_y]
          args.state.held_item = nil
        end
      end

    # if the selected area is an inventory area (as opposed to within the craft area)
    elsif inventory_area

      # check to see if there is already an item in that inventory slot
      # the item_at_inventory_slot helper method returns an item or nil
      item_already_there = item_at_inventory_slot args, inventory_area[:ordinal_x], inventory_area[:ordinal_y]

      # if there is already an item there, and the item types/id match
      if item_already_there && item_already_there[:id] == args.state.held_item[:id]
        # then merge the item quantities
        held_quantity = args.state.held_item[:quantity]
        item_already_there[:quantity] += held_quantity

        # remove the item being held from the items collection (since it's quantity is now 0)
        args.state.items.reject! { |i| i[:location] == :held }

        # nil out the held_item so a new item can be picked up
        args.state.held_item = nil

      # if there currently isn't an item there, then put the held item in the slot
      elsif !item_already_there
        args.state.held_item[:location] = :inventory
        args.state.held_item[:ordinal_x] = inventory_area[:ordinal_x]
        args.state.held_item[:ordinal_y] = inventory_area[:ordinal_y]

        # nil out the held_item so a new item can be picked up
        args.state.held_item = nil
      end
    end
  end
end
# Alrighty! This is where all the fun happens
Alrighty. This is where all the fun happens
Alrighty . This is where all the fun happens
def input args
  return if !args.inputs.mouse.click
  args.state.click_ripples << { x: args.inputs.mouse.x - 5, y: args.inputs.mouse.y - 5, w: 10, h: 10, path: 'sprites/circle-gray.png', a: 128 }
  if !args.state.held_item
    found = args.state.items.find do |item|
      args.inputs.mouse.click.point.inside_rect?(item)
    end
    if found
      args.state.held_item = found
      found[:location] = :held
    end
  elsif args.state.held_item
    craft_area = args.state.craft_area.find { |a| args.inputs.mouse.click.point.inside_rect? a }
    inventory_area = args.state.inventory_area.find { |a| args.inputs.mouse.click.point.inside_rect? a }
    if craft_area
      item_already_there = item_at_craft_slot args, craft_area[:ordinal_x], craft_area[:ordinal_y]
      if !item_already_there
        if args.state.held_item[:quantity] > 1
          new_item = args.state.held_item.merge(quantity: 1,
                                                location: :craft,
                                                ordinal_x: craft_area[:ordinal_x],
                                                ordinal_y: craft_area[:ordinal_y])
          args.state.items << new_item
          args.state.held_item[:quantity] -= 1
        elsif args.state.held_item[:quantity] == 1
          args.state.held_item[:location] = :craft
          args.state.held_item[:ordinal_x] = craft_area[:ordinal_x]
          args.state.held_item[:ordinal_y] = craft_area[:ordinal_y]
          args.state.held_item = nil
        end
      end
    elsif inventory_area
      item_already_there = item_at_inventory_slot args, inventory_area[:ordinal_x], inventory_area[:ordinal_y]
      if item_already_there && item_already_there[:id] == args.state.held_item[:id]
        held_quantity = args.state.held_item[:quantity]
        item_already_there[:quantity] += held_quantity
        args.state.items.reject! { |i| i[:location] == :held }
        args.state.held_item = nil
      elsif !item_already_there
        args.state.held_item[:location] = :inventory
        args.state.held_item[:ordinal_x] = inventory_area[:ordinal_x]
        args.state.held_item[:ordinal_y] = inventory_area[:ordinal_y]
        args.state.held_item = nil
      end
    end
  end
end
def input args return if ! args . inputs . mouse . click args . state . click_ripples << { x : args . inputs . mouse . x - 5 , y : args . inputs . mouse . y - 5 , w : 10 , h : 10 , path : 'sprites/circle-gray.png' , a : 128 } if ! args . state . held_item found = args . state . items . find do | item | args . inputs . mouse . click . point . inside_rect? ( item ) end if found args . state . held_item = found found [ :location ] = :held end elsif args . state . held_item craft_area = args . state . craft_area . find { | a | args . inputs . mouse . click . point . inside_rect? a } inventory_area = args . state . inventory_area . find { | a | args . inputs . mouse . click . point . inside_rect? a } if craft_area item_already_there = item_at_craft_slot args , craft_area [ :ordinal_x ] , craft_area [ :ordinal_y ] if ! item_already_there if args . state . held_item [ :quantity ] > 1 new_item = args . state . held_item . merge ( quantity : 1 , location : :craft , ordinal_x : craft_area [ :ordinal_x ] , ordinal_y : craft_area [ :ordinal_y ] ) args . state . items << new_item args . state . held_item [ :quantity ] -= 1 elsif args . state . held_item [ :quantity ] == 1 args . state . held_item [ :location ] = :craft args . state . held_item [ :ordinal_x ] = craft_area [ :ordinal_x ] args . state . held_item [ :ordinal_y ] = craft_area [ :ordinal_y ] args . state . held_item = nil end end elsif inventory_area item_already_there = item_at_inventory_slot args , inventory_area [ :ordinal_x ] , inventory_area [ :ordinal_y ] if item_already_there && item_already_there [ :id ] == args . state . held_item [ :id ] held_quantity = args . state . held_item [ :quantity ] item_already_there [ :quantity ] += held_quantity args . state . items . reject! { | i | i [ :location ] == :held } args . state . held_item = nil elsif ! item_already_there args . state . held_item [ :location ] = :inventory args . state . held_item [ :ordinal_x ] = inventory_area [ :ordinal_x ] args . state . held_item [ :ordinal_y ] = inventory_area [ :ordinal_y ] args . state . held_item = nil end end end end
Alrighty!
Alrighty!
# if the mouse is clicked and not item is currently being held # args.state.held_item is nil when the game starts. # If the player clicks, the property args.inputs.mouse.click will # be a non nil value, we don't want to process any of the code here # if the mouse hasn't been clicked # if a click occurred, add a ripple to the ripple queue # if the mouse has been clicked, and no item is currently held... # see if any of the items intersect the pointer using the inside_rect? method # the find method will either return the first object that returns true # for the match clause, or it'll return nil if nothing matches the match clause # for each item in args.state.items, run the following boolean check # if an item intersects the mouse pointer, then set the item's location to :held and # set args.state.held_item to the item for later reference # if the mouse is clicked and an item is currently beign held.... # determine if a slot within the craft area was clicked # also determine if a slot within the inventory area was clicked # if the click was within a craft area # check to see if an item is already there and ignore the click if an item is found # item_at_craft_slot is a helper method that returns an item or nil for a given oridinal # position # if an item *doesn't* exist in the craft area # if the quantity they are currently holding is greater than 1 # remove one item (creating a seperate item of the same type), and place it # at the oridinal position and location of the craft area # the .merge method on Hash creates a new Hash, but updates any values # passed as arguments to merge # after the item is crated, place it into the args.state.items collection # then subtract one from the held item # if the craft area is available and there is only one item being held # instead of creating any new items just set the location of the held item # to the oridinal position of the craft area, and then nil out the # held item state so that a new item can be picked up # if the selected area is an inventory area (as opposed to within the craft area) # check to see if there is already an item in that inventory slot # the item_at_inventory_slot helper method returns an item or nil # if there is already an item there, and the item types/id match # then merge the item quantities # remove the item being held from the items collection (since it's quantity is now 0) # nil out the held_item so a new item can be picked up # if there currently isn't an item there, then put the held item in the slot # nil out the held_item so a new item can be picked up
args