Oxygen Basic

Programming => Example Code => Topic started by: Peter on March 16, 2013, 01:33:29 AM

Title: GdiPlus last chance
Post by: Peter on March 16, 2013, 01:33:29 AM
Deleted
Title: Re: GdiPlus last chance
Post by: JRS on March 16, 2013, 06:46:53 AM
Hi Peter,

Your GDIPlus include file looks very much like sw.inc. Would it be worth converting the SB SokoMouse game to GDIPlus or is this a one time experiment and there will be no further updates to this library?

John
Title: Re: GdiPlus last chance
Post by: JRS on March 16, 2013, 07:37:27 AM
I will wait until you give the green light.

Thanks!
Title: Re: GdiPlus last chance
Post by: JRS on March 16, 2013, 10:58:20 AM
Quote
Sadly, we cannot use GdiPlus for games, is too slow.

Why am I not surprised?

Thanks for posting this game. I will convert it to SB. Maybe more Basic programmers will use ScriptBasic if they can easily create simple games.

BTW: Do you have any more level maps for SokoMouse beyond the 9 that were provided?

Title: Re: GdiPlus last chance
Post by: JRS on March 16, 2013, 11:13:59 AM
My error. There are 30 maps. Sorry.
Title: Re: GdiPlus last chance
Post by: JRS on March 16, 2013, 09:29:49 PM
Here is your Bird Shooter game running in ScriptBasic.

@Peter: Other than trying to dodge the turds, how does the plane fight back (shoot, ...) You have a couple lines of code that checks for the Key() to be two different values at the same time. ???

