This repository has been archived by the owner on Nov 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
render.py
154 lines (113 loc) · 6.96 KB
/
render.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from sett import *
import libtcodpy as libtcod
class Camera(object):
def __init__(self, w = CAMERA_WIDTH, h = CAMERA_HEIGHT, x=0, y=0, player = None, fov_map = None, gamemap = None, con = None):
self.width = w
self.height = h
self.x = x
self.y = y
self.player = player
self.fov_map = fov_map
self.gamemap = gamemap
self.con = con
def reset_position(self, coord = 'both'):
if coord == 'xreset' or coord == 'both': self.x = self.player.x - self.width/2 # less than 0 type errors get dont happen because of setter properties
if coord == 'yreset' or coord == 'both': self.y = self.player.y - self.height/2 # centers camera on self.self.player
libtcod.console_clear(self.con)
def check_for_posreset(self, xdiff = FREEMOVE_WIDTH, ydiff = FREEMOVE_HEIGHT):
centerx, centery = self.center
if (self.player.x > centerx + xdiff or self.player.x < centerx - xdiff) and (self.player.y > centery + ydiff or self.player.y < centery - ydiff): #the ugliest code
return 'both'
if self.player.x > centerx + xdiff: return 'xreset'
elif self.player.x < centerx - xdiff: return 'xreset'
#
if self.player.y > centery + ydiff: return 'yreset'
elif self.player.y < centery - ydiff: return 'yreset'
return False
def camera_render(self):
if self.check_for_posreset(): self.reset_position(self.check_for_posreset())
for camy in range(self.height):
mapy = self.y + camy
for camx in range(self.width):
mapx = self.x + camx
visible = libtcod.map_is_in_fov(self.fov_map, mapx, mapy)
wall = self.gamemap[mapx][mapy].block_sight
special = self.gamemap[mapx][mapy].special
if not visible:
if self.gamemap[mapx][mapy].explored:
if wall:
libtcod.console_put_char_ex(self.con, camx, camy, '#', color_dark_wall, libtcod.black) #
else: #
libtcod.console_put_char_ex(self.con, camx, camy, '.', color_dark_ground, libtcod.black) # OK this looks bad but it's quite simple actually, i'm sure it could be written more elegantly with abs or something
if special and wall: # basically there are 3 nested rectangles: the biggest beingthe actual map where objects interact and the game happens, the second is the camera, which gets rendered to con in camera_render method
libtcod.console_put_char_ex(self.con, camx, camy, special.char, color_dark_wall, libtcod.black) # the third is a phantom FREEMOVE square which is checked in check_for_posreset and all it does is center the camera position (separately for x and y) when the self.player walks outside of it
elif special and not wall: #most of the complexity is just in juggling coordinates between camera and map, but it more or less comes down to :
libtcod.console_put_char_ex(self.con, camx, camy, special.char, color_dark_ground, libtcod.black) #mapcoord = camera_origin_coord + current_camera_coord: that's those mapx and mapy variables. works like poschengband camera
else: #it's visible
if wall:
libtcod.console_put_char_ex(self.con, camx, camy, '#', color_light_wall, libtcod.black)
else:
libtcod.console_put_char_ex(self.con, camx, camy, '.', color_light_ground, libtcod.black)
if special:
libtcod.console_put_char_ex(self.con, camx, camy, special.char, special.foreground, special.background)
self.gamemap[mapx][mapy].explored = True
@property
def center(self):
centerx = self.x + self.width/2
centery = self.y + self.height/2
return centerx, centery
@property
def x2(self):
return self.x + self.width
@property
def y2(self):
return self.y + self.height
@property
def x(self):
return self._x
@property
def y(self):
return self._y
@x.setter
def x(self, value):
if value < 0: value = 0
if value > MAP_WIDTH - self.width: value = MAP_WIDTH - self.width
self._x = value
@y.setter
def y(self, value):
if value < 0: value = 0
if value > MAP_HEIGHT - self.height: value = MAP_HEIGHT - self.height
self._y = value
def render_all(gldir, camera, panel, con):
if gldir.fov_recompute:
gldir.fov_recompute = False
libtcod.map_compute_fov(gldir.fov_map, gldir.player.x, gldir.player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO)
camera.camera_render()
for obj in gldir.game_objs:
if obj.in_camera(): obj.draw()
gldir.player.draw()
for obj in gldir.game_objs:
if obj.name == 'targeter': obj.draw()
#blits the content of the 'con' console to the root console
libtcod.console_blit(con, 0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, 0, 0, 0)
libtcod.console_set_default_background(panel, libtcod.black)
libtcod.console_clear(panel)
#print game messages, one line at a time
y = 1
for (line, color) in gldir.game_msgs:
libtcod.console_set_default_foreground(panel,color)
libtcod.console_print_ex(panel,MSG_X, y, libtcod.BKGND_NONE, libtcod. LEFT, line)
y += 1
render_bar(1, 1, BAR_WIDTH, 'Health', gldir.player.fighter.hp, gldir.player.fighter.max_hp, libtcod.dark_red, libtcod.darkest_red, panel) # display health
libtcod.console_print_ex(panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, 'Dungeon level ' + str(gldir.dungeon_level)) #display dungeon level
#blits the content of the 'panel' console to the root console
libtcod.console_blit(panel, 0, 0, SCREEN_WIDTH, PANEL_HEIGHT, 0, 0, PANEL_Y)
def render_bar(x, y, total_width, name, value, maximum, bar_color, back_color, panel):
bar_width = int(float(value) / maximum * total_width)
libtcod.console_set_default_background(panel, back_color)
libtcod.console_rect(panel, x, y, total_width, 1, False, libtcod.BKGND_SCREEN)
libtcod.console_set_default_background(panel, bar_color)
if bar_width > 0:
libtcod.console_rect(panel,x,y,bar_width, 1, False, libtcod.BKGND_SCREEN)
libtcod.console_set_default_foreground(panel, libtcod.white)
libtcod.console_print_ex(panel, x + total_width / 2, y, libtcod.BKGND_NONE, libtcod.CENTER, name + ': ' + str(value) + '/' + str(maximum))