Moving a piece

BlitzPlus Forums/BlitzPlus Programming/Moving a piece

Martin W(Posted 2010) [#1]
I have a problem with a square game board, and moving pieces. What I want to do is click on a piece I want to move, and have that piece image attach to and move with the mouse pointer to a new location, then drop the piece on the new location. Subsequently I update the game position by changing the occupancy of the tile vacated and the tile where the piece has been moved to. Sounds simple enough but I haven't been able to find anything in the BlitzPlus help files about changing the mouse pointer to a new image, moving the image around over the rest of the board as background and putting the moved image in the new location. Any ideas?


Matty(Posted 2010) [#2]
There are many ways of doing this, I'm not sure what your experience is with programming but I'll try and give some general tips.

To change the mousepointer:

Use the 'hidepointer' command to hide the windows mouse pointer.
Create an image (or images) which you want to use for your mouse pointer, and use the drawimage command with the coordinates of the mouse position (mousex() mousey()) for the location. The 'frame' flag is useful if you want to have different appearances for the mouse cursor, simply change the frame value, assuming you loaded your image with the loadanimimage command.

For moving the game pieces / objects what I may suggest is as follows:

keep a type list of all your pieces containing (at least) the following variables:

eg:

type mygamepieceobject

field scrx,scry,gameimagehandle,pieceselected

end type



Then, when a piece is clicked on (compare mouse coordinates with the coordinates of your gamepieceobject (scrx & scry), if it is within a certain bounding area set all other pieces "pieceselected" to 0, then set the current piece pieceslected to 1, this is to indicate which piece is selected.

Then in your loop, scan through the list of gamepieces, and for the one which has 'pieceselected' set to 1 draw it at the mouse coordinates.

Hope that gives you some idea.


Martin W(Posted 2010) [#3]
Thanks, Matty. Years ago I programmed a crossword game on the Commodore 64, using sprites for the letters and placing them on the board. That's the effect I was trying to create in BlitzPlus. Here is some code that appears to work. Not very efficient or polished I'll admit.

Global gfxBoardImage, BoardSize, CardsOnBoard
;(other definitions)
Graphics 800, 600, 16, 2 ;a convenient window size
SetBuffer BackBuffer()

; load a game image
BoardSize = 6 ; 6x6 square version

Const CardPath$ = "C:\Data\Projects\BlitzBasic\Kartik\"

gfxBoardImage = LoadImage(CardPath$ + "Kartik" + BoardSize +".bmp")
DrawImage (gfxBoardImage, 0, 0)
;The image has been previously stored from a different program.
Flip
;Save the current state of the game as a background image
SaveBuffer (FrontBuffer(), CardPath$+"Kartik"+"Game.bmp")
WaitKey() ;so that we have a random seed time
SeedRnd MilliSecs()
CardSize = 568/BoardSize - 3 ;defines the size of the card image
Kltr = Rand(59)+1 ; In the real game this was determined in the deal
CardFiles$ = "aaaAbbBccCddeeeEffgghhiiIjkkllLmmnnNooOppqrrRssSttuUvwwxyyz*"
Klnam$ = Mid$(CardFiles$,Kltr,1) ;a letter in the string above
KltA=Asc(Klnam$) ;ASCII value of the letter will be 65 to 90, 97 to 122
;get card image to be played from file
If Kltr = 60 Then
CardImage$ = "KLtrG-"+".bmp" ;naming convention from old version
ElseIf KLtA > 91 Then
CardImage$ = "KLtrB"+Klnam$+".bmp"
Else
CardImage$ = "KLtrR"+Klnam$+".bmp"
End If
;load card image
gfxCardImg = LoadImage(CardPath$ + CardImage$)
ScaleImage gfxCardImg, (0.8*6/BoardSize), (0.8*6/BoardSize)
;it needs scaling to the window size etc.

MoveMouse(100-CardSize/2, 212) ;set the mouse to the initial location

DrawImage(gfxCardImg, 100-CardSize/2, 212) ;draw the card image

Flip

WaitKey() ;just to allow viewing the image
;moving the sprite loop
While CardsOnBoard < BoardSize * BoardSize
gfxBoardImage = LoadImage(CardPath$+"KartikGame.bmp")

While Not MouseDown(1)
;redraw the game state
DrawImage (gfxBoardImage, 0, 0)
;clean up the lines as these tend to be wiped by the card when moving
Color 0, 0, 0 ;color for dividing lines
Rect 216, 16, 568, 568, 0 ;draw edge of tray area.
For i = 1 To BoardSize-1 ;draw grid in tray area
Line 216+(568*i/BoardSize), 16, 216+(568*i/BoardSize), 584
Line 216, 16+568*i/BoardSize, 784, 16+568*i/BoardSize
Next

;Draw card image attached to mouse
DrawImage (gfxCardImg, MouseX(), MouseY())
Flip
Wend
;move sprite to nearest allowed location for card. i & j are cell row & col.
i = Int((MouseX()-216)/(568/BoardSize))
j = Int((MouseY()-16)/(568/BoardSize))
MoveMouse(218+(568*i/BoardSize), 18+(568*j/BoardSize))
DrawImage (gfxBoardImage, 0, 0)
For i = 1 To BoardSize-1 ;draw grid in tray area
Line 216+(568*i/BoardSize), 16, 216+(568*i/BoardSize), 584
Line 216, 16+568*i/BoardSize, 784, 16+568*i/BoardSize
Next

DrawImage (gfxCardImg, MouseX(), MouseY())
Flip

CardsOnBoard = CardsOnBoard + 1
Kltr = Rand(59)+1 ;this isn't how determined in the game
Klnam$ = Mid$(CardFiles$,Kltr,1) ;a letter in the string above

KltA=Asc(Klnam$) ;ASCII value of the letter will be 65 to 90, 97 to 122


If Kltr = 60 Then
CardImage$ = "KLtrG-"+".bmp" ;green star card
ElseIf KLtA > 91 Then
CardImage$ = "KLtrB"+Klnam$+".bmp" ;black letter card
Else
CardImage$ = "KLtrR"+Klnam$+".bmp" ;red letter card
End If

gfxCardImg = LoadImage(CardPath$ + CardImage$)
ScaleImage gfxCardImg, (0.8*6/BoardSize), (0.8*6/BoardSize)
MoveMouse(100-CardSize/2, 212)

DrawImage(gfxCardImg, 100-CardSize/2, 212)

WaitKey() ;now save revised board state
SaveBuffer (FrontBuffer(), CardPath$+"KartikGame.bmp")

Wend

WaitKey()

Some additional comments:
This is just a tryout program to get the basic idea working. The card sprite, attached to the Windows mouse pointer, moves over the background image smoothly and the lines separating the board spaces are redrawn at each interval before the card is redrawn, as I found the lines were getting erased. When the card is positioned somewhere in a board space, it and the mouse are moved to the correct point to center the card on the space. In the real game the board is an array of type BoardCell which has parameters like the coordinates of the card top left point so the calculation here isn't needed, it's done up front. Also the cards aren't randomly selected, they have been "shuffled" and dealt to the players and are taken from each player's hand in turn (more types).
It's a lot less complicated in C-64 BASIC or for that matter Sinclair QL.
Next step, to implement something similar in BlitzMax.