(http://files.allbasic.info/ScriptBasic/BS.png)

Code: OxygenBasic
  1. INCLUDE "sw.inc"
  2.  
  3.  
  4. '        *************
  5. FUNCTION CircleCollide(x1, y1, r1, x2, y2, r2)
  6. '        *************
  7.  IF SQR((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) <  r1 + r2 THEN
  8.     CircleCollide = 1
  9.   END IF
  10. END FUNCTION
  11.  
  12. '   ******
  13. SUB Timer1
  14. '   ******
  15.  dv = dv + 0.1
  16.   IF dv >= 1 THEN
  17.     dv = 0
  18.     zFrame = zFrame + 1
  19.     IF zFrame = 8 THEN zFrame = 0
  20.   END IF
  21. END SUB
  22.  
  23. '   ******
  24. SUB Timer2
  25. '   ******
  26.  jv = jv + 1
  27.   IF jv = 50 THEN
  28.     jv = 0
  29.     jx = jx + 1
  30.     IF jx = 21 THEN jx = 0
  31.   END IF
  32. END SUB
  33.  
  34. '   ******
  35. SUB Timer3
  36. '   ******
  37.  Drop = SW_Rnd(0,40)
  38. END SUB
  39.  
  40. '   ******
  41. SUB Timer4
  42. '   ******
  43.  IF Ok = 1 THEN EXIT SUB
  44.   za += .2
  45.   IF za >= 5 THEN
  46.     za = 0
  47.     count = count - 1
  48.     IF count <= 0 THEN count = 0
  49.   END IF
  50. END SUB
  51.  
  52. '   *********
  53. SUB SetExplos(xx, yy, ii)
  54. '   *********
  55.  FOR iDx = 0 TO 39
  56.     IF yBum[iDx] = 0 THEN
  57.       xBum[iDx] = xx
  58.       yBum[iDx] = yy
  59.       iBum[iDx] = ii
  60.       EXIT SUB
  61.     END IF
  62.   NEXT
  63. END SUB
  64.  
  65. '   **********
  66. SUB ShowExplos
  67. '   **********
  68.  FOR iDx = 0 TO 39
  69.   IF iBum[iDx] = 1 THEN
  70.     SW_DrawTile bmap, xBum[iDx], yBum[iDx], 64, 64, zBum[iDx], 1
  71.     vBum[iDx] = vBum[iDx] + 0.1
  72.     IF vBum[iDx] >= 1 THEN
  73.       vBum[iDx] = 0
  74.       zBum[iDx] = zBum[iDx] + 1
  75.     END IF
  76.     IF zBum[iDx] = 8 THEN
  77.       zBum[iDx] = 0
  78.       yBum[iDx] = 0
  79.       iBum[iDx] = 0
  80.       vBum[iDx] = 0
  81.     END IF
  82.   END IF
  83.   NEXT
  84. END SUB
  85.  
  86. '   *********
  87. SUB SetRocket(xx, yy)
  88. '   *********
  89.  FOR iAx = 0 TO 39
  90.   IF yRok[iAx] = 0 THEN
  91.     xRok[iAx] = xx
  92.     yRok[iAx] = yy
  93.     rRok[iAx] = 1
  94.     EXIT SUB
  95.   END IF
  96.   NEXT
  97. END SUB
  98.  
  99. '   **********
  100. SUB ScanRocket
  101. '   **********
  102.  FOR iAx = 0 TO 39
  103.   IF rRok[iAx] = 1 AND yRok[iAx] <= -32 THEN
  104.     rRok[iAx] = 0
  105.     yRok[iAx] = 0
  106.   END IF
  107.   NEXT
  108. END SUB
  109.  
  110. '   **********
  111. SUB ShowRocket
  112. '   **********
  113.  FOR iAx = 0 TO 39
  114.   IF rRok[iAx] = 1 THEN
  115.     SW_DrawTile bmap, xRok[iAx], yRok[iAx], 64, 64, zFrame, 0
  116.     yRok[iAx] = yRok[iAx] - 4
  117.     IF yRok[iAx] = 400 THEN zRak = 0
  118.   END IF
  119.   NEXT
  120. END SUB
  121.  
  122. '   **********
  123. SUB ScanRakete
  124. '   **********
  125.  IF rRak = 5 THEN EXIT SUB
  126.   IF SW_Key(32) AND SW_Key(39) AND zRak = 0 THEN
  127.     SetRocket(xRak, yRak)
  128.     rRak = 1
  129.     zRak = 1
  130.     SW_PlayWav w1
  131.   ELSE IF SW_Key(32) AND SW_Key(37) AND zRak = 0 THEN
  132.     SetRocket(xRak, yRak)
  133.     rRak = 2
  134.     zRak =1
  135.     SW_PlayWav w1
  136.   ELSE IF SW_Key(32) AND zRak = 0 THEN
  137.     SetRocket(xRak, yRak)
  138.     zRak = 1
  139.     SW_PlayWav w1
  140.   ELSE IF SW_Key(39) AND xRak < 736 THEN
  141.     rRak = 1
  142.   ELSE IF SW_Key(37) AND xRak > 0 THEN
  143.     rRak = 2
  144.   ELSE
  145.     rRak = 0
  146.   END IF
  147. END SUB
  148.  
  149. '   **********
  150. SUB ShowRakete
  151. '   **********
  152.  IF rRak = 0 THEN
  153.     SW_DrawTile bmap, xRak, yRak, 64, 64, zFrame, 4
  154.   ELSE IF rRak = 1 THEN
  155.     SW_DrawTile bmap, xRak, yRak, 64, 64, zFrame, 4
  156.     xRak = xRak + 1
  157.   ELSE IF rRak = 2 THEN
  158.     SW_DrawTile bmap, xRak, yRak, 64, 64, zFrame, 4
  159.     xRak = xRak - 1
  160.   END IF
  161. END SUB
  162.  
  163. '   ***************
  164. SUB RocketCollision
  165. '   ***************
  166.  FOR iBx = 0 TO uz
  167.     FOR iCx = 0 TO 39
  168.       IF rRok[iCx] > 0 AND rUfo[iBx] > 0 THEN
  169.         IF CircleCollide(xRok[iCx] + 32, yRok[iCx] + 32, 16, xUfo[iBx] + 32, yUfo[iBx] + 32, 16) = 1 THEN
  170.           SetExplos(xUfo[iBx], yUfo[iBx], 1)
  171.           rRok[iCx] = 0
  172.           yRok[iCx] = 0
  173.           rUfo[iBx] = 0
  174.           yUfo[iBx] = 0
  175.           SW_PlayWav w2
  176.           sc = sc + 25
  177.           EXIT SUB
  178.         END IF
  179.       END IF
  180.     NEXT
  181.   NEXT
  182. END SUB
  183.  
  184. '   ***************
  185. SUB RaketeCollision
  186. '   ***************
  187.  IF Ok = 1 THEN EXIT SUB
  188.   FOR iAx = 0 TO 40
  189.     IF yMeg[iAx] > 0 THEN
  190.       IF CircleCollide(xRak, yRak, 16, xMeg[iAx], yMeg[iAx], 16) = 1 THEN
  191.         SetExplos(xRak, yRak, 1)
  192.         rRak = 5
  193.         Ok = 1
  194.         SW_PlayWav w3
  195.         EXIT SUB
  196.       END IF
  197.     END IF
  198.   NEXT
  199. END SUB
  200.  
  201. '   *******
  202. SUB SetUfos
  203. '   *******
  204.  FOR iAx = 0 TO uz
  205.     xUfo[iAx] = SW_Rnd(16,736)
  206.     yUfo[iAx] = SW_Rnd(16,300)
  207.     rUfo[iAx] = SW_Rnd(1,4)
  208.     zUfo[iAx] = 0
  209.     nUfo[iAX] = 0
  210.   NEXT
  211. END SUB
  212.  
  213. '   ********
  214. SUB ScanUfos
  215. '   ********
  216.  FOR iBx = 0 TO uz
  217.     IF rUfo[iBx] = 1 AND xUfo[iBx] >= 736 THEN
  218.       rUfo[iBx] = 2
  219.     ELSE IF rUfo[iBx] = 2 AND xUfo[iBx] <= 0 THEN
  220.       rUfo[iBx] = 1
  221.     ELSE IF rUfo[iBx] = 3 AND yUfo[iBx] <= 0 THEN
  222.       rUfo[iBx] = 4
  223.     ELSE IF rUfo[iBx] = 4 AND yUfo[iBx] >= 350 THEN
  224.       rUfo[iBx] = 3
  225.     ELSE IF jx = 5 AND rUfo[iBx] = 4 THEN
  226.       rUfo[iBx] = SW_Rnd(1,4)
  227.     ELSE IF jx = 10 AND rUfo[iBx] = 3 THEN
  228.       rUfo[iBx] = SW_Rnd(1,4)
  229.     ELSE IF jx = 15 AND rUfo[iBx] = 2 THEN
  230.       rUfo[iBx] = SW_Rnd(1,4)
  231.     ELSE IF jx = 20 AND rUfo[iBx] = 1 THEN
  232.       rUfo[iBx] = SW_Rnd(1,4)
  233.     END IF
  234.   NEXT
  235. END SUB
  236.  
  237. '   ********
  238. SUB ShowUfos
  239. '   ********
  240.  FOR iBx = 0 TO uz
  241.     IF rUfo[iBx] = 1 THEN
  242.       SW_DrawTile bmap, xUfo[iBx], yUfo[iBx], 64, 64, zFrame, 2
  243.       xUfo[iBx] = xUfo[iBx] + 1
  244.     ELSE IF rUfo[iBx] = 2 THEN
  245.       SW_DrawTile bmap, xUfo[iBx], yUfo[iBx], 64, 64, zFrame, 2
  246.       xUfo[iBx] = xUfo[iBx] - 1
  247.     ELSE IF rUfo[iBx] = 3 THEN
  248.       SW_DrawTile bmap, xUfo[iBx], yUfo[iBx], 64, 64, zFrame, 2
  249.       yUfo[iBx] = yUfo[iBx] - 1
  250.     ELSE IF rUfo[iBx] = 4 THEN
  251.       SW_DrawTile bmap, xUfo[iBx], yUfo[iBx], 64, 64, zFrame, 2
  252.       yUfo[iBx] = yUfo[iBx] + 1
  253.     END IF
  254.   NEXT
  255. END SUB
  256.  
  257. '   *******
  258. SUB SetData
  259. '   *******
  260.  xRak = 384
  261.   yRak = 536
  262.   rRak = 0
  263.   za = 0
  264.   uz = 40
  265.   sc = 0
  266.   Ok = 0
  267.   zFrame = 0
  268.   count = 300
  269.   SetUfos
  270.   FOR iBx = 0 TO 40
  271.     yMeg[iBx] = 0
  272.     xMeg[iBx] = 0
  273.   NEXT
  274. END SUB
  275.  
  276. '   ********
  277. SUB TestUfos
  278. '   ********
  279.  FOR iAx = 0 TO 40
  280.     IF yUfo[iAx] > 0 OR Ok = 1 THEN EXIT SUB
  281.   NEXT
  282.   Ok = 1
  283.   sc += count
  284. END SUB
  285.  
  286. '   ************
  287. SUB ScanUfoBombs
  288. '   ************
  289.  FOR iAx = 0 TO drop STEP 2
  290.     IF rUfo[iAx] > 0 THEN
  291.       IF yMeg[iAx] = 0 THEN
  292.         xMeg[iAx] = xUfo[iAx]
  293.         yMeg[iAx] = yUfo[iAx] + 32
  294.       END IF
  295.     END IF
  296.   NEXT
  297. END SUB
  298.  
  299. '   ********
  300. SUB UfoBombs
  301. '   ********
  302.  FOR iDx = 0 TO 40
  303.     IF yMeg[iDx] > 0 THEN
  304.       IF iDx < 20 THEN
  305.         SW_DrawTile bmap, xMeg[iDx], yMeg[iDx], 64, 64, zFrame, 3
  306.       ELSE IF iDx >= 20 THEN
  307.         SW_DrawTile bmap, xMeg[iDx], yMeg[iDx], 64, 64, zFrame, 3
  308.       END IF
  309.       yMeg[iDx] = yMeg[iDx] + 1
  310.       IF yMeg[iDx] >= 600 THEN yMeg[iDx] = 0
  311.     END IF
  312.   NEXT
  313. END SUB
  314.  
  315. ' *******
  316. '  MAIN *
  317. ' *******  
  318.  
  319. SW_Window 800, 600, 1
  320. SW_SetFPS 60
  321. SW_SetFont 28, 48, 0, ""
  322. bmap = SW_LoadTile("bmp/bitmap.bmp", 8, 5)
  323. w1 = "bmp/shoot.wav"
  324. w2 = "bmp/explo.wav"
  325. w3 = "bmp/xship.wav"
  326. SW_ShowMouse 0
  327. SetData
  328.  
  329. WHILE SW_Key(27) = 0
  330.   SW_Cls 0
  331.   SW_SetCaption "Frames " & SW_ShowFPS()
  332.   IF Ok = 1 THEN
  333.     SW_SetText 460, 0, "SCORE " & sc, SW_RGB(255,255,255)
  334.   ELSE IF Ok = 0 THEN
  335.     SW_SetText 460, 0, "SCORE " & sc, SW_RGB(255,255,255)
  336.   END IF
  337.   ScanUfos
  338.   ShowUfos
  339.   ScanRocket
  340.   ShowRocket
  341.   ScanRakete
  342.   ShowRakete
  343.   ScanUfoBombs
  344.   UfoBombs
  345.   ShowExplos
  346.   RocketCollision
  347.   RaketeCollision
  348.   TestUfos
  349.   Timer1
  350.   Timer2
  351.   Timer3
  352.   Timer4
  353.   IF Ok = 1 THEN
  354.     SW_SetText 240, 300, "ONCE AGAIN?", SW_RGB(255,255,255)
  355.     SW_SetText 240, 344, "HIT [c] KEY", SW_RGB(255,255,255)
  356.     IF SW_Key(67) THEN SetData
  357.   END IF
  358.   SW_SetText 16, 0, "BONUS " & count, SW_RGB(255,255,255)
  359.   SW_Sync
  360. WEND
  361. SW_Quit
  362.  
Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 07:54:51 AM
That is what I thought as well looking at the code and being a natural key to use. I only have left and right arrow key functionality. My guess is that your IF statements checking the Key() function for two different values is the problem. (guess)

Code: OxygenBasic
  1. ELSE IF SW_Key(32) AND SW_Key(37) AND zRak = 0 THEN
  2.  

How can the return of your Key() function be equal to 32 & 37 at the same time?

Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 09:55:02 AM
Here is the code for the game in ScriptBasic if you want to give it a try and maybe figure out why I only have left and right arrow keyboard support.

I had mentioned this with the SokoMouse game and I see you didn't get the hint. The CPU takes a big hit if you do a SetFps() call in the WHILE/WEND loop. It only needs to be set ONCE to keep the frame rate at the desired value.

FYI If I remark out the SetFps(), SB is runs at 150+ FPS in a XP VirtualBox. (on top of Ubuntu 64)

Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 11:03:14 AM
Once again, DO NOT use scribaw.exe with anything other than IUP GUI scripts. PLEASE use scriba.exe from the console command line. Make sure the path to the SB bin directory is set and DLLC.dll is in the modules directory.

This updated attachment reflects the changes I made to BS.sbx (main game script) and includes the most recent dllc.dll file.

Update

Like SokoMouse, using SetFPS(60) outside the WHILE/WEND loop and using Sync() rather than Redraw() gives me the best game play. (Frames average around 90 in the title bar) It reduces CPU usage by 75% without changing the anything with the game.

X
Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 01:53:06 PM
Peter,

I think you will find the root of our problems if you realize all variables return undef until assigned. I had to add zFrame = 0 to SetData as it was calling Simple Windows with it set as undef causing a GPF. If you can look at the code and determine what absolutely must be initialized prior to use we may find the problem. In the O2 version DIMing the arrarys must initialize them to zero.

Quote
Another thing is SW_RAND, dosn't work like Simple Window RND.

SW_Rnd is a wrapper for your Simple Windows API function and used in both SokoMouse and Angry Birds II. The ScriptBasic version of RND() isn't compatible with yours but is a SB keyword and SW_Rnd() is what your random generator function is calling in the games.

John

P.S. Hope you're not living in a Starbucks if you weren't kidding about the house burning down.

 
Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 03:14:36 PM
I put the following in the WHILE/WEND loop and it printed fine when pressing the space bar.

Code: [Select]
 IF SW_Key(32) THEN PRINT "Space Key\n"

Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 08:34:19 PM
Quote
It seems, there is a bug in ScriptBasic! I changed (zFrame = zFrame +1) in (zFrame +=1) and then there was animation!

Your observation made me curious so I wrote a little program to test your theory.

Code: [Select]
a += 1
PRINT "A: ",a,"\n"

b = b + 1
PRINT "B: ",b,"\n"

c = 0
c += 1
PRINT "C: ",c,"\n"

d = 0
d = d + 1
PRINT "D: ",d,"\n"

C:\SB22\test>scriba plusone.sb
A: 1
B: undef
C: 1
D: 1

C:\SB22\test>

It seems your right about there is a different result if referencing an uninitialized variable and then incrementing it. It seems to work correctly either way if the variable is assigned (initialized)  before hand.

Thanks for pointing this out!

Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 09:05:05 PM
Peter,

I was right about the initialization of variables for this game. Add this SUB to the top of the program and call it in Main before starting. Everything seems to be working except using the Windows MM API for playing the wave is causing delays. I'm assuming the Bass call lets the game continue and plays the sound in another thread?

John

Code: OxygenBasic
  1. SUB InitVars
  2.  
  3.   SPLITA STRING(40,"0") BY "" TO xMeg
  4.   SPLITA STRING(40,"0") BY "" TO yMeg
  5.   SPLITA STRING(40,"0") BY "" TO zMeg
  6.   SPLITA STRING(40,"0") BY "" TO xUfo
  7.   SPLITA STRING(40,"0") BY "" TO yUfo
  8.   SPLITA STRING(40,"0") BY "" TO zUfo
  9.   SPLITA STRING(40,"0") BY "" TO rUfo
  10.   SPLITA STRING(40,"0") BY "" TO iUfo
  11.   SPLITA STRING(40,"0") BY "" TO nUfo
  12.   SPLITA STRING(40,"0") BY "" TO xRok
  13.   SPLITA STRING(40,"0") BY "" TO yRok
  14.   SPLITA STRING(40,"0") BY "" TO rRok
  15.   SPLITA STRING(40,"0") BY "" TO xBum
  16.   SPLITA STRING(40,"0") BY "" TO yBum
  17.   SPLITA STRING(40,"0") BY "" TO iBum
  18.   SPLITA STRING(40,"0") BY "" TO zBum
  19.   SPLITA STRING(40,"0") BY "" TO vBum
  20.  
  21.   xRak = 0
  22.   yRak = 0
  23.   rRak = 0
  24.   zRak = 0
  25.   iBx = 0
  26.   iDx = 0
  27.   iCx = 0
  28.   iAx = 0
  29.   zFrame = 0
  30.   z1 = 0
  31.   z2 = 0
  32.   z3 = 0
  33.   z4 = 0
  34.   bmap = 0
  35.   w1 = 0
  36.   w2 = 0
  37.   w3 = 0
  38.   s = 0
  39.   y = 0
  40.   sc = 0
  41.   uz = 0
  42.   jx = 0
  43.   drop = 0
  44.   Ok = 0
  45.   count = 0
  46.   px = 0
  47.  
  48.   jv = 0.0
  49.   zv = 0.0
  50.   dv = 0.0
  51.   za = 0.0
  52.  
  53. END SUB
  54.  
Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 09:43:00 PM
Peter,

I remarked out the call to the Windows wave API and the game worked as expected. I was even able to clear the screen of birds.  :o

John

X
Title: Re: GdiPlus last chance
Post by: JRS on March 17, 2013, 10:38:38 PM
ScriptBasic may be doing exactly as its told. There is a difference between incrementing an uninitialized variable and adding 1 to it.

Code: OxygenBasic
  1. a += 1
  2. PRINT "A: ",a,"\n"
  3.  
  4. b = b + 1
  5. PRINT "B: ",b,"\n"
  6.  
  7. c = 0
  8. c += 1
  9. PRINT "C: ",c,"\n"
  10.  
  11. d = 0
  12. d = d + 1
  13. PRINT "D: ",d,"\n"
  14.  
  15. undef u
  16. PRINT "U: ",u + 1,"\n"
  17.  

C:\SB22\test>scriba plusone.sb
A: 1
B: undef
C: 1
D: 1
U: undef

C:\SB22\test>

ScriptBasic defaults to careful but lazy programmer mode as default.  8)

You have the option to tell SB that you want some warning (errors) that you forgot an assignment and how you want SB to react to undef in expressions.  Setting Options (http://www.scriptbasic.org/docs/ug/ug_22.html)

Quote from: SB Docs
BASIC languages generally do not require variable declaration to be programmer friendly. ScriptBasic is no exception for compatibility reasons: you can write huge programs without declaring any variable. Although this is possible this is not a good practice. Programmers can easily mistype a variable name and end up getting a new variable with undef value instead of getting compilation error. This may cost a lot of debugging time.

Forcing Variable Declaration (http://www.scriptbasic.org/docs/ug/ug_9.6.html)

Another cool SB feature is switching between TEXT or BINARY mode on the fly with STDIN/OUT operations.

Switching between binary and text mode (http://www.scriptbasic.org/docs/ug/ug_12.3.html)
Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 01:53:52 AM
Hi John,

Glad to hear that we come nearer to a super Basic language.
A good way to declare variables is the LUA way, a variabe is always NIL when  no value is  assigned.
This forces  programmer to think in another direction.

I think I have an idea.
Title: Re: GdiPlus last chance
Post by: Maxim on March 18, 2013, 02:21:18 AM
Sadly, we cannot use GdiPlus for games, is too slow.
I got 6 frames/sec in a small game. Is only good for Graphic.

This was only a test,  here is this game with Simple Window.
Hi Peter,

What about GDI+ optimisation?
http://forums.codeguru.com/showthread.php?523273-GDI-and-double-buffering

Game return error with OxygenBasic line 1: include "sw.inc"


Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 04:47:32 AM
Hi Maxim,

I use double buffer!
This GDIPLUS thing is really slow, I think that the Engineers were drunken!  :D

Check it for fun! Look at the frames, I have adjusted 200 frames!
Wait a little bit to see the shock wave!
Code: [Select]
include "gp.inc"

Window 640,480,1
int x, y, a=255, d=1
worm = LoadImage "img/worm.png",1

while Key(27)=0
  
Cls ARGB(255,255,255,255)
SetCaption "FRAMES  " + GetFPS  
  for y=0 to 480 step 16
     for x=0 to 640 step 16
        'Line x, y, x+10, y+10, 2, ARGB(a,255,0,0)
        Line x, y, -x+10, -y+10, 2, ARGB(a,0,0,255)
     next
  next      
  SpriteZoom worm,40,0,512,512
  if d=1
     a -=4
     if a <=1 Then d=2
  end if  
  if d=2
     a +=2
     if a >=255 Then d=2
  end if  
  Redraw  
  SetFPS 200

wend
Quit

X
Title: Re: GdiPlus last chance
Post by: Charles Pegge on March 18, 2013, 04:52:04 AM
Some of my neighbours do the bird shoot for real, though with less powerful weapons, and no lethal feathers from the birds - (I think pheasants and partridges should be able to fight back :) )
Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 05:02:49 AM
Quote
Game return error with OxygenBasic line 1: include "sw.inc"

only for fun  ;D

X
Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 05:32:37 AM
If I want to pack into a DLL Opengl.  what is the call condition?
STDCALL CDECL FASTCALL, or so!

The Dll is already there, but OxygenBasic cannot  localize it.
Everything is in the same directory!

I struggle now two days with this crap.
I think, it gets time  for a better user help !
But that isn't your thing, I think, no time for kids games.  :D
Title: Re: GdiPlus last chance
Post by: Maxim on March 18, 2013, 07:02:06 AM
I use double buffer!
This GDIPLUS thing is really slow, I think that the Engineers were drunken!  :D
Thanks for sw.inc, but this is use sw.dll (gp.inc - gp.dll). Can you do pure GDI+ example?

Perhaps for images it is not good choice, but vector functions with path work enought fast, I use this for game editor.
Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 07:27:58 AM
Quote
Thanks for sw.inc, but this is use sw.dll (gp.inc - gp.dll). Can you do pure GDI+ example?

Code: [Select]
include "gp.inc"
def Escape 27

gdiPlus = LoadLibrary "gdiplus.dll"

Bind gdiPlus
(
  GdipDrawImageRect GdipDrawImageRect
  GdipGetImageDimension GdipGetImageDimension
  GdipResetWorldTransform GdipResetWorldTransform
  GdipRotateWorldTransform GdipRotateWorldTransform
  GdipTranslateWorldTransform GdipTranslateWorldTransform
)

Window 640,480,1
font= LoadFont "arial",32,2
Cls ARGB(155,0,0,255)
gdc = GetScreenDC()
single angle=180, width, height

image= LoadImage "img/toy.gif",1
iHdc = GetImageDC(image)
GdipGetImageDimension(iHdc, &width, &height)

while Key(Escape)=0
  Cls ARGB(255,0,0,255)
  GdipRotateWorldTransform (gdc, angle, MatrixOrderPrepend)
  GdipTranslateWorldTransform(gdc, width, height, MatrixOrderAppend)
  GdipDrawImageRect(gdc, iHdc, 0.0,0.0, 200.0,200.0) 'width, height)
  GdipResetWorldTransform (gdc)                                        
  Text font,0,0,"ImageWidth " + width + "  ImageHeight " + height,ARGB(255,0,255,0)

  Redraw
  SetFPS 80
  angle +=1
  if angle =540 then angle=180
wend

Quit

X
Title: Re: GdiPlus last chance
Post by: Maxim on March 18, 2013, 07:38:36 AM
Code: [Select]
include "gp.inc"
def Escape 27

gdiPlus = LoadLibrary "gdiplus.dll"

Bind gdiPlus
(
  GdipDrawImageRect GdipDrawImageRect
  GdipGetImageDimension GdipGetImageDimension
  GdipResetWorldTransform GdipResetWorldTransform
  GdipRotateWorldTransform GdipRotateWorldTransform
  GdipTranslateWorldTransform GdipTranslateWorldTransform
)

Window 640,480,1
font= LoadFont "arial",32,2
Cls ARGB(155,0,0,255)
gdc = GetScreenDC()
single angle=180, width, height

image= LoadImage "img/toy.gif",1
iHdc = GetImageDC(image)
GdipGetImageDimension(iHdc, &width, &height)

while Key(Escape)=0
  Cls ARGB(255,0,0,255)
  GdipRotateWorldTransform (gdc, angle, MatrixOrderPrepend)
  GdipTranslateWorldTransform(gdc, width, height, MatrixOrderAppend)
  GdipDrawImageRect(gdc, iHdc, 0.0,0.0, 200.0,200.0) 'width, height)
  GdipResetWorldTransform (gdc)                                        
  Text font,0,0,"ImageWidth " + width + "  ImageHeight " + height,ARGB(255,0,255,0)

  Redraw
  SetFPS 80
  angle +=1
  if angle =540 then angle=180
wend

Quit
this is not pure
you can not do some optimisation with this code
Title: Re: GdiPlus last chance
Post by: Aurel on March 18, 2013, 08:00:03 AM
oxymap editor use sw.inc only and i made few maps with this Peter program
and seems to me that work very fine.
I think that Peter says that he create sw.dll because he need more speed but i
simply don't see almost any important difference...maybe i am completely wrong... :-\
Title: Re: GdiPlus last chance
Post by: Maxim on March 18, 2013, 08:13:10 AM
game builder (http://pywingui.googlecode.com/files/game_builder_03.zip)
short video (http://youtu.be/BJpxwWgCmjM)
example source for editor (http://code.google.com/p/pywingui/source/browse/trunk/pywingui_tests/test_GdiPlus_live_grid_form.py)
I use GdipSetClipRectI also, but this is not in main loop, it is in MouseMove event, and in addition path functional is enought fast width vector primitives
Title: Re: GdiPlus last chance
Post by: Aurel on March 18, 2013, 08:27:17 AM
 :o
u use python + windows api for your program, uff i dont like python but
this look very cool... ;)
Title: Re: GdiPlus last chance
Post by: JRS on March 18, 2013, 01:41:37 PM
Good News!

I didn't have to use Bass after all and just changing the last parameter to 1 for the SW_PlayWav call allowed ASYNC operation and smooth game play. Attached is my current working version of the game.

X
Title: Re: GdiPlus last chance
Post by: Peter on March 18, 2013, 02:51:49 PM
John,

Why don't you use PlayWav and LoadWav from the sw library? Is the same Api!
If you had asked me, then I had said, set the last parameter on 1!
I know about 800 Api's invocations.
Title: Re: GdiPlus last chance
Post by: JRS on March 18, 2013, 04:21:55 PM
Thanks for the info Peter about now using the MS MM API call with SW.

Here is an updated version of the Soko Mouse game with a new background and 30 levels. I almost had level three solve but got screwed in the final few moves. If you have solved level 3 or beyond, send me a screen shot showing the level completed and the number of moves. You will hold the Big Cheese for that level unless someone can solve the level in fewer moves. (results posted on All Basic)

(http://files.allbasic.info/ScriptBasic/sbsm2.png)

Code: [Select]
' ScriptBasic SokoMouse

INCLUDE "sbsw.inc"

SUB Initialize
  SW_DrawBmp p1, 0, 0, 640, 480, 0
' SW_BmpText fo, 200, 8, "SokoMouse", 24, 24
  zA = 0
  Notified = FALSE
  CALL ShowLevel
  FOR bc = 0 TO 299
    xBox[bc] = 0
    yBox[bc] = 0
    rBox[bc] = 0
    zBox[bc] = 0
    iBox[bc] = 0
  NEXT
  zR = 0
  vR = 0
  pHead = 3
  Ready = 0
  sl = 0
  cV = 0
  cR = 0
  Steps = 0
  RasReg = 0
  KeyR = 0
  KeyL = 0
  KeyU = 0
  KeyD = 0
  BoxRas = 0
  Turn = 1
  zTurn = 0
END SUB

SUB LoadMaps
  SW_LoadBytes "Maps/Map" & lev & "-1.bin", Map1
  SW_LoadBytes "Maps/Map" & lev & "-2.bin", Map2
  SW_LoadBytes "Maps/Map" & lev & "-3.bin", Map3
END SUB  
  
SUB ShowLevel
  SW_Sprite s8, 480, 450, zA
  SW_Sprite s9, 576, 450, zA
  SW_BmpText fo, 520, 450, FORMAT("%~00~",lev), 24, 24
  vA += 1
  IF vA = 8 THEN
    vA = 0
    zA = zA + 1
    IF zA = 4 THEN zA = 0
  END IF
END SUB

SUB ShowMaps
  FOR icx = 0 TO 14
    FOR idx = 0 TO 19
      ibx = icx * 20 + idx
      IF ASC(Map1[ibx]) = 3 THEN SW_Sprite s1, idx * 32, icx * 32, 3
      IF ASC(Map3[ibx]) = 2 THEN SW_Sprite s1, idx * 32, icx * 32, 2
      IF ASC(Map2[ibx]) = 5 THEN SW_Sprite s2, idx * 32, icx * 32, zR
    NEXT
  NEXT
  vR += 1
  IF vR = 10 THEN
    vR = 0
    zR += 1
  END IF
  IF zR = 4 THEN zR = 0
END SUB

SUB FindHead
  FOR icx = 0 TO 14
    FOR idx = 0 TO 19
      ibx = icx * 20 + idx
      IF ASC(Map3[ibx]) = 6 THEN
        xHead = idx * 32
        yHead = icx * 32
        rHead = 0
        zHead = 0
        EXIT SUB
      END IF
    NEXT
  NEXT
END SUB

SUB AllDone
  IF Ready >= 1 THEN EXIT SUB
  FOR icx = 0 TO 14
    FOR idx = 0 TO 19
      ibx = icx * 20 + idx
      IF ASC(Map2[ibx]) = 5 AND ASC(Map3[ibx]) <> 4 THEN
        EXIT SUB
      END IF
    NEXT
  NEXT
  Ready = 2
  RasReg = 1
  Turn = 0
  pHead = 0
  rTurn = SW_Rnd(1, 2)
  xTurn = xHead
  yTurn = yHead
END SUB

SUB TurnHead
  IF Turn > 0 THEN EXIT SUB
  IF rTurn = 1 THEN
    SW_Sprite s6, xTurn, yTurn, zTurn
  ELSE IF rTurn = 2 THEN
    SW_Sprite s7, xTurn, yTurn, zTurn
  END IF
  zTurn = zTurn + 1
  IF zTurn = 64 THEN zTurn = 0
END SUB

SUB FlashBox
  FOR icx = 0 TO 14
    FOR idx = 0 TO 19
      ibx = icx * 20 + idx
      IF ASC(Map2[ibx]) = 5 AND ASC(Map3[ibx]) = 4 THEN
        SW_Sprite s4, idx * 32, icx * 32, cR
      END IF
    NEXT
  NEXT
  cV += 1
  IF cV = 10 THEN
    cV = 0
    cR += 1
  END IF
  IF cR = 4 THEN cR = 0
END SUB

SUB ScanBoxes
  IF BoxRas > 0 THEN EXIT SUB
  FOR icx = 0 TO 14
    FOR idx = 0 TO 19
      ibx = icx * 20 + idx
      IF ASC(Map3[ibx]) = 4 THEN
        iBox[ibx] = 1
        xBox[ibx] = idx * 32
        yBox[ibx] = icx * 32
        rBox[ibx] = 0
      END IF
    NEXT
  NEXT
END SUB

SUB ShowBoxes
  FOR ibx = 20 TO 280
    IF iBox[ibx] = 1 AND rBox[ibx] = 0 THEN
      SW_Sprite s1, xBox[ibx], yBox[ibx], 4
    ELSE IF iBox[ibx] = 1 AND rBox[ibx] = 1 THEN
      xBox[ibx] = xBox[ibx] + 2
      SW_Sprite s1, xBox[ibx], yBox[ibx], 4
      zBox[ibx] = zBox[ibx] + 2
      IF zBox[ibx] = 32 THEN
        zBox[ibx] = 0
        iBox[ibx] = 0
        icx = (yBox[ibx] * 20 + xBox[ibx]) / 32
        Map3[icx] = CHR(4)
      END IF
    ELSE IF iBox[ibx] = 1 AND rBox[ibx] = 2 THEN
      xBox[ibx] = xBox[ibx] - 2
      SW_Sprite s1, xBox[ibx], yBox[ibx], 4
      zBox[ibx] = zBox[ibx] + 2
      IF zBox[ibx] = 32 THEN
        zBox[ibx] = 0
        iBox[ibx] = 0
        icx = (yBox[ibx] * 20 + xBox[ibx]) / 32
        Map3[icx] = CHR(4)
      END IF
    ELSE IF iBox[ibx] = 1 AND rBox[ibx] = 3 THEN
      yBox[ibx] = yBox[ibx] - 2
      SW_Sprite s1, xBox[ibx], yBox[ibx], 4
      zBox[ibx] = zBox[ibx] + 2
      IF zBox[ibx] = 32 THEN
        zBox[ibx] = 0
        iBox[ibx] = 0
        icx = (yBox[ibx] * 20 + xBox[ibx]) / 32
        Map3[icx] = CHR(4)
      END IF
    ELSE IF iBox[ibx] = 1 AND rBox[ibx] = 4 THEN
      yBox[ibx] = yBox[ibx] + 2
      SW_Sprite s1, xBox[ibx], yBox[ibx], 4
      zBox[ibx] = zBox[ibx] + 2
      IF zBox[ibx] = 32 THEN
        zBox[ibx] = 0
        iBox[ibx] = 0
        icx = (yBox[ibx] * 20 + xBox[ibx]) / 32
        Map3[icx] = CHR(4)
      END IF
    END IF
  NEXT
END SUB

SUB ScanHead
  IF RasReg > 0 THEN EXIT SUB
  idx = xHead / 32
  icx = yHead / 32
  ibx = icx * 20 + idx
  IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_right) AND ASC(Map3[ibx + 1]) = 4 AND ASC(Map3[ibx + 2]) = 0 AND KeyR = 0 THEN
    Map3[ibx] = CHR(0)
    Map3[ibx + 1] = CHR(6)
    rHead = 1
    pHead = 1
    BoxRas = 0
    xBox[ibx + 1] = xHead + 32
    yBox[ibx + 1] = yHead
    rBox[ibx + 1] = 1
    iBox[ibx + 1] = 1
    Steps += 1
    SW_PlayWav w2
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_left) AND ASC(Map3[ibx - 1]) = 4 AND ASC(Map3[ibx - 2]) = 0 AND KeyL = 0 THEN
    Map3[ibx] = CHR(0)
    Map3[ibx - 1] = CHR(6)
    rHead = 2
    pHead = 2
    BoxRas = 0
    xBox[ibx - 1] = xHead - 32
    yBox[ibx - 1] = yHead
    rBox[ibx - 1] = 2
    iBox[ibx - 1] = 1
    Steps += 1
    SW_PlayWav w2
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_up) AND ASC(Map3[ibx - 20]) = 4 AND ASC(Map3[ibx - 40]) = 0 AND KeyU = 0 THEN
    Map3[ibx] = CHR(0)
    Map3[ibx - 20] = CHR(6)
    rHead = 3
    pHead = 3
    BoxRas = 0
    xBox[ibx - 20] = xHead
    yBox[ibx - 20] = yHead - 32
    rBox[ibx - 20] = 3
    iBox[ibx - 20] = 1
    Steps += 1
    SW_PlayWav w2
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_down) AND ASC(Map3[ibx + 20]) = 4 AND ASC(Map3[ibx + 40]) = 0 AND KeyD = 0 THEN
    Map3[ibx] = CHR(0)
    Map3[ibx + 20] = CHR(6)
    rHead = 4
    pHead = 4
    BoxRas = 0
    xBox[ibx + 20] = xHead
    yBox[ibx + 20] = yHead + 32
    rBox[ibx + 20] = 4
    iBox[ibx + 20] = 1
    Steps += 1
    SW_PlayWav w2
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_right) AND ASC(Map3[ibx + 1]) = 0 AND KeyR = 0 THEN
    rHead = 1
    pHead = 1
    Map3[ibx] = CHR(0)
    Map3[ibx + 1] = CHR(6)
    Steps += 1
    SW_PlayWav w1
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_left) AND ASC(Map3[ibx - 1]) = 0 AND KeyL = 0 THEN
    rHead = 2
    pHead = 2
    Map3[ibx] = CHR(0)
    Map3[ibx - 1] = CHR(6)
    Steps += 1
    SW_PlayWav w1
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_up) AND ASC(Map3[ibx - 20]) = 0 AND KeyU = 0 THEN
    rHead = 3
    pHead = 3
    Map3[ibx] = CHR(0)
    Map3[ibx - 20] = CHR(6)
    Steps += 1
    SW_PlayWav w1
  ELSE IF ASC(Map3[ibx]) = 6 AND SW_Key(vk_down) AND ASC(Map3[ibx + 20]) = 0 AND KeyD = 0 THEN
    rHead = 4
    pHead = 4
    Map3[ibx] = CHR(0)
    Map3[ibx + 20] = CHR(6)
    Steps += 1
    SW_PlayWav w1
  ELSE
    rHead = 0
  END IF
