Commit 736bcbbc3c5596032ce11887cb023237e0ad81f9

Authored by Marius Hanne
1 parent 172ca62ee5
Exists in master

use chipmunk to handle rotation and add spinning enemy

Showing 7 changed files with 43 additions and 30 deletions Side-by-side Diff

... ... @@ -78,6 +78,7 @@
78 78 ship = self.objects.find {|o| o.shape == ship_shape }
79 79 next unless bullet && ship
80 80 next if bullet.options[:shooter] == ship
  81 + next if bullet.options[:shooter].is_a?(Enemy) && ship.is_a?(Enemy)
81 82 bullet.hit(ship)
82 83 @space.remove_body(bullet_shape.body)
83 84 @space.remove_shape(bullet_shape)
1 1 class Bullet < Movable
2 2  
3 3 def initialize game, opts = {}
4   - opts[:rot] = opts[:dir] == :down ? 180.0 : 0.0
5 4 opts.merge!(m: 10.0, ctype: :bullet)
6 5 super(game, opts)
7   - p = opts[:dir] == :down ? pos.add(@shape.r) : pos.sub(@shape.r)
8   - @body.p = CP::Vec2.new(*p)
9 6 end
10 7  
11 8 def draw screen
... ... @@ -10,6 +10,8 @@
10 10 p: [0.0, 0.0],
11 11 v: [0.0, 0.0],
12 12 v_limit: 10.0,
  13 + a: 0.0,
  14 + w: 0.0,
13 15 rot: 0.0,
14 16 ctype: :object,
15 17 }
... ... @@ -18,7 +20,7 @@
18 20 def initialize game, opts = {}
19 21 @game, @options = game, DEFAULTS.merge(opts)
20 22 @surface = Surface.load(File.join(@game.data_dir, "images", options[:image]))
21   - .rotozoom(options[:rot], options[:zoom]).to_display_alpha
  23 + .rotozoom(0.0, options[:zoom]).to_display_alpha
22 24 @image = @surface
23 25 @body = CP::Body.new(options[:m], 1.0)
24 26  
... ... @@ -28,6 +30,8 @@
28 30 @body.p = CP::Vec2.new(*options[:p])
29 31 @body.v = CP::Vec2.new(*options[:v])
30 32 @body.v_limit = options[:v_limit]
  33 + @body.a = options[:a]
  34 + @body.w = options[:w]
31 35  
32 36 game.space.add_body(@body)
33 37 game.space.add_shape(@shape)
... ... @@ -35,8 +39,9 @@
35 39 @alive = true
36 40 end
37 41  
38   - def pos; @body.p.to_a; end
39   - def vel; @body.v.to_a; end
  42 + def pos; @body.p.to_a; end; alias_method :p, :pos
  43 + def vel; @body.v.to_a; end; alias_method :v, :vel
  44 + def rot; @body.a; end; alias_method :a, :rot
40 45  
41 46 def rect
42 47 Rect.new(@body.p.to_a, @surface.size)
... ... @@ -51,7 +56,8 @@
51 56 end
52 57  
53 58 def draw screen
54   - @surface.blit(screen, pos.sub(@shape.r))
  59 + s = @surface.rotozoom(@body.a, 1.0).to_display_alpha
  60 + s.blit(screen, pos.sub(s.size[0] / 2))
55 61 screen.draw_circle(pos, @shape.r, :red) if @game.options[:debug]
56 62 end
57 63  
... ... @@ -73,7 +79,7 @@
73 79  
74 80 def debug
75 81 @font ||= @game.font("FreeSans", 10)
76   - @debug = @font.render("[ #{self.class}: v: #{@body.v}, m: #{@body.m} ]", false, :white).to_display
  82 + @debug = @font.render("[ #{self.class}: v: #{@body.v}, a: #{@body.a}, m: #{@body.m} ]", false, :white).to_display
77 83 end
78 84  
79 85 end
... ... @@ -14,8 +14,8 @@
14 14 rescue
15 15 p $!
16 16 puts *$@
17   - end
18   - sleep rand(2)
  17 + end
  18 + sleep rand(0.5)
19 19 end
20 20 end
21 21 end
... ... @@ -43,7 +43,7 @@
43 43 end
44 44  
45 45 def self.generate game
46   - e = new(game, p: [0, 0], type: [:glider, :drone, :fighter].sample)
  46 + e = new(game, p: [0, 0], type: [:glider, :drone, :fighter, :spinner].sample)
47 47 e.show
48 48 game.enemies << e
49 49 end
... ... @@ -4,6 +4,7 @@
4 4  
5 5 def initialize game, options
6 6 options[:type] = :fighter
  7 + options[:a] = 180.0
