samples/04_physics_and_collisions/02_moving_objects/app/main.rb
# Performs calculations to move objects on the screen
Performs calculations to move objects on the screen
Performs calculations to move objects on the screen
def calc args
  args.state.player.x  += args.state.player.dx
  args.state.player.y  += args.state.player.dy
  args.state.player.dy += args.state.gravity
  args.state.player.y  = args.state.player.y.greater(args.state.bridge_top)
  args.state.player.x  = args.state.player.x.greater(0)
  args.state.player.falling = false if args.state.player.y == args.state.bridge_top
  args.state.player.rect = [args.state.player.x, args.state.player.y, args.state.player.h, args.state.player.w] 
  args.state.enemy.x += args.state.enemy.dx 
  args.state.enemy.y += args.state.enemy.dy 
  args.state.enemy.y  = args.state.enemy.y.greater(args.state.bridge_top)
  args.state.enemy.x  = args.state.enemy.x.greater(0)
  args.state.enemy.dy += args.state.gravity
  args.state.enemy.y  = args.state.enemy.y.greater(args.state.bridge_top)
  args.state.enemy.rect = [args.state.enemy.x, args.state.enemy.y, args.state.enemy.h, args.state.enemy.w]
  if args.state.enemy.y == args.state.bridge_top 
    args.state.enemy.dy = 0 
  end
  if args.state.tick_count.mod_zero?(args.state.enemy_jump_interval) && args.state.enemy.dy == 0
    args.state.enemy.dy = args.state.enemy_jump_power 
  end
  if args.state.tick_count.mod_zero?(args.state.hammer_throw_interval) || args.state.game_over_at.elapsed_time == 5
    volley_dx   = (rand(args.state.hammer_launch_power_default) + 1) * -1 
    if (args.state.player.x - args.state.enemy.x).abs < 128
      volley_dx = (rand(args.state.hammer_launch_power_near) + 1) * -1
    end
    if (args.state.player.x - args.state.enemy.x).abs > 300
      volley_dx = (rand(args.state.hammer_launch_power_far) + 1) * -1 
    end
    (rand(args.state.max_hammers_per_volley) + 1).map_with_index do |i|
      args.state.enemy.hammer_queue << { 
        x: args.state.enemy.x,
        w: args.state.hammer_size,
        h: args.state.hammer_size,
        dx: volley_dx, 
        throw_at: args.state.tick_count + i * args.state.gap_between_hammers
      }
    end
  end
  args.state.enemy.hammers += args.state.enemy.hammer_queue.find_all do |h|
    h[:throw_at] < args.state.tick_count
  end
  args.state.enemy.hammers.each do |h| 
    h[:y]  ||= args.state.enemy.y + 130
    h[:dy] ||= args.state.hammer_upward_launch_power
    h[:dy]  += args.state.gravity 
    h[:x]   += h[:dx] 
    h[:y]   += h[:dy]
    h[:rect] = [h[:x], h[:y], h[:w], h[:h]] 
  end
  args.state.enemy.hammer_queue = args.state.enemy.hammer_queue.reject do |h|
    h[:throw_at] < args.state.tick_count
  end
  args.state.enemy.hammers = args.state.enemy.hammers.reject { |h| h[:y] < 0 }
  if args.state.enemy.hammers.any? { |h| h[:rect].intersect_rect?(args.state.player.rect) }
    reset_player args
  end
  if args.state.enemy.rect.intersect_rect? args.state.player.rect
    reset_player args
  end
