From c34e1d372676709f4eb05237025c67b878bf76d6 Mon Sep 17 00:00:00 2001 From: realtradam Date: Tue, 10 Aug 2021 00:15:17 -0400 Subject: readme and cleanup --- Gemfile.lock | 2 +- README.mdown | 31 +++++++++++++++- assets/Background.png | Bin 210943 -> 0 bytes assets/aquarium.png | Bin 0 -> 210943 bytes assets/background.jpg | Bin 0 -> 63732 bytes lib/mobs/fish.rb | 1 - lib/mobs/piranha.rb | 1 - lib/rules/limit.rb | 2 +- lib/rules/target.rb | 23 +++++++----- run.rb | 100 +++++++++++++++++++++++++++++++++++--------------- 10 files changed, 115 insertions(+), 45 deletions(-) delete mode 100644 assets/Background.png create mode 100644 assets/aquarium.png create mode 100644 assets/background.jpg 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) +![Piranha](https://naked.catgirls.rodeo/images/Predator%201.png) -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. +[![MIT License](https://img.shields.io/github/license/realtradam/FelFlame?label=license&style=flat)](https://github.com/realtradam/FelFlame/blob/master/LICENSE) +[![Ko-Fi](https://img.shields.io/static/v1?message=Buy%20me%20a%20coffee&logo=kofi&labelColor=ff5e5b&color=434B57&logoColor=white&label=%20)](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) + +![Ruboid Example](https://naked.catgirls.rodeo/images/ruboid-example.gif) + +## 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/Background.png deleted file mode 100644 index a865ecd..0000000 Binary files a/assets/Background.png and /dev/null differ diff --git a/assets/aquarium.png b/assets/aquarium.png new file mode 100644 index 0000000..a865ecd Binary files /dev/null and b/assets/aquarium.png differ diff --git a/assets/background.jpg b/assets/background.jpg new file mode 100644 index 0000000..fe22d45 Binary files /dev/null and b/assets/background.jpg differ 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 diff --git a/run.rb b/run.rb index e836681..fafaca3 100644 --- a/run.rb +++ b/run.rb @@ -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 -- cgit v1.2.3