dl-tetris 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,6 +9,15 @@ Arrow keys move, up arrow rotates and space drops your piece.
9
9
 
10
10
  ![Tetris Screenshot 1](http://kzar.co.uk/images/tetris.png)
11
11
 
12
+ Installation
13
+ ------------
14
+
15
+ `gem install dl-tetris`
16
+
17
+ `dl-tetris`
18
+
19
+ (Checkout [Rubygems.org](https://rubygems.org/gems/dl-tetris) for more info.)
20
+
12
21
  Notes
13
22
  -----
14
23
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ # A hack but it was deemed impossible: http://bit.ly/eBKJIu
3
+ `rsdl #{File.dirname(__FILE__)}/boot.rb`
@@ -1,2 +1 @@
1
- #!/usr/bin/env rsdl
2
- load boot.rb
1
+ %x[rsdl $PWD/boot.rb]
@@ -1,7 +1,7 @@
1
1
  class Game
2
2
  def initialize(w, h, speed, font_file)
3
3
  # Setup rubygame stuff
4
- @screen = Rubygame::Screen.new([w * $TileSize, h * $TileSize], 0,
4
+ @screen = Rubygame::Screen.new([w * $TileSize, h * $TileSize], 0,
5
5
  [Rubygame::HWSURFACE, Rubygame::DOUBLEBUF])
6
6
  @queue = Rubygame::EventQueue.new
7
7
  @clock = Rubygame::Clock.new
@@ -18,14 +18,14 @@ class Game
18
18
  @step = 0
19
19
  @score = 0
20
20
  end
21
-
21
+
22
22
  def run
23
23
  loop do
24
24
  update(@clock.tick)
25
25
  draw
26
26
  end
27
27
  end
28
-
28
+
29
29
  def update(time_delta)
30
30
  # Process the event queue
31
31
  @queue.each do |ev|
@@ -45,7 +45,7 @@ class Game
45
45
  end
46
46
  when Rubygame::QuitEvent
47
47
  Rubygame.quit
48
- exit
48
+ exit
49
49
  end
50
50
  end
51
51
  # Update the game state
@@ -57,7 +57,7 @@ class Game
57
57
  @piece.update(@map) {|x, y, colour| @map.set(x, y, colour)}
58
58
  @score += @map.update
59
59
  end
60
-
60
+
61
61
  def draw_square(x, y, colour, border=true)
62
62
  # Setup the points for SDL
63
63
  x_pos = x * $TileSize
@@ -68,12 +68,15 @@ class Game
68
68
  @screen.draw_box_s(pt1, pt2, colour)
69
69
  @screen.draw_box(pt1, pt2, :black) if border
70
70
  end
71
-
71
+
72
72
  def draw
73
73
  @screen.fill(@background)
74
- @piece.squares {|x, y, colour| draw_square(x, y, colour)}
75
- @map.draw {|coords, colour| draw_square(coords[0], coords[1], colour)}
74
+
75
+ draw_squares = lambda {|x, y, colour| draw_square(x, y, colour)}
76
+ @piece.squares.each &draw_squares
77
+ @map.squares.each &draw_squares
78
+
76
79
  @ttf.render("Score: " + @score.to_s, true, :black).blit(@screen, [0,0])
77
80
  @screen.flip
78
81
  end
79
- end
82
+ end
@@ -0,0 +1,79 @@
1
+ class Game
2
+ def initialize(w, h, speed, font_file)
3
+ # Setup rubygame stuff
4
+ @screen = Rubygame::Screen.new([w * $TileSize, h * $TileSize], 0,
5
+ [Rubygame::HWSURFACE, Rubygame::DOUBLEBUF])
6
+ @queue = Rubygame::EventQueue.new
7
+ @clock = Rubygame::Clock.new
8
+ @clock.target_framerate = 30
9
+ Rubygame::TTF.setup
10
+ @ttf = Rubygame::TTF.new(font_file, 20)
11
+
12
+ # Setup the game of tetris
13
+ @screen.title = "Tetris"
14
+ @map = Map.new(w, h)
15
+ @piece = Piece.new
16
+ @background = :white
17
+ @speed = speed
18
+ @step = 0
19
+ @score = 0
20
+ end
21
+
22
+ def run
23
+ loop do
24
+ update(@clock.tick)
25
+ draw
26
+ end
27
+ end
28
+
29
+ def update(time_delta)
30
+ # Process the event queue
31
+ @queue.each do |ev|
32
+ case ev
33
+ when Rubygame::KeyDownEvent
34
+ case(ev.key)
35
+ when Rubygame::K_LEFT
36
+ @piece.move(-1, 0, @map)
37
+ when Rubygame::K_RIGHT
38
+ @piece.move(1, 0, @map)
39
+ when Rubygame::K_DOWN
40
+ @piece.move(0, 1, @map)
41
+ when Rubygame::K_UP
42
+ @piece.rotate(@map)
43
+ when Rubygame::K_SPACE
44
+ @piece.drop(@map)
45
+ end
46
+ when Rubygame::QuitEvent
47
+ Rubygame.quit
48
+ exit
49
+ end
50
+ end
51
+ # Update the game state
52
+ @step += time_delta
53
+ if @step > @speed
54
+ @step -= @speed
55
+ @piece.move(0, 1, @map)
56
+ end
57
+ @piece.update(@map) {|x, y, colour| @map.set(x, y, colour)}
58
+ @score += @map.update
59
+ end
60
+
61
+ def draw_square(x, y, colour, border=true)
62
+ # Setup the points for SDL
63
+ x_pos = x * $TileSize
64
+ y_pos = y * $TileSize
65
+ pt1 = [x_pos, y_pos]
66
+ pt2 = [x_pos + $TileSize, y_pos + $TileSize]
67
+ # Draw the square and then the border
68
+ @screen.draw_box_s(pt1, pt2, colour)
69
+ @screen.draw_box(pt1, pt2, :black) if border
70
+ end
71
+
72
+ def draw
73
+ @screen.fill(@background)
74
+ @piece.squares {|x, y, colour| draw_square(x, y, colour)}
75
+ @map.draw {|coords, colour| draw_square(coords[0], coords[1], colour)}
76
+ @ttf.render("Score: " + @score.to_s, true, :black).blit(@screen, [0,0])
77
+ @screen.flip
78
+ end
79
+ end
@@ -2,67 +2,46 @@ class Map
2
2
  def initialize(w, h)
3
3
  @w = w
4
4
  @h = h
5
- @tiles = Array.new(w, nil)
6
- end
7
-
8
- def clear(x, y, w, h)
9
- (x..(x + w)).each do |x|
10
- (y..(y + h)).each do |y|
11
- set(x, y, nil)
12
- end
13
- end
5
+ @tiles = Array.new(h) {Array.new(w, nil)}
14
6
  end
15
7
 
16
8
  def set(x, y, colour)
17
- @tiles[pos(x,y)] = colour
18
- end
19
-
20
- def draw
21
- @tiles.each_with_index do |colour, p|
22
- yield(coords(p), colour) if colour
9
+ @tiles[y][x] = colour
10
+ end
11
+
12
+ def squares
13
+ Enumerator.new do |yielder|
14
+ @tiles.each_with_index do |line, y|
15
+ line.each_with_index do |colour, x|
16
+ yielder.yield(x, y, colour) if colour
17
+ end
18
+ end
23
19
  end
24
20
  end
25
21
 
26
22
  def free?(x, y)
27
- x >= 0 and x < @w and y >= 0 and y < @h and not @tiles[pos(x,y)]
23
+ x >= 0 and x < @w and y >= 0 and y < @h and not @tiles[y][x]
28
24
  end
29
25
 
30
26
  def update
31
27
  points = 0
32
- shift_lines! do |line|
33
- # Enumerable should have an every? method
34
- if not line.each.any? {|tile| not tile} then
35
- points += 1
36
- true
37
- end
38
- end
28
+ shift_lines! {|line| points += 1 if line.all?}
39
29
  points
40
30
  end
41
31
 
42
32
  private
43
33
 
44
- def coords(p)
45
- [p % @w, p / @w]
46
- end
47
-
48
- def pos(x, y)
49
- x + y * @w
50
- end
51
-
52
34
  def shift_lines!
53
- (0..@h).each do |y|
54
- row = (0..@w-1).collect {|x| @tiles[pos(x,y-1)] }
55
- shift_line(y-1, 1) if yield row
56
- end
57
- end
58
-
59
- def shift_line(y, distance)
60
- if y < 1 then
61
- @tiles[pos(0,y + distance)..pos(@w-1,y + distance)] = [nil] * @w
62
- else
63
- @tiles[pos(0,y)..pos(@w-1,y)] =
64
- @tiles[pos(0,y-distance)..pos(@w-1,y-distance)]
65
- shift_line(y-1, distance)
35
+ @tiles.each_with_index {|line, y| shift_line(y) if yield line}
36
+ end
37
+
38
+ def shift_line(y)
39
+ case y
40
+ when 0
41
+ @tiles[y].fill(nil)
42
+ when 1..@h
43
+ @tiles[y] = @tiles[y - 1]
44
+ shift_line(y - 1)
66
45
  end
67
46
  end
68
- end
47
+ end
@@ -0,0 +1,68 @@
1
+ class Map
2
+ def initialize(w, h)
3
+ @w = w
4
+ @h = h
5
+ @tiles = Array.new(w, nil)
6
+ end
7
+
8
+ def clear(x, y, w, h)
9
+ (x..(x + w)).each do |x|
10
+ (y..(y + h)).each do |y|
11
+ set(x, y, nil)
12
+ end
13
+ end
14
+ end
15
+
16
+ def set(x, y, colour)
17
+ @tiles[pos(x,y)] = colour
18
+ end
19
+
20
+ def draw
21
+ @tiles.each_with_index do |colour, p|
22
+ yield(coords(p), colour) if colour
23
+ end
24
+ end
25
+
26
+ def free?(x, y)
27
+ x >= 0 and x < @w and y >= 0 and y < @h and not @tiles[pos(x,y)]
28
+ end
29
+
30
+ def update
31
+ points = 0
32
+ shift_lines! do |line|
33
+ # Enumerable should have an every? method
34
+ if not line.each.any? {|tile| not tile} then
35
+ points += 1
36
+ true
37
+ end
38
+ end
39
+ points
40
+ end
41
+
42
+ private
43
+
44
+ def coords(p)
45
+ [p % @w, p / @w]
46
+ end
47
+
48
+ def pos(x, y)
49
+ x + y * @w
50
+ end
51
+
52
+ def shift_lines!
53
+ (0..@h).each do |y|
54
+ row = (0..@w-1).collect {|x| @tiles[pos(x,y-1)] }
55
+ shift_line(y-1, 1) if yield row
56
+ end
57
+ end
58
+
59
+ def shift_line(y, distance)
60
+ if y < 1 then
61
+ @tiles[pos(0,y + distance)..pos(@w-1,y + distance)] = [nil] * @w
62
+ else
63
+ @tiles[pos(0,y)..pos(@w-1,y)] =
64
+ @tiles[pos(0,y-distance)..pos(@w-1,y-distance)]
65
+ shift_line(y-1, distance)
66
+ end
67
+ end
68
+ end
@@ -11,29 +11,13 @@ class Piece
11
11
  @colour = $Colours.rand_item
12
12
  end
13
13
 
14
- def parse_piece_string(s)
15
- s.chars.each_with_object([]) do |c, result|
16
- case c
17
- when " " then result << false
18
- when "," then next
19
- else result << true
20
- end
21
- end
22
- end
23
-
24
- def load_pieces(pieces)
25
- pieces.collect do |piece|
26
- piece.collect {|rotation| parse_piece_string rotation}
27
- end
28
- end
29
-
30
14
  def squares(piece=current)
31
- result = []
32
- piece.each_with_index do |tile, i|
33
- x, y = coords(i)
34
- result << yield(@x+x, @y+y, @colour) if tile
15
+ Enumerator.new do |yielder|
16
+ piece.each_with_index do |tile, i|
17
+ x, y = coords(i)
18
+ yielder.yield(@x+x, @y+y, @colour) if tile
19
+ end
35
20
  end
36
- return result
37
21
  end
38
22
 
39
23
  def move(x, y, map)
@@ -53,13 +37,29 @@ class Piece
53
37
 
54
38
  def update(map)
55
39
  if collision?(map, 0, 1)
56
- squares {|x, y, colour| map.set(x, y, colour)}
40
+ squares.each {|x, y, colour| map.set(x, y, colour)}
57
41
  initialize
58
42
  end
59
43
  end
60
44
 
61
45
  private
62
46
 
47
+ def parse_piece_string(s)
48
+ s.chars.each_with_object([]) do |c, result|
49
+ case c
50
+ when " " then result << false
51
+ when "," then next
52
+ else result << true
53
+ end
54
+ end
55
+ end
56
+
57
+ def load_pieces(pieces)
58
+ pieces.collect do |piece|
59
+ piece.collect {|rotation| parse_piece_string rotation}
60
+ end
61
+ end
62
+
63
63
  def current
64
64
  @type[@rotation]
65
65
  end
@@ -77,6 +77,6 @@ class Piece
77
77
  end
78
78
 
79
79
  def collision?(map, x_offset, y_offset, piece=current)
80
- squares(piece) {|x, y, c| not map.free?(x + x_offset, y + y_offset)}.any?
80
+ squares(piece).any? {|x, y, c| not map.free?(x + x_offset, y + y_offset)}
81
81
  end
82
- end
82
+ end
@@ -0,0 +1,82 @@
1
+ class Piece
2
+ @@type_width = 4
3
+
4
+ def initialize
5
+ @@types ||= load_pieces($Pieces)
6
+
7
+ @type = @@types.rand_item
8
+ @rotation = 0
9
+ @x = 0
10
+ @y = 0
11
+ @colour = $Colours.rand_item
12
+ end
13
+
14
+ def parse_piece_string(s)
15
+ s.chars.each_with_object([]) do |c, result|
16
+ case c
17
+ when " " then result << false
18
+ when "," then next
19
+ else result << true
20
+ end
21
+ end
22
+ end
23
+
24
+ def load_pieces(pieces)
25
+ pieces.collect do |piece|
26
+ piece.collect {|rotation| parse_piece_string rotation}
27
+ end
28
+ end
29
+
30
+ def squares(piece=current)
31
+ result = []
32
+ piece.each_with_index do |tile, i|
33
+ x, y = coords(i)
34
+ result << yield(@x+x, @y+y, @colour) if tile
35
+ end
36
+ return result
37
+ end
38
+
39
+ def move(x, y, map)
40
+ unless collision?(map, x, y)
41
+ @x += x
42
+ @y += y
43
+ end
44
+ end
45
+
46
+ def drop(map)
47
+ @y += 1 while not collision?(map, 0, 1)
48
+ end
49
+
50
+ def rotate(map)
51
+ @rotation = next_rotation unless collision?(map, 0, 0, @type[next_rotation])
52
+ end
53
+
54
+ def update(map)
55
+ if collision?(map, 0, 1)
56
+ squares {|x, y, colour| map.set(x, y, colour)}
57
+ initialize
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def current
64
+ @type[@rotation]
65
+ end
66
+
67
+ def next_rotation
68
+ if @rotation > @type.count - 2
69
+ return 0
70
+ else
71
+ return @rotation + 1
72
+ end
73
+ end
74
+
75
+ def coords(p)
76
+ [p % @@type_width, p / @@type_width]
77
+ end
78
+
79
+ def collision?(map, x_offset, y_offset, piece=current)
80
+ squares(piece) {|x, y, c| not map.free?(x + x_offset, y + y_offset)}.any?
81
+ end
82
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Dave Barker
@@ -52,7 +52,7 @@ description: Simple tetris clone written using the rubygame library. Arrow keys
52
52
  email:
53
53
  - kzar@kzar.co.uk
54
54
  executables:
55
- - tetris
55
+ - dl-tetris
56
56
  extensions: []
57
57
 
58
58
  extra_rdoc_files: []
@@ -60,12 +60,15 @@ extra_rdoc_files: []
60
60
  files:
61
61
  - bin/boot.rb
62
62
  - bin/boot.rb~
63
- - bin/tetris
63
+ - bin/dl-tetris
64
64
  - bin/tetris~
65
65
  - lib/tetris/core_ruby_ext.rb
66
66
  - lib/tetris/game.rb
67
+ - lib/tetris/game.rb~
67
68
  - lib/tetris/map.rb
69
+ - lib/tetris/map.rb~
68
70
  - lib/tetris/piece.rb
71
+ - lib/tetris/piece.rb~
69
72
  - lib/tetris.rb
70
73
  - test/game_test.rb
71
74
  - test/test_helper.rb
data/bin/tetris DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env rsdl
2
- load "boot.rb"