Guest User

Untitled

a guest
Dec 12th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.86 KB | None | 0 0
  1. require 'java'
  2.  
  3. %w(JPanel JTextField JLabel JFrame JButton Timer).each { |c| java_import "javax.swing.#{c}"}
  4. %w(Rectangle Insets Color BasicStroke Dimension Canvas image.BufferStrategy BorderLayout GridBagLayout GridBagConstraints Font).each { |c| java_import "java.awt.#{c}" }
  5.  
  6. WORLD_WIDTH = 800
  7. WORLD_HEIGHT = 600
  8.  
  9. DELAY = 50
  10. G = 9.81
  11. $current_time = 0
  12. $images = []
  13.  
  14. Y_0 = 500
  15. X_0 = 10
  16. VX_0 = 40
  17. VY_0 = 0
  18.  
  19. class Pair
  20. attr_accessor :first, :second
  21. def initialize(first, second)
  22. @first = first
  23. @second = second
  24. end
  25. end
  26.  
  27. def find_impact(y_0, vy_0, radius)
  28. discriminant = vy_0.to_f*vy_0.to_f - 2*G*(y_0.to_f-WORLD_HEIGHT+radius*2) # Simplified 4*G*(y_0-h)/2
  29. puts "Discriminant: #{discriminant} #{y_0}, #{vy_0}" if $DEBUG
  30. first_solution = (-vy_0 - Math.sqrt(discriminant)) / -G # Simplified 2*G/2
  31. second_solution = (-vy_0 + Math.sqrt(discriminant)) / -G # Simplified 2*G/2
  32.  
  33. puts "first solution: #{first_solution} - second solution: #{second_solution}" if $DEBUG
  34. if vy_0 < 0
  35. [first_solution, second_solution].min.abs
  36. else
  37. [first_solution, second_solution].max
  38. end
  39. end
  40.  
  41.  
  42. class Organism < Rectangle
  43. attr_accessor :x, :y, :radius, :vx_0, :vy_0, :x_final
  44. def initialize
  45. @x_final = false
  46. end
  47.  
  48. def draw(g)
  49. recalculate(g)
  50. g.color = Color::ORANGE
  51. g.draw_oval(@x, @y, @radius*2, @radius*2)
  52. g.fill_oval(@x+@radius, @y+@radius, 1, 1)
  53. end
  54.  
  55. def recalculate(g)
  56. if !@x_final
  57. @x_final_value = @vx_0*find_impact(@y, @vy_0, @radius) + @x
  58. @x_final = true
  59. end
  60.  
  61. $current_time += DELAY/100.0
  62. t = $current_time
  63. if @y < (WORLD_HEIGHT - @radius*2)
  64. @y = 0.5*G*t*t + @vy_0*t + Y_0
  65. else
  66. @y = WORLD_HEIGHT - @radius*2
  67. end
  68.  
  69. if @x < (WORLD_WIDTH - @radius*2) && @y < (WORLD_HEIGHT - @radius*2)
  70. @x = @vx_0*t + X_0
  71. $images << Pair.new(@x, @y)
  72. else
  73. @x = @x_final_value
  74. $images << Pair.new(@x, @y)
  75. end
  76.  
  77. if @y == (WORLD_HEIGHT - @radius*2)
  78. vx = vy = 0
  79. else
  80. vx = @vx_0
  81. vy = G*t + @vy_0
  82. end
  83.  
  84. g.color = Color::BLUE
  85. g.draw_line(@x+@radius, @y+@radius, @x+@radius+vx, @y+@radius+vy)
  86.  
  87. g.color = Color::GREEN
  88. g.font = Font.new("Courier new", Font::BOLD, 12)
  89. g.draw_string("x = #{@x.round(1)}, y = #{@y.round(1)}, v_x = #{vx.round(1)}, v_y = #{vy.round(1)}", WORLD_WIDTH - 310, 20)
  90. puts "x = #{@x.round(1)}, y = #{@y.round(1)}, v_x = #{vx.round(1)}, v_y = #{vy.round(1)}" if $DEBUG
  91.  
  92. end
  93. end
  94.  
  95. class Universe < Canvas
  96. def initialize
  97. super()
  98. self.preferred_size = Dimension.new(WORLD_WIDTH, WORLD_HEIGHT)
  99. self.minimum_size = self.preferred_size
  100. self.background = Color::BLACK
  101.  
  102. @running = true
  103. @organisms = []
  104. end
  105.  
  106. def game_loop
  107.  
  108. if @running
  109. last_run = Time.now
  110.  
  111. create_buffer_strategy(2)
  112. @strategy = self.buffer_strategy
  113. now = Time.now
  114. delta = now - last_run
  115. last_run = now
  116.  
  117. g = @strategy.draw_graphics
  118. draw_frame(g)
  119.  
  120. $images.each do |p|
  121. g.color = Color::GRAY
  122. g.fill_oval(p.first, p.second, 10, 10)
  123. end
  124.  
  125. @organisms.each do |o|
  126. o.draw(g)
  127. end
  128.  
  129. # flip buffer
  130. g.dispose()
  131. @strategy.show()
  132. end
  133. end
  134.  
  135. def add_organism(organism)
  136. @organisms << organism
  137. end
  138.  
  139. private
  140. def draw_frame(g)
  141. g.color = Color::WHITE
  142. old_stroke = g.stroke
  143. thindashed = BasicStroke.new(1.0, BasicStroke::CAP_BUTT, BasicStroke::JOIN_BEVEL, 1.0, [8.0, 3.0, 2.0, 3.0].to_java(:float), 0.0)
  144. g.set_stroke(thindashed)
  145. (0..WORLD_WIDTH).step(40) do |x|
  146. (0..WORLD_HEIGHT).step(40) do |y|
  147. g.drawLine(0, y, WORLD_WIDTH, y)
  148. g.drawLine(x, 0, x, WORLD_HEIGHT)
  149. end
  150. end
  151. g.stroke = old_stroke
  152. end
  153. end
  154.  
  155. class ControlPanel < JPanel
  156.  
  157.  
  158. def initialize(organism)
  159. super()
  160. self.layout = GridBagLayout.new
  161. self.preferred_size = Dimension.new(200, WORLD_HEIGHT)
  162.  
  163. constraints = GridBagConstraints.new
  164. constraints.weightx = 1.0
  165. constraints.fill = GridBagConstraints::HORIZONTAL
  166. constraints.insets = Insets.new(3, 5, 3, 5)
  167. self.add(JLabel.new("v_x0:"), constraints)
  168.  
  169. constraints.gridwidth = GridBagConstraints::REMAINDER
  170. constraints.weightx = 10.0
  171. @velocity_x_field = JTextField.new(VX_0.to_s)
  172. self.add(@velocity_x_field, constraints)
  173.  
  174. constraints.weightx = 1.0
  175. constraints.gridwidth = GridBagConstraints::RELATIVE
  176. self.add(JLabel.new("v_y0:"), constraints)
  177.  
  178. constraints.gridwidth = GridBagConstraints::REMAINDER
  179. @velocity_y_field = JTextField.new(VY_0.to_s)
  180. self.add(@velocity_y_field, constraints)
  181.  
  182. constraints.weighty = 1
  183. constraints.anchor = GridBagConstraints::NORTH;
  184. constraints.gridheight = GridBagConstraints::REMAINDER
  185. constraints.fill = GridBagConstraints::NONE
  186. button = JButton.new("Restart")
  187. button.add_action_listener do |e|
  188. organism.x = X_0
  189. organism.y = Y_0
  190. organism.x_final = false
  191.  
  192. organism.vx_0 = initial_velocity_x
  193. organism.vy_0 = initial_velocity_y
  194. $current_time = 0
  195. end
  196. self.add(button, constraints)
  197.  
  198. end
  199.  
  200. def initial_velocity_x
  201. @velocity_x_field.text.to_f
  202. end
  203.  
  204. def initial_velocity_y
  205. @velocity_y_field.text.to_f
  206. end
  207. end
  208.  
  209. class ShowFrame < JFrame
  210. attr_accessor :universe
  211. def initialize
  212. super()
  213. self.title = "First Try"
  214. self.ignore_repaint = true
  215.  
  216. organism = Organism.new
  217. organism.x = X_0
  218. organism.y = Y_0
  219. organism.vx_0 = VX_0
  220. organism.vy_0 = VY_0
  221. organism.radius = 5
  222.  
  223. @universe = Universe.new
  224. @universe.add_organism(organism)
  225. self.content_pane.add(@universe, BorderLayout::CENTER)
  226. self.content_pane.add(ControlPanel.new(organism), BorderLayout::WEST)
  227.  
  228. self.default_close_operation = JFrame::EXIT_ON_CLOSE
  229. self.pack()
  230. self.visible = true
  231. self.resizable = false
  232.  
  233. Timer.new(DELAY, ->(e) { @universe.game_loop }).start
  234. end
  235.  
  236. end
  237.  
  238. java.awt.EventQueue::invokeLater do
  239. ShowFrame.new
  240. end
Add Comment
Please, Sign In to add comment