Author Topic: Learning from examples of O2 and expanding them  (Read 531 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Hero Member
  • *****
  • Posts: 931
Learning from examples of O2 and expanding them
« on: October 28, 2019, 07:36:51 AM »
Hello,

in my opinion there are many interesting examples provided with Oxygenbasic which can be used to learn more about the WinApi. For instance, \WinGui\GraphWin.o2bas is a nice sample for this purpose. These are my modifications:

instead of function WinMain() I applied MainWindow() (of winutil.inc)
filled the shapes with color
Space bar can be used to change the size of the Red Square
Left Mouse Button can be used to move the Red Square
Arrow keys can be used to move the Blue Ball (these routines are already provided)
added a Green Ball which happily moves across the window

For me this little demo was very instructive and the routines can probably be applied in more extended apps too.

Roland

This is GraphWin2.o2bas
Code: OxygenBasic
  1. 'Derived from examples\WinGui\GraphWin.o2bas
  2.  
  3. $ filename "GraphWin2.exe"
  4. 'uses rtl32
  5. 'uses rtl64
  6.  
  7. uses winutil
  8.  
  9. % GCLP_HBRBACKGROUND = -10
  10. % COLOR_3DSHADOW=16
  11. % MK_LBUTTON = 1
  12.  
  13. #lookahead ' for procedures
  14.  
  15. 'GLOBAL DEFINITIONS
  16.  
  17. % ID_Timer1  3000
  18. % ID_Timer2  3001
  19.  
  20. sys hdc
  21.  
  22. int r =15, idx =5, idy=5, xball=200, yball=100 'Blue ball
  23. int ix=0 'Green ball interval move
  24. int sLen=50
  25. int sL=50, sT=200
  26. RECT square = {sL, sT, sL+sLen, sT+sLen} 'Red square
  27.  
  28. sys brush_blue = CreateSolidBrush BLUE
  29. sys brush_green = CreateSolidBrush GREEN
  30. sys brush_red = CreateSolidBrush RED
  31.  
  32. dim as RECT crect 'for WndProc and TimerProc
  33.  
  34. string crlf = chr(13,10)
  35.  
  36. -------------------------------------------------------------
  37. MainWindow(800,600, WS_OVERLAPPEDWINDOW)
  38. -------------------------------------------------------------
  39.  
  40. function WndProc (sys hWnd, uint uMsg, sys wParam, lParam) as sys callback
  41.     static as sys count=0, hdc, htimer1, htimer2
  42.     static as String txt
  43.     static as PaintStruct Paintst
  44.     POINT pt
  45.     static bool mayDrag
  46.    
  47.  
  48.     select uMsg
  49.  
  50.     case WM_CREATE
  51.         SetWindowText(hwnd, "OxygenBasic Demo - F1 for Help")
  52.         'Adjust color of MainWindow
  53.        SetClassLongPtr(hwnd,GCLP_HBRBACKGROUND, GetSysColorBrush(COLOR_3DSHADOW))
  54.  
  55.         htimer1 = SetTimer (hWnd, ID_Timer1, 50, &TimerProc)
  56.         htimer2 = SetTimer (hWnd, ID_Timer2, 10, &TimerProc)
  57.         GetClientRect  hWnd,&cRect
  58.  
  59.     case WM_LBUTTONDOWN
  60.         ' Check if square is in the client area.
  61.        GetClientRect(hwnd, &crect)
  62.         pt.x = LOWORD(lParam)
  63.         pt.y = HIWORD(lParam)
  64.  
  65.         if pt.x >= square.left and pt.x <= square.right and
  66.            pt.y >= square.top  and pt.y <= crect.bottom then          
  67.              mayDrag = true              
  68.              SetCapture(hWnd)
  69.         end if
  70.  
  71.      case WM_MOUSEMOVE
  72.         if mayDrag and (MK_LBUTTON & wParam) then
  73.            'Move Red square        
  74.           square.left = LOWORD(lParam)
  75.            square.top  = HIWORD(lParam)
  76.            square.right = square.left + sLen
  77.            square.bottom = square.top + sLen
  78.            Rectangle hdc, square.left, square.top, square.right, square.bottom  
  79.         end if
  80.  
  81.     case WM_LBUTTONUP
  82.         ReleaseCapture()
  83.         mayDrag = false
  84.            
  85.     case WM_PAINT
  86.         'TEXT
  87.        'http://msdn.microsoft.com/en-us/library/dd144821(v=VS.85).aspx
  88.  
  89.         'DRAWING AND PAINTING
  90.        'http://msdn.microsoft.com/en-us/library/dd162760(v=VS.85).aspx
  91.  
  92.         hDC=BeginPaint hWnd,&Paintst
  93.         GetClientRect  hWnd,&cRect
  94.         'style
  95.        '0x20 DT_SINGLELINE
  96.        '0x04 DT_VCENTER
  97.        '0x01 DT_CENTER
  98.        '0x25
  99.  
  100.         SetBkColor   hdc,yellow
  101.         SetTextColor hdc,red
  102.         txt="Blue Ball - x y pos: " str(xball) " , " str(yball)
  103.         DrawText hDC, txt,-1, &cRect, 0x25
  104.         SelectObject(hDC, brush_blue);
  105.         Ellipse hdc, xball-r, yball-r, xball+r, yball+r      'Blue ball
  106.        SelectObject(hDC, brush_green)
  107.         Ellipse hdc, ix, 300, ix+50, 350  'Green Ball
  108.        SelectObject(hDC, brush_red)        
  109.         Rectangle hdc, square.left, square.top, square.right, square.bottom  'Red square
  110.  
  111.         EndPaint hWnd,&Paintst
  112.         ValidateRect hwnd,&crect
  113.  
  114.     case WM_KEYDOWN
  115.         select wParam
  116.  
  117.         case VK_LEFT   : xball -= idx   'LEFT
  118.        case VK_RIGHT  : xball += idx   'RIGHT
  119.        case VK_UP     : yball -= idy   'UP
  120.        case VK_DOWN   : yball += idy   'DOWN
  121.        case VK_SPACE  : sLen += 10 : square.right += 10 : square.bottom += 10   'SPACE
  122.                         if square.right = square.left + 200 then
  123.                            sLen = 50
  124.                            square.right = square.left + sLen
  125.                            square.bottom = square.top + sLen
  126.                          end if  
  127.         case VK_ESCAPE : SendMessage hwnd, WM_CLOSE, 0, 0           'ESCAPE
  128.        case VK_F1 : mbox "Arrow Keys to move Blue Ball" + crlf +
  129.                           "Space bar to change size of Red Square" + crlf +
  130.                           "Press Left MouseButton to move Red Square" + crlf +
  131.                           "Escape to quit"
  132.                  
  133.         end select
  134.  
  135.         'InvalidateRect hwnd, &cRect, 1 'FULL SCREEN REFRESH
  136.  
  137.     case WM_CLOSE
  138.         SendMessage(hWnd, WM_DESTROY, 0,0)
  139.                
  140.     case WM_DESTROY
  141.         KillTimer(hWnd,ID_Timer1)
  142.         KillTimer(hWnd,ID_Timer2)
  143.         DeleteObject(brush_blue)
  144.         DeleteObject(brush_green)
  145.         DeleteObject(brush_red)
  146.         PostQuitMessage 0
  147.  
  148.     case else
  149.         function=DefWindowProc hWnd,uMsg,wParam,lParam
  150.  
  151.     end select
  152. end function ' WndProc
  153.  
  154.  
  155. function TimerProc(sys hWnd, uint uMsg, nIDEvent, dword dwTime) as sys callback
  156.     static sys d=1
  157.  
  158.     select uMsg
  159.  
  160.     case WM_TIMER
  161.         if nIDEvent=ID_Timer1 then        'Blue ball
  162.            InvalidateRect hwnd,&crect,1
  163.             if r=100 then d=-1
  164.             if r=10 then d=1
  165.             r+=d
  166.         end if
  167.         if nIDEvent=ID_Timer2 then        'Green ball
  168.            ix+=2
  169.             if ix>crect.right then ix=-100
  170.         end if
  171.        
  172.         function = 0        
  173.     end select
  174. end function ' TimerProc
  175.  

Arnold

  • Hero Member
  • *****
  • Posts: 931
Re: Learning from examples of O2 and expanding them
« Reply #1 on: October 31, 2019, 04:11:06 AM »
This is a nice game which should be understandable after exploring the code of GraphWin2.o2bas above and HelloWin.o2bas:
https://www.oxygenbasic.org/forum/index.php?topic=1974.msg21098#msg21098

The logic and design of this Breakout Clone is taken from vazbreak.cpp by Phil Vaz:
http://www.vazgames.com/retro/

The exe file and complete code can be found at Bitbucket. I applied this code for several reasons:

- the C-code is very well structured and very well documented
- it is easy to compare the code with the OxygenBasic code and see the differences
- this is a nice way to learn about C and about OxygenBasic
- the logic of the game is complete. I could not do it better.

These are the differences compared with the original:
- instead of using WinMain the game loop is built on MainWindow of \inc\winutil.inc
- VazBreak runs in FullScreen. OxyBricks aims to run in a normal Window with fixed size
- The keys are checked in WndProc, ommiting the GetAsyncKeyState function which is problematic anyway.
- The app is started with pressing: 1 - using Mouse (pressing a MouseButton is not necessary)
-    or pressing: 2 - using the arrow keys to move the paddle
- I also added F1 option for Help

There are two minor issues, where I hope to find a solutions some day: Minimize and Restore (disabled) does not work correctly. Moving the window off the screen and back does also not work quite correctly.

The game itself runs very well in 32-bit and 64-bit mode. Maybe the path for using sound must be corrected:

Code: [Select]
...
'Perhaps must be adapted
string o2dir = "d:\Oxygenbasic\"
string sound_dir = "c:/windows/media/"

string SOUND_HIT1   = "hit1.wav"
string SOUND_HIT2   = "hit2.wav"
string SOUND_HIT3   = "hit3.wav"
string SOUND_MISS   = o2dir +"projectsB\SDL\bmp\shoot.wav"  ' "miss.wav"
string SOUND_PADDLE = sound_dir + "chord.wav"               ' "paddle.wav"
string SOUND_SERVE  = o2dir +"projectsB\SDL\bmp\explo.wav"  ' "serve.wav"
string SOUND_SIDE   = sound_dir + "chimes.wav"              ' "side.wav"
string SOUND_TOP    = sound_dir + "chimes.wav"              ' "top.wav"
...

I only used three wav files of the original, if wished the remaining wav files can be found in the BitBucket repo. BTW: there are a lot more interesting apps and info provided at vazgames.com which would be worth to apply in O2 or get ideas for new projects.

Attached is the code of OxyBricks as a zip file.

This is probably my last major project this year. Other duties will have priority. But hopefully the project will once again show other Oxygenbasic students that many applications are possible with this language.

Roland
« Last Edit: October 31, 2019, 07:49:53 AM by Arnold »

Aurel

  • Sr. Member
  • ****
  • Posts: 428
Re: Learning from examples of O2 and expanding them
« Reply #2 on: October 31, 2019, 10:44:12 AM »
Very well Roland / Arnold  :D
and what about Vaz-asteroids ?  or
Move and Rotate small ship (GDI)...yes it is in cpp
but logic of game should be same ?

Aurel
my site:BLOG and FORUM
https://aurelsoft.ucoz.com/

Arnold

  • Hero Member
  • *****
  • Posts: 931
Re: Learning from examples of O2 and expanding them
« Reply #3 on: November 01, 2019, 03:07:30 AM »
Hi Zlatko,

probably many of the games could be ported to O2 in some way. Personally I was especially interested in this article:

Intro to Game Programming:
http://www.vazgames.com/retro/IntroGameProg.htm

For me as a hobbyist, the text and the examples are very instructive. My attempt at the moment is to create a general game loop template in O2 using the function WinMain or MainWindow, similar to GameLoop1.cpp and GameFullScreen.cpp (can be downloaded from: Demos / Source - C/C++ Win32 Game Loop at vazgames/retro). In OxyBricks I almost managed to adapt the logic loop for a normal sized window, but I think it is not yet complete. Charles has already implemented many of the essential routines in WinUtil.inc, OpenglSceneFrame.inc, GraphUtil.inc and other include files; the goal will be to use these files in a project.

Roland

Aurel

  • Sr. Member
  • ****
  • Posts: 428
Re: Learning from examples of O2 and expanding them
« Reply #4 on: November 01, 2019, 05:57:56 AM »
Quote
the goal will be to use these files in a project
yeah that would be good , most of them are too general ,i am not interested in GL  and i prefer
only GDI, direct X is somehow abandoned from o2 even is main part of any popular windows games.
my site:BLOG and FORUM
https://aurelsoft.ucoz.com/