Xavier Nayrac

Rubyiste accro au TDD, serial blogger, apprenti data scientist, 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