diff options
| -rw-r--r-- | Gemfile.lock | 2 | ||||
| -rw-r--r-- | README.mdown | 31 | ||||
| -rw-r--r-- | assets/aquarium.png (renamed from assets/Background.png) | bin | 210943 -> 210943 bytes | |||
| -rw-r--r-- | assets/background.jpg | bin | 0 -> 63732 bytes | |||
| -rw-r--r-- | lib/mobs/fish.rb | 1 | ||||
| -rw-r--r-- | lib/mobs/piranha.rb | 1 | ||||
| -rw-r--r-- | lib/rules/limit.rb | 2 | ||||
| -rw-r--r-- | lib/rules/target.rb | 23 | ||||
| -rw-r--r-- | run.rb | 100 |
9 files changed, 115 insertions, 45 deletions
diff --git a/Gemfile.lock b/Gemfile.lock index 2c8d3d8..f65c4cc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: felflame (3.0.0) ruby2d (0.10.0) - ruby2d-camera (1.0.0) + ruby2d-camera (1.1.0) ruby2d (~> 0.10) PLATFORMS diff --git a/README.mdown b/README.mdown index 82ebbca..6e0f6b4 100644 --- a/README.mdown +++ b/README.mdown @@ -1,3 +1,30 @@ -## Boids simulation made using [Ruby2D](http://www.ruby2d.com) and [FelFlame](https://github.com/realtradam/FelFlame) + -Making this mostly as a test of using FelFlame in a real project, to try out and see if I can find bugs of flaws in it. +[](https://github.com/realtradam/FelFlame/blob/master/LICENSE) +[](https://ko-fi.com/tradam) + + +# Ruboids + +Ruboids is a [Boids Algorithm Simulation](https://en.wikipedia.org/wiki/Boids) made using [Ruby2D](http://www.ruby2d.com), [FelFlame](https://github.com/realtradam/FelFlame) and [Ruby2D-Camera](https://github.com/realtradam/ruby2d-camera) + + + +## How to Play + +### Without Bundler +once you gem install `ruby2d`, `felflame`, and `ruby2d-camera` simple do `ruby run.rb` + +### Using Bundler +`bundler install` followed by `bundler exec ruby run.rb` + +## Controls +Left click on the screen to create a Piranha. +Right Click and drag to move the camera. (`w` `a` `s` `d` works as well) +Scrollwheel to zoom. (`z` and `x` work as well) + +## Playing around with the parameters +All the parameters you can change are nicely stored inside the `SingletomConfig` component in the `$config` variable in `run.rb` so it is easy to quickly and easily change and play around with them. + +## Purpose +I made this to stress test my new framework FelFlame and see how it is, and it was really nice and easy making this game so I will probably continue to use it for future projects. Also just I wanted to play around with boids. 😁 diff --git a/assets/Background.png b/assets/aquarium.png Binary files differindex a865ecd..a865ecd 100644 --- a/assets/Background.png +++ b/assets/aquarium.png diff --git a/assets/background.jpg b/assets/background.jpg Binary files differnew file mode 100644 index 0000000..fe22d45 --- /dev/null +++ b/assets/background.jpg diff --git a/lib/mobs/fish.rb b/lib/mobs/fish.rb index a9999ae..a2ba7cd 100644 --- a/lib/mobs/fish.rb +++ b/lib/mobs/fish.rb @@ -1,6 +1,5 @@ class Fish def self.create(x, y) - puts 'creating...' FF::Ent.new( FF::Cmp::Fish[0], FF::Cmp::Boids.new(x: x, y: y), diff --git a/lib/mobs/piranha.rb b/lib/mobs/piranha.rb index c7ce8b1..8cbb2c6 100644 --- a/lib/mobs/piranha.rb +++ b/lib/mobs/piranha.rb @@ -1,6 +1,5 @@ class Piranha def self.create(x, y) - puts 'creating...' FF::Ent.new( FF::Cmp::Piranha[0], FF::Cmp::Boids.new(x: x, y: y), diff --git a/lib/rules/limit.rb b/lib/rules/limit.rb index b2a8f32..5df8bc4 100644 --- a/lib/rules/limit.rb +++ b/lib/rules/limit.rb @@ -10,7 +10,7 @@ FF::Sys.new('Limit') do end absolute_velocity = Math.sqrt((boid.vx**2) + (boid.vy**2)) - if absolute_velocity > $config.limit + if absolute_velocity > ($config.limit * multi) boid.vx = (boid.vx / absolute_velocity) * $config.limit * multi boid.vy = (boid.vy / absolute_velocity) * $config.limit * multi end diff --git a/lib/rules/target.rb b/lib/rules/target.rb index 9177845..c0ced5c 100644 --- a/lib/rules/target.rb +++ b/lib/rules/target.rb @@ -5,13 +5,17 @@ FF::Sys.new('Target', priority: 50) do boid = ent.components[FF::Cmp::Boids].first FF::Cmp::Fish[0].entities.each do |_fish| fish = _fish.components[FF::Cmp::Boids].first - if closest[0].nil? || Math.sqrt(((boid.x - fish.x)**2) + ((boid.y - fish.y)**2)).abs < closest[0] - closest[0] = Math.sqrt(((boid.x - fish.x)**2) + ((boid.y - fish.y)**2)).abs - closest[1] = fish + unless (fish.x > $config.xmax) || (fish.x < $config.xmin) || (fish.y > $config.ymax) || (fish.y < $config.ymin) + if closest[0].nil? || Math.sqrt(((boid.x - fish.x)**2) + ((boid.y - fish.y)**2)).abs < closest[0] + closest[0] = Math.sqrt(((boid.x - fish.x)**2) + ((boid.y - fish.y)**2)).abs + closest[1] = fish + end end end - boid.cx += ((closest[1].x - boid.x) / $config.target_strength) - boid.cy += ((closest[1].y - boid.y) / $config.target_strength) + unless closest[0].nil? + boid.cx += ((closest[1].x - boid.x) / $config.target_strength) + boid.cy += ((closest[1].y - boid.y) / $config.target_strength) + end end FF::Cmp::Fish[0].entities.each do |ent| @@ -19,10 +23,11 @@ FF::Sys.new('Target', priority: 50) do boid = ent.components[FF::Cmp::Boids].first FF::Cmp::Piranha[0].entities.each do |_piranha| piranha = _piranha.components[FF::Cmp::Boids].first - unless Math.sqrt(((boid.x - piranha.x)**2) + ((boid.y + piranha.y)**2)).abs > 250 - boid.cx -= ($config.target_strength / (piranha.x - boid.x)) - boid.cy -= ($config.target_strength / (piranha.y - boid.y)) - #boid.cy -= ((piranha.y - boid.y) / (1.0 / $config.target_strength)) + unless Math.sqrt(((boid.x - piranha.x)**2) + ((boid.y - piranha.y)**2)).abs > $config.target_fear + #boid.cx -= ($config.target_strength / (piranha.x + boid.x)) + #boid.cy -= ($config.target_strength / (piranha.y + boid.y)) + boid.cx -= ((piranha.x - boid.x) / ($config.target_strength)) + boid.cy -= ((piranha.y - boid.y) / ($config.target_strength)) end #if closest[0].nil? || Math.sqrt(((boid.x - fish.x)**2) + ((boid.y + fish.y)**2)).abs < closest[0] # closest[0] = Math.sqrt(((boid.x - fish.x)**2) + ((boid.y + fish.y)**2)).abs @@ -1,7 +1,13 @@ require 'ruby2d' require 'ruby2d/camera' require 'felflame' - +module Ruby2D + class Window + def mouse_pry + @mouse_buttons_down + end + end +end # configuration for the simulation # change values here to see a change in the simulation FF::Cmp.new('SingletonConfig', @@ -17,28 +23,31 @@ FF::Cmp.new('SingletonConfig', # How strong the bounds should be # Higher is stronger - bounds_strength: 1.0, + bounds_strength: 10.0, # What the bounds are xmax: 450.0, xmin: -580.0, ymax: 250.0, ymin: -340.0, # How much the boids try to pull together # Smaller is stronger - cohesion: 6000.0, + cohesion: 10000.0, # How much the boids push away from eachother # Smaller is stronger - seperation: 60.0, + seperation: 115.0, # What the range of seperating should be - seperation_distance: 50.0, + seperation_distance: 70.0, + # Alignment rule disabled # How strong their vector alignment should be # Smaller is stronger alignment: 1000.0, # How much they try to follow their target - # Larger is strongzer - target_strength: 500.0, + # smaller is stronger + target_strength: 40.0, + # Radius that fish should avoid the piranha + target_fear: 150.0, # These are later set by the mouse position target_x: 0, target_y: 0) @@ -50,26 +59,33 @@ set(title: "Ruboids", width: 1164, height: 764, resizable: true) Dir[File.join(__dir__, 'lib/**', '*.rb')].sort.each { |file| require file } -# Comment out to remove a rule -FF::Scn::BoidCalculations.add FF::Sys::Cohesion -#FF::Scn::BoidCalculations.add FF::Sys::Alignment -FF::Scn::BoidCalculations.add FF::Sys::Seperation -FF::Scn::BoidCalculations.add FF::Sys::Target -FF::Scn::BoidCalculations.add FF::Sys::Bounds - -FF::Stg.add FF::Scn::BoidCalculations - class GameWindow < Ruby2D::Window def initialize super - Camera::Image.new('assets/Background.png', x: -get(:width)+57, y: -get(:height)+97, z: -99) - randspot = ((-get(:height) / 2)..(get(:height)/2)).to_a - 50.times do - Fish.create(randspot.sample.to_f, randspot.sample.to_f) + # Comment out to remove a rule + FF::Scn::BoidCalculations.add FF::Sys::Cohesion + #FF::Scn::BoidCalculations.add FF::Sys::Alignment + FF::Scn::BoidCalculations.add FF::Sys::Seperation + FF::Scn::BoidCalculations.add FF::Sys::Target + FF::Scn::BoidCalculations.add FF::Sys::Bounds + + FF::Stg.add FF::Scn::BoidCalculations + + # background + Camera::Image.new('assets/aquarium.png', x: -get(:width)+57, y: -get(:height)+97, z: -98) + + # stores array of valid positions on which to spawn + # (not actually valid but close enough) + randspot = [(($config.xmin.to_i)..($config.xmax.to_i)).to_a, (($config.ymin.to_i)..($config.ymax.to_i)).to_a] + + @mouse_right_held = false + @x_mouse_previous = get(:mouse_x) + @y_mouse_previous = get(:mouse_y) + + 70.times do + Fish.create(randspot[0].sample.to_f, randspot[1].sample.to_f) end - #2.times do - # Piranha.create(randspot.sample.to_f, randspot.sample.to_f) - #end + unless $config.debug FF::Cmp::BoidVisuals.each do |boid| boid.vect.remove @@ -78,22 +94,46 @@ class GameWindow < Ruby2D::Window end def update + if mouse_down(:right) + @mouse_right_held = true + elsif mouse_up(:right) + @mouse_right_held = false + end + + if @mouse_right_held && mouse_move + Camera.x += Camera.coordinate_to_worldspace(@x_mouse_previous, @y_mouse_previous)[0] - Camera.coordinate_to_worldspace(get(:mouse_x), get(:mouse_y))[0] + Camera.y += Camera.coordinate_to_worldspace(@x_mouse_previous, @y_mouse_previous)[1] - Camera.coordinate_to_worldspace(get(:mouse_x), get(:mouse_y))[1] + #Camera.y -= (@mouse_move_delta_y * 5) / Camera.zoom #Camera.coordinate_to_worldspace(@mouse_move_delta_y,0) + end + + if mouse_scroll + if @mouse_scroll_delta_y < 0 + Camera.zoom *= 1.1 + elsif @mouse_scroll_delta_y > 0 + Camera.zoom /= 1.1 + end + end + + @x_mouse_previous = get(:mouse_x) + @y_mouse_previous = get(:mouse_y) + $config.target_x = Camera.coordinate_to_worldspace(get(:mouse_x), get(:mouse_y))[0] $config.target_y = Camera.coordinate_to_worldspace(get(:mouse_y), get(:mouse_y))[1] - if key_down('space') - Piranha.create($config.target_x, $config.target_y) + if mouse_down(:left) + a = Piranha.create($config.target_x - 75, $config.target_y - 75) + a.components[FF::Cmp::BoidVisuals][0].vect.remove unless $config.debug end FF::Stage.call - Camera.y += 1 if key_held('s') - Camera.y -= 1 if key_held('w') - Camera.x += 1 if key_held('d') - Camera.x -= 1 if key_held('a') + Camera.y += 5 if key_held('s') + Camera.y -= 5 if key_held('w') + Camera.x += 5 if key_held('d') + Camera.x -= 5 if key_held('a') Camera.zoom *= 1.1 if key_held('z') Camera.zoom /= 1.1 if key_held('x') end def render - puts get(:fps) + #puts get(:fps) end end |
