Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do i do it ( Playing Card Flip) 2

Status
Not open for further replies.

urosv

Programmer
Mar 3, 2008
10
0
0
SI
Hi all...
I have a problem and need to get your point of view regarding card game.

1. I need to build some kind of animation on event to flip playing card from back side to front and vice versa when needed. My idea is to assign picture to Timage with fron side first. Then over that i add another tImage with Back side animated gif ( trasparent , created Page curl with gif animator), and assign proper gif ( Open / Close ) animation each time i want to show or close card.

I hope my idea is correct. If anybody has different or simplier idea please help me...!

Regards
 
Do you need to flip both ways?
If not why not have the animation end with the flipped image. Then I believe you only need to display the gif and start the animation to display the flip.
I think newer versions of Delphi support .gif by default early ones don't.
I have a third party component called TGifimage that can handle most things to do with gif's
I also found that attempting to run several animated gifs at the same time is very heavy on the CPU (things go very sloooowley), so try to minimise how much animation you do using gifs.
Alternatively might be surprised how few steps you need in an animation to get an effect.
So it could be better to create 3 or 4 stages and update a Timage in steps.




Steve: N.M.N.F.
Playing the blues isn't about feeling better. It's about making other people feel worse.
 
I need to flip only one side the first is static the second is some kind of gif transition that is getiing over the first front face of the card. I used TgifImage component to this but it is dificould to track so many components on the form. First you need 52 cards front faces now i need 52 transition faces in array of the fron faces to access the flipping to certain card,...
 
Have you considered creating an interface to C:\WINDOWS\system32\cards.dll?

Roo
Delphi Rules!
 
Have you considered creating an interface to C:\WINDOWS\system32\cards.dll?

And not that incredibly tough, either, from the documentation I see. Hey, I might make that my next demo program (a good break from figuring out my text-file device driver problem, or my SFN on XP problem. LOL)
 
Okay the fun stuff about cards.dll. First, you don't want to try this on a 95/98/ME system (unless you're on Delphi 1), because guess what? Cards.dll is 16-bit there! Anyway, these projects always end up leading somewhere that involves something I don't know (and end up wanting to know).

Anyway, do know that you'll have to thunk call (I guess) this stuff there. Or easier for this day and age, throw this stuff into a LoadLibrary/GetProcAddress (I did find 16-bit equivalents of those) and simply lock out access to anything that's not NT.

Here you go, there's a few clunky sections (namely the card back names are the old ones, nothing animates in the new cards.dll, and the Draw call has problems with my enumerated types), but hopefully the documentation is there.

Code:
unit cards;
  { interface for CARDS.DLL, allows drawing cards on the screen for card games }
  interface
    type
      DWORD = Integer;
      ColorRef = DWORD;
      HDC = Integer;
      card_type = (ecsFront, ecsBack, ecsSelected, ecsEmpty, ecsErase,
                   ecsEmptyNB, ecsDrawX, ecsDrawO);
      card_suit = (ecsClubs, ecsDiamonds, ecsHearts, ecsSpades);
      card_name = (ecsAce, ecsTwo, ecsThree, ecsFour, ecsFive, ecsSix, ecsSeven,
                   ecsEight, ecsNine, ecsTen, ecsJack, ecsQueen, ecsKing);
    const
      cardsdll = 'CARDS.DLL';
      { card backs }
      ecbCrossHatch = 53;
      ecbWeave1 = 54;
      ecbWeave2 = 55;
      ecbRobot = 56;
      ecbFlowers = 57;
      ecbVine1 = 58;
      ecbVine2 = 59;
      ecbFish1 = 60;
      ecbFish2 = 61;
      ecbShells = 62;
      ecbCastle = 63;
      ecbIsland = 64;
      ecbCardHand = 65;
      ecbUnused = 66;
      ecbThe_X = 67;
      ecbThe_0 = 68;
    var
      carddimx, carddimy: integer; { default card dimensions for cdtDraw }
    { cdtInit initalizes cards, width is card width, height is card height }
    function cdtInit(var width, height: Integer): boolean; stdcall;

    { cdtDraw draws a card on HDC at x, y, with descriptions afterward
      face = 0 or 2, card front, 1 card back
      card = card id (0-51) if type 0 or 2, card back (53-68) if type 1
      color = background color for card back 53 (crosshatch) }
    function cdtDraw(HDC_Canvas: HDC; x, y,
                    card: integer; ctype: card_type; color: ColorRef): boolean; stdcall;

    { same as cdtDraw, except dx and dy specify card dimensions }
    function cdtDrawExt(HDC_Canvas: HDC; x, y, dx, dy,
                    card: integer; ctype: card_type; color: ColorRef): boolean; stdcall;

    { animate card backs - start with frame = 0 and increment until true }
    function cdtAnimate(HDC_Canvas: HDC; cardback,
                    x, y, frame: integer): boolean; stdcall;

    { terminate processing }
    procedure cdtTerm; stdcall;

    function card_desc(incardname: card_name; insuit: card_suit): integer;

  implementation
    function card_desc(incardname: card_name; insuit: card_suit): integer;
    { get card value for descriptions, takes in suit and face,
      and returns proper card #, for displaying specific cards }
      begin
        Result := Integer(incardname) + (Integer(insuit) * 4);
      end;
    function cdtInit; external cardsdll name 'cdtInit';
    function cdtdraw; external cardsdll name 'cdtDraw';
    function cdtdrawext; external cardsdll name 'cdtDrawExt';
    function cdtAnimate; external cardsdll name 'cdtAnimate';
    procedure cdtTerm; external cardsdll name 'cdtTerm';
  initialization
    cdtInit(carddimx, carddimy);
  finalization
    cdtTerm;
  end.

Now to use this thing. Here's the mainly interesting blocks of code:

This draws fronts of cards. Card_desc is defined above and is how to get a specific card and suit - cboCardName and cboCardSuit are Comboboxes which hold that stuff in the same order as the DLL expects it (look in the types for documentation to that end). 250 and 25 are the x and y coords on the Canvas.

Code:
if cdtDraw(Form1.Canvas.Handle, 250, 25,
     Card_desc(card_name(cboCardName.ItemIndex), card_suit(cboCardSuit.ItemIndex)),
          ecsFront, 20) then
        label1.caption := 'Card drawn.'
      else
        label1.caption := 'Card not drawn successfully.';
    end;
end;

You can use either ecsFront or ecsSelected to do your drawing. The first is regular appearance, the second is reversed (highlighted, like if your user clicks on it).

This draws card backs:
Code:
if cdtDraw(Form1.Canvas.Handle, 250, 125,
           cboCardBack.ItemIndex + 54, ecsBack, 20) then
   label1.caption := 'Card drawn.'
else
   label1.caption := 'Card not drawn successfully.';

This should animate cards (though like I said I don't think they animate these days) - better to test this one before you run with it:
Code:
var
  curr_frame: integer;
  retvalue: boolean;
begin
  curr_frame := 0;
  repeat
    retvalue := cdtAnimate(Form1.Canvas.Handle, cboCardBack.ItemIndex + 53,
                    250, 125, curr_frame);
    inc(curr_frame);
  until retvalue = true;
end;

Of course, you can pull the resources out and draw them yourself, but why bother?
 
More documentation on some of the drawmodes (type card_type) (have a peek at Classic Solitaire to understand these):

1) ecsEmpty - puts a cross-hatch over the card area and erases the card. Same effect as clearing the card area (the 4 boxes in the upper right on Solitaire).

2) ecsErase - completely erases the card area.