END SUB

SUB ShowHead
  IF rHead = 0 AND pHead = 1 THEN
    SW_Sprite s3, xHead, yHead, 3
  ELSE IF rHead = 0 AND pHead = 2 THEN
    SW_Sprite s3, xHead, yHead, 1
  ELSE IF rHead = 0 AND pHead = 3 THEN
    SW_Sprite s3, xHead, yHead, 0
  ELSE IF rHead = 0 AND pHead = 4 THEN
    SW_Sprite s3, xHead, yHead, 2
  ELSE IF rHead = 1 THEN
    xHead += 2
    SW_Sprite s3, xHead, yHead, 3
    RasReg += 2
    IF RasReg = 32 THEN
      RasReg = 0
      rHead = 0
    END IF
  ELSE IF rHead = 2 THEN
    xHead -= 2
    SW_Sprite s3, xHead, yHead, 1
    RasReg += 2
    IF RasReg = 32 THEN
      RasReg = 0
      rHead = 0
    END IF
  ELSE IF rHead = 3 THEN
    yHead -= 2
    SW_Sprite s3, xHead, yHead, 0
    RasReg += 2
    IF RasReg = 32 THEN
      RasReg = 0
      rHead = 0
    END IF
  ELSE IF rHead = 4 THEN
    yHead += 2
    SW_Sprite s3, xHead, yHead, 2
    RasReg += 2
    IF RasReg = 32 THEN
      RasReg = 0
      rHead = 0
    END IF
  END IF
