123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- MODULE MapEditor;
- IMPORT G := Graph, S := SimpleGui, Out, Int, Strings, E := GameEngine;
- CONST window = FALSE;
- TYPE
- MapWidget = POINTER TO MapWidgetDesc;
- MapWidgetDesc = RECORD(S.WidgetDesc)
- curX, curY: INTEGER
- END;
- TilesetWidget = POINTER TO TilesetWidgetDesc;
- TilesetWidgetDesc = RECORD(S.ScrollBox)
- curTile: INTEGER
- END;
- VAR
- frmMain: S.Form;
- pnlTop: S.Panel;
- lblMapName: S.Label;
- edtMapName: S.Edit;
- btnOpen: S.Button;
- btnSave: S.Button;
- btnExit: S.Button;
- pnlSide: S.Panel;
- sbxMap: S.ScrollBox;
- wgtMap: MapWidget;
- wgtTileset: TilesetWidget;
- game: E.Game;
- PROCEDURE Limit(x, min, max: INTEGER): INTEGER;
- BEGIN
- IF x < min THEN x := min ELSIF x > max THEN x := max END
- RETURN x END Limit;
- (** Map Widget **)
- PROCEDURE MapWidgetHandleDraw(c: S.Widget; VAR msg: S.DrawMsg);
- VAR x: INTEGER;
- X, Y, i, j: INTEGER;
- cx, cy, cw, ch: INTEGER;
- x0, y0, x1, y1: INTEGER;
- col: G.Color;
- m: MapWidget;
- BEGIN
- m := c(MapWidget);
- G.GetClip(cx, cy, cw, ch);
- (*INC(cx, E.cellW * 2);
- INC(cy, E.cellW * 2);
- DEC(cw, E.cellW * 4);
- DEC(ch, E.cellW * 4);*)
- x0 := (cx - msg.x) DIV E.cellW;
- IF x0 < 0 THEN x0 := 0 END;
- y0 := (cy - msg.y) DIV E.cellH;
- IF y0 < 0 THEN y0 := 0 END;
- x1 := (cx - msg.x + cw - 1) DIV E.cellW;
- IF x1 >= game.map.w THEN x1 := game.map.w - 1 END;
- y1 := (cy - msg.y + ch - 1) DIV E.cellH;
- IF y1 >= game.map.h THEN y1 := game.map.h - 1 END;
- G.MakeCol(col, 255, 0, 128);
- G.FillRect(0, 0, 2000, 2000, col);
- x := msg.x + x0 * E.cellW;
- Y := msg.y + y0 * E.cellH;
- FOR i := y0 TO y1 DO
- X := x;
- FOR j := x0 TO x1 DO
- E.DrawCell(game.map.cells[i, j], i, j, X, Y);
- INC(X, E.cellW)
- END;
- INC(Y, E.cellH)
- END;
- IF m.curX >= 0 THEN
- G.MakeCol(col, 240, 0, 0);
- X := msg.x + m.curX * E.cellW;
- Y := msg.y + m.curY * E.cellH;
- G.Rect(X - 1, Y - 1, X + E.cellW, Y + E.cellH, col);
- END
- END MapWidgetHandleDraw;
- (** (x; y) in cells *)
- PROCEDURE OnMapMouseDown(x, y: INTEGER);
- BEGIN
- E.SetCell(game.map, x, y, wgtTileset.curTile);
- S.Redraw(wgtMap)
- END OnMapMouseDown;
- PROCEDURE MapWidgetHandleMouseDown(c: S.Widget; VAR msg: S.MouseDownMsg);
- VAR m: MapWidget;
- x, y: INTEGER;
- BEGIN
- m := c(MapWidget);
- x := Limit(msg.x DIV E.cellW, 0, game.map.w - 1);
- y := Limit(msg.y DIV E.cellH, 0, game.map.h - 1);
- IF msg.btn = 1 THEN
- OnMapMouseDown(x, y)
- END
- END MapWidgetHandleMouseDown;
- PROCEDURE MapWidgetHandleMouseMove(c: S.Widget; VAR msg: S.MouseMoveMsg);
- VAR m: MapWidget;
- x, y: INTEGER;
- BEGIN
- m := c(MapWidget);
- x := Limit(msg.x DIV E.cellW, 0, game.map.w - 1);
- y := Limit(msg.y DIV E.cellH, 0, game.map.h - 1);
- IF (x # m.curX) OR (y # m.curY) THEN
- m.curX := x; m.curY := y;
- IF 1 IN msg.btns THEN
- OnMapMouseDown(x, y)
- END;
- S.Redraw(c)
- END
- END MapWidgetHandleMouseMove;
- PROCEDURE MapWidgetHandler(c: S.Widget; VAR msg: S.Message);
- BEGIN
- IF msg IS S.MouseMoveMsg THEN
- MapWidgetHandleMouseMove(c, msg(S.MouseMoveMsg))
- ELSIF msg IS S.MouseLeaveMsg THEN
- c(MapWidget).curX := -1; S.Redraw(c)
- ELSIF msg IS S.MouseDownMsg THEN
- MapWidgetHandleMouseDown(c, msg(S.MouseDownMsg))
- ELSIF msg IS S.DrawMsg THEN
- MapWidgetHandleDraw(c, msg(S.DrawMsg))
- ELSE
- S.WidgetHandler(c, msg)
- END
- END MapWidgetHandler;
- PROCEDURE NewMapWidget(where: S.Widget; x, y, w, h: INTEGER): MapWidget;
- VAR c: MapWidget;
- BEGIN
- NEW(c); S.InitWidget(c, w, h);
- c.curX := -1; c.curY := 0;
- c.handle := MapWidgetHandler;
- S.Put(c, where, x, y)
- RETURN c END NewMapWidget;
- (** Tileset Widget **)
- PROCEDURE TilesetWidgetOnInnerPaint(c: S.Widget; x, y, w, h: INTEGER);
- VAR col: G.Color;
- n, X, Y: INTEGER;
- t: TilesetWidget;
- BEGIN
- t := c.parent.parent(TilesetWidget);
- G.Draw(E.tiles, x, y);
- G.MakeCol(col, 0, 110, 240);
- X := x + t.curTile MOD E.tilesInRow * E.cellW;
- Y := y + t.curTile DIV E.tilesInRow * E.cellH;
- G.Rect(X, Y, X + E.cellW - 1, Y + E.cellH - 1, col)
- END TilesetWidgetOnInnerPaint;
- PROCEDURE TilesetWidgetOnMouseDown(c: S.Widget; x, y, btn: INTEGER);
- VAR t: TilesetWidget;
- n: INTEGER;
- BEGIN t := c.parent.parent(TilesetWidget);
- IF btn = 1 THEN
- IF x < 0 THEN x := 0 ELSIF x >= c.w THEN x := c.w - 1 END;
- IF y < 0 THEN y := 0 ELSIF y >= c.h THEN y := c.h - 1 END;
- n := y DIV E.cellH * E.tilesInRow + x DIV E.cellW;
- IF t.curTile # n THEN
- t.curTile := n;
- S.Redraw(c)
- END
- END
- END TilesetWidgetOnMouseDown;
- PROCEDURE TilesetWidgetOnMouseMove(c: S.Widget; x, y: INTEGER; btns: SET);
- BEGIN IF 1 IN btns THEN TilesetWidgetOnMouseDown(c, x, y, 1) END
- END TilesetWidgetOnMouseMove;
- PROCEDURE NewTilesetWidget(where: S.Widget; x, y, w, h: INTEGER): TilesetWidget;
- VAR c: TilesetWidget;
- BEGIN
- NEW(c); S.InitScrollBox(c, where, x, y, w, h);
- S.ScrollBoxSetInnerSize(c, E.tiles.w, E.tiles.h);
- S.SetOnPaint(c.inner, TilesetWidgetOnInnerPaint);
- S.SetOnMouseMove(c.inner, TilesetWidgetOnMouseMove);
- S.SetOnMouseDown(c.inner, TilesetWidgetOnMouseDown);
- c.curTile := 0
- RETURN c END NewTilesetWidget;
- (** - **)
- PROCEDURE BtnOpenOnClick(c: S.Widget);
- VAR s: ARRAY 256 OF CHAR;
- BEGIN
- S.EditGetText(edtMapName, s);
- IF s[0] # 0X THEN
- Strings.Append('.gam', s);
- IF E.LoadGame(game, s) THEN END;
- S.Redraw(wgtMap)
- END
- END BtnOpenOnClick;
- PROCEDURE BtnSaveOnClick(c: S.Widget);
- VAR s: ARRAY 256 OF CHAR;
- BEGIN
- S.EditGetText(edtMapName, s);
- IF s[0] # 0X THEN
- Strings.Append('.gam', s);
- E.SaveGame(game, s)
- END
- END BtnSaveOnClick;
- PROCEDURE BtnExitOnClick(c: S.Widget);
- BEGIN
- S.Quit
- END BtnExitOnClick;
- PROCEDURE InitInterface(): BOOLEAN;
- VAR W, H, w, h: INTEGER;
- color: G.Color;
- BEGIN
- G.GetScreenSize(W, H);
- frmMain := S.NewForm(0, 0, W, H);
- pnlTop := S.NewPanel(frmMain, 0, 0, W, 40);
- lblMapName := S.NewLabel(pnlTop, 8, 9, 88, 22, 'Имя файла:');
- S.LabelSetAlign(lblMapName, S.alRight);
- edtMapName := S.NewEdit(pnlTop, lblMapName.x + lblMapName.w + 8,
- 9, 40, 22);
- btnOpen := S.NewButton(pnlTop, edtMapName.x + edtMapName.w + 8,
- 8, 70, 24, 'Открыть');
- S.SetOnClick(btnOpen, BtnOpenOnClick);
- btnSave := S.NewButton(pnlTop, btnOpen.x + btnOpen.w + 8,
- 8, 80, 24, 'Сохранить');
- S.SetOnClick(btnSave, BtnSaveOnClick);
- btnExit := S.NewButton(pnlTop, W - 68, 8, 52, 24, 'Выход');
- S.SetOnClick(btnExit, BtnExitOnClick);
- pnlSide := S.NewPanel(frmMain, 0, pnlTop.h, 144, H - pnlTop.h);
- G.MakeCol(color, 40, 150, 40);
- S.SetBgColor(pnlSide, color);
- wgtTileset := NewTilesetWidget(pnlSide, 0, 0, pnlSide.w, pnlSide.h);
- sbxMap := S.NewScrollBox(frmMain, pnlSide.w, pnlTop.h,
- W - pnlSide.w, H - pnlTop.h);
- w := game.map.w * E.cellW;
- h := game.map.h * E.cellH;
- S.ScrollBoxSetInnerSize(sbxMap, w, h);
- (*S.ScrollBoxSetNoBg(sbxMap, TRUE);*)
- wgtMap := NewMapWidget(sbxMap, 0, 0, w, h)
- RETURN TRUE END InitInterface;
- PROCEDURE Init(): BOOLEAN;
- VAR ok: BOOLEAN;
- BEGIN ok := TRUE;
- G.Settings(320, 200, {});
- IF window THEN G.Settings(1240, 780, {G.window(*, G.maximized*)}) END;
- G.Init;
- IF ~G.Done THEN ok := FALSE END;
- IF ok THEN
- S.Init;
- IF ~S.Done THEN ok := FALSE END
- END;
- IF ok & ~E.Init() THEN ok := FALSE END;
- IF ok THEN E.InitGame(game) END;
- IF ok & ~InitInterface() THEN ok := FALSE END
- RETURN ok END Init;
- PROCEDURE Close;
- BEGIN
- G.Close
- END Close;
- BEGIN
- IF Init() THEN S.Run ELSE Out.String('Error loading.'); Out.Ln END;
- Close
- END MapEditor.
|