Stars

When I was a kid, I had an Amiga 500 – and I absolutely loved watching demos, especially when they had starfields…I saw the evolution of simple parallax starfields out to more complex starfields that you would fly through and they would rotate and do all-sorts of snazzy things.

Roll on 2015 and I still haven’t grown up…I still love starfields. I was preparing some content for the AU/NZ User group conference (IMUN) so I thought I would have some fun!

Sadly, due to some technical issues I was unable to demonstrate my pride and joy (and infact had to compress an already compressed death-by-PowerPoint presentation down to about 25 minutes from 40).

But given I feel it is my duty to relieve the boredom and monotony of ERP, I present you an animated starfield that demonstrates the area the controller.RenderEngine.Content object encompasses.

(most of the code is adapted from http://codentronix.com/2011/07/22/html5-canvas-3d-starfield/ and no, it isn’t optimised or really commented because it was really done for amusement 🙂 )

Enjoy!

import System;
import System.Windows;
import System.Windows.Controls;
import MForms;

import System.Windows.Media;
import System.Windows.Shapes;
import System.Windows.Media.Imaging;

import System.Windows.Threading;

package MForms.JScript
{
	class stars2
	{
		var MAX_DEPTH = 32;
	 
		//var canvas, ctx;
		var stars = new Array(512);
		var pi2 = Math.PI*2;
		
		// the density of the starfield
		var density = 256.0;
	
		var gContent;
		var gDebug;

		var gdtTimer : DispatcherTimer = null;
		
		public function Init(element: Object, args: Object, controller : Object, debug : Object)
		{
			gContent = controller.RenderEngine.Content;
			gDebug = debug;
			initStars();
			
			gdtTimer = new DispatcherTimer(System.Windows.Threading.DispatcherPriority.Background, System.Windows.Threading.Dispatcher.CurrentDispatcher);
			gdtTimer.Interval = new TimeSpan(1000);
			gdtTimer.add_Tick(dispatcher_Tick);
			gdtTimer.IsEnabled = true;
		}
		
		private function dispatcher_Tick(sender : Object, e : EventArgs)
		{
			//gDebug.Debug("Tick");
			loop();
		}		
		
    /* Returns a random number in the range [minVal,maxVal] */
    function randomRange(minVal,maxVal) {
      return Math.floor(Math.random() * (maxVal - minVal - 1)) + minVal;
    }
 
    function initStars() {
      for( var i = 0; i < stars.length; i++ ) {
        stars[i] = {
          x: randomRange(-25,25),
          y: randomRange(-25,25),
          z: randomRange(1,MAX_DEPTH)
         }
      }
    }
 

		
		function loop()
		{
			var halfWidth  = gContent.ActualWidth / 2;
			var halfHeight = gContent.ActualHeight / 2;
			
			// https://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap.aspx
			var bitmap = new RenderTargetBitmap(gContent.ActualWidth, gContent.ActualHeight, 0, 0, PixelFormats.Pbgra32);
			
			var drawingVisual = new DrawingVisual();
			var drawingContext = drawingVisual.RenderOpen();
			
			drawingContext.DrawRectangle(new SolidColorBrush(Color.FromRgb(0, 0, 0, 0)), null, new Rect(0, 0, gContent.ActualWidth, gContent.ActualHeight));

			// we do a sort so that far away stars don't overwrite nearer stars
			//stars.sort(mycompare);
			//gDebug.WriteLine("Stars Array length = " + stars.length);
			for( var i = 0; i < stars.length; i++ ) 
			{
				stars[i].z -= 0.2;

				if( stars[i].z <= 0 ) 
				{
				  stars[i].x = randomRange(-25,25);
				  stars[i].y = randomRange(-25,25);
				  stars[i].z = MAX_DEPTH;
				}

				var k  = density / stars[i].z;
				var px = stars[i].x * k + halfWidth;
				var py = stars[i].y * k + halfHeight;

				if( px >= 0 && px <= gContent.ActualWidth && py >= 0 && py <= gContent.ActualHeight ) 
				{
					var size = (1 - stars[i].z / 32.0) * 5;
					var shade = parseInt((1 - stars[i].z / 32.0) * 255);
					
					drawingContext.DrawEllipse(new SolidColorBrush(Color.FromRgb(shade, shade, shade, 0)), null, new Point(px, py), size, size)
				}
			}
			drawingContext.Close();
			bitmap.Render(drawingVisual);
			
			
			gContent.Background = new ImageBrush(bitmap);

		}	

		public function mycompare(a, b) 
		{ 
			return (a.z > b.z) ? -1 : ((b.z > a.z) ? 1 : 0); 
		}		
	}
}

This entry was posted in Development, How Far is Too Far?, Misc. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s