Bimso.Mod 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. MODULE Bimso; (** AUTHOR "TF"; PURPOSE "Template/Example for component windows"; *)
  2. (** This program shows the implementation of a multi instance component containing window *)
  3. IMPORT
  4. Strings, WMGraphics, WMMessages, WMComponents, WMStandardComponents,
  5. Modules, KernelLog, WMRectangles, WMGraphicUtilities, Random, Kernel, WMDialogs,
  6. WM := WMWindowManager;
  7. CONST
  8. MaxLevel = 1000;
  9. TYPE
  10. KillerMsg = OBJECT
  11. END KillerMsg;
  12. Window* = OBJECT (WMComponents.FormWindow)
  13. VAR b : ARRAY 4 OF WMStandardComponents.Button;
  14. startButton : WMStandardComponents.Button;
  15. start, alive : BOOLEAN;
  16. c, cflash : ARRAY 4 OF WMGraphics.Color;
  17. random : Random.Generator;
  18. game : ARRAY MaxLevel OF SHORTINT;
  19. level : LONGINT;
  20. step : LONGINT;
  21. error : BOOLEAN;
  22. timer : Kernel.Timer;
  23. s, levelStr : ARRAY 32 OF CHAR;
  24. PROCEDURE CreateForm() : WMComponents.VisualComponent;
  25. VAR
  26. panel : WMStandardComponents.Panel;
  27. i : LONGINT;
  28. BEGIN
  29. NEW(panel); panel.bounds.SetExtents(200, 200);
  30. panel.fillColor.Set(LONGINT(0DDFFDDFFH)); panel.takesFocus.Set(TRUE);
  31. NEW(b[0]); b[0].alignment.Set(WMComponents.AlignTop); b[0].bounds.SetHeight(50);
  32. b[0].bearing.Set(WMRectangles.MakeRect(50,0,50,0));
  33. panel.AddContent(b[0]);
  34. NEW(b[1]); b[1].alignment.Set(WMComponents.AlignBottom); b[1].bounds.SetHeight(50);
  35. b[1].bearing.Set(WMRectangles.MakeRect(50,0,50,0));
  36. panel.AddContent(b[1]);
  37. NEW(b[2]); b[2].alignment.Set(WMComponents.AlignLeft); b[2].bounds.SetWidth(50);
  38. panel.AddContent(b[2]);
  39. NEW(b[3]); b[3].alignment.Set(WMComponents.AlignRight); b[3].bounds.SetWidth(50);
  40. panel.AddContent(b[3]);
  41. NEW(startButton); startButton.alignment.Set(WMComponents.AlignClient);
  42. startButton.caption.SetAOC("Start!"); startButton.onClick.Add(Start);
  43. panel.AddContent(startButton);
  44. (* set the default colours of the buttons *)
  45. FOR i := 0 TO 3 DO b[i].clDefault.Set(c[i]) END;
  46. (* set the same color for the case where the mouse is over *)
  47. FOR i := 0 TO 3 DO b[i].clHover.Set(c[i]) END;
  48. (* set the flashcolor for the case where the button is pressed*)
  49. FOR i := 0 TO 3 DO b[i].clPressed.Set(cflash[i]) END;
  50. FOR i := 0 TO 3 DO b[i].onClick.Add(Evaluate) END;
  51. RETURN panel
  52. END CreateForm;
  53. PROCEDURE &New*;
  54. VAR vc : WMComponents.VisualComponent;
  55. i : LONGINT;
  56. BEGIN
  57. IncCount;
  58. (* initialize the button colours *)
  59. cflash[0] := WMGraphics.Green; cflash[1] := WMGraphics.Red;
  60. cflash[2] := WMGraphics.Blue; cflash[3] := WMGraphics.Magenta;
  61. (* scale the default colours to 50% of the flash colour *)
  62. FOR i := 0 TO 3 DO c[i] := WMGraphicUtilities.ScaleColor(cflash[i], 128) END;
  63. (* a timer may not be shared between processes so instantiate a new one *)
  64. NEW(timer);
  65. (* To create a multi language app, try loading the respective XML instead of CreateForm()
  66. if the XML was not found or does not contain all needed elements, use CreateForm as fallback *)
  67. vc := CreateForm();
  68. (* create a new random number generator *)
  69. NEW(random);
  70. random.InitSeed(Kernel.GetTicks());
  71. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
  72. SetContent(vc);
  73. WM.DefaultAddWindow(SELF);
  74. SetTitle(Strings.NewString("Bimso Game"));
  75. END New;
  76. PROCEDURE Close*;
  77. BEGIN
  78. Close^;
  79. DecCount
  80. END Close;
  81. PROCEDURE Handle*(VAR x : WMMessages.Message);
  82. BEGIN
  83. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) & (x.ext IS KillerMsg) THEN Close
  84. ELSE Handle^(x)
  85. END
  86. END Handle;
  87. PROCEDURE CreateLevel;
  88. BEGIN
  89. game[level] := SHORT(SHORT(random.Dice(4)));
  90. INC(level)
  91. END CreateLevel;
  92. PROCEDURE ShowLevel;
  93. VAR i : LONGINT;
  94. BEGIN
  95. FOR i := 0 TO level - 1 DO
  96. b[game[i]].clDefault.Set(cflash[game[i]]);
  97. timer.Sleep(150);
  98. b[game[i]].clDefault.Set(c[game[i]]);
  99. timer.Sleep(150);
  100. END;
  101. END ShowLevel;
  102. PROCEDURE EnableInput;
  103. VAR i : LONGINT;
  104. BEGIN
  105. FOR i := 0 TO 3 DO b[i].enabled.Set(TRUE) END;
  106. END EnableInput;
  107. PROCEDURE DisableInput;
  108. VAR i : LONGINT;
  109. BEGIN
  110. FOR i := 0 TO 3 DO b[i].enabled.Set(FALSE) END;
  111. END DisableInput;
  112. PROCEDURE Evaluate(sender, data : ANY);
  113. VAR i : LONGINT;
  114. BEGIN {EXCLUSIVE}
  115. FOR i := 0 TO 3 DO
  116. IF sender = b[i] THEN
  117. IF game[step] = i THEN INC(step) ELSE error := TRUE END;
  118. RETURN
  119. END
  120. END
  121. END Evaluate;
  122. PROCEDURE Start(sender, data : ANY);
  123. BEGIN
  124. Started;
  125. startButton.visible.Set(FALSE)
  126. END Start;
  127. PROCEDURE Started;
  128. BEGIN {EXCLUSIVE}
  129. start := TRUE
  130. END Started;
  131. PROCEDURE Play;
  132. BEGIN {EXCLUSIVE}
  133. step := 0;
  134. EnableInput;
  135. AWAIT(error OR (step = level))
  136. END Play;
  137. BEGIN {ACTIVE}
  138. alive := TRUE;
  139. WHILE alive DO
  140. start := FALSE;
  141. error := FALSE; level := 0;
  142. startButton.visible.Set(TRUE);
  143. BEGIN {EXCLUSIVE}
  144. AWAIT(start)
  145. END;
  146. error := FALSE;
  147. REPEAT
  148. KernelLog.Ln;
  149. DisableInput;
  150. timer.Sleep(500);
  151. CreateLevel;
  152. ShowLevel;
  153. Play;
  154. UNTIL error OR (level >= MaxLevel);
  155. IF level = MaxLevel THEN
  156. WMDialogs.Information("You win !!", "There are no more levels")
  157. ELSE
  158. Strings.IntToStr(level, levelStr);
  159. s := "You made it to level "; Strings.Append(s, levelStr);
  160. WMDialogs.Information("You lose !!", s)
  161. END;
  162. alive := WMDialogs.Message(WMDialogs.TQuestion, "Play again ?", "Do you want to play again ?",
  163. {WMDialogs.ResYes, WMDialogs.ResNo}) = WMDialogs.ResYes
  164. END;
  165. Close
  166. END Window;
  167. VAR
  168. nofWindows : LONGINT;
  169. PROCEDURE Open*;
  170. VAR winstance : Window;
  171. BEGIN
  172. NEW(winstance);
  173. END Open;
  174. PROCEDURE IncCount;
  175. BEGIN {EXCLUSIVE}
  176. INC(nofWindows);
  177. END IncCount;
  178. PROCEDURE DecCount;
  179. BEGIN {EXCLUSIVE}
  180. DEC(nofWindows);
  181. END DecCount;
  182. PROCEDURE Cleanup;
  183. VAR die : KillerMsg;
  184. msg : WMMessages.Message;
  185. m : WM.WindowManager;
  186. BEGIN {EXCLUSIVE}
  187. NEW(die);
  188. msg.ext := die;
  189. msg.msgType := WMMessages.MsgExt;
  190. m := WM.GetDefaultManager();
  191. m.Broadcast(msg);
  192. AWAIT(nofWindows = 0)
  193. END Cleanup;
  194. BEGIN
  195. Modules.InstallTermHandler(Cleanup)
  196. END Bimso.
  197. SystemTools.Free Bimso ~
  198. Bimso.Open ~