diff options
Diffstat (limited to 'samples/03_rendering_sprites/03_animation_states/app/main.rb')
| -rw-r--r-- | samples/03_rendering_sprites/03_animation_states/app/main.rb | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/samples/03_rendering_sprites/03_animation_states/app/main.rb b/samples/03_rendering_sprites/03_animation_states/app/main.rb new file mode 100644 index 0000000..63608a4 --- /dev/null +++ b/samples/03_rendering_sprites/03_animation_states/app/main.rb @@ -0,0 +1,183 @@ +class Game + attr_gtk + + def defaults + state.show_debug_layer = true if state.tick_count == 0 + player.tile_size = 64 + player.speed = 3 + player.slash_frames = 15 + player.x ||= 50 + player.y ||= 400 + player.dir_x ||= 1 + player.dir_y ||= -1 + player.is_moving ||= false + state.watch_list ||= {} + state.enemies ||= [] + end + + def add_enemy + state.enemies << { x: 1200 * rand, y: 600 * rand, w: 64, h: 64 } + end + + def sprite_horizontal_run + tile_index = 0.frame_index(6, 3, true) + tile_index = 0 if !player.is_moving + + { + x: player.x, + y: player.y, + w: player.tile_size, + h: player.tile_size, + path: 'sprites/horizontal-run.png', + tile_x: 0 + (tile_index * player.tile_size), + tile_y: 0, + tile_w: player.tile_size, + tile_h: player.tile_size, + flip_horizontally: player.dir_x > 0, + # a: 40 + } + end + + def sprite_horizontal_stand + { + x: player.x, + y: player.y, + w: player.tile_size, + h: player.tile_size, + path: 'sprites/horizontal-stand.png', + flip_horizontally: player.dir_x > 0, + # a: 40 + } + end + + def sprite_horizontal_slash + tile_index = player.slash_at.frame_index(5, player.slash_frames.idiv(5), false) || 0 + + { + x: player.x - 41.25, + y: player.y - 41.25, + w: 165, + h: 165, + path: 'sprites/horizontal-slash.png', + tile_x: 0 + (tile_index * 128), + tile_y: 0, + tile_w: 128, + tile_h: 128, + flip_horizontally: player.dir_x > 0 + } + end + + def render_player + if player.slash_at + outputs.sprites << sprite_horizontal_slash + elsif player.is_moving + outputs.sprites << sprite_horizontal_run + else + outputs.sprites << sprite_horizontal_stand + end + end + + def render_enemies + outputs.borders << state.enemies + end + + def render_debug_layer + return if !state.show_debug_layer + outputs.labels << state.watch_list.map.with_index do |(k, v), i| + [30, 710 - i * 28, "#{k}: #{v || "(nil)"}"] + end + + outputs.borders << player.slash_collision_rect + end + + def slash_initiate? + # buffalo usb controller has a button and b button swapped lol + inputs.controller_one.key_down.a || inputs.keyboard.key_down.j + end + + def input + # player movement + if slash_complete? && (vector = inputs.directional_vector) + player.x += vector.x * player.speed + player.y += vector.y * player.speed + end + player.slash_at = slash_initiate? if slash_initiate? + end + + def calc_movement + # movement + if vector = inputs.directional_vector + state.debug_label = vector + player.dir_x = vector.x + player.dir_y = vector.y + player.is_moving = true + else + state.debug_label = vector + player.is_moving = false + end + end + + def calc_slash + # re-calc the location of the swords collision box + if player.dir_x.positive? + player.slash_collision_rect = [player.x + player.tile_size, + player.y + player.tile_size.half - 10, + 40, 20] + else + player.slash_collision_rect = [player.x - 32 - 8, + player.y + player.tile_size.half - 10, + 40, 20] + end + + # recalc sword's slash state + player.slash_at = nil if slash_complete? + + # determine collision if the sword is at it's point of damaging + return unless slash_can_damage? + + state.enemies.reject! { |e| e.intersect_rect? player.slash_collision_rect } + end + + def slash_complete? + !player.slash_at || player.slash_at.elapsed?(player.slash_frames) + end + + def slash_can_damage? + # damage occurs half way into the slash animation + return false if slash_complete? + return false if (player.slash_at + player.slash_frames.idiv(2)) != state.tick_count + return true + end + + def calc + # generate an enemy if there aren't any on the screen + add_enemy if state.enemies.length == 0 + calc_movement + calc_slash + end + + # source is at http://github.com/amirrajan/dragonruby-link-to-the-past + def tick + defaults + render_enemies + render_player + outputs.labels << [30, 30, "Gamepad: D-Pad to move. B button to attack."] + outputs.labels << [30, 52, "Keyboard: WASD/Arrow keys to move. J to attack."] + render_debug_layer + input + calc + end + + def player + state.player + end +end + +$game = Game.new + +def tick args + $game.args = args + $game.tick +end + +$gtk.reset |
