ang 9.19.0

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
@@ -0,0 +1,339 @@
1
+ # Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
2
+ ###########################################################################
3
+ # agent.rb : planetoide game multi player
4
+ #--------------------------------------------------------------------------
5
+ # install ruby
6
+ # install Gosu > gem install gosu
7
+ # download this > gem install ang
8
+ # run > angm
9
+ ###########################################################################
10
+ if RUBY_VERSION >= "2.0.0"
11
+ puts "Sorry, not ready for ruiby 2..."
12
+ exit(0)
13
+ end
14
+ require 'thread'
15
+ require 'timeout'
16
+ begin
17
+ require 'gosu'
18
+ rescue Exception => e
19
+ puts "Not completly installed !\nPlease do : \n> gem install gosu"
20
+ sleep(3)
21
+ exit(0)
22
+ end
23
+
24
+
25
+ ##################### Tuning ##########################
26
+
27
+ KK= 0.5
28
+ KKI= KK / 1
29
+ SX=1280 / KK # window size width
30
+ SY=900 / KK # height
31
+
32
+ $INITIALE_SCORE=3000
33
+ $NB_STAR=55
34
+ $RANGE_STAR_SIZE=(10..50) # more planet / bigger planets ==>> harder game!
35
+ $NET_TRANSMIT=80
36
+ $NB_PLANET=6
37
+ $NB_PL=$NB_STAR+$NB_PLANET
38
+ $ACCELERATION_WHEIGHT=2
39
+
40
+ #######################################################
41
+
42
+
43
+
44
+ $id=((Time.now.to_f*1000).to_i)* 100 + rand(100)
45
+ sleep(0.01*($id%100))
46
+ Thread.abort_on_exception=true
47
+
48
+ STDOUT.sync=true
49
+ def log(*txt) puts "%-80s | %s" % [txt.join(" "),caller[0].to_s.split(':in',2)[0]] end
50
+
51
+
52
+ require_relative 'tools.rb'
53
+ require_relative 'net.rb'
54
+ require_relative 'star.rb'
55
+ require_relative 'player.rb'
56
+ require_relative 'missile.rb'
57
+
58
+
59
+ ###########################################################################
60
+ # W i n d o w
61
+ ###########################################################################
62
+
63
+ class GameWindow < Gosu::Window
64
+ attr_reader :star,:ping
65
+ def initialize
66
+ super((SX*KKI).to_i, (SY*KKI).to_i, false)
67
+ # "KbRangeBegin", "KbEscape", "KbF1",..., "KbF12", "Kb1", ... "Kb0", "KbA",... "KbZ",
68
+ # "KbTab", "KbReturn", "KbSpace", "KbLeftShift", "KbRightShift", "KbLeftControl",
69
+ # "KbRightControl", "KbLeftAlt", "KbRightAlt", "KbLeftMeta", "KbRightMeta",
70
+ # "KbBackspace", "KbLeft", "KbRight", "KbUp", "KbDown", "KbHome", "KbEnd",
71
+ # "KbInsert", "KbDelete", "KbPageUp", "KbPageDown", "KbEnter", "KbNumpad1", ... "KbNumpad0",
72
+ # "KbNumpadAdd", "KbNumpadSubtract", "KbNumpadMultiply", "KbNumpadDivide",
73
+ # "KbRangeEnd", "KbNum"]
74
+
75
+ @text_field = Gosu::TextInput.new()
76
+ @text_field.text = "Input..."
77
+ self.text_input=@text_field
78
+ @comment=""
79
+
80
+ self.caption = "Gosu Tutorial Game"
81
+ @player_anim= Gosu::Image::load_tiles(self, "Starfighter.bmp", 50,50, false)
82
+
83
+ @lp=[]; 100.times { x=rand(SX) ; y=rand(SY); @lp<<x;@lp<<y }
84
+ @players={}
85
+
86
+ @player = Player.new(self,@player_anim,true)
87
+ @player.warp(SX*KKI/2,SY*KKI/2)
88
+
89
+ @font = Gosu::Font.new(self, Gosu::default_font_name, (20/KK).round)
90
+ @font2 = Gosu::Font.new(self, Gosu::default_font_name, (40/KK).round)
91
+
92
+ @star_anim = Gosu::Image::load_tiles(self, "Star.bmp", 100,100, false)
93
+
94
+ @ping=0
95
+ @start=0
96
+ @mouse=nil
97
+ self.go("Multiplayer version, in development ! Start")
98
+ NetClient.init(self)
99
+ Thread.new {
100
+ sleep 3
101
+ if @players.size>0
102
+ master=@players.keys.sort.first
103
+ NetClient.connect() if master<$id
104
+ end
105
+ }
106
+ end
107
+
108
+ ######################## Game global state
109
+ def egow(text)
110
+ @text=text
111
+ @start=@ping+800
112
+ go1(text)
113
+ end
114
+ def ego(text)
115
+ return if @ping < @start
116
+ @text=text
117
+ @start=@ping+200
118
+ Thread.new { sleep 4 ; self.go("Start...") }
119
+ end
120
+ def go(text)
121
+ display_comment "Avaler les points rouges, consommer le moins d'energie possible..."
122
+ @start=@ping+200
123
+ @text=text
124
+ go1(text)
125
+ end
126
+ def go1(text)
127
+ @stars = Array.new
128
+ @missiles=[]
129
+ @player.restart
130
+ @global_score=0
131
+ @touch={}
132
+ $NB_PLANET.times { @stars.push( Star.new(@stars,false,@star_anim) ) }
133
+ $NB_STAR.times { @stars.push( Star.new(@stars,true,@star_anim) ) }
134
+ if @players.size>0
135
+ NetClient.connect()
136
+ end
137
+ end
138
+ def pending?(d=0) (@start+d > @ping) end
139
+
140
+ def finish()
141
+ egow("Game Over...")
142
+ end
143
+ def looser() egow("Game Over") end
144
+ def winner(n)
145
+ return unless NetClient.is_master
146
+ NetClient.send_success()
147
+ ego("Success, Very good")
148
+ end
149
+ def receive_success(id)
150
+ ego("Success, Very good")
151
+ end
152
+ def receive_echec(id)
153
+ ego("Game over...")
154
+ end
155
+ def recho(*args) end
156
+
157
+ def send_positions(id)
158
+ stars=@stars.map { |s| s.get_pos() }
159
+ NetClient.send_position([id,stars])
160
+ end
161
+ def get_positions(id,data)
162
+ id_dest,stars=data
163
+ if id_dest==$id
164
+ stars.zip(@stars) { |pos,star| star.set_pos(pos) }
165
+ end
166
+ end
167
+
168
+ def star_deleted(index)
169
+ @stars.delete_if { |star| star.index() == index}
170
+ end
171
+
172
+ def init_player(id)
173
+ player = Player.new(self,@player_anim,false)
174
+ player.warp(320, 240)
175
+ @players[id]=player
176
+ end
177
+ def del_player(id) @players.delete(id) end
178
+ ######################## Global interactions : mouse/keyboard
179
+
180
+ ########### Server+client
181
+
182
+ def update_payers(id,data)
183
+ if @players[id]
184
+ @touch.delete(id) if @touch[id]
185
+ @players[id].update_by_net(data)
186
+ else
187
+ init_player(id)
188
+ @players[id].update_by_net(data)
189
+ end
190
+ end
191
+
192
+ ########### client
193
+
194
+ def button_down(id)
195
+ if id == Gosu::KbEscape
196
+ NetClient.is_stoping()
197
+ end
198
+ end
199
+
200
+ def interactions_client()
201
+ k=nil
202
+ (@player.turn_left;k=Gosu::KbLeft) if button_down? Gosu::KbLeft or button_down? Gosu::GpLeft
203
+ (@player.turn_right;k=Gosu::KbRight) if button_down? Gosu::KbRight or button_down? Gosu::GpRight
204
+ (@player.accelerate(true);k=Gosu::KbUp) if button_down? Gosu::KbUp or button_down? Gosu::GpButton0
205
+ (@player.accelerate(false);k=Gosu::KbDown)if button_down? Gosu::KbDown or button_down? Gosu::GpButton1
206
+ if @missiles.select {|m| m.local }.size<= 20
207
+ (@player.fire_missile();k=Gosu::KbNumpad0) if button_down? Gosu::KbNumpad0 or button_down? Gosu::KbInsert
208
+ end
209
+ if k==nil
210
+ @kbcars
211
+ end
212
+ end
213
+ def watchdog()
214
+ t=false
215
+ @touch.keys.each { |id| (t=true; @players.delete(id)) if @players[id] }
216
+ NetClient.reinit_master(@players.keys) if t
217
+ @players.keys.each { |id| @touch[id]=true }
218
+ end
219
+ def add_missile(m)
220
+ @missiles << m
221
+ end
222
+ def new_missile(data)
223
+ @missiles << Missile.new(self,@player_anim,false,*data)
224
+ end
225
+ def end_missile(id)
226
+ @missiles.reject! {|m| m.id==id}
227
+ end
228
+ ######################## Global draw : update()/draw() are invoked continuously by Gosu engine
229
+
230
+ def update()
231
+ @ping+=1
232
+ watchdog() if @ping%60==0
233
+ @player.clear()
234
+ NetClient.event_invoke()
235
+ now=Time.now.to_f
236
+ @players.each { |id,pl| pl.move(@stars,now) } if @player.score>0
237
+ @stars.each { |star| star.move(self,@stars) }
238
+ return if @ping<@start
239
+ missiles_behavior(now)
240
+
241
+ if @player.score>0
242
+ interactions_client()
243
+ @player.move(@stars,now)
244
+ @player.collect_stars(@stars)
245
+ end
246
+ @global_score=@player.score+@players.values.inject(0) { |sum,pl| (sum+pl.score) }
247
+ winner(@global_score) if 0 == (@stars.select { |s| s.type }.size )
248
+ end
249
+ def missiles_behavior(now)
250
+ @missiles.reject! do |m|
251
+ next(true) if m.move(@stars,now)
252
+ m.draw(self,@stars)
253
+ next(false ) unless m.local
254
+ if m.collision_players(@player)
255
+ NetClient.end_missile([m.id])
256
+ @player.dead
257
+ true
258
+ elsif idpl=@players.detect {|id,player| m.collision_players(player) }
259
+ NetClient.end_missile([m.id])
260
+ idpl[1].dead
261
+ true
262
+ end
263
+ end
264
+ end
265
+
266
+ def draw
267
+ scale(KKI,KKI) {
268
+ draw_background
269
+ @players.each {|id,p| p.draw(self,@stars) }
270
+ @player.draw(self,@stars)
271
+ @stars.each { |star| star.draw() }
272
+ @missiles.each { |m| m.draw(self,@stars) }
273
+ draw_variable_background()
274
+ }
275
+ end
276
+ def draw_background
277
+ @lp.each_slice(2) do |x,y|
278
+ draw_triangle(
279
+ x, y, 0xAAFFFFFF,
280
+ x+(4..8).rand, y+(4..8).rand, 0xAAFFFFFF,
281
+ x+(4..8).rand, y, 0xAAFFFFFF)
282
+ end
283
+ end
284
+ def draw_text(text,option)
285
+ w=option[:font].text_width(@text, option[:scale])
286
+ h=10*option[:scale];
287
+ option[:font].draw(text,
288
+ option[:x]<0 ? -option[:x] : (option[:x]-w/2),
289
+ option[:y]<0 ? -option[:y] : (option[:y]-h/2),
290
+ ZOrder::UI,
291
+ option[:scale],option[:scale],option[:color])
292
+ end
293
+ def draw_variable_background()
294
+ if @ping<@start
295
+ draw_text(@text+ " ! !",x: SX/2,y: SY/2,scale: 1,color: 0xf0f0f000,font: @font2)
296
+ draw_text("",x: 10,y: 10,scale: 1,color: 0xffffff00,font: @font)
297
+ else
298
+ #----------- barr graph energies reserve level
299
+ h=5+(@player.score/2000.0)*(SY-10)
300
+ draw_quad(5, 5, 0xBB55FF55, 20/KK, 5, 0xBB55FF55, 20/KK, h, 0xBBFFFF55, 5 , h , 0xBBFFFF55)
301
+ i=2
302
+ @players.each { |id,player|
303
+ h=5+(player.score/2000.0)*(SY-10)
304
+ draw_quad(
305
+ 20/KK*i , 5, 0xBB55FF55,
306
+ 20/KK*(i+1), 5, 0xBB55FF55,
307
+ 20/KK*(i+1), h, 0xBBFF9090+i*0x1010,
308
+ 20/KK*i , h , 0xBBFF9090+i*0x1010)
309
+ i+=1
310
+ }
311
+
312
+ #------------ textual energie reserve level
313
+ draw_text("Global Score: #{@global_score}", x: -25/KK,y: 10/KK,scale: 1,color: 0xffffff00,font: @font)
314
+ #------------ is Master
315
+ if NetClient.is_master
316
+ draw_text("Master", x: 25/KK,y: 20/KK,scale: 1,color: 0xffffff00,font: @font)
317
+ end
318
+ #----------------- Input
319
+ if @comment.size>0
320
+ draw_text(@comment, x: SX/2,y: SY-100,scale: 1,color: 0xffeeeeee,font: @font)
321
+ end
322
+ s=@text_field.text
323
+ if s && s.size>0
324
+ if s =~/\.$/
325
+ @text_field.text=""
326
+ NetClient.comment(s[0..-1])
327
+ end
328
+ draw_text("Input (end with '.') : "+ s,x: SX/4,y: SY-100,scale: 1,color: 0xffeeeeee,font: @font)
329
+ end
330
+ end
331
+ end
332
+ def display_comment(text)
333
+ @comment=text
334
+ Thread.new { sleep 10; @comment="" }
335
+ end
336
+ end
337
+
338
+ $game=GameWindow.new
339
+ $game.show
@@ -0,0 +1,10 @@
1
+ require '../../utils.rb'
2
+ require 'zlib'
3
+ message = (0..100).to_a.map { |i| i**2*1.1234}.inspect.gsub(", ",",")
4
+ p message.size
5
+ p message[0..100]
6
+ message1=""
7
+ 1.upto(9) { |level|
8
+ n=chrono(nil,100) { message1= Zlib::Deflate.new(level).deflate(message, Zlib::FINISH) }
9
+ puts "#{message1.size} #{level} #{n}"
10
+ }
@@ -0,0 +1,51 @@
1
+ # Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
2
+ ###########################################################################
3
+ # P l a y e r
4
+ ###########################################################################
5
+ class Missile < Player
6
+ def initialize(window,animation,local,id,x,y,vx,vy,weight)
7
+ super(window,animation,local)
8
+ @id=id if id
9
+ @age=0
10
+ @r=weight
11
+ @vangle = 0.0
12
+ @angle=Math.atan2(vx,vy)
13
+ @x,@y,@vel_x,@vel_y = x,y,vx,vy
14
+ @vx,@vy=[0,0]
15
+ @now=Time.now.to_f * 1000
16
+ @top=0
17
+ @app.add_missile(self)
18
+ NetClient.new_missile([@id,x,y,vx,vy,weight]) unless id
19
+ end
20
+ def clear() @pos=5 end
21
+ def restart() end
22
+
23
+ def warp(x, y) @x, @y = x, y ; end
24
+
25
+ def move(stars,now)
26
+ @age+=1
27
+ return(true) if @x >= SX+@r || @x+@r <= 0 || @y+@r >= SY || @y+@r <= 0
28
+ vx,vy=newton(stars)
29
+ @vel_x+=vx
30
+ @vel_y+=vy
31
+ @vel_x.minmax(-50,+50)
32
+ @vel_y.minmax(-50,+50)
33
+ @x += @vel_x
34
+ @y += @vel_y
35
+ @angle=Math.atan2(@vel_y,@vel_x)
36
+ n=now*1000
37
+ @now=now
38
+ dead if local && stars.any? { |star| ! star.type && Gosu::distance(@x, @y, star.x, star.y) < (15+star.r)/2 }
39
+ return(false)
40
+ end
41
+ def update_by_net(data) end
42
+ def draw(app,stars)
43
+ img = @animation[@local ? 8 : 9]
44
+ img.draw_rot(@x, @y, ZOrder::Player, 90.0+@angle*180.0/3.14159)
45
+ end
46
+ # test missile collision with some player(s)
47
+ def collision_players(player)
48
+ @age>(60*5) && local && Gosu::distance(@x, @y, player.x, player.y) < (7+player.r)
49
+ end
50
+
51
+ end
@@ -0,0 +1,74 @@
1
+ # Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
2
+ ###########################################################################
3
+ # multicast_test.rb : CLI tool for checking angm multicast communications
4
+ #--------------------------------------------------------------------------
5
+ # Usage
6
+ # term1> ruby multi_cast_text.rb
7
+ # temr2> ruby multi_cast_text.rb
8
+ # otherhost> ruby multi_cast_text.rb
9
+ ###########################################################################
10
+ require 'thread'
11
+ require 'timeout'
12
+ require_relative 'net.rb'
13
+
14
+
15
+ $id=((Time.now.to_f*1000).to_i)* 100 + rand(100)
16
+ Thread.abort_on_exception=true
17
+
18
+ STDOUT.sync=true
19
+ def log(*txt) puts "%-80s " % [txt.join(" ")] end
20
+
21
+
22
+ puts <<EEND
23
+ *****************************************************
24
+ Multicast Test
25
+
26
+ Checking Multicast group used by ANGM :
27
+ MULTICAST_ADDR = #{MCast::MULTICAST_ADDR}
28
+ PORT = #{MCast::PORT}
29
+ Interface = #{MCast::BIND_ADDR}
30
+
31
+ If multicast do not work :
32
+ * check your route table, a entry should exist on 224.0.0.0
33
+ * check if virtual host are configured,
34
+ * check multihoming (alias ip)
35
+ if host ip showed in trace is not a ip binded in your physical
36
+ interface, your multicast will work strangly...
37
+
38
+ My ID is #{$id}. this value is second parameter of
39
+ each message sended/received (startup time in ms * 100 + random(100)
40
+ hoping ot will be unic on the network...
41
+
42
+ *****************************************************
43
+
44
+ EEND
45
+ sleep 4
46
+ class App
47
+ def initialize
48
+ NetClient.init(self)
49
+ NetClient.set_trace(true)
50
+ Thread.new { loop { NetClient.wait_and_invoke() } }
51
+ Thread.new {
52
+ loop {
53
+ #NetClient.connect()
54
+ log "\n\Sending echo..."
55
+ NetClient.echo([$id,(Time.now.to_f*1000).to_i])
56
+ sleep 4
57
+ }
58
+ }
59
+ Thread.new { sleep 4 ; puts "\n\nEnd Traces\n\n"; NetClient.set_trace(false) }
60
+ end
61
+ def method_missing(name,*args)
62
+ if name==:recho
63
+ id_sender,id_demander,time=*args
64
+ log("Echo timing for #{id_sender} : #{(Time.now.to_f*1000).to_i - time} ms") if id_demander==$id
65
+ else
66
+ log(("%15s : %s" % ["<#{name}>",args.inspect])[0..100]) if name!=:move && name!=:update_payers
67
+ end
68
+ end
69
+ end
70
+
71
+ app=App.new
72
+ sleep
73
+
74
+