dl-tetris 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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"