Xavier Nayrac

Accro au TDD, rubyiste mais pas que, maker, heureux utilisateur de Vim, accordéoniste.
Si vous vous sentez particulièrement généreux, suivez moi sur Twitter.

Un space invaders avec Opal.rb - partie 10

| Comments

Niveau : intermédiaire

Le code suivant ne me convient toujours pas :

1
2
3
@enemies.map do |enemy|
  @direction == :left ? enemy.move_left : enemy.move_right
end

Pourquoi ne pas dire simplement à la classe Enemy ce qu’elle doit faire en une seule fois:

1
@enemies.map {|enemy| enemy.move(@direction) }

C’est quand même bien plus simple ! Bien sûr, pour que ça fonctionne il faut ajouter une méthode à la classe Enemy:

1
2
3
  def move(direction)
    direction == :left ? move_left : move_right
  end

Et tant qu’on y est, on fait pareil avec la méthode enemies_down.

Avant:

1
2
3
4
5
  def enemies_down
    @enemies.each do |e|
      e.y = e.y + 4
    end
  end

Après:

1
2
3
  def enemies_down
    @enemies.map(&:move_down)
  end

Et on ajoute ceci à Enemy:

1
2
3
  def move_down
    @y += 4
  end

Pour terminer cet article, voici le code des classes Enemy et Enemies:

app/enemy.rb
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
class Enemy
  DELTA = 2

  attr_accessor :x, :y, :w, :h, :color

  def initialize(x, y, w, h, color)
    @x = x
    @y = y
    @w = w
    @h = h
    @color = color
  end

  def move_left
    @x -= DELTA
  end

  def move_right
    @x += DELTA
  end

  def move(direction)
    direction == :left ? move_left : move_right
  end

  def move_down
    @y += 4
  end
end
app/enemies.rb
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
class Enemies
  include Enumerable
  ENEMIES_PER_ROW = 10

  def initialize
    @enemies = []
    @direction = :right
    build(60, '#0000ff')
    build(120, '#0000dd')
    build(180, '#0000bb')
    build(240, '#000099')
    build(300, '#000077')
  end

  def each(&block)
    @enemies.each(&block)
  end

  def update
    @enemies.each do |e|
      if e.x <= 10 || e.x + e.w >= 690
        change_enemies_direction
        enemies_down
        break
      end
    end
    @enemies.map {|enemy| enemy.move(@direction) }
  end

  private

  def change_enemies_direction
    if @direction == :left
      @direction = :right
    else
      @direction = :left
    end
  end

  def enemies_down
    @enemies.map(&:move_down)
  end

  def build(y, color)
    (1..ENEMIES_PER_ROW).each do |i|
      @enemies << Enemy.new(50 + i * 60, y, 40, 40, color)
    end
  end

end

Il reste encore un peu de travail…

À demain.

Articles connexes

Commentaires