3) ecsEmptyNB - does the same as #1, but does not erase what is underneath.

These operate with the last parm passed in the cdtDraw - in reality this is a TColor type and can be changed to be such if desired. But I notice that while something like clGreen works, clBtnFace will not.

(hope this all helps someone out)
 
Glenn. Please correct me on this but I did look at Cards.dll a while back and couldn't find a way to.

a. Assign images other than the predefined ones (as listed in your code'
b. Change the size of the cards, I considered this to be the most restrictive thing for the project I was looking at at the time.

Perhaps these things are possible I didn't dig that deep, but these restrictions do seem to effect the windows games (Solitaire and Spider) Try playing Spider maximised on a large screen to see what I mean.


Steve: N.M.N.F.
Playing the blues isn't about feeling better. It's about making other people feel worse.
 
Thanks guys for some tips. dll will not help me simply because restrictions that sggaunt mentioned... Im doing a some kind of gif animation transition over the card now. Its not exacly what i wanted but for now it should be... How about doing card in 3D space OpenGl, DirectX in delphi and put texture of both card sides to very slim restangle???...One question still remains in my problem. When creating components at RunTime, how can you define wich component is behind or in front of other ???

Regards
 
Visual things usually have .bringtofront and .sendtoback methods.
A friend of mine has done DirectX programming in Delphi, I have seen some nice 3D space vector drawing routines he has done. So its certainly possible, but I haven't explored it myself.



Steve: N.M.N.F.
Playing the blues isn't about feeling better. It's about making other people feel worse.
 
sggaunt said:
a. Assign images other than the predefined ones (as listed in your code'

Which could be done - the images are image resources and can be added/changed. Now what Microsoft allows with Cards.dll legally is another story, but ultimately all cards.dll is, is a resource loader/drawer.

sggaunt said:
b. Change the size of the cards, I considered this to be the most restrictive thing for the project I was looking at at the time.

That's what cdtDrawExt does, though all it will do is just stretch scale the image, and doesn't produce something which looks good..

urosv said:
Thanks guys for some tips. dll will not help me simply because restrictions that sggaunt mentioned

If it won't help, at least it should give you a pointer on how to implement your own.
 
urosv said:
Im doing a some kind of gif animation transition over the card now. Its not exacly what i wanted but for now it should be...

As a thought, if you notice all the cards.dll functions take canvas handles. You should be able to define a TCanvas device context within your application and then do whatever you want that you can do through TCanvas.
 
Have you considered creating an interface to C:\WINDOWS\system32\cards.dll?
Wouldn't it be great if there were more people willing to hit the ground running for every idea that was just thrown out there? Glenn, another
star.gif
4U!

Roo
Delphi Rules!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top