John.Wiley.and.Sons.Rapid.Mobile.Enterprise.Development.for.Symbian.OS.An.Introduction.to.OPL.Application.Design.and.Programming.May.2005.eBook-LinG (779881), страница 17
Текст из файла (страница 17)
This technique of using masks will be discussedlater because it’s really important and something you can use in prettymuch any application you build.The CursorUsed to move around the grid so the user can see where the next piecewill be placed.The Othello BoardA completely empty board is saved in our MBM file and copied to themain window at the start of the game.5.1.6Creating the BitmapsCreate your bitmaps in any graphics application (personally I useMicrosoft Windows Paint because it’s simple and gives you pixel perfectcontrol – but anything similar will do).
If you download the example filesfor this project from www.symbian.com/books/rmed/rmed-info.html theoriginal bitmaps can be found in the \Chapter5\Othello\Graphics\folder, along with a text file and a small PC .exe file called BMConv.5.1.7 Using BMConvBMConv (Bitmap File Convertor) is a command line tool that will takea number of Microsoft Windows-format bitmap files, compile them intoa single MBM file, and compress the resultant file for use on SymbianOS. While it is possible to input all the filenames of all your bitmaps onone command line, and not make any spelling mistakes, and get all thestrings right first time, it is highly unlikely!For this reason you can set up a small script in a text file that lists eachcommand to be passed to BMConv on a separate line. This is the txt filein the \Graphics\ folder for Othello.A BMConv ScriptLet’s have a look at the BMConv script for Othello’s three graphics:Othello.mbm/c12Pieces.bmp/c12Cursor.bmp/c12Board.bmp84USING GRAPHICS IN AN OTHELLO GAMEThe first line gives the filename of the MBM we want to make; in thiscase, Othello.mbm.
We then list each bitmap file to be included on aseparate line, and prefix the name of the bitmap file with the color depththat we want that graphic to be stored with in the MBM file.In all these examples, we’ve used 12-bit color; /c for color, and 12 for12-bit. You can equally use /c8 for 8-bit color, and /c16 for 16-bit color.You can also drop the c so /8 corresponds to 8-bit grayscale (which isuseful for legacy devices, but not directly needed on current SymbianOS phones). Given that BMConv isn’t great at scaling down the colorsin your bitmaps, you should ensure you save them from your graphicspackage at the same depth as you specify in the BMConv script file.Note that the bitmap files need to be in the same directory asBMConv.exe for this method to work.Sending the MBM to the PhoneOn the final distribution of any application you would package the MBMfile into your SIS file, but while you are developing, this isn’t alwayspractical.
Assuming you have planned your application correctly, youshould only need to copy over the MBM file once.You can get the file onto your phone using the same techniques as wediscussed in Chapter 2 (Section 2.4.4) for transferring the .opo file.5.2 Designing OthelloIf you’ve never played Othello then here is a quick recap of the rules.The object is to end the game with more of your pieces on the boardthan your opponent.
Play starts with two pieces of each color in thecenter of an 8 × 8 board (see Figure 5.4). The two players take turns tocapture their opponent’s pieces by ‘sandwiching’ one or more opposingpieces in a straight line. When a piece is played at the end of a line ofpieces that starts with another of his pieces, the pieces that have been‘sandwiched’ are captured and change color to that player’s color.When there are no more moves possible for either player, or the boardhas no more empty squares, then the game is over and the player withthe most of his own pieces on the board is the winner.These rules are going to be incredibly useful in planning our computerversion of Othello.
This is a very structured game, and while it is easy torepresent in a program, it still provides a very good challenge for the user.At the start of any program, you need to sketch out how things aregoing to work and how things are done. That’s a lot of things to cover.We’ve identified four areas, one of which (graphics) we’ve just looked at.Let’s now look at the next three areas (representing the board, reading theplayer’s move, making the computer’s move), and then put it all togetherREPRESENTING THE BOARD85Figure 5.4 Othello board at startto make our game.
(As an aside, this is just a real-world example ofbreaking a large problem into smaller and smaller steps. Once you getto the smallest steps possible, it’s those steps you use to write your OPLsource code.)5.3 Representing the Board5.3.1The Board as an ArrayThe Othello board is an 8 × 8 structure, so 64 squares in total. The easiestway to represent this is with an array called Board, with 64 elements. Soright at the top of the skeleton code from Event Core, we’ll add:GLOBAL Board%(64)Any newly declared variable is initially set to a zero value, so if we wereto check any element of Board%() now, we would find it had a valueof 0. Therefore, if a ‘square’ of the Othello board has no pieces on it, thevalue of the corresponding space in the array will be 0.There are two other types of pieces on an Othello board, a white pieceand a black piece.
In our version, white will be the player and black willbe the computer. These will be represented in the Board%() array bythe number 1 (for the player) and 2 (for the computer).86USING GRAPHICS IN AN OTHELLO GAME5.3.2 Using CoordinatesOPL does not have two-dimensional arrays like other BASIC languages, sothe board array is a strip of 64 ‘squares’, while the Othello board is actuallyeight strips of eight. Now while we could just do a lot of hard maths allover the place to work out what square is what array box, we’ll add twoprocedures to our code to simplify our array-based approach to the board:PROC BoardIn:(Sx%,Sy%,Value%)rem *** Place Value% at (Sx,Sy) on Board (0,0 being top left)Board%((KBoardWidth%*Sy%)+(Sx%+1))=Value%ENDPPROC BoardOut%:(Sx%,Sy%)LOCAL Foo%ONERR Marker::rem *** What is at (sx,sy) in the grid? RETURN this value.Foo%=Board%((KBoardWidth*Sy%)+(Sx%+1))ONERR OFFRETURN Foo%Marker::ONERR OFFRETURN 0ENDPWhen you call BoardIn:, you pass three numbers.
The coordinates ofa square on the board (and as noted in the rem comment, the top leftsquare of the board is (0,0)) and the value you want to place in the gridposition. For example, if you wanted to place a player piece (a value of1) in the bottom right square, you would call the procedure with:BoardIn:(7,7,1)Discovering what piece is at a certain square is just as simple.
You callBoardOut%: with the correct coordinate and the value of that square isRETURNed. So after the previous example:WhatIsHere%=BoardOut%:(7,7)would RETURN the value of 1 in to WhatIsHere%.Also note that rather than explicitly state the dimensions of the board,we use a constant to say it is eight squares wide. This is paired withanother constant (can you guess) in the opening lines of the code:CONST KBoardWidth%=8CONST KBoardHeight%=8The code for the board reading is now transportable, and can be droppedinto any program you care to use. For example, a Go board can be 9, 13READING THE PLAYER’S MOVE87or 17 squares wide.
To represent this, all you do is change the constants.This is an example of how code can be re-used between more than oneprogram, and a further benefit of using consistent programming style andvariable names.5.3.3 Setting up Variables and ArraysThe other main value we need to keep track of in the game is the score.In Othello, the score is simply the number of pieces that each player hason the board.
These can be stored in two variables, which again shouldbe globally declared:GLOBAL PlayerScore%, ComputerScore%There is also a constant called KGridSize%. This is the size (in pixels)of one square on the board. In more advanced programs, this could bea variable and one would calculate (when the app is initialized) the bestsize and create all the graphics at the time of starting the game.
In Othello,we’re not going down this road because it’s needlessly complex for ourexample; we’re going to use a fixed size on the grid size of 17 pixels,giving a grid of 136 pixels square, which comfortably fits on the screenof all Symbian OS phones:CONST KGridSize%=17CONST KGridWidth%=8CONST KgridHeight%=8Scaling the KGridSize% could be a good exercise once you have thebasic Othello project working.Finally, KGridWidth% and KGridHeight% say how many squaresare in the grid on each side.
Othello is played on an 8×8 grid.5.4 Reading the Player’s MoveAs with any program, how you get information from the user is sometimesjust as important as what you do with it. In Othello there are two mainareas of interaction. The first will be a simple menu system that allows youto quit the current game and display the current scores. We’ve coveredmenus in the previous chapter, so check you can understand what’s goingon in the source code, as we won’t go over it again here.The second will be how to make a move. This is dependent on thetarget phone. The easiest way to make a move would be on a touchscreen,but devices using Series 60 will need to use a ‘cursor and click’ control.88USING GRAPHICS IN AN OTHELLO GAME5.4.1 Reading the (X,Y) from a Pen TapWith a touch-sensitive screen, the easiest way to make a move is to tapthe square that you want to place your piece on.
Remember that we havea separate graphical window for just the board (where the top left (0,0)coordinate represents the very top left of the physical board). When a pentap happens, the code flows from the main Event Loop procedure intothe PointerDriver: procedure.PROC PointerDriver:IF Ev&(4)=0 : rem Pen has been removed from the screenIF Ev&(3)=Id%(2) : rem Was it in the window with theboard?FooX%=INT(Ev&(6)/GridSize%)FooY%=INT(Ev&(7)/GridSize%)FooValue%=BoardOut:(FooX%,FooY%)MakePlayerMove:(FooX%,FooY%,1)ENDIFENDIFENDPWe’re using more of the values that are returned in the Ev& array (a fulllist of what is in each array element is in the appendix of this book.