summaryrefslogtreecommitdiffhomepage
path: root/samples/99_genre_dungeon_crawl/classics_jam/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_dungeon_crawl/classics_jam/app
parent2f845281f133849256b57bb08fd3e9ae57600784 (diff)
parenteaa29e72939f5edf61735ccbb73c36ee89369f65 (diff)
downloaddragonruby-game-toolkit-contrib-master.tar.gz
dragonruby-game-toolkit-contrib-master.zip
Merge branch 'DragonRuby:master' into masterHEADmaster
Diffstat (limited to 'samples/99_genre_dungeon_crawl/classics_jam/app')
-rw-r--r--samples/99_genre_dungeon_crawl/classics_jam/app/main.rb213
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