2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  resolv  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Space represents a collision space. Internally, each Space contains a 2D array of Cells, with each Cell being the same size. Cells contain information on which  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Objects occupy those spaces.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Space  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Cells                  [ ] [ ] * Cell 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CellWidth ,  CellHeight  int  // Width and Height of each Cell in "world-space" / pixels / whatever 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewSpace creates a new Space. spaceWidth and spaceHeight is the width and height of the Space (usually in pixels), which is then populated with cells of size  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// cellWidth by cellHeight. Generally, you want cells to be the size of the smallest collide-able objects in your game, and you want to move Objects at a maximum  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// speed of one cell size per collision check to avoid missing any possible collisions.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewSpace ( spaceWidth ,  spaceHeight ,  cellWidth ,  cellHeight  int )  * Space  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:20:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sp  :=  & Space { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sp . CellWidth  =  cellWidth 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sp . CellHeight  =  cellHeight 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sp . Resize ( spaceWidth / cellWidth ,  spaceHeight / cellHeight ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// [WARNING] The slice type boxing/unboxing is proved by profiling to be heavy after transpiled to JavaScript, thus adding some "XxxSingle" shortcuts here.  
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Add adds the specified Objects to the Space, updating the Space's cells to refer to the Object.  
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sp  * Space )  AddSingle ( obj  * Object )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sp  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "ERROR: space is nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									obj . Space  =  sp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We call Update() once to make sure the object gets its cells added. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									obj . Update ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Add ( objects  ... * Object )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sp  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "ERROR: space is nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  obj  :=  range  objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj . Space  =  sp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We call Update() once to make sure the object gets its cells added. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj . Update ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Remove removes the specified Objects from being associated with the Space. This should be done whenever an Object is removed from the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// game.  
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sp  * Space )  RemoveSingle ( obj  * Object )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sp  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "ERROR: space is nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  0  <  obj . TouchingCells . Cnt  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cell  :=  obj . TouchingCells . Pop ( ) . ( * Cell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cell . unregister ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									obj . Space  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Remove ( objects  ... * Object )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sp  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( "ERROR: space is nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  obj  :=  range  objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  0  <  obj . TouchingCells . Cnt  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cell  :=  obj . TouchingCells . Pop ( ) . ( * Cell ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											cell . unregister ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj . Space  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Objects loops through all Cells in the Space (from top to bottom, and from left to right) to return all Objects  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// that exist in the Space. Of course, each Object is counted only once.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Objects ( )  [ ] * Object  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectsAdded  :=  map [ * Object ] bool { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objects  :=  [ ] * Object { } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:20:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cyUpper  :=  len ( sp . Cells ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  cy  :=  0 ;  cy  <  cyUpper ;  cy ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cxUpper  :=  len ( sp . Cells [ cy ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  cx  :=  0 ;  cx  <  cxUpper ;  cx ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rb  :=  sp . Cells [ cy ] [ cx ] . Objects 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  i  :=  rb . StFrameId ;  i  <  rb . EdFrameId ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												o  :=  rb . GetByFrameId ( i ) . ( * Object ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  _ ,  added  :=  objectsAdded [ o ] ;  ! added  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													objects  =  append ( objects ,  o ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													objectsAdded [ o ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  objects 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Resize resizes the internal Cells array.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Resize ( width ,  height  int )  {  
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sp . Cells  =  make ( [ ] [ ] * Cell ,  height ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  y  :=  0 ;  y  <  height ;  y ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sp . Cells [ y ]  =  make ( [ ] * Cell ,  width ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										for  x  :=  0 ;  x  <  width ;  x ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											sp . Cells [ y ] [ x ]  =  newCell ( x ,  y ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( sp  * Space )  GetCell ( x ,  y  int )  * Cell  {  
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  y  >=  0  &&  y  <  len ( sp . Cells )  &&  x  >=  0  &&  x  <  len ( sp . Cells [ y ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  sp . Cells [ y ] [ x ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// CheckCells checks a set of cells (from x,y to x + w, y + h in cellular coordinates) and return the first object within those Cells that contains any of the tags given.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If no tags are given, then CheckCells will return the first Object found in any Cell.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  CheckCells ( x ,  y ,  w ,  h  int ,  tags  ... string )  * Object  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ix  :=  x ;  ix  <  x + w ;  ix ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  iy  :=  y ;  iy  <  y + h ;  iy ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cell  :=  sp . GetCell ( ix ,  iy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  cell  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rb  :=  cell . Objects 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  len ( tags )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  cell . ContainsTags ( tags ... )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														for  i  :=  rb . StFrameId ;  i  <  rb . EdFrameId ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															obj  :=  rb . GetByFrameId ( i ) . ( * Object ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															if  obj . HasTags ( tags ... )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																return  obj 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  cell . Occupied ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  rb . GetByFrameId ( rb . StFrameId ) . ( * Object ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// CheckCellsWorld checks the cells of the Grid with the given world coordinates.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Internally, this is just syntactic sugar for calling Space.WorldToSpace() on the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// position and size given.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  CheckCellsWorld ( x ,  y ,  w ,  h  float64 ,  tags  ... string )  * Object  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sx ,  sy  :=  sp . WorldToSpace ( x ,  y ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cw ,  ch  :=  sp . WorldToSpace ( w ,  h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sp . CheckCells ( sx ,  sy ,  cw ,  ch ,  tags ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// UnregisterAllObjects unregisters all Objects registered to Cells in the Space.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  UnregisterAllObjects ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  y  :=  0 ;  y  <  len ( sp . Cells ) ;  y ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  x  :=  0 ;  x  <  len ( sp . Cells [ y ] ) ;  x ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cell  :=  sp . Cells [ y ] [ x ] 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 12:02:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rb  :=  cell . Objects 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  i  :=  rb . StFrameId ;  i  <  rb . EdFrameId ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												o  :=  rb . GetByFrameId ( i ) . ( * Object ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sp . RemoveSingle ( o ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WorldToSpace converts from a world position (x, y) to a position in the Space (a grid-based position).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  WorldToSpace ( x ,  y  float64 )  ( int ,  int )  {  
						 
					
						
							
								
									
										
										
										
											2023-03-01 18:20:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// [WARNING] DON'T use "int(...)" syntax to convert float to int, it's not supported by go2cs! 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  fx  int  =  ( int ) ( Floor ( x  /  float64 ( sp . CellWidth ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  fy  int  =  ( int ) ( Floor ( y  /  float64 ( sp . CellHeight ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  fx ,  fy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SpaceToWorld converts from a position in the Space (on a grid) to a world-based position, given the size of the Space when first created.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  SpaceToWorld ( x ,  y  int )  ( float64 ,  float64 )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fx  :=  float64 ( x  *  sp . CellWidth ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fy  :=  float64 ( y  *  sp . CellHeight ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fx ,  fy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Height returns the height of the Space grid in Cells (so a 320x240 Space with 16x16 cells would have a height of 15).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Height ( )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  len ( sp . Cells ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Width returns the width of the Space grid in Cells (so a 320x240 Space with 16x16 cells would have a width of 20).  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  Width ( )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( sp . Cells )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  len ( sp . Cells [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( sp  * Space )  CellsInLine ( startX ,  startY ,  endX ,  endY  int )  [ ] * Cell  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cells  :=  [ ] * Cell { } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cell  :=  sp . GetCell ( startX ,  startY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									endCell  :=  sp . GetCell ( endX ,  endY ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cell  !=  nil  &&  endCell  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dv  :=  Vector { float64 ( endX  -  startX ) ,  float64 ( endY  -  startY ) } . Unit ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dv [ 0 ]  *=  float64 ( sp . CellWidth  /  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dv [ 1 ]  *=  float64 ( sp . CellHeight  /  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pX ,  pY  :=  sp . SpaceToWorld ( startX ,  startY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p  :=  Vector { pX  +  float64 ( sp . CellWidth / 2 ) ,  pY  +  float64 ( sp . CellHeight / 2 ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										alternate  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  cell  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  cell  ==  endCell  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cells  =  append ( cells ,  cell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cells  =  append ( cells ,  cell ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  alternate  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p [ 1 ]  +=  dv [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p [ 0 ]  +=  dv [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cx ,  cy  :=  sp . WorldToSpace ( p [ 0 ] ,  p [ 1 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-02 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											c  :=  sp . GetCell ( cx ,  cy ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-25 18:44:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  c  !=  cell  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cell  =  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											alternate  =  ! alternate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cells 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}