Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Graphics & Simulations
(& Games), Oh My!
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Setting Expectations50% Show & Tell50% TutorialMedium CodeAll Levels of Developer
~180 slides / 35 min = ~5 spm�2
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Ryan DavisCoding professionally 27 years, 18 years Ruby.Founder, Seattle.rb; First & Oldest Ruby Brigade.Author: minitest, flog, flay, debride, ruby_parser, etc.Pushed over 1000 gems into the Ruby Ecosystem.Developer’s Developer: I ❤ building tools.Run Seattle.rb Consulting http://seattlerb.com/I’m available for hire.
�3
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
What is Graphics?
�4
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
gem install graphics --pre
�5
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simple Framework
�6
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simulations�7
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Art�8
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Visualizations�9
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Games�10
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Grade-School Maths
�11
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
NOT Game Programming
Conventions�12
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Demystify�13
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
New Tool in Your Toolbox
�14
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
WARNING:
�15
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
I Suck at Art�16
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Aesthetically Challenged
�17
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Maths = OK�18
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
!scientist�19
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
!game_dev�20
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Just Like You!�21
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Damn Good Tool Dev
�22
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
graphics =
simple�23
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Jumping Straight In
�24
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Totally Blank Canvas
�25
require "graphics"
class SimpleSimulation < G::S include WhiteBackground end
SimpleSimulation.new.run
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Drawing a Circle
�26
# class SimpleSimulation def draw n super circle w/2, h/2, 15, :blue, :filled end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Drawing a Circle, via Body
�27
class Ball < Graphics::Body COUNT = 1
class View def self.draw w, b w.circle b.x, b.y, 15, :blue, :filled end end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Using a Body
�28
# class SimpleSimulation def initialize super
register_bodies populate Ball end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Adding Behavior
�29
# class Ball def initialize w super
self.a = random_angle self.m = rand 5..15 end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Moving the body—asteroids
�30
# class Ball def update move wrap end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Moving the body—pong
�31
# class Ball def update move bounce 0 # (0 == no friction) end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Moving the body—bouncing
�32
# class Ball G = V[0, -0.3]
def update self.velocity += G move bounce end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Many bodies
�33
# class Ball COUNT = 25
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Final Versionrequire "graphics"
class SimpleSimulation < Graphics::Simulation include WhiteBackground
def initialize super
register_bodies populate Ball end end # … SimpleSimulation.new.run
�34
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
class Ball < Graphics::Body COUNT = 25 G = V[0, -18 / 60.0]
def initialize w super
self.a = random_angle self.m = rand 5..15 end
def update self.velocity += G move bounce end end
�35
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
class Ball class View def self.draw w, b w.circle b.x, b.y, 15, :blue, :filled end end end
�36
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
require "graphics"
class SimpleSimulation < G::S include WhiteBackground
def initialize super register_bodies populate Ball end
class Ball < Graphics::Body COUNT = 25 G = V[0, -18 / 60.0]
def initialize w super self.a = random_angle self.m = rand 5..15 end
def update self.velocity += G move bounce end
class View def self.draw w, b w.circle b.x, b.y, 15, :blue, :filled end end end end
SimpleSimulation.new.run
�37
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Art Gallery
�38
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Generative Art
�39
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�40
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�41
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�42
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�43
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�44
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�45
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Mathy / Nerdy Things
�46
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�47
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�48
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�49
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�50
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simulations
�51
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�52
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�53
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�54
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
fluid.rb—fluid dynamics aka Smoothed particle dynamics
�55
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�56
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�57
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�58
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Games
�59
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�60
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�61
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�62
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�63
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�64
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Graphics
�65
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
How is it Different?
�66
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Approachable�67
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Undemanding�68
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Understandable
�69
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Empowering�70
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Experimentable
�71
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Real Maths!
�72
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Uses degrees.�73
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Draws in quadrant 1
(0-90 degrees).
�74
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Game Math Coordinates
�75
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�76
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Comprehensible
�77
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Opinionatedly Pretty
�78
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
20+ Drawing Primitives
�79
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Pretty drawing!
�80
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Decoratorsclass MySimulation < Graphics::Simulation include WhiteBackground include ShowFPS include DrawGrid; GRID_WIDTH = 100 end
�81
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Architecture
�82
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Update & Draw Loop
�83
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
30,000 Foot View
�84
CanvasModel screen
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Translates to:
�85
drawupdate present
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Abstraction of Drawing
�86
CanvasModel screen
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
“Reality”
�87
Previous Canvas
Current Canvas
Model
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Run Looploop do iter_per_tick.times { update n; n += 1 } draw n renderer.present end
�88
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
updatedef update n _bodies.each do |ary| ary.each(&:update) end end
�89
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
drawdef draw n clear
_bodies.each do |ary| draw_collection ary end end
def draw_collection ary return if ary.empty?
cls = get_view_class ary
ary.each do |obj| cls.draw self, obj end end
�90
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
renderrenderer.present
�91
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Class Heirarchy
�92
AbstractSimulation
Drawing Simulation
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simulation
�93
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
“Normal” Functionality
�94
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Animation�95
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Clears the window
�96
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Smooth Drawing
�97
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Drawing
�98
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Never Clears�99
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Single Canvas�100
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Single Buffered�101
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Static�102
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Primitives
�103
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Shortcutsm = 50 # margin rx = rand w # random x ry = rand h # random y rc = color.keys.sample # random color rb = [true, false].sample # random bool
def r50 # random value rand 50 end
�104
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
clear
�105
clear # defaults to CLEAR_COLOR clear :red
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
point
�106
1000.times do point rx, ry, rc end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
line
�107
line m, h-n-m, w-m, n+m, :red
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
angle
�108
angle w/2, h/2, 3*n, h/2-m, :red
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
hline/vline
�109
hline (3*n)%h, :red vline (3*n)%w, :blue
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
circle
�110
circle rx, ry, r50, rc, rb
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
ellipse
�111
ellipse rx, ry, r50, r50, rc, rb
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
fast_rect
�112
fast_rect rx, ry, r50, r50, rc
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
rect
�113
rect rx, ry, r50, r50, rc, rb
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
polygon
�114
points = rand(3..8).times.map { [rx, ry] } polygon *points, rc
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
bezier
�115
bezier(m, m+n, # p1 2*m, 0, # c1 w-2*m, h, # c2 w-m, h-m-n, # p2 rc)
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
sprite & blit
�116
self.tank = sprite 40, 30 do rect 0, 0, 39, 29, :black rect 0, 4, 39, 21, :black
line 0, 2, 39, 2, :black line 0, 27, 39, 27, :black end
self.turret = sprite 41, 16 do # … more of the same end
blit tank, w/2, h/2, n*2 blit turret, w/2, h/2, n*3
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
image & blit
�117
self.tank = image "body.png" self.turret = image "turret.png"
blit tank, w/2, h/2, n*2 blit turret, w/2, h/2, n*3
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
render_text & put
�118
font = find_font("Livory", 32) hello = render_text( "Hello RubyConf!”, :red, font)
put hello, w/2, h/2, -n
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
text
�119
hello = "Hello RubyConf!" text hello, m, n*30, rc
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
debug, fps, & mouse
�120
fps n, :black x, y, * = mouse debug "n=%d x=%d, y=%d", n, x, y
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
save
�121
x, y, * = mouse debug "n=%d x=%d, y=%d", n, x, y fps n, :black
save "debug.png" if n == 100
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Generative Art
�122
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�123
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Mondrian-Style Generative Art
�124
http://www.zenspider.com/ruby/2018/06/interesting-problems-mondrian.html
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sketch
�125
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blank
�126
class Mondrian < G::D W = 20 include WhiteBackground include DrawGrid; GRID_WIDTH=W
def initialize super do art end end
def art # where the work goes end
alias r fast_rect # other helpers: rx, ry, etc end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Black Rectangle
�127
def art r 120, 0, W, h, :black r 0, 80, w, W, :black end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Stripes Spanning Window
�128
def art xs = rx rand 2..5 ys = ry rand 2..5
xs.each do |x| r x, 0, W, h, :black end
ys.each do |y| r 0, y, w, W, :black end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Filled Regions
�129
COLOR = [:red, :yellow, :blue]
def regions xs, ys rand(1..5).times.each do xi = rand(xs.size-1) yi = rand(ys.size-1) x0, x1 = xs[xi..xi+1] y0, y1 = ys[yi..yi+1] c = COLOR.sample
r x0, y0, x1-x0, y1-y0, c end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Comparing
�130
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Visualization
�131
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Plotting
�132
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Too Much Data
�133
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Message Size / Time
�134
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Gathering Data is Easy
�135
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Just Looking Doesn’t Help>> d = Marshal.load File.read "plot.cache"; nil => nil >> d.size => 954165 >> d.first 5 => [[100, 0.5], [30, 0.1], [46, 0.6], [439, 0.6], [215, 0.1]] >> d.transpose.map(&:min) => [30, 0.0] >> d.transpose.map(&:avg) => [151, 0.240460507354598] >> d.transpose.map(&:max) => [1740, 88.8] >> dsr = d.map { |a| a.map { |f| f.round 2 } }; nil => nil >> h = d.count_by(&:itself); nil >> pp h.sort_by { |(k,v), c| [-v, -c, k] }.first 5; nil [[[20.4, 500.0], 1], [[13.51, 479.17], 1], [[20.11, 462.84], 1], [[20.4, 458.9], 1]] => nil
�136
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
But Plotting It?�137
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
R?�138
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Excel?�139
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Or…?�140
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Just Use Ruby™!
�141
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sketch
�142
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blank Canvas
�143
class Plot < G::S MAX = 500
include WhiteBackground include DrawGrid GRID_WIDTH = 50
def initialize data super MAX, MAX end
def draw n super end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Prepare Dataattr_accessor :data
def initialize d super MAX, MAX
register_color :point, 255, 0, 0, 16 # very translucent red
d = scale_to d # scale to window self.data = d.group_by(&:itself) # group by values
data.each do |k, v| data[k] = Math.log(v.size) # count groups, log scale end end
�144
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Visualize
�145
def draw n super
data.each do |(x, y), c| point x, y, :gray circle x, y, c, :point, :fill end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�146
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Extend�147
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Experiment!�148
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simulations
�149
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
https://en.wikipedia.org/wiki/Langton's_ant
Langston’s Ants
�150
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Simple Rulesif ⚪: draw ⚫, turn ↰if ⚫: draw ⚪, turn ↱move onerepeat
�151
Draw BlackTurn Left
Forward 1
Draw WhiteTurn RightForward 1
Black
White
BlackWhite
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sketch
�152
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blank canvas
�153
class Vants0 < Graphics::Drawing include WhiteBackground
def initialize super
register_bodies populate Vant end
# …other stuff…
class Vant < Graphics::Body COUNT = 100 end end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Drawing
�154
def draw if s[x, y] == white then s[x, y] = black turn 270 else s[x, y] = white turn 90 end move_by a, 1 end
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Ant Farm!
�155
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Boids
�156
https://en.wikipedia.org/wiki/Boids
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Rulescohesion: steer to move toward the average position (center of mass) of local flockmates.separation: steer to avoid crowding local flockmates.alignment: steer towards the average heading of local flockmates.
�157
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
The Usual Startclass Boids < G::S include WhiteBackground include ShowFPS
attr_accessor :boids
def initialize super
self.boids = populate Boid register_bodies boids end end
�158
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
class Boid < G::B COUNT = 25 MAX_DISTANCE = 100 MAX_VELOCITY = 5
def initialize w super
self.m = rand * MAX_VELOCITY self.a = random_angle end
class View def self.draw w, b x, y, a, m = b.x, b.y, b.a, b.m
w.circle x, y, MAX_DISTANCE, :gray90 w.angle x, y, a, 3 * m, :red w.circle x, y, 5, :black, :filled end end end
�159
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Rule 1: Cohesiondef rule1 (center_mass - position) * PCT_DAMPENER end
def center_mass nearby = self.nearby
return position if nearby.empty?
nearby.avg(V::ZERO, &:position) end
�160
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Rule 2: Separationdef rule2 too_close = nearby.filter_map { |b| diff = b.position - self.position next if diff.magnitude > TOO_CLOSE diff }
if too_close.empty? then V::ZERO else -too_close.avg(V::ZERO) / 8 end end
�161
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Rule 3: Alignmentdef rule3 nearby = self.nearby
return velocity if nearby.empty?
v = nearby.avg(V::ZERO, &:velocity)
(v - velocity) / 4 end
�162
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sum and Movedef update v1 = rule1 v2 = rule2 v3 = rule3
self.velocity += v1 + v2 + v3 limit_velocity
move wrap end
�163
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider�164
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Game
�165
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Tanks (pew pew)
�166
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sketch
�167
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Rulestank is in arenaleft/right: turn tankforward/back: accelerate/decelerate‘a’ / ’s’: turn the turret Bullets and firing left as an exercise.
�168
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blank canvasrequire "graphics"
class TankGame < Graphics::Simulation def initialize super 640, 640
register_body Tank.new self end end
TankSprites.new.run
�169
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Bare Tank Canvasclass Tank < Graphics::Body attr_accessor :turret
def initialize w super
self.x = w.w/2 self.y = w.h/2 self.turret = 0 end end
�170
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sprite# class TankGame def initialize # … a, b = 40, 30 self.body_img = sprite a, b do rect 0, 0, a-1, 29, :black rect 0, 4, a-1, 21, :black
line 0, 2, a-2, 2, :black line 0, b-4, a-2, b-4, :black end
a, b = 41, 16 self.turret_img = sprite a, b do rect a/2-8, b/2-8, 15, 15, :black angle a/2-1, b/2-1, 0, 28, :black line a/2+20, b/2-3, a/2+20, b/2+1, :black end end
�171
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blit# class Tank class View def self.draw w, b x, y, a, t = b.x, b.y, b.a, b.turret
w.blit w.body_img, x, y, a w.blit w.turret_img, x, y, t end end
�172
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Behavior# class Tank def update self.m = m.clamp 0, MAX_SPEED move clip end
def turn_right; self.a -= ROTATION; aim_right; end def turn_left; self.a += ROTATION; aim_left; end def aim_right; self.turret -= ROTATION; end def aim_left; self.turret += ROTATION; end def accelerate; self.m += ACCELERATE; end def decelerate; self.m -= DECELERATE; end
�173
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Event Handling# class TankGame def initialize_keys super
add_key_handler(:RIGHT) { tank.turn_right } add_key_handler(:LEFT) { tank.turn_left } add_key_handler(:UP) { tank.accelerate } add_key_handler(:DOWN) { tank.decelerate } add_key_handler(:A) { tank.aim_left } add_key_handler(:S) { tank.aim_right } end
�174
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Final Result
�175
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Conventions
�176
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Sketch & Rules�177
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Blank Canvas�178
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Build Up�179
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Drawing ➡ Simulation
�180
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
MVC
�181
MyApp (Controller)
Simulation Body (Model)
View
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
DecoratorsDisplayFPSWhiteBackgroundDrawGridetc
�182
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
🔬🛠
�183
Graphics & Simulations (& Games), Oh My!
RubyConf 2018, Los Angeles, CA
Ryan Davis, Seattle.rb
@the_zenspider
Thank You!If you want to sponsor my work on Open
Source: https://www.patreon.com/zenspider
If you want to hire me: http://www.seattlerb.com/