end
def calc args args . state . player . x += args . state . player . dx args . state . player . y += args . state . player . dy args . state . player . dy += args . state . gravity args . state . player . y = args . state . player . y . greater ( args . state . bridge_top ) args . state . player . x = args . state . player . x . greater ( 0 ) args . state . player . falling = false if args . state . player . y == args . state . bridge_top args . state . player . rect = [ args . state . player . x , args . state . player . y , args . state . player . h , args . state . player . w ] args . state . enemy . x += args . state . enemy . dx args . state . enemy . y += args . state . enemy . dy args . state . enemy . y = args . state . enemy . y . greater ( args . state . bridge_top ) args . state . enemy . x = args . state . enemy . x . greater ( 0 ) args . state . enemy . dy += args . state . gravity args . state . enemy . y = args . state . enemy . y . greater ( args . state . bridge_top ) args . state . enemy . rect = [ args . state . enemy . x , args . state . enemy . y , args . state . enemy . h , args . state . enemy . w ] if args . state . enemy . y == args . state . bridge_top args . state . enemy . dy = 0 end if args . state . tick_count . mod_zero? ( args . state . enemy_jump_interval ) && args . state . enemy . dy == 0 args . state . enemy . dy = args . state . enemy_jump_power end if args . state . tick_count . mod_zero? ( args . state . hammer_throw_interval ) || args . state . game_over_at . elapsed_time == 5 volley_dx = ( rand ( args . state . hammer_launch_power_default ) + 1 ) * - 1 if ( args . state . player . x - args . state . enemy . x ) . abs < 128 volley_dx = ( rand ( args . state . hammer_launch_power_near ) + 1 ) * - 1 end if ( args . state . player . x - args . state . enemy . x ) . abs > 300 volley_dx = ( rand ( args . state . hammer_launch_power_far ) + 1 ) * - 1 end ( rand ( args . state . max_hammers_per_volley ) + 1 ) . map_with_index do | i | args . state . enemy . hammer_queue << { x : args . state . enemy . x , w : args . state . hammer_size , h : args . state . hammer_size , dx : volley_dx , throw_at : args . state . tick_count + i * args . state . gap_between_hammers } end end args . state . enemy . hammers += args . state . enemy . hammer_queue . find_all do | h | h [ :throw_at ] < args . state . tick_count end args . state . enemy . hammers . each do | h | h [ :y ] ||= args . state . enemy . y + 130 h [ :dy ] ||= args . state . hammer_upward_launch_power h [ :dy ] += args . state . gravity h [ :x ] += h [ :dx ] h [ :y ] += h [ :dy ] h [ :rect ] = [ h [ :x ] , h [ :y ] , h [ :w ] , h [ :h ] ] end args . state . enemy . hammer_queue = args . state . enemy . hammer_queue . reject do | h | h [ :throw_at ] < args . state . tick_count end args . state . enemy . hammers = args . state . enemy . hammers . reject { | h | h [ :y ] < 0 } if args . state . enemy . hammers . any? { | h | h [ :rect ] . intersect_rect? ( args . state . player . rect ) } reset_player args end if args . state . enemy . rect . intersect_rect? args . state . player . rect reset_player args end end
Performs calculations to move objects on the screen
Performs calculations to move objects on the screen
# Since velocity is the change in position, the change in x increases by dx. Same with y and dy. # Since acceleration is the change in velocity, the change in y (dy) increases every frame # player's y position is either current y position or y position of top of # bridge, whichever has a greater value # ensures that the player never goes below the bridge # player's x position is either the current x position or 0, whichever has a greater value # ensures that the player doesn't go too far left (out of the screen's scope) # player is not falling if it is located on the top of the bridge # sets definition for player # velocity; change in x increases by dx # same with y and dy # ensures that the enemy never goes below the bridge # ensures that the enemy never goes too far left (outside the screen's scope) # objects that go up must come down because of gravity #sets definition of enemy # if enemy is located on the top of the bridge # there is no change in y # if 60 frames have passed and the enemy is not moving vertically # the enemy jumps up # if 40 frames have passed or 5 frames have passed since the game ended # rand will return a number greater than or equal to 0 and less than given variable's value (since max is excluded) # that is why we're adding 1, to include the max possibility # horizontal movement (follow order of operations) # if the horizontal distance between the player and enemy is less than 128 pixels # the change in x won't be that great since the enemy and player are closer to each other # if the horizontal distance between the player and enemy is greater than 300 pixels # change in x will be more drastic since player and enemy are so far apart # more drastic change # stores hammer values in a hash # change in horizontal position # multiplication operator takes precedence over addition operator # add elements from hammer_queue collection to the hammers collection by # finding all hammers that were thrown before the current frame (have already been thrown) # sets values for all hammers in collection # acceleration is change in gravity # incremented by change in position # sets definition of hammer's rect # reject hammers that have been thrown before current frame (have already been thrown) # any hammers with a y position less than 0 are rejected from the hammers collection # since they have gone too far down (outside the scope's screen) # if there are any hammers that intersect with (or hit) the player, # the reset_player method is called (so the game can start over) # if the enemy's rect intersects with (or hits) the player, # the reset_player method is called (so the game can start over)
args