Browse code
tweaking field of view effects
edwlan authored on 26/07/2013 20:52:27
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -6,6 +6,7 @@ from src import player |
6 | 6 |
from src import console |
7 | 7 |
from src import map |
8 | 8 |
|
9 |
+import random |
|
9 | 10 |
|
10 | 11 |
|
11 | 12 |
class Application(object): |
... | ... |
@@ -18,6 +19,9 @@ class Application(object): |
18 | 19 |
self.events = events.EventHandler() |
19 | 20 |
player.ArrowHandler(self.player, self.events) |
20 | 21 |
|
22 |
+ |
|
23 |
+ |
|
24 |
+ |
|
21 | 25 |
tc.sys_set_fps(60) |
22 | 26 |
|
23 | 27 |
def init(self): |
... | ... |
@@ -2,6 +2,7 @@ import numpy as np |
2 | 2 |
import libtcodpy as tc |
3 | 3 |
import yaml |
4 | 4 |
import libs.bresenham |
5 |
+import libs.cache |
|
5 | 6 |
|
6 | 7 |
def squeeze(val, low, high): |
7 | 8 |
return min(max(val, low), high) |
... | ... |
@@ -14,9 +15,7 @@ class TerrainGen(object): |
14 | 15 |
def generate(self): |
15 | 16 |
w,h = self.width, self.height |
16 | 17 |
terrains, probs = self.terrain_registry.get_terrain_types() |
17 |
- print terrains, probs |
|
18 | 18 |
map = np.random.choice(terrains, (w,h), p=probs) |
19 |
- print map[map>4] |
|
20 | 19 |
chars = np.zeros((w,h)).astype('int') |
21 | 20 |
fgcolors = np.zeros((w,h,3)) |
22 | 21 |
bgcolors = np.zeros((w,h,3)) |
... | ... |
@@ -33,6 +32,8 @@ class TerrainGen(object): |
33 | 32 |
class Map(object): |
34 | 33 |
def __init__(self, w, h, terrain_registry): |
35 | 34 |
self.pov = None |
35 |
+ self.povcache = libs.cache.Cache() |
|
36 |
+ |
|
36 | 37 |
self.width = w |
37 | 38 |
self.height = h |
38 | 39 |
self.terrain_registry = terrain_registry |
... | ... |
@@ -46,7 +47,6 @@ class Map(object): |
46 | 47 |
self.overlays.setdefault(object.pos,[]).append(object) |
47 | 48 |
|
48 | 49 |
def move(self, object, dx,dy): |
49 |
- print self.overlays, |
|
50 | 50 |
self.overlays[object.pos].remove(object) |
51 | 51 |
|
52 | 52 |
if abs(dx) < 2 and abs(dy) < 2: |
... | ... |
@@ -75,28 +75,45 @@ class Map(object): |
75 | 75 |
if (x,y) in self.overlays and self.overlays[x,y] == []: |
76 | 76 |
self.overlays.pop((x,y)) |
77 | 77 |
|
78 |
- def get_rgb(self, fg=True,slices=(slice(0),slice(0))): |
|
79 |
- if fg: |
|
80 |
- result = np.rollaxis(self.fgcolors[slices], 2) |
|
81 |
- else: |
|
82 |
- result = np.rollaxis(self.bgcolors[slices], 2) |
|
78 |
+ def get_rgb(self, colors, fg=True,slices=(slice(0),slice(0))): |
|
79 |
+ result = np.rollaxis(colors[slices], 2) |
|
83 | 80 |
return [x.transpose() for x in result] |
84 | 81 |
|
85 | 82 |
def draw(self, con, tl=(0,0)): |
86 | 83 |
br = tl[0]+con.width, tl[1]+con.height |
84 |
+ |
|
85 |
+ fgcolors = self.fgcolors.astype('int') |
|
86 |
+ bgcolors = self.bgcolors.astype('int') |
|
87 |
+ color_mask = np.ones( (con.width, con.height, 3) ) |
|
88 |
+ char_mask = np.ones( (con.width, con.height) ).astype('bool') |
|
89 |
+ if self.pov is not None: |
|
90 |
+ origin, radius = self.pov |
|
91 |
+ def calc_mask(): |
|
92 |
+ for x in range(tl[0], br[0]): |
|
93 |
+ for y in range(tl[1], br[1]): |
|
94 |
+ if not self.fov.is_visible(origin, radius, (x,y)): |
|
95 |
+ color_mask[x,y] = (0.25, 0.5, 0.5) |
|
96 |
+ char_mask[x,y] = False |
|
97 |
+ return color_mask, char_mask |
|
98 |
+ color_mask, char_mask = self.povcache.get( (origin,radius), calc_mask ) |
|
99 |
+ fgcolors = (fgcolors * color_mask).astype('int') |
|
100 |
+ bgcolors = (bgcolors * color_mask).astype('int') |
|
101 |
+ |
|
87 | 102 |
slices = slice(tl[0], tl[0]+con.width), slice(tl[1], tl[1]+con.height) |
88 |
- tc.console_fill_foreground(con.con, *self.get_rgb(slices=slices)) |
|
89 |
- tc.console_fill_background(con.con, *self.get_rgb(False,slices=slices)) |
|
103 |
+ tc.console_fill_foreground(con.con, *self.get_rgb(fgcolors, slices=slices)) |
|
104 |
+ tc.console_fill_background(con.con, *self.get_rgb(bgcolors, False,slices=slices)) |
|
90 | 105 |
|
91 | 106 |
chars = np.copy(self.map[slices]) |
92 | 107 |
for x,y in self.overlays: |
93 | 108 |
screen_x = x-tl[0] |
94 | 109 |
screen_y = y-tl[1] |
110 |
+ if not char_mask[screen_x,screen_y]: continue |
|
95 | 111 |
if 0 <= screen_x < con.width and 0 <= screen_y < con.height: |
96 | 112 |
obj = self.overlays[x,y][-1] |
97 | 113 |
chars[screen_x,screen_y] = obj.char |
98 |
- tc.console_set_char_foreground(con.con, screen_x,screen_y, tc.black) |
|
99 |
- tc.console_set_char_background(con.con, screen_x,screen_y, tc.white) |
|
114 |
+ tc.console_set_char_background(con.con, screen_x,screen_y, tc.Color(*bgcolors[screen_x,screen_y])) |
|
115 |
+ tc.console_set_char_foreground(con.con, screen_x,screen_y, tc.Color(*obj.color)) |
|
116 |
+ chars[np.logical_not(char_mask)] = ord(' ') |
|
100 | 117 |
tc.console_fill_char(con.con, chars.transpose()) |
101 | 118 |
|
102 | 119 |
def coord_iter(self): |
... | ... |
@@ -110,6 +127,8 @@ class Map(object): |
110 | 127 |
class FovCache(object): |
111 | 128 |
# TODO: get allow updates to base_map |
112 | 129 |
def __init__(self, map, terrain_registry): |
130 |
+ self.width, self.height = map.dim |
|
131 |
+ |
|
113 | 132 |
self.base_map = tc.map_new(*map.dim) |
114 | 133 |
|
115 | 134 |
for x,y in map.coord_iter(): |
... | ... |
@@ -122,7 +141,7 @@ class FovCache(object): |
122 | 141 |
|
123 | 142 |
self.fovmaps = {} |
124 | 143 |
|
125 |
- def get_fovmap(self, terrain_registry, origin, radius): |
|
144 |
+ def get_fovmap(self, origin, radius): |
|
126 | 145 |
key = origin,radius |
127 | 146 |
|
128 | 147 |
if key in self.fovmaps: fovmap = self.fovmaps[key] |
... | ... |
@@ -136,6 +155,10 @@ class FovCache(object): |
136 | 155 |
|
137 | 156 |
return fovmap |
138 | 157 |
|
158 |
+ def is_visible(self, origin, radius, coord): |
|
159 |
+ fovmap = self.get_fovmap(origin, radius) |
|
160 |
+ return tc.map_is_in_fov(fovmap, *coord) |
|
161 |
+ |
|
139 | 162 |
def is_transparent(self, coord): |
140 | 163 |
return tc.map_is_transparent(self.base_map, *coord) |
141 | 164 |
def is_passable(self, coord): |
... | ... |
@@ -190,7 +213,6 @@ class TerrainRegistry(object): |
190 | 213 |
def new_terrain(self, name, char, |
191 | 214 |
passable=False, transparent=False, fg=(255,255,255), bg=(0,0,0), prob=1 |
192 | 215 |
): |
193 |
- print 'prob: %f' % prob |
|
194 | 216 |
ter = TerrainInfo.make_terrain(name, char, passable, transparent, fg,bg, prob=prob) |
195 | 217 |
return self.register(ter) |
196 | 218 |
|
... | ... |
@@ -1,6 +1,9 @@ |
1 | 1 |
import libtcodpy as tc |
2 | 2 |
|
3 |
-class Player(object): |
|
3 |
+class Actor(object): |
|
4 |
+ char = ord('@') |
|
5 |
+ color = (255,0,0) |
|
6 |
+ |
|
4 | 7 |
@property |
5 | 8 |
def pos(self): |
6 | 9 |
return self.x, self.y |
... | ... |
@@ -8,19 +11,20 @@ class Player(object): |
8 | 11 |
def __init__(self, x,y, map): |
9 | 12 |
self.x = x |
10 | 13 |
self.y = y |
11 |
- self.char = ord('@') |
|
12 |
- self.color = tc.Color(255,255,255) |
|
13 | 14 |
self.map = map |
14 | 15 |
|
15 | 16 |
def draw(self): |
16 | 17 |
self.map.add(self) |
17 | 18 |
|
18 | 19 |
def move(self, dx, dy): |
19 |
- print self.pos, |
|
20 | 20 |
dx, dy = self.map.move(self, dx,dy) |
21 | 21 |
self.x += dx |
22 | 22 |
self.y += dy |
23 |
- print self.pos |
|
23 |
+ self.map.pov = (self.pos, 10) |
|
24 |
+ |
|
25 |
+class Player(Actor): |
|
26 |
+ char = ord('@') |
|
27 |
+ color = (255,255,255) |
|
24 | 28 |
|
25 | 29 |
class ArrowHandler(object): |
26 | 30 |
def __init__(self, player, eh): |
... | ... |
@@ -30,28 +34,24 @@ class ArrowHandler(object): |
30 | 34 |
eh.register(tc.KEY_UP,self.up) |
31 | 35 |
eh.register(tc.KEY_DOWN,self.down) |
32 | 36 |
def left(self, alt, shift, ctrl): |
33 |
- print 'left' |
|
34 | 37 |
val = 10 if shift else 1 |
35 | 38 |
if alt: |
36 | 39 |
self.player.move(-val, -val) |
37 | 40 |
else: |
38 | 41 |
self.player.move(-val, 0) |
39 | 42 |
def right(self, alt, shift, ctrl): |
40 |
- print 'right' |
|
41 | 43 |
val = 10 if shift else 1 |
42 | 44 |
if alt: |
43 | 45 |
self.player.move(val, val) |
44 | 46 |
else: |
45 | 47 |
self.player.move(val, 0) |
46 | 48 |
def up(self, alt, shift, ctrl): |
47 |
- print 'up' |
|
48 | 49 |
val = 10 if shift else 1 |
49 | 50 |
if alt: |
50 | 51 |
self.player.move(val, -val) |
51 | 52 |
else: |
52 | 53 |
self.player.move(0, -val) |
53 | 54 |
def down(self, alt, shift, ctrl): |
54 |
- print 'down' |
|
55 | 55 |
val = 10 if shift else 1 |
56 | 56 |
if alt: |
57 | 57 |
self.player.move(-val, val) |