7 8 super game, options
8 9 @score = 0
9 10 end
10 11  
11 12  
... ... @@ -16,20 +17,14 @@
16 17 @body.p += CP::Vec2.new(0.0, 1.0 * @params[:speed] * 10)
17 18 when :left
18 19 @body.p += CP::Vec2.new(-1.0 * @params[:speed] * 10, 0.0)
  20 + # @body.a += 5
19 21 when :right
20 22 @body.p += CP::Vec2.new(1.0 * @params[:speed] * 10, 0.0)
  23 + # @body.a -= 5
21 24 end
22 25 end
23 26  
24 27 def draw *a
25   - p, v = pos, vel
26   - p[0], v[0] = 0, 0 if p[0] < 0
27   - p[1], v[1] = 0, 0 if p[1] < 0
28   - p[0], v[0] = screen.size[0], 0 if p[0] > screen.size[0]
29   - p[1], v[1] = screen.size[1], 0 if p[1] > screen.size[1]
30   - if pos != p
31   - @body.p = CP::Vec2.new(*p)
32   - end
33 28 @body.v = CP::Vec2.new(0,0)
34 29 super *a
35 30 end
... ... @@ -6,11 +6,10 @@
6 6 drone: { power: 75, shield: 50, speed: 2, weapons: [:missile],
7 7 image: { image: "ship.png", zoom: 0.7 }},
8 8 fighter: { power: 100, shield: 100, speed: 1, weapons: [
9   - :laser,
10   - :torpedo,
11   - :missile
12   - ],
  9 + :laser, :torpedo, :missile ],
13 10 image: { image: "ship.png", zoom: 1.0 }},
  11 + spinner: { power: 50, shield: 50, speed: 2, rot: 0.1, weapons: [:laser],
  12 + image: { image: "ship.png", zoom: 0.7 }},
14 13 }
15 14  
16 15 attr_accessor :power, :image, :type, :debug
17 16  
... ... @@ -20,11 +19,24 @@
20 19 image = @params[:image]
21 20 image[:rot] = is_a?(Enemy) ? 0.0 : 180.0
22 21 super game, options.merge(image)
23   - @max_power = @params[:power]
24   - @power = @max_power
  22 + @max_power = @params[:power] * 2
  23 + @power = @params[:power]
25 24 @weapons = @params[:weapons].map {|w| Weapon.new(self, w) }
26 25 end
27 26  
  27 + def draw *a
  28 + p, v = pos, vel
  29 + p[0], v[0] = 0, 0 if p[0] < 0
  30 + p[1], v[1] = 0, 0 if p[1] < 0
  31 + p[0], v[0] = screen.size[0], 0 if p[0] > screen.size[0]
  32 + p[1], v[1] = screen.size[1], 0 if p[1] > screen.size[1]
  33 + if pos != p
  34 + @body.p = CP::Vec2.new(*p)
  35 + end
  36 + @body.w = @params[:rot] if @params[:rot]
  37 + super *a
  38 + end
  39 +
28 40 def fire
29 41 @weapons.each(&:fire)
30 42 end
... ... @@ -56,7 +68,7 @@
56 68 end
57 69  
58 70 def debug
59   - text = "[ #{@type}: #{@power}, v: #{@body.v}, m: #{@body.m} ]"
  71 + text = "[ #{@type}: #{@power}, v: #{@body.v}, a: #{@body.a}, m: #{@body.m} ]"
60 72 @debug = @game.font("FreeSans").render(text, false, :white).to_display
61 73 end
62 74  
1 1 class Weapon
2 2  
3 3 WEAPONS = {
4   - laser: { damage: 10, speed: 15, freq: 500,
  4 + laser: { damage: 10, speed: 15, freq: 900,
5 5 image: { image: "bullet.png", zoom: 1.0 }},
6 6 missile: { damage: 20, speed: 5, freq: 300,
7 7 image: { image: "bullet.png", zoom: 2.0 }},
... ... @@ -18,9 +18,11 @@
18 18  
19 19 def fire
20 20 if game.steps - @last_shot >= (1000 - params[:freq])
21   - calc = @ship.is_a?(Player) ? :sub : :add
22   - v = @ship.body.v.to_a.send(calc, [0.0, params[:speed] / 10.0])
23   - opts = params[:image].merge(p: @ship.pos,
  21 + v = [0.0, 1.0]
  22 + a = 0 - ((@ship.a * Math::PI / 180 ) % 360)
  23 + cos, sin = Math.cos(a), Math.sin(a)
  24 + v = [v[0] * cos - v[1] * sin, v[0] * sin + v[1] * cos]
  25 + opts = params[:image].merge(p: @ship.p, a: @ship.a + 180.0,
24 26 v: v, shooter: @ship, damage: params[:damage], m: params[:damage])
25 27 Bullet.new(game, opts).show
26 28 @last_shot = game.steps