public AnimatedCellBitmapSet(FramerateDelay delay, params CellBitmap[] bitmaps) { Id = Interlocked.Increment(ref _idCounter); Delay = delay.Delay; Bitmaps = bitmaps; _rotatedCloneLazy = new Lazy <AnimatedCellBitmapSet>(() => new AnimatedCellBitmapSet( delay, Bitmaps .Select(x => BitmapExtensions.Get90DegreesRotatedClone(x.Bitmap)) .Select(x => new CellBitmap(x)).ToArray() )); _bitmapEnumerator = Bitmaps.GetInifiniteEnumerator(); _bitmapEnumerator.MoveNext(); }
public PartSetter(Action <string> addCommandAction) { Search = new DelegateCommand(() => { string searchString = Led.ToSearchString(Text); int searchStringLength = searchString.Length; LedPartDefinitionExtension oldDef = null; if (Cur >= 0 && CurrentDefs.Count != 0) { oldDef = CurrentDefs[Cur]; } CurrentDefs = Bitmaps.Select(b => { return(b.Bitmap.Definitions.FindAll(d => { return d.SearchNames.Any(n => { bool isEmpty = searchString == ""; bool isMatchFromStart = false; if (n.Length >= searchStringLength) { isMatchFromStart = n.Substring(0, searchStringLength) == searchString; } return isEmpty || isMatchFromStart; }); }).ConvertAll(d => { return new LedPartDefinitionExtension() { Definition = d, ParentBitmap = b, Y = b.Bitmap.Definitions.IndexOf(d), }; })); }).SelectMany(d => d).ToList(); CanSelect = CurrentDefs.Count < 200; Collection.Clear(); Collection.AddRange(CurrentDefs.ConvertAll(d => $"{d.ParentBitmap.ParentControlName}\\{d.ParentBitmap.ParentPartName}\\{d.ParentBitmap.Bitmap.Name}\\{d.Definition.Name}")); Cur = -1; if (Collection.Count == 0) { Collection.Add("(該当無し)"); Cur = 0; Help = "(候補 0 件 / " + TotalCount + " 件)"; } else if (!CurrentDefs.Contains(oldDef)) { Cur = 0; Help = "(候補 " + Collection.Count + " 件 / " + TotalCount + " 件)"; } else { Cur = CurrentDefs.IndexOf(oldDef); Help = "(候補 " + Collection.Count + " 件 / " + TotalCount + " 件)"; } }); Cancel = new DelegateCommand(() => Text = ""); Down = new DelegateCommand(() => { if (Cur - 1 < Collection.Count) { Cur += 1; } }); Up = new DelegateCommand(() => { if (Cur != 0) { Cur -= 1; } }); Run = new DelegateCommand(() => { if (Cur != -1 && Collection[0] != "(該当無し)") { LedPartDefinitionExtension currentDef = CurrentDefs[Cur]; addCommandAction.Invoke($"{{prt:{currentDef.ParentBitmap.Bitmap.Path},{currentDef.Y},{XIndex}}}"); } }); BindingOperations.EnableCollectionSynchronization(Collection, new object()); }
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); }