2 # -*- coding: utf-8 -*-
4 GalTacK runtime-loadable module.
6 # Copyright (C) 2007 Michael Carter
7 # Copyright (C) 2007 Felix Rabe <public@felixrabe.textdriven.com>
8 # Copyright (C) 2007 Phil Hassey (originator of ld488 code)
10 # WARNING: This code contains bits from the Ludum Dare version of Galcon,
11 # which is licensed under the GNU GPL. Watch out for "ld488" markers.
12 # This file is under the GNU GPL license for now.
14 # This matter has not yet been discussed with Phil Hassey. I, Felix Rabe,
15 # do not want any legal grey area in the code, so the whole project might
16 # change from MIT license to GPL license, or Phil gives his blessing to
17 # include those bits in MIT-licensed code.
19 #### IGNORE THIS PART:
21 # Permission is hereby granted, free of charge, to any person obtaining a
22 # copy of this software and associated documentation files (the
23 # "Software"), to deal in the Software without restriction, including
24 # without limitation the rights to use, copy, modify, merge, publish,
25 # distribute, sublicense, and/or sell copies of the Software, and to permit
26 # persons to whom the Software is furnished to do so, subject to the
27 # following conditions:
29 # The above copyright notice and this permission notice shall be included
30 # in all copies or substantial portions of the Software.
32 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
33 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
35 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
36 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
37 # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
38 # THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 # Recommended line length or text width: 75 characters.
44 from galtack_client
import *
47 class GaltackUniverseView(DrawingArea
):
49 GalTacK universe canvas.
53 super(GaltackUniverseView
, self
).__init
__()
55 self
.connect("expose-event", self
.__cb
_expose
_event
)
56 self
.set_size_request(640, 480)
59 self
.planet_info_list
= []
61 def __cb_expose_event(self
, widget
, event
):
62 x
, y
, w
, h
= self
.allocation
63 cr
= self
.window
.cairo_create()
66 cr
.rectangle(0, 0, w
, h
)
67 cr
.set_source_rgba(0.1, 0.0, 0.2, 1)
71 fascent
, fdescent
, fheight
, fxadvance
, fyadvance
= e
74 for planet_info
in self
.planet_info_list
:
75 cr
.set_source_rgba(1, 1, 1, 1)
76 px
, py
= planet_info
.x
, planet_info
.y
77 cr
.arc(px
, py
, planet_info
.radius
, 0, PI2
)
80 txt
= "%u" % planet_info
.num
81 e
= cr
.text_extents(txt
)
82 xbearing
, ybearing
, width
, height
, xadvance
, yadvance
= e
83 cr
.move_to(px
+ 0.5 - xbearing
- width
/ 2,
84 py
+ 0.5 - fdescent
+ fheight
/ 2)
85 cr
.set_source_rgba(1, 0, 0, 1)
89 if self
.window
is not None:
90 self
.window
.invalidate_rect(self
.allocation
, False)
94 class GaltackUniverseWindow(WindowF12RawConsoleMixin
):
96 A Window displaying a view of the GalTacK universe.
100 super(GaltackUniverseWindow
, self
).__init
__()
101 self
.set_title("Universe Window - GalTacK")
102 self
.universe_view
= self(GaltackUniverseView())
105 class LoadableController(object):
107 Provide some shortcuts for interactive use.
110 def __init__(self
, galtack_client
, *a
, **kw
):
111 self
.gc
= galtack_client
112 self
.uw
= GaltackUniverseWindow()
113 self
.uv
= self
.uw
.universe_view
115 def __call__(self
, *a
):
116 self
.gc
.send_commands(a
)
119 def __stabilize_planet_pos(planet_pos_list
):
120 FPS
= 32 # ld488: cnst.py:11
121 BORDER
= 40 # ld488: level.py:27
122 PADDING
= 8 # ld488: level.py:28
124 for n
in xrange(0,FPS
):
129 for i
, (p
, x
, y
) in enumerate(planet_pos_list
):
131 x
= min(max(x
, left
+ rad
), right
- rad
)
132 y
= min(max(y
, top
+ rad
), bottom
- rad
)
133 planet_pos_list
[i
] = (p
, x
, y
)
134 self
.__planet
_flock
_loop
(planet_pos_list
)
137 def __planet_flock_loop(planet_pos_list
): # ld488: flock.pyp:55
139 ## First 'for' loop unnecessary, as "p->loop = 0" in:
140 ## ld488: flock.pyp:128
141 for n
, (ap
, ax
, ay
) in enumerate(planet_pos_list
):
142 for m
, (bp
, bx
, by
) in enumerate(planet_pos_list
[n
+1:]):
145 r
= ap
.radius
+ bp
.radius
146 if abs(dx
) > r
or abs(dy
) > r
:
148 dist
= math
.sqrt(dx
*dx
+ dy
*dy
)
150 ## no targets (but what about the part with index 0?)
154 ## w = weight and a->w == b->w == 100000 for
155 ## planets: ld488: flock.pyp:130.
156 ## Here, we cancel down to a->w == b->w == 1
160 ax
= mx
- ((r
* dx
) / (dist
* w
))
161 ay
= my
- ((r
* dy
) / (dist
* w
))
162 bx
= mx
+ ((r
* dx
) / (dist
* w
))
163 by
= my
+ ((r
* dy
) / (dist
* w
))
166 if self
.gc
.u64data
is None:
169 planets
= self
.gc
.u64data
.planets
172 planet_pos_list
.append((p
, p
.x
, p
.y
))
173 self
.__stabilize
_planet
_pos
(planet_pos_list
)
174 self
.uv
.planet_info_list
= planets
178 def run_loadable(*a
, **kw
):
179 return LoadableController(*a
, **kw
)