diff options
| author | _Tradam <[email protected]> | 2021-12-16 19:22:26 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-12-16 19:22:26 -0500 |
| commit | 5954b9beb4d4a3b4f248d72d1851195f030558a8 (patch) | |
| tree | fecd8aa840a25afdb502915b0fdb4d03b7ed339a /samples/99_genre_dungeon_crawl/classics_jam/app/main.rb | |
| parent | 2f845281f133849256b57bb08fd3e9ae57600784 (diff) | |
| parent | eaa29e72939f5edf61735ccbb73c36ee89369f65 (diff) | |
| download | dragonruby-game-toolkit-contrib-5954b9beb4d4a3b4f248d72d1851195f030558a8.tar.gz dragonruby-game-toolkit-contrib-5954b9beb4d4a3b4f248d72d1851195f030558a8.zip | |
Diffstat (limited to 'samples/99_genre_dungeon_crawl/classics_jam/app/main.rb')
| -rw-r--r-- | samples/99_genre_dungeon_crawl/classics_jam/app/main.rb | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/samples/99_genre_dungeon_crawl/classics_jam/app/main.rb b/samples/99_genre_dungeon_crawl/classics_jam/app/main.rb new file mode 100644 index 0000000..d14b50e --- /dev/null +++ b/samples/99_genre_dungeon_crawl/classics_jam/app/main.rb @@ -0,0 +1,213 @@ +class Game + attr_gtk + + def tick + defaults + render + input + calc + end + + def defaults + player.x ||= 640 + player.y ||= 360 + player.w ||= 16 + player.h ||= 16 + player.attacked_at ||= -1 + player.angle ||= 0 + player.future_player ||= future_player_position 0, 0 + player.projectiles ||= [] + player.damage ||= 0 + state.level ||= create_level level_one_template + end + + def render + outputs.sprites << level.walls.map do |w| + w.merge(path: 'sprites/square/gray.png') + end + + outputs.sprites << level.spawn_locations.map do |s| + s.merge(path: 'sprites/square/blue.png') + end + + outputs.sprites << player.projectiles.map do |p| + p.merge(path: 'sprites/square/blue.png') + end + + outputs.sprites << level.enemies.map do |e| + e.merge(path: 'sprites/square/red.png') + end + + outputs.sprites << player.merge(path: 'sprites/circle/green.png', angle: player.angle) + + outputs.labels << { x: 30, y: 30.from_top, text: "damage: #{player.damage || 0}" } + end + + def input + player.angle = inputs.directional_angle || player.angle + if inputs.controller_one.key_down.a || inputs.keyboard.key_down.space + player.attacked_at = state.tick_count + end + end + + def calc + calc_player + calc_projectiles + calc_enemies + calc_spawn_locations + end + + def calc_player + if player.attacked_at == state.tick_count + player.projectiles << { at: state.tick_count, + x: player.x, + y: player.y, + angle: player.angle, + w: 4, + h: 4 }.center_inside_rect(player) + end + + if player.attacked_at.elapsed_time > 5 + future_player = future_player_position inputs.left_right * 2, inputs.up_down * 2 + future_player_collision = future_collision player, future_player, level.walls + player.x = future_player_collision.x if !future_player_collision.dx_collision + player.y = future_player_collision.y if !future_player_collision.dy_collision + end + end + + def calc_projectile_collisions entities + entities.each do |e| + e.damage ||= 0 + player.projectiles.each do |p| + if !p.collided && (p.intersect_rect? e) + p.collided = true + e.damage += 1 + end + end + end + end + + def calc_projectiles + player.projectiles.map! do |p| + dx, dy = p.angle.vector 10 + p.merge(x: p.x + dx, y: p.y + dy) + end + + calc_projectile_collisions level.walls + level.enemies + level.spawn_locations + player.projectiles.reject! { |p| p.at.elapsed_time > 10000 } + player.projectiles.reject! { |p| p.collided } + level.enemies.reject! { |e| e.damage > e.hp } + level.spawn_locations.reject! { |s| s.damage > s.hp } + end + + def calc_enemies + level.enemies.map! do |e| + dx = 0 + dx = 1 if e.x < player.x + dx = -1 if e.x > player.x + dy = 0 + dy = 1 if e.y < player.y + dy = -1 if e.y > player.y + future_e = future_entity_position dx, dy, e + future_e_collision = future_collision e, future_e, level.enemies + level.walls + e.next_x = e.x + e.next_y = e.y + e.next_x = future_e_collision.x if !future_e_collision.dx_collision + e.next_y = future_e_collision.y if !future_e_collision.dy_collision + e + end + + level.enemies.map! do |e| + e.x = e.next_x + e.y = e.next_y + e + end + + level.enemies.each do |e| + player.damage += 1 if e.intersect_rect? player + end + end + + def calc_spawn_locations + level.spawn_locations.map! do |s| + s.merge(countdown: s.countdown - 1) + end + level.spawn_locations + .find_all { |s| s.countdown.neg? } + .each do |s| + s.countdown = s.rate + s.merge(countdown: s.rate) + new_enemy = create_enemy s + if !(level.enemies.find { |e| e.intersect_rect? new_enemy }) + level.enemies << new_enemy + end + end + end + + def create_enemy spawn_location + to_cell(spawn_location.ordinal_x, spawn_location.ordinal_y).merge hp: 2 + end + + def create_level level_template + { + walls: level_template.walls.map { |w| to_cell(w.ordinal_x, w.ordinal_y).merge(w) }, + enemies: [], + spawn_locations: level_template.spawn_locations.map { |s| to_cell(s.ordinal_x, s.ordinal_y).merge(s) } + } + end + + def level_one_template + { + walls: [{ ordinal_x: 25, ordinal_y: 20}, + { ordinal_x: 25, ordinal_y: 21}, + { ordinal_x: 25, ordinal_y: 22}, + { ordinal_x: 25, ordinal_y: 23}], + spawn_locations: [{ ordinal_x: 10, ordinal_y: 10, rate: 120, countdown: 0, hp: 5 }] + } + end + + def player + state.player ||= {} + end + + def level + state.level ||= {} + end + + def future_collision entity, future_entity, others + dx_collision = others.find { |o| o != entity && (o.intersect_rect? future_entity.dx) } + dy_collision = others.find { |o| o != entity && (o.intersect_rect? future_entity.dy) } + + { + dx_collision: dx_collision, + x: future_entity.dx.x, + dy_collision: dy_collision, + y: future_entity.dy.y + } + end + + def future_entity_position dx, dy, entity + { + dx: entity.merge(x: entity.x + dx), + dy: entity.merge(y: entity.y + dy), + both: entity.merge(x: entity.x + dx, y: entity.y + dy) + } + end + + def future_player_position dx, dy + future_entity_position dx, dy, player + end + + def to_cell ordinal_x, ordinal_y + { x: ordinal_x * 16, y: ordinal_y * 16, w: 16, h: 16 } + end +end + +def tick args + $game ||= Game.new + $game.args = args + $game.tick +end + +$gtk.reset +$game = nil |
