wilkie and many others are using Hackety Hack to learn how to code.

Hackety Hack is a free program for Windows, Mac OS X and Linux that can teach you how to make games, applications and more and share those programs with your friends. You can ask other budding programmers questions and follow them to see what code they're working on through the Hackety Hack website.

Sign up Learn More

invaders by wilkie

# Space Invaders clone

# Create a new window for us to use
Shoes.app :width => 600, :height => 400, :resizable => false do
  background black
  
  # Create those monsters
  monsters_per_row = 10
  rows = 5
  
  @monsters = []
  @bullets = []
  
  # They have some girth that will fit on the screen
  # Remember, we have to play fair and give them room to move!
  monster_girth = self.height / monsters_per_row / 2.4
  monster_space = monster_girth * 2

  # Monsters are slow at first
  monster_movement = self.width / 600
  
  # Monsters start centered
  start_x = (self.width - monster_space * monsters_per_row) / 2
    
  # Each of them will be represented by a square
  rows.times do |y|
    monsters_per_row.times do |x|
      mx = x * monster_space + start_x
      my = y * monster_space + monster_girth*2
      @monsters << rect(mx, my, monster_girth, :fill => white)
    end
  end
  
  # The player is a square
  px = (self.width - monster_girth) / 2
  @player = rect px, self.height - monster_girth * 2, monster_girth, :fill => blue
  
  # The bullets are oval
  @bullet = oval 0, 0, 4, 7, :fill => yellow
  @bullet.hide
  
  # The player is initially at rest
  @moving = 0
  
  every 3 do
    # Find a monster to shoot at the player
    m = @monsters[rand(@monsters.size)]
    
    # Center that bullet!
    bx = m.left + monster_girth / 2 + 5
    by = m.top + monster_girth - 5
    
    # Fire!
    @bullets << oval(bx, by, 10, :fill => green)
  end
  
  @anim = animate 200 do
    change_directions = false
    
    # All of the monsters go left and right
    @monsters.each do |m|
      m.move m.left + monster_movement, m.top
      
      # Did the monster hit a wall?
      if m.left + monster_girth + monster_movement > self.width or m.left + monster_movement < 0
        change_directions = true
      end
      
      # Did the monster get to Earth?
      if m.top + monster_girth > @player.top
        @anim.stop and alert('You lose!')
        break
      end
    end
    
    # Are the monsters defeated?
    if @monsters.size == 0
      @anim.stop and alert('You win!')
    end
  
    # Move the monsters down, increase their speed, change directions!
    if change_directions
      monster_movement = -monster_movement * 1.1
      
      # Monsters go toward the player
      @monsters.each do |m|
        m.move m.left, m.top + monster_girth
      end
    end
    
    # Move the player
    @player.move @player.left + @moving, @player.top
    
    # Move bullet
    @bullet.move @bullet.left, @bullet.top - 10
    
    # Move invader bullets
    @bullets.each do |b|
      b.move b.left, b.top + 7

      # Check to see if bullet hit player or went off screen
      if b.top > @player.top
        if b.left + 5 > @player.left and b.left + 5 < @player.left + monster_girth
          # Bullet hit player
          @anim.stop and alert('You were shot!') and break
        end
        @bullets.delete b and b.hide
      end
    end
    
    # Does bullet hit monster?
    @monsters.each do |m|
      if @bullet.left + 2 > m.left and @bullet.left + 2 < m.left + monster_girth
        if @bullet.top + 3 > m.top and @bullet.top + 3 < m.top + monster_girth
          @bullet.move 0, 0 and @bullet.hide
          @monsters.delete m and m.hide
        end
      end
    end 
  end
  
  # Respond to key presses to move player and shoot
  keypress do |key|
    if key == :left
      @moving = -4
    elsif key == :right
      @moving = 4
    elsif key == " "
      @bullet.move @player.left + monster_girth / 2 - 2, @player.top
      @bullet.show
    end
  end
end