END SUB

SUB MousePos
  xPos = FIX(SW_xMouse() / 32)
  yPos = FIX(SW_yMouse() / 32)
  IF SW_MouseButton() = 1 THEN
    IF xPos = 15 AND yPos = 14 AND lev > 1 AND ButtonC = 0 THEN
      lev -= 1
      ButtonC = 1
      SW_PlayWav w4
      Initialize
      LoadMaps
      FindHead
      EXIT SUB
    END IF
  END IF
  IF SW_MouseButton() = 1 THEN
    IF xPos = 18 AND yPos = 14 AND lev < 30 AND ButtonC = 0 THEN
      lev += 1
      ButtonC = 1
      SW_PlayWav w4
      Initialize
      LoadMaps
      FindHead
    END IF
  END IF
  IF SW_MouseButton() = 0 THEN ButtonC = 0
END SUB


' MAIN

SW_Window 640, 480, 1
SW_SetCaption "ScriptBasic SokoMouse"

SW_SetFps(60)

Q  = SW_LoadBmp("SokoMedia/sokomouse.bmp", 1)
p1 = SW_LoadBmp("SokoMedia/smbg.bmp", 1)
Fo = SW_LoadBmp("SokoMedia/FontStrip.bmp", 96)
s1 = SW_LoadBmp("SokoMedia/SokoStrip.bmp", 5)
s2 = SW_LoadBmp("SokoMedia/RundStrip.bmp", 4)
s3 = SW_LoadBmp("SokoMedia/HeadStrip.bmp", 4)
s4 = SW_LoadBmp("SokoMedia/BoxsStrip.bmp", 4)
s6 = SW_LoadBmp("SokoMedia/HeadStripR.bmp", 64)
s7 = SW_LoadBmp("SokoMedia/HeadStripL.bmp", 64)
s8 = SW_LoadBmp("SokoMedia/ArroStripL.bmp", 4)
s9 = SW_LoadBmp("SokoMedia/ArroStripR.bmp", 4)

w1 = "SokoMedia/move.wav"
w2 = "SokoMedia/push.wav"
w3 = "SokoMedia/done.wav"
w4 = "SokoMedia/clic.wav"


SW_Cls  0xCCCCCC
SW_Sprite Q, 180, 60, 0
SW_BmpText fo, 205, 32, "SOKOMOUSE", 24, 24
SW_BmpText fo, 170, 428, "PRESS ANY KEY", 24, 24
SW_WaitKey

lev = 1
Initialize
LoadMaps
ShowLevel
FindHead

WHILE SW_Key(27) = 0
  ShowMaps
  IF sl THEN ShowLevel
  ScanBoxes
  ScanHead
  ShowBoxes
  ShowHead
  FlashBox
  AllDone
  MousePos
  TurnHead
  IF SW_Key(vk_space) THEN
    SW_BmpText fo, 64, 420, "Wait...", 24, 24
    Initialize
    LoadMaps
    FindHead
  END IF
  IF Ready = 2 AND NOT(Notified) THEN
    SW_BmpText fo, 64, 450, Steps & " moves to solve.", 20, 20
    SW_Sync
    SW_PlayWav w3
    sl = 1
    Notified = TRUE
  END IF
  BoxRas += 2
  IF BoxRas = 32 THEN BoxRas = 0
  IF SW_Key(vk_right) = 0 THEN KeyR = 1
  IF SW_Key(vk_right)THEN KeyR = 0
  IF SW_Key(vk_left) = 0 THEN KeyL = 1
  IF SW_Key(vk_left) THEN KeyL = 0
  IF SW_Key(vk_up) = 0 THEN KeyU = 1
  IF SW_Key(vk_up) THEN KeyU = 0
  IF SW_Key(vk_down) = 0 THEN KeyD = 1
  IF SW_Key(vk_down) THEN KeyD = 0
  SW_Sync
WEND
SW_CloseWindow



X
Title: Re: GdiPlus last chance
Post by: JRS on March 18, 2013, 08:21:20 PM
I noticed since the sound isn't providing a delay any longer after pressing a key, I was seeing a faster repeat rate than I would like. I added a 10 msec delay after a arrow key being pressed and it seems to have solved the issue for me.

Code: [Select]
 IF SW_Key(vk_right) = 0 THEN KeyR = 1
  IF SW_Key(vk_right)THEN
    KeyR = 0
    SW_Wait(10)
  END IF
  IF SW_Key(vk_left) = 0 THEN KeyL = 1
  IF SW_Key(vk_left) THEN
    KeyL = 0
    SW_Wait(10)
  END IF
  IF SW_Key(vk_up) = 0 THEN KeyU = 1
  IF SW_Key(vk_up) THEN
    KeyU = 0
    SW_Wait(10)
  END IF
  IF SW_Key(vk_down) = 0 THEN KeyD = 1
  IF SW_Key(vk_down) THEN
    KeyD = 0
    SW_Wait(10)
  END IF

@Peter: I would have never thought of using ScriptBasic for games like yours. Thanks for the cool library and putting up with me when things don't work.



Title: Re: GdiPlus last chance
Post by: Maxim on March 19, 2013, 01:14:04 AM
:o
u use python + windows api for your program, uff i dont like python but
this look very cool... ;)
Thanks, but I only want say - gdiplusflat can be used for game programming, for example: tetris, lines, chess and other not massive count sprites or used only vector graphics with good effects. Also gdi+ have good distinction from gdi - internal mechanism like garbage collection, therefore memory use is optimal.
These is function GdipDisposeImage, but this was not suitable for me.

Editor from this game builder do data levels and glues with template game source, if you have possibility do OxygenBasic game template, well then this also can use OxygenBasic compiler.
Title: Re: GdiPlus last chance
Post by: Peter on March 19, 2013, 01:35:35 AM
Hi John,

Quote
You will hold the Big Cheese

Oh man, is a long time ago when I played this game.
I had to make many attempts.
I solved some Levels and i needed 30 minutes for ten Levels.
 

X
Title: Re: GdiPlus last chance
Post by: JRS on March 19, 2013, 07:45:18 AM
Quote
I solved some Levels and i needed 30 minutes for ten Levels.

I think that is how much time I spent on level 3 alone.  ;D

You are a true genius!

Thanks for the screen shots. It will give the other Big Cheese's the motivation to give Soko Mouse a try.