private void AddNextDualPortal() { //WriteLine("Orange View: " + PortalADir.RadiansToDegrees()); //WriteLine("Blue View: " + PortalBDir.RadiansToDegrees()); #region create a dual portal var PortalA = new PortalInfo { Color = 0xFF6A00, }.AddTo(Portals); EgoView.Sprites.Add(PortalA.Sprite); var PortalB = new PortalInfo { Color = 0xff00, }.AddTo(Portals); EgoView.Sprites.Add(PortalB.Sprite); #endregion DualPortals.Add(new DualPortal { Orange = PortalA, Blue = PortalB }); }
private void Initialize() { txtMain = new TextField { defaultTextFormat = new TextFormat { font = "Verdana", align = TextFormatAlign.LEFT, size = 10, color = 0xffffff }, autoSize = TextFieldAutoSize.LEFT, text = "0" }; AddFullscreenMenu(); EgoView = new ViewEngineBase(DefaultWidth, DefaultHeight) { FloorAndCeilingVisible = false, ViewPosition = new Point { x = 4, y = 22 }, ViewDirection = 90.DegreesToRadians(), }; var Portals = new List<PortalInfo>(); EgoView.ViewDirectionChanged += () => Portals.ForEach(Portal => Portal.View.ViewDirection = EgoView.ViewDirection); #region create a dual portal var PortalA = new PortalInfo { Color = 0xFF6A00, ViewVector = new Vector { Direction = EgoView.ViewDirection, Position = new Point { x = 4.5, y = 14 } }, SpriteVector = new Vector { Direction = EgoView.ViewDirection, Position = new Point { x = 3.5, y = 20 } }, }.AddTo(Portals); EgoView.Sprites.Add(PortalA.Sprite); var PortalB = new PortalInfo { Color = 0xff00, ViewVector = PortalA.SpriteVector, SpriteVector = PortalA.ViewVector, }.AddTo(Portals); EgoView.Sprites.Add(PortalB.Sprite); #endregion var Ego = default(SpriteInfo); EgoView.ViewPositionChanged += delegate { foreach (var Portal in Portals) { var p = EgoView.SpritesFromPointOfView.SingleOrDefault(i => i.Sprite == Portal.Sprite); if (p != null) { if (p.Distance < Portal.Sprite.Range) { // we are going thro the portal, show it new Bitmap(EgoView.Buffer.clone()) { scaleX = DefaultScale, scaleY = DefaultScale }.AttachTo(this).FadeOutAndOrphanize(1000 / 24, 0.2); Assets.SoundFiles.teleport.ToSoundAsset().play(); // fixme: should use Ego.MovementDirection instead // currently stepping backwards into the portal will behave recursivly EgoView.ViewPosition = Portal.View.ViewPosition.MoveToArc(EgoView.ViewDirection, Portal.Sprite.Range + p.Distance); break; } } } }; var CameraView = new ViewEngineBase(64, 48) { }; EgoView.RenderOverlay += DrawMinimap; EgoView.FramesPerSecondChanged += () => txtMain.text = EgoView.FramesPerSecond + " fps " + new { EgoView.ViewPositionX, EgoView.ViewPositionY }; EgoView.Image.AttachTo(this); txtMain.AttachTo(this); EgoView.Image.scaleX = DefaultScale; EgoView.Image.scaleY = DefaultScale; //this.filters = new[] { new BlurFilter() }; KeyboardButton fKeyTurnLeft = new uint[] { Keyboard.LEFT, 'j', 'J', }; KeyboardButton fKeyTurnRight = new uint[] { Keyboard.RIGHT, 'l', 'L', }; KeyboardButton fKeyStrafeLeft = new uint[] { 'a', 'A' }; KeyboardButton fKeyStrafeRight = new uint[] { 'd', 'D' }; KeyboardButton fKeyUp = new uint[] { Keyboard.UP, 'i', 'I', 'w', 'W' }; KeyboardButton fKeyDown = new uint[] { Keyboard.DOWN, 'k', 'K', 's', 'S' }; stage.keyDown += e => { var key = e.keyCode; fKeyStrafeLeft.ProcessKeyDown(key); fKeyStrafeRight.ProcessKeyDown(key); fKeyTurnLeft.ProcessKeyDown(key); fKeyTurnRight.ProcessKeyDown(key); fKeyUp.ProcessKeyDown(key); fKeyDown.ProcessKeyDown(key); }; stage.keyUp += e => { var key = e.keyCode; fKeyStrafeLeft.ProcessKeyUp(key); fKeyStrafeRight.ProcessKeyUp(key); fKeyTurnLeft.ProcessKeyUp(key); fKeyTurnRight.ProcessKeyUp(key); fKeyUp.ProcessKeyUp(key); fKeyDown.ProcessKeyUp(key); }; Action UpdateEgoPosition = delegate { if (Ego != null) { Ego.Position = EgoView.ViewPosition; Ego.Direction = EgoView.ViewDirection; } }; EgoView.ViewPositionChanged += delegate { UpdateEgoPosition(); }; (1000 / 30).AtInterval( delegate { if (fKeyTurnRight.IsPressed) EgoView.ViewDirection += 10.DegreesToRadians(); else if (fKeyTurnLeft.IsPressed) EgoView.ViewDirection -= 10.DegreesToRadians(); if (fKeyUp.IsPressed || fKeyStrafeLeft.IsPressed || fKeyStrafeRight.IsPressed) { var d = EgoView.ViewDirection; if (fKeyStrafeLeft.IsPressed) d -= 90.DegreesToRadians(); else if (fKeyStrafeRight.IsPressed) d += 90.DegreesToRadians(); EgoView.MoveTo( EgoView.ViewPositionX + Math.Cos(d) * 0.2, EgoView.ViewPositionY + Math.Sin(d) * 0.2 ); } else if (fKeyDown.IsPressed) EgoView.MoveTo( EgoView.ViewPositionX + Math.Cos(EgoView.ViewDirection) * -0.2, EgoView.ViewPositionY + Math.Sin(EgoView.ViewDirection) * -0.2 ); } ); var UpdatePortals = true; stage.keyUp += e => { if (e.keyCode == Keyboard.V) { UpdatePortals = !UpdatePortals; } if (e.keyCode == Keyboard.N) { EgoView.RenderLowQualityWalls = !EgoView.RenderLowQualityWalls; } if (e.keyCode == Keyboard.M) { DrawMinimapEnabled = !DrawMinimapEnabled; } if (e.keyCode == Keyboard.B) { EgoView.SpritesVisible = !EgoView.SpritesVisible; } if (e.keyCode == Keyboard.F) { EgoView.FloorAndCeilingVisible = !EgoView.FloorAndCeilingVisible; } if (e.keyCode == Keyboard.DELETE) { EgoView.Sprites.RemoveAll(p => p != Ego); } }; Action<Bitmap[]> BitmapsLoadedAction = Bitmaps => { if (Bitmaps == null) throw new Exception("No bitmaps"); Func<Texture64[], Texture64[]> Reorder8 = p => Enumerable.ToArray( from i in Enumerable.Range(0, 8) select p[(i + 6) % 8] ); var BitmapStream = Bitmaps.Select(i => (Texture64)i).GetEnumerator(); Func<Texture64[]> Next8 = delegate { // keeping compiler happy with full delegate form if (BitmapStream == null) throw new Exception("BitmapStream is null"); return Reorder8(BitmapStream.Take(8)); }; var Stand = Next8(); var Spawn = default(Func<SpriteInfo>); if (Bitmaps.Length == 8) { Spawn = () => CreateWalkingDummy(Stand); } else { var Walk = new[] { Next8(), Next8(), Next8(), Next8(), }; Spawn = () => CreateWalkingDummy(Stand, Walk); } Ego = Spawn(); UpdateEgoPosition(); stage.keyUp += e => { if (e.keyCode == Keyboard.SPACE) { var s = Spawn(); //s.Direction += 180.DegreesToRadians(); CameraView.ViewPosition = s.Position; CameraView.ViewDirection = s.Direction; } if (e.keyCode == Keyboard.INSERT) { var s = Spawn(); s.Direction += 180.DegreesToRadians(); s.Position = Ego.Position.MoveToArc(Ego.Direction, 0.5); } if (e.keyCode == Keyboard.ENTER) { EgoView.ViewPosition = new Point { x = 4, y = 22 }; EgoView.ViewDirection = 270.DegreesToRadians(); } if (e.keyCode == Keyboard.BACKSPACE) { (1000 / 30).AtInterval( t => { EgoView.ViewDirection += 18.DegreesToRadians(); if (t.currentCount == 10) t.stop(); } ); } }; }; Assets.ZipFiles.MyZipFile .ToFiles() .Where(f => f.FileName.EndsWith(".png")) .ToBitmapArray(BitmapsLoadedAction); Assets.ZipFiles.MyStuff.ToFiles().ToBitmapDictionary( f => { // ! important // ---------------------------------------------------- // ! loading png via bytes affects pixel values // ! this is why map is in gif format EgoView.Map.WorldMap = Texture32.Of(f["Map1.gif"], false); Action<IEnumerator<Texture64.Entry>, Texture64, Action<SpriteInfo>> AddSpriteByTexture = (SpaceForStuff, tex, handler) => SpaceForStuff.Take().Do(p => CreateDummy(tex).Do(handler).Position.To(p.XIndex + 0.5, p.YIndex + 0.5)); var FreeSpaceForStuff = EgoView.Map.WorldMap.Entries.Where(i => i.Value == 0).Randomize().GetEnumerator(); Action<Bitmap> AddSprite = e => AddSpriteByTexture(FreeSpaceForStuff, e, null); Assets.ZipFiles.MySprites.ToFiles().ToBitmapArray( sprites => { foreach (var s in sprites) { for (int i = 0; i < 3; i++) { AddSprite(s); } } } ); #region gold Assets.ZipFiles.MyGold.ToFiles().ToBitmapArray( sprites => { var GoldSprites = new List<SpriteInfo>(); foreach (var s in sprites) { for (int i = 0; i < 20; i++) { // compiler bug: get a delegate to BCL class //AddSpriteByTexture(FreeSpaceForStuff, s, GoldSprites.Add); AddSpriteByTexture(FreeSpaceForStuff, s, k => { k.Range = 0.5; GoldSprites.Add(k); } ); } } var LastPosition = new Point(); EgoView.ViewPositionChanged += delegate { // only check for items each 0.5 distance travelled if ((EgoView.ViewPosition - LastPosition).length < 0.5) return; Action Later = delegate { }; foreach (var Item in EgoView.SpritesFromPointOfView) { var Item_Sprite = Item.Sprite; if (Item.Distance < Item_Sprite.Range) { if (GoldSprites.Contains(Item_Sprite)) { // ding-ding-ding! new Bitmap(new BitmapData(DefaultWidth, DefaultHeight, false, 0xffff00)) { scaleX = DefaultScale, scaleY = DefaultScale }.AttachTo(this).FadeOutAndOrphanize(1000 / 24, 0.2); InternalGotGold(); Later += () => EgoView.Sprites.Remove(Item_Sprite); } } } Later(); LastPosition = EgoView.ViewPosition; }; } ); #endregion #region ammo Assets.ZipFiles.ammo.ToFiles().ToBitmapArray( sprites => { var AmmoSprites = new List<SpriteInfo>(); foreach (var s in sprites) { for (int i = 0; i < 20; i++) { // compiler bug: get a delegate to BCL class //AddSpriteByTexture(FreeSpaceForStuff, s, GoldSprites.Add); AddSpriteByTexture(FreeSpaceForStuff, s, k => { k.Range = 0.5; AmmoSprites.Add(k); } ); } } var LastPosition = new Point(); EgoView.ViewPositionChanged += delegate { // only check for items each 0.5 distance travelled if ((EgoView.ViewPosition - LastPosition).length < 0.5) return; Action Later = delegate { }; foreach (var Item in EgoView.SpritesFromPointOfView) { var Item_Sprite = Item.Sprite; if (Item.Distance < Item_Sprite.Range) { if (AmmoSprites.Contains(Item_Sprite)) { // ding-ding-ding! new Bitmap(new BitmapData(DefaultWidth, DefaultHeight, false, 0x8080ff)) { scaleX = DefaultScale, scaleY = DefaultScale }.AttachTo(this).FadeOutAndOrphanize(1000 / 24, 0.2); InternalGotAmmo(); Later += () => EgoView.Sprites.Remove(Item_Sprite); } } } Later(); LastPosition = EgoView.ViewPosition; }; } ); #endregion Func<string, Texture64> t = texname => f[texname + ".png"]; EgoView.FloorTexture = t("floor"); EgoView.CeilingTexture = t("roof"); var DynamicTextureBitmap = new Bitmap(new BitmapData(Texture64.SizeConstant, Texture64.SizeConstant, false, 0)); Texture64 DynamicTexture = DynamicTextureBitmap; uint DynamicTextureKey = 0xffffff; EgoView.Map.WorldMap[2, 22] = DynamicTextureKey; EgoView.Map.WorldMap[3, 15] = DynamicTextureKey; EgoView.Map.Textures = new Dictionary<uint, Texture64> { {0xff0000, t("graywall")}, {0x0000ff, t("bluewall")}, {0x00ff00, t("greenwall")}, {0x7F3300, t("woodwall")}, {DynamicTextureKey, DynamicTexture} }; if (EgoView.CurrentTile != 0) throw new Exception("bad start position: " + new { EgoView.ViewPositionX, EgoView.ViewPositionY, EgoView.CurrentTile }.ToString()); CameraView.Map.WorldMap = EgoView.Map.WorldMap; CameraView.Map.Textures = EgoView.Map.Textures; CameraView.Sprites = EgoView.Sprites; CameraView.ViewPosition = EgoView.ViewPosition; foreach (var Portal in Portals) { Portal.View.Map.WorldMap = EgoView.Map.WorldMap; Portal.View.Map.Textures = EgoView.Map.Textures; Portal.View.Sprites = EgoView.Sprites; Portal.AlphaMask = f["portalmask.png"]; } EgoView.RenderScene(); var MirrorFrame = f["mirror.png"]; var counter = 0; stage.enterFrame += e => { counter++; if (UpdatePortals) { // updateing it too often causes framerate to drop foreach (var Portal in Portals) { Portal.Update(); } DynamicTextureBitmap.bitmapData.fillRect(DynamicTextureBitmap.bitmapData.rect, (uint)(counter * 8 % 256)); var m = new Matrix(); // to center m.translate(0, 10); // m.scale(0.3, 0.3); CameraView.RenderScene(); DynamicTextureBitmap.bitmapData.draw(CameraView.Image.bitmapData, m); DynamicTextureBitmap.bitmapData.draw(MirrorFrame.bitmapData); DynamicTexture.Update(); } EgoView.RenderScene(); }; } ); AttachMovementInput(EgoView); }