public
Description: High-level game framework, built on Rubygame & OpenGL. (On hold)
Homepage: http://blog.rubygame.org/rebirth
Clone URL: git://github.com/jacius/rebirth.git
rebirth / games / paddle_ball.rb
100644 178 lines (121 sloc) 3.398 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
=begin
 
THE GAME:
 
A ball flies back and forth across a playing field. Use the arrow
keys to move your paddle up and down to deflect the ball. If the
ball flies off your opponent's side of the screen, you get a point,
but if it flies off your side of the screen, your opponent gets the
point. The first player to get 10 points wins the game!
 
 
DEMONSTRATES:
 
* Keyboard input
* Player-controlled game objects
* AI-controlled game objects
* Collision detection
* Rectangle shape
 
CURRENT STATUS:
 
* Nonfunctional (code incomplete; and library not implemented.)
 
 
AUTHOR:
 
John Croisant, 2008-05-29
 
=end
 
 
 
VERY_MASSIVE = 10**15
 
 
 
class Paddle < GameObject
 
  attr_accessor :direction, :top_speed, :clamp_x
 
 
  def initialize( params = {} )
    base_params = {
      :color => :white,
      :size => [16,64],
      :mass => VERY_MASSIVE,
      :elast => 1.10,
      :gravity => false
    }
 
    add_shape Rectangle.new( base_params.merge(params) )
 
    @direction = 0; # moving up (1), down (-1), or none (0)
    @top_speed = 30
    @clamp_x = nil;
 
    before_update( :name => "move" ) do |tick|
      self.velocity = v(0,1) * top_speed * direction
    end
 
    after_update( :name => "clamp x" ) do
      if @clamp_x
        self.position.x = @clamp_x
        self.velocity.x = 0
      end
    end
 
  end
 
 
  def bind_keys( up, down )
    when_key_pressed( :key => up, :name => "+up" ) do
      self.direction += 1
    end
 
    when_key_released( :key => up, :name => "-up" ) do
      self.direction -= 1
    end
 
    when_key_pressed( :key => down, :name => "+down" ) do
      self.direction -= 1
    end
 
    when_key_released( :key => down, :name => "-down" ) do
      self.direction += 1
    end
  end
 
 
  def clear_keys
    clear_hooks "+up", "-up", "+down", "-down"
  end
 
 
  def ai_track_ball( ball )
    @ball = ball
    @fuzz = 10
 
    before_update( :name => "tracking", :priority => 10 ) do
      diff = @ball.y - self.y
 
      if diff > @fuzz
        self.direction = 1
      elsif diff < -@fuzz
        self.direction = 1
      else
        self.direction = 0
      end
    end
  end
 
end
 
 
 
class Ball < GameObject
 
  def initialize( params={} )
    base_params = {
      :color => :red,
      :radius => 10.0,
    }
    
    add_shape Circle.new( base_params.merge(params) )
 
    @base_speed = 30
  end
 
 
  def start( direction )
    self.velocity =
      case direction
      when "left"
        v(1,1).magnitude(-@base_speed)
      when "right"
        v(1,1).magnitude( @base_speed)
      end
  end
end
 
 
 
class Wall < GameObject
  def initialize( p1, p2 )
    base_params = {
      :color => :white,
      :thickness => 3.0,
      :static => true,
      :elast => 1.0
    }
  
    add_shape Line.new( base_params.merge(:points => [p1,p2]) )
  end
end
 
 
 
def setup
  $game = Game.new
 
  # Initialize scores
  $game["scores"] = { "left" => 0, "right" => 0 }
 
  # Make the walls
  $game.add( "top_wall" => Wall.new(v(-400, 240), v( 400, 240)),
             "bottom_wall" => Wall.new(v(-400,-240), v( 400,-240)),
             "left_wall" => Wall.new(v(-400, 240), v(-400,-240)),
             "right_wall" => Wall.new(v( 400, 240), v( 400,-240)))
 
  ["left," "right"].each do |side|
    $game["#{side}_wall"].when_collide( :with => Ball ) do
      $game["scores"][side] += 1
      $game["ball"].die
    end
  end
end