A very jank circle algorithm that overdraws many of the lines but mostly works.
This commit is contained in:
		
							parent
							
								
									d4b6c35120
								
							
						
					
					
						commit
						d916d1c383
					
				
					 5 changed files with 93 additions and 8 deletions
				
			
		|  | @ -5,7 +5,7 @@ | |||
|     "PLAYER_TILE": "\ua66b", | ||||
|     "ENEMY_TILE": "\u1d5c", | ||||
|     "BG_TILE": "█", | ||||
|     "WATER_TILE": "\u26c6" | ||||
|     "WATER_TILE": "\u224b" | ||||
|   }, | ||||
|   "enemy": { | ||||
|     "HEARING_DISTANCE": 8 | ||||
|  |  | |||
							
								
								
									
										52
									
								
								matrix.cpp
									
										
									
									
									
								
							
							
						
						
									
										52
									
								
								matrix.cpp
									
										
									
									
									
								
							|  | @ -179,6 +179,58 @@ namespace matrix { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   circle::circle(Point center, int radius) : | ||||
|     center(center), radius(radius) | ||||
|   { | ||||
|     xi = 0; | ||||
|     yi = radius; | ||||
|     m = 5 - 4 * radius; | ||||
|     step = 0; | ||||
|   } | ||||
| 
 | ||||
|   void circle::update() { | ||||
|     if(m > 0) { | ||||
|       yi--; | ||||
|       m -= 8 * yi; | ||||
|     } | ||||
|     xi++; | ||||
|     m += 8 * xi + 4; | ||||
|   } | ||||
| 
 | ||||
|   bool circle::next() { | ||||
|     if(xi <= yi) { | ||||
|       switch(step % 4) { | ||||
|         case 0: | ||||
|           x0 = center.x - xi; | ||||
|           y = center.y - yi; | ||||
|           x1 = center.x + xi; | ||||
|           break; | ||||
|         case 1: | ||||
|           x0 = center.x - yi; | ||||
|           y = center.y - xi; | ||||
|           x1 = center.x + yi; | ||||
|           break; | ||||
|         case 2: | ||||
|           x0 = center.x - yi; | ||||
|           y = center.y + xi; | ||||
|           x1 = center.x + yi; | ||||
|           break; | ||||
|         case 3: | ||||
|           x0 = center.x - xi; | ||||
|           y = center.y + yi; | ||||
|           x1 = center.x + xi; | ||||
|           update(); | ||||
|           break; | ||||
|       } | ||||
| 
 | ||||
|       step++; | ||||
|       return true; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void dump(const std::string &msg, Matrix &map, int show_x, int show_y) { | ||||
|     println("----------------- {}", msg); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										16
									
								
								matrix.hpp
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								matrix.hpp
									
										
									
									
									
								
							|  | @ -108,4 +108,20 @@ namespace matrix { | |||
|     line(Point start, Point end); | ||||
|     bool next(); | ||||
|   }; | ||||
| 
 | ||||
|   struct circle { | ||||
|     Point center; | ||||
|     int radius = 0; | ||||
|     int xi = 0; | ||||
|     int yi = 0; | ||||
|     int m = 0; | ||||
|     int step = 0; | ||||
|     int x0; | ||||
|     int x1; | ||||
|     int y; | ||||
| 
 | ||||
|     circle(Point center, int radius); | ||||
|     void update(); | ||||
|     bool next(); | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -5,23 +5,18 @@ TODAY'S GOAL: | |||
| * Flame pillars icon \u2e3e | ||||
| * Room should always be found. | ||||
| 
 | ||||
| * Change the test matrix to be irregular dimensions. | ||||
| * Study https://github.com/hirdrac/gx_lib/blob/main/gx/Unicode.hh | ||||
| * Study this https://en.cppreference.com/w/cpp/language/explicit | ||||
| * Study https://en.cppreference.com/w/cpp/language/member_functions#Special_member_functions | ||||
| 
 | ||||
| * Light should flood using the dijkstra map rather than use a box. | ||||
| 
 | ||||
| -1. Learn std::initializer_list by using it. | ||||
| 0. \ua3fd causes the character immediately after to vanish. Make a test and solve it. | ||||
| 1. Why do Sliders only have to be kept around forever and can't go in containers like everything else? | ||||
| 
 | ||||
| * Make a for-loop generator thing, and figure out whatever this magic matrix-processing-without-for-loops tech is (that probably doesn't exist). | ||||
| 
 | ||||
| "you could make an iterator type that you create with the Matrix & a box - then it iterates though each row/column and updates its x/y values. More code over all but loops like you're doing now could be simpler" | ||||
| 
 | ||||
| TODO: | ||||
| 
 | ||||
| * Add a char lookup input to the designer. | ||||
| 
 | ||||
| * Make the light directional. | ||||
| 
 | ||||
| * Hot key for debug view. | ||||
|  |  | |||
|  | @ -224,3 +224,25 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") { | |||
|     REQUIRE(f_found); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("prototype circle algorithm", "[matrix:circle]") { | ||||
|   size_t width = Random::uniform<size_t>(10, 13); | ||||
|   size_t height = Random::uniform<size_t>(10, 15); | ||||
|   Map map(width,height); | ||||
|   // create a target for the paths
 | ||||
|   Point start{.x=map.width() / 2, .y=map.height()/2}; | ||||
| 
 | ||||
|   for(int radius = 2; radius < 5; radius++) { | ||||
|     // use an empty map
 | ||||
|     Matrix result = map.walls(); | ||||
| 
 | ||||
|     for(matrix::circle it{start, radius}; it.next();) { | ||||
|       println("y={}, x0={}, x1={}", it.y, it.x0, it.x1); | ||||
|       for(int i = it.x0; i < it.x1; i++) { | ||||
|         result[it.y][i] += 1; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     matrix::dump("RESULT AFTER CIRCLE", result, start.x, start.y); | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Zed A. Shaw
						Zed A. Shaw