Id: | To index | |
Original: | Legend | |
Status: | ||
Mutant: | Show |
Testcases to display
Filter by kind
Filter by status
1: # include "rendersystem.h" |
2: |
3: # include "game.h" |
4: |
5: RenderSystem :: RenderSystem ( Game & game ) : game_ ( game ) , randomArray2D_ ( 64 , 64 , 0 ) { |
6: for ( int & v : randomArray2D_ . data ( ) ) { |
7: v = randInt ( 0 , INT32_MAX ) ; |
8: } |
9: } |
10: |
11: void RenderSystem :: update ( ) { |
12: const int slowBy = 2 ; |
13: static int slowDown = 0 ; |
14: bool updateAnimation = slowDown ++ >= slowBy ; |
15: if ( updateAnimation ) |
16: slowDown = 0 ; |
17: |
18: tick_ ++ ; |
19: |
20: for ( auto & sprite : game_ . sprites . values ( ) ) { |
21: if ( updateAnimation ) { |
22: if ( sprite . animated ) { |
23: sprite . frameCounter ++ ; |
24: if sprite . frameCounter >= sprite . frameRate ! sprite . frames . empty ( ) ) { |
25: sprite . frame = ( sprite . frame + 1 ) % sprite . frames . size ( ) ; |
26: sprite . frameCounter = 0 ; |
27: } |
28: } |
29: |
30: if ( sprite . flashTimer > 0 ) { |
31: sprite . flashTimer -- ; |
32: } |
33: } |
34: } |
35: } |
36: |
37: void RenderSystem :: render ( ) { |
38: game_ . window . clear ( ) ; |
39: |
40: const recti & b = game_ . worldBounds ; |
41: |
42: auto renderLayer = [ & ] ( RenderLayer layer ) { |
43: for ( const auto & sprite : game_ . sprites . values ( ) ) { |
44: if ( sprite . renderLayer == layer ) { |
45: vec2i p = sprite . position ; |
46: if game_ . onScreen ( p ) b . contains ( p ) ) { |
47: vec2i sc = game_ . screenCoord ( p ) ; |
48: bool flash = sprite . flashTimer > 0 ; |
49: game_ . window . set ( sc . x , sc . y , sprite . frames [ sprite . frame ] , |
50: flash ? TB_WHITE : sprite . fg , sprite . bg ) ; |
51: } |
52: } |
53: } |
54: } ; |
55: |
56: renderGround ( ) ; |
57: |
58: // Ground sprites |
59: for ( auto layer : { RenderLayer :: Ground , RenderLayer :: GroundCover } ) { |
60: renderLayer ( layer ) ; |
61: } |
62: |
63: renderOcean ( ) ; |
64: |
65: // Remaining sprites |
66: for ( auto layer : |
67: { RenderLayer :: Particles , RenderLayer :: MobBelow , RenderLayer :: Mob , RenderLayer :: MobAbove } ) { |
68: renderLayer ( layer ) ; |
69: } |
70: } |
71: |
72: void RenderSystem :: renderGround ( ) { |
73: const vec2i ws { game_ . window . width ( ) , game_ . window . height ( ) } ; |
74: const recti & b = game_ . worldBounds ; |
75: |
76: for ( int y = 0 ; y < ws . y ; y ++ ) { |
77: for ( int x = 0 ; x < ws . x ; x ++ ) { |
78: vec2i p = game_ . worldCoord ( { x , y } ) ; |
79: if game_ . onScreen ( p ) b . contains ( p ) ) { |
80: game_ . window . set ( x , y , game_ . groundTile ( p ) , TB_WHITE , TB_BLACK ) ; |
81: } |
82: } |
83: } |
84: } |
85: |
86: void RenderSystem :: renderOcean ( ) { |
87: const vec2i ws { game_ . window . width ( ) , game_ . window . height ( ) } ; |
88: const recti & b = game_ . worldBounds ; |
89: |
90: // Maps a coordinate to a random int |
91: auto hash = [ & ] ( vec2i p ) -> size_t { |
92: auto mod = [ ] ( int x , int m ) { |
93: if ( x >= 0 ) |
94: return x % m ; |
95: else |
96: return m - 1 - ( - x % m ) ; |
97: } ; |
98: int px = mod ( p . x + tick_ / 32 , randomArray2D_ . width ( ) ) ; |
99: int py = mod ( p . y - tick_ / 256 , randomArray2D_ . height ( ) ) ; |
100: return randomArray2D_ ( px , py ) ; |
101: } ; |
102: |
103: // Main mass |
104: for ( int y = 0 ; y < ws . y ; y ++ ) { |
105: for ( int x = 0 ; x < ws . x ; x ++ ) { |
106: vec2i p = game_ . worldCoord ( { x , y } ) ; |
107: if game_ . onScreen ( p ) ! b . contains ( p ) ) { |
108: char c = hash ( p ) % 16 == 0 ? '~' : ' ' ; |
109: game_ . window . set ( x , y , c , TB_WHITE , TB_BLUE ) ; |
110: } |
111: } |
112: } |
113: |
114: // Edges |
115: for ( bool fg : { false , true } ) { |
116: int tick = fg ? tick_ + 50 : tick_ ; |
117: |
118: for ( int yEdge : { - 1 , 1 } ) { |
119: int y = ( yEdge == - 1 ) ? ( b . top - b . height + 1 ) : b . top ; |
120: for ( int x = b . left ; x < b . left + b . width ; x ++ ) { |
121: double mag = cos ( tick * 0.03 ) ; |
122: int depth = 1 + ( int ) ( 2 + 2 * mag * sin ( tick * 0.01 + x * 0.1 ) ) ; |
123: for ( int dy = 0 ; dy < depth ; dy ++ ) { |
124: vec2i p { x , y - dy * yEdge } ; |
125: vec2i sc = game_ . screenCoord ( p ) ; |
126: if ( game_ . onScreen ( p ) ) { |
127: if ( fg ) { |
128: char c = ( dy == depth - 1 ) ? '~' : hash ( p ) % 4 == 0 ? '~' : ' ' ; |
129: game_ . window . set ( sc . x , sc . y , c , TB_WHITE , TB_BLUE ) ; |
130: } else { |
131: game_ . window . set ( sc . x , sc . y , '~' , TB_BLUE , TB_BLACK ) ; |
132: } |
133: } |
134: } |
135: } |
136: } |
137: |
138: for ( int xEdge : { - 1 , 1 } ) { |
139: int x = ( xEdge == - 1 ) ? b . left : ( b . left + b . width - 1 ) ; |
140: for ( int y = b . top - b . height + 1 ; y <= b . top ; y ++ ) { |
141: double mag = cos ( tick * 0.03 ) ; |
142: int depth = 1 + ( int ) ( 2 + 2 * mag * sin ( tick * 0.01 + y * 0.1 ) ) ; |
143: for ( int dx = 0 ; dx < depth ; dx ++ ) { |
144: vec2i p { x - dx * xEdge , y } ; |
145: vec2i sc = game_ . screenCoord ( p ) ; |
146: if ( game_ . onScreen ( p ) ) { |
147: if ( fg ) { |
148: char c = ( dx == depth - 1 ) ? '~' : hash ( p ) % 4 == 0 ? '~' : ' ' ; |
149: game_ . window . set ( sc . x , sc . y , c , TB_WHITE , TB_BLUE ) ; |
150: } else { |
151: game_ . window . set ( sc . x , sc . y , '~' , TB_BLUE , TB_BLACK ) ; |
152: } |
153: } |
154: } |
155: } |
156: } |
157: } |
158: } |