Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit b89fed1ce55c1b5ac31359ac2a9b0c8680c74fdb @adminmyserver committed May 18, 2009
Showing with 168 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +2 −0 README
  3. +110 −0 pong.rb
  4. +54 −0 pong_sounds.rb
@@ -0,0 +1,2 @@
+.DS_Store
+bloops
@@ -0,0 +1,2 @@
+Sorry, there's no real documentation. Check the blog article here:
+http://www.adminmyserver.com/articles/ruby-pong-with-shoes-and-bloopsaphone
@@ -0,0 +1,110 @@
+require 'pong_sounds'
+
+Shoes.app :width => 640, :height => 480, :resizable => false do
+ paddle_size = 75
+ half_paddle = paddle_size / 2
+
+ ball_size = 10
+ half_ball = ball_size / 2
+
+ start_speed_x, start_speed_y = 4, 2
+ vx, vy = start_speed_x, start_speed_y
+
+ comp_speed = app.width / 80
+ bounce = 1.2
+ paddle_width = 4
+
+ winning_score = 7
+
+ # set up the playing board
+ nostroke and background black
+ center_line = rect app.width / 2, 0, 4, app.height, :fill => white
+
+ @ball = rect 0, 0, ball_size, ball_size, :fill => white
+ @you, @comp = [app.width - paddle_width, 0].map {|x| rect x, 0, paddle_width, paddle_size, :curve => 2, :fill => white}
+
+ @my_score, @comp_score = 0, 0
+ @my_score_txt = title @my_score, :top => 25, :left => 500, :stroke => white, :font => 'Network'
+ @comp_score_txt = title @comp_score, :top => 25, :left => 100, :stroke => white, :font => 'Network'
+
+ paused_text = title "PAUSED", :size => 32, :top => 140, :align => 'center', :stroke => white, :hidden => true
+
+ # animates at 40 frames per second
+ @animation = animate 40 do
+ keypress do |key|
+ # allow user to pause by pressing spacebar
+ if key == " "
+ @animation.toggle
+ paused_text.toggle
+ end
+ end
+
+ # check for a score
+ if @ball.left + ball_size < 0 || @ball.left > app.width
+ PongSounds.play :score
+
+ if @ball.left + ball_size < 0
+ @my_score_txt.replace(@my_score += 1)
+ @ball.move app.width, 0
+ vx, vy = -start_speed_x, -start_speed_y
+ else
+ @comp_score_txt.replace(@comp_score += 1)
+ @ball.move 0, 0
+ vx, vy = start_speed_x, start_speed_y
+ end
+
+ # check for game over
+ if @my_score > winning_score || @comp_score > winning_score
+ para strong("GAME OVER", :size => 32), "\n",
+ (@my_score > @comp_score ? "You win!" : "Computer wins"),
+ :top => 140, :align => 'center', :stroke => white
+ @ball.hide and center_line.hide and @animation.stop
+
+ # sleep for 1 second then resume play
+ else
+ sleep 1
+ end
+ end
+
+ # move the @you paddle, following the mouse
+ @you.top = (mouse[2] - half_paddle).to_i
+
+ # determine new x/y coordinates based on old position + velocity
+ nx, ny = (@ball.left + vx).to_i, (@ball.top + vy).to_i
+
+ # move the @comp paddle, speed based on 'comp_speed' variable
+ @comp.top +=
+ if ny + half_ball > @comp.top + paddle_size
+ # ball is above us, move up towards it
+ comp_speed
+ elsif ny < @comp.top
+ # ball is below us, move down towards it
+ -comp_speed
+ else
+ 0
+ end
+
+ # if the @you paddle hits the ball
+ if nx + ball_size > app.width and vx > 0 and (0..paddle_size).include?(ny + half_ball - @you.top)
+ vy = (ny - @you.top - half_paddle) * 0.25
+ vx = -vx * bounce
+ nx = app.width - ball_size
+
+ PongSounds.play :hit
+ # if the @comp paddle hits the ball
+ elsif nx < 0 and vx < 0 and (0..paddle_size).include?(ny + half_ball - @comp.top)
+ vy = (ny - @comp.top - half_paddle) * 0.25
+ vx = -vx * bounce
+ nx = 0
+
+ PongSounds.play :hit
+ # ball hits top/bottom of screen
+ elsif ny + ball_size > app.height or ny < 0
+ vy = -vy
+
+ PongSounds.play :bounce
+ end
+
+ @ball.move nx, ny
+ end
+end
@@ -0,0 +1,54 @@
+require 'bloops/bloops'
+require 'singleton'
+
+class PongSounds
+ include Singleton
+
+ class << self
+ def bloops
+ @bloops ||= Bloops.new
+ end
+
+ def sounds
+ @sounds ||= begin
+ @hit = bloops.sound Bloops::SQUARE
+ @hit.volume = 0.4
+ @hit.sustain = 0.02
+ @hit.attack = 0.02
+ @hit.decay = 0.1
+ @hit.punch = 0.1
+
+ @score = bloops.sound Bloops::SAWTOOTH
+ @score.volume = 0.2
+ @score.sustain = 0.25
+ @score.attack = 0.02
+ @score.decay = 0.1
+ @score.punch = 0.5
+ @score.arp = 0.1
+ @score.phase = 0.1
+
+ @bounce = bloops.sound Bloops::SINE
+ @bounce.volume = 0.5
+ @bounce.sustain = 0.1
+ @bounce.attack = 0.02
+ @bounce.decay = 0.1
+ @bounce.punch = 0.5
+ @bounce.arp = 0.1
+ @bounce.phase = 0.1
+
+ {:hit => [@hit, "32 + A#"], :score => [@score, "16 - D#"], :bounce => [@bounce, "16 - F#"]}
+ end
+
+ @sounds
+ end
+
+ def play(name)
+ Thread.new do
+ bloops.tune *sounds[name]
+ bloops.play
+ sleep 0.1 until bloops.stopped?
+ bloops.clear
+ end
+ end
+ end
+end

0 comments on commit b89fed1

Please sign in to comment.