void OnShown(object sender, EventArgs ee) { // Note: Events are fired in the order (Load, Activated, Shown), // It is said that using a MessageBox() can perturb the order of these events, // causing Shown to occur before Load. // http://stackoverflow.com/questions/3070163/order-of-form-load-form-shown-and-form-activated-events // It is also said that "depending on the order of events fired" is undesirable / bad style; // so perhaps once I understand what the idiomatic alternative would be, // this should be changed. // // To call any GL methods (such as setting the GL Viewport, or loading textures) // the OpenGL system must be initialized, which occurs upon the 'Load' event // firing for a Form which contains a GLControl. // http://www.opentk.com/doc/chapter/2/glcontrol // See also, regarding OpenTK.Graphics.GraphicsContext: // http://www.opentk.com/book/export/html/140 // // For this reason, the GL setup, and GL texture loading (via TileSheet constructor calls) // code has been moved here, in a method we set up to be called upon the 'Shown' event // (which is fired upon the first display of this Form). ts = new TileSheet(@"Main/U4.B_enhanced-32x32.png", 16, 16); // causes GL textures to be loaded, needs some GL setup prior... f1234 = new TileSheet(@"Main/example_all_facings.4_frames.intra_1.png", 4, 9, 32, 32, 1, 1, 1, 1); ui_ts = new TileSheet(@"Main/bright_marquee.frame_1.png", 4, 4); // Sprite ID 272 is the reticle //ui_ts = new TileSheet(@"Main/bright_marquee.frame_1.alpha.png", 4, 4); // Hmmm...not quite right... //ui_ts = new TileSheet(@"Main/bright_marquee.frame_1.alpha.2.png", 4, 4); // Hmmm...not quite right... wp_ts = new TileSheet(@"Main/whirlpool_bright.png", 4, 1); // TODO: // After setting up all these AnimTileSprite instances, the utility is clear for // various constructor overloads which infer the wanted StaticTileSprite IDs... AnimTileSprite anim_blue_wiz = new AnimTileSprite(ts, ts[32], ts[33]); AnimTileSprite anim_red_wiz = new AnimTileSprite(ts, ts[0, 14], ts[1, 14], ts[2, 14], ts[3, 14]); // Counters for 3 frames (A,B,C) and for 4 frames (1,2,3,4) // This illustrates why the master frame cycle need be the Least Common Multiple of (3,4) // (or whatever other set of ITileSprite.num_frames values). AnimTileSprite count_ABC = new AnimTileSprite(ts, ts[0, 6], ts[1, 6], ts[2, 6]); AnimTileSprite count_1234 = new AnimTileSprite(f1234, f1234[0, 0], f1234[1, 0], f1234[2, 0], f1234[3, 0]); AnimTileSprite whirlpool = new AnimTileSprite(wp_ts, wp_ts[0], wp_ts[1], wp_ts[2], wp_ts[3]); LF = new TileSheet(@"Main/lava.wave_down.speed_4.frames_8.png", 8, 1); // LF == LavaFlow AnimTileSprite lava_flow = new AnimTileSprite(LF, LF[0], LF[1], LF[2], LF[3], LF[4], LF[5], LF[6], LF[7]); // TileSheet TW = new TileSheet(@"Main/example_wave_test.intra_1.png", 1, 9); // Will need WaveTileSprite to support this... int[] path_rect_5x4 = new int[] { // 5 = grass, 7 = trees, 58 = boulder 58, 5, 5, 7, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 0, 5, 5, 7, 5, 5, }; int lava_ID = ts[12, 4].ID; // Lava //DenseGrid map_16x64 = new DenseGrid(16, 64, lava_ID); // StaticTileSprite lava DenseGrid map_16x64 = new DenseGrid(16, 64, lava_flow.ID); // AnimTileSprite flowing lava DenseGrid flip_none = new DenseGrid(5, 4, path_rect_5x4); // Test with width != height, the better to see the rotations and flips DenseGrid flip_we = flip_none.Flip_WE(); DenseGrid flip_ns = flip_none.Flip_NS(); DenseGrid flip_wens = flip_we.Flip_NS(); DenseGrid.BlitFromAOntoB(flip_none, map_16x64, 1, 1); DenseGrid.BlitFromAOntoB(flip_we, map_16x64, 7, 1); DenseGrid.BlitFromAOntoB(flip_ns, map_16x64, 1, 7); DenseGrid.BlitFromAOntoB(flip_wens, map_16x64, 7, 7); DenseGrid flip_none_rot090 = flip_none.Rotate090(); DenseGrid flip_we_rot090 = flip_we.Rotate090(); DenseGrid flip_ns_rot090 = flip_ns.Rotate090(); DenseGrid flip_wens_rot090 = flip_wens.Rotate090(); DenseGrid.BlitFromAOntoB(flip_none_rot090, map_16x64, 1, 52); DenseGrid.BlitFromAOntoB(flip_we_rot090, map_16x64, 7, 52); DenseGrid.BlitFromAOntoB(flip_ns_rot090, map_16x64, 1, 58); DenseGrid.BlitFromAOntoB(flip_wens_rot090, map_16x64, 7, 58); map = new SimpleMapV1(16, 64, ts); map.AddTerrainRegion(map_16x64, 0, 0); //tvp = new TileViewPort(this.tvp_control, // 15, 15, // //ViewPortScrollingConstraint.EntireMap, // ScrollConstraint.CenterTile, // //ViewPortScrollingConstraint.EdgeCorner, // map, 0, 0); tvpc.scroll_constraint = ScrollConstraint.CenterTile; tvpc.set_center(map, 2, 2); // Add some elements to the Beings layer of the Map: // TODO: Still using hard-coded Sprite ID values here... map.layers[MapLayers.Beings].set_contents_at_XY( 8, 7, 21); // Horse map.layers[MapLayers.Beings].set_contents_at_XY( 8, 7, 21); // Horse map.layers[MapLayers.Beings].set_contents_at_XY( 4, 15, 21); // Horse map.layers[MapLayers.Beings].set_contents_at_XY( 8, 20, 33); // Wizard map.layers[MapLayers.Beings].set_contents_at_XY( 3, 25, 70); // Force field map.layers[MapLayers.Beings].set_contents_at_XY(10, 30, 29); // Stair down map.layers[MapLayers.Beings].set_contents_at_XY( 9, 35, 30); // Ruin map.layers[MapLayers.Beings].set_contents_at_XY( 6, 40, 45); // Archer map.layers[MapLayers.Beings].set_contents_at_XY(12, 45, 23); // Purple tiles map.layers[MapLayers.Beings].set_contents_at_XY( 5, 50, 19); // Ship map.layers[MapLayers.Beings].set_contents_at_XY(2, 1, anim_blue_wiz.ID); // Blue Wizard, animated (2 frames) map.layers[MapLayers.Beings].set_contents_at_XY(3, 3, anim_red_wiz.ID); // Red Wizard, animated (4 frames) map.layers[MapLayers.Beings].set_contents_at_XY(4, 1, count_ABC.ID); // 3 frames (A,B,C) map.layers[MapLayers.Beings].set_contents_at_XY(5, 1, count_1234.ID); // 4 frames (1,2,3,4) map.layers[MapLayers.Beings].set_contents_at_XY(0, 0, whirlpool.ID); // Add some elements to the UI_elements layer of the TileViewPort: int reticle = ui_ts[3, 3].ID; // avoiding hard-coding Sprite ID 272 tvpc.layers[ViewPortLayers.UI_Elements].set_contents_at_XY(tvpc.center_x, tvpc.center_y, reticle); // Center tvpc.layers[ViewPortLayers.UI_Elements].set_contents_at_XY(0, 0, reticle); // NW tvpc.layers[ViewPortLayers.UI_Elements].set_contents_at_XY(tvpc.max_x, 0, reticle); // NE tvpc.layers[ViewPortLayers.UI_Elements].set_contents_at_XY(0, tvpc.max_y, reticle); // SW tvpc.layers[ViewPortLayers.UI_Elements].set_contents_at_XY(tvpc.max_x, tvpc.max_y, reticle); // SE }
private void OnPaint(object sender, PaintEventArgs ee) { // Demonstrate the GDI_Draw_Tile() method on top of the main form // Not sure how often such a thing will be wanted for UI purposes, // but it is nice to have the capability. Graphics gg = this.CreateGraphics(); StaticTileSprite spr = ui_ts[3, 3];// ts[8, 1]; // Balloon AnimTileSprite ani = new AnimTileSprite(ts, ts[0, 14], ts[1, 14], ts[2, 14], ts[3, 14]); // Might also get an Image Attributes value, rather than passing null for the last argument... int x1 = 10; int x2 = 10 + 32 + 10; // to the right of the first tile int y1 = 512 + 10 + 10 + 13 + 10; // below the TVPC spr.GDI_Draw_Tile(gg, x1, y1, null); ani.GDI_Draw_Tile(gg, x2, y1, null, tvpc.frame); // Demonstrate an animated tile via GDI }