Xojo Conferences
MBSSep2018MunichDE
XDCMay2019MiamiUSA

Re: [Ann] Making a Card Game with Cards.dll (Real Studio games Mailinglist archive)

Back to the thread list
Previous thread: How do I assign a texture to a material in RB3D?
Next thread: Cloning Trimesh


Re: [Ann] Making a Card Game with Cards.dll   -   Barry Traver
  Re: [Ann] Making a Card Game with Cards.dll   -   Barry Traver
  Re: [Ann] Making a Card Game with Cards.dll   -   Aaron Ballman
   Re: [Ann] Making a Card Game with Cards.dll   -   Barry Traver
    Re: [Ann] Making a Card Game with Cards.dll   -   Aaron Ballman
     Re: [Ann] Making a Card Game with Cards.dll   -   Barry Traver
      Re: [Ann] Making a Card Game with Cards.dll   -   Aaron Ballman
       Re: [Ann] Making a Card Game with Cards.dll   -   Barry Traver

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 05:16 (Tue, 15 Nov 2005 23:16:03 -0500)
From: Barry Traver
Aaron,

I've run into one small problem (probably because I don't really
understand how graphics work).

I've figured out how to use x, y, cx, cy, md, bk, CardNumber, Rank,
Suit, etc., etc., in your sample War card game program, but what I can't
figure out is how to handle the hdc (handle for device context) <sigh>.

What I want to do is something very simple: someone clicks on a
PushButton, and the Ace of Spades appears in a certain location on the
screen. If I can figure out how to do that much, I can do anything else
I need to do at this point to port over the card trick program and to
write some other fun programs (including some simple solitaire programs)..

I'm not sure which "Draw" method to use, but whichever one it is, it
will involve passing a value for hdc. I've figured out that I need to
use Hacks.HDCFromGraphics(g) to get a value for hdc, but I don't know
what to do about the "g." How do I get a value for "g"?? In the
program, I note that it always seems to come into a Sub as a passed
parameter, but I can't seem to see anything on the outside of the Sub
that is passing anything in. Example: the Paint event handler. The
Paint event isn't called by code; it "just happens."

I'm probably missing something very fundamental here. I panic over
graphics. Other types of things that you mentioned in your article I
can do. For example, I didn't understand the graphics in William Yu's
addictive Shisen-So either, but that didn't stop me from adding a high
score feature, the ability to save and reload games, the ability to go
back a step at a time (all the way to the beginning, if desired) or,
having gone back, to go forward again, etc.

But I have trouble following what's going on with "g for graphics,"
partly because when you see changes on the screen, often the code that
caused the changes really was executed a while back, often in a totally
different Method. Thus stepping through the code one step of time,
watching to see what happens when a particular line is executed, often
doesn't reveal much. (And "refresh"? Sometimes it apparently erases
the screen, whereas at other times it makes visible things that have
already been prepared. I don't get it.)

But I can get a lot of mileage out of knowing how to do relatively
simple things, such as making a particular card visible at a particular
location. Any assistance toward that end - from you or from any others
here - will be much appreciated. It's probably pretty elementary stuff
to many here, but not so for me.

Barry Traver

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 05:22 (Tue, 15 Nov 2005 23:22:29 -0500)
From: Barry Traver
The correct spelling for William Yu's game is Shisen-Sho, a tile
solitaire game somewhat like MahJong. It's among the example programs
included with REALbasic. Sorry about the misspelling (I think I also
misspelled Jose's name earlier this evening).

Barry Traver

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 05:51 (Tue, 15 Nov 2005 22:51:44 -0600)
From: Aaron Ballman
> I'm not sure which "Draw" method to use, but whichever one it is, it
> will involve passing a value for hdc. I've figured out that I need to
> use Hacks.HDCFromGraphics(g) to get a value for hdc, but I don't know
> what to do about the "g." How do I get a value for "g"??

g is a Graphics object; usually it's the one passed into the Paint event
for a Canvas or Window object.

> In the
> program, I note that it always seems to come into a Sub as a passed
> parameter, but I can't seem to see anything on the outside of the Sub
> that is passing anything in. Example: the Paint event handler. The
> Paint event isn't called by code; it "just happens."

Correct, Paint is an event that is called by the framework when it's
time to repaint an item. It gets passed a Graphics handle that all the
drawing should happen on. So you can take that Graphics object and use
it when calling one of the Draw methods.

HTH!

~Aaron
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 14:25 (Wed, 16 Nov 2005 08:25:59 -0500)
From: Barry Traver
Aaron,

> g is a Graphics object; usually it's the one passed into the Paint
> event for a Canvas or Window object.
>
> Correct, Paint is an event that is called by the framework when it's
> time to repaint an item. It gets passed a Graphics handle that all
> the drawing should happen on. So you can take that Graphics object
> and use it when calling one of the Draw methods.

OK. Let me see if I'm following this. If "g is a Graphics object,
usually ... the one passed into the _Paint_ event for a Canvas or Window
object" and "_Paint_ is an event that is called by the framework when
it's time to repaint an item" and in that situation _Paint_ "gets passed
a Graphics handle that all the drawing should happen on" and in those
circumstances "you can take that Graphics object and use it when calling
one of the _Draw_ methods," does that mean that you can only use one of
the _Draw_ methods when a _Paint_ event for a Canvas or Window object
has somehow been triggered (since that is that is "usually" how it is done)?

If so, how to you trigger the Paint event (if that's required in order
to be able to use g in one of the Draw methods)? If not - i.e., if the
Paint event is only the "usual" way to get a meaningful value for g as a
passed parameter and not the "only" way - then how else can we
(figuratively speaking) get a "handle" on g?

Or, asking it a somewhat different way, does the Draw method itself
somehow have to be triggered by (or inside) a Paint event?

Or, to put it yet another way, how does one accomplish the simple act of
drawing a particular card face up at a particular location?

From your response, apparently I'm saying the "Correct" words, but I
don't have any confidence that I really have hold on what's happening,
and I still don't understand it well enough to accomplish what should be
a simple task, i.e., making a card appear where I want it to appear when
I want it to appear.

Since, as you said earlier, classes are "so powerful and really are the
crux of what object-oriented programming is all about," let me venture
for a moment to try my hand at classes (and OOP)....

Here's my idea of how a class and object-oriented programming _should_
work ideally. A programming object such as a "card" has attributes
that are as much as possible just like the real-world object, i.e., it
has suit, rank, x-location, y-location, visibility, side showing, etc..

If "card" is the class and "PlayerCard" is a specific object based on
that class, then to make that card into the Ace of Spades, it should be
a simple matter of saying PlayerCard.Rank = "Ace" and PlayerCard.Suit =
"Spades." And to put that card in the left-hand corner of the screen,
it should be a simple matter of saying PlayerCard.X = "0" and
PlayerCard.Y = 0. And to make that card visible, it should be a simple
matter of saying PlayerCard.Visible = True. And so on.

To give a slightly more complicated example (one using arrays), to deal
out a poker hand should be a simple matter of having five cards for each
player, e.g., for four players defining in the process
Player(1).Card(1).Rank, etc. through Player(4).Card(5).Rank, etc.
(including also definitions for Suit, X- and Y- positions, Visibility,
SideShowing, etc.), all the Properties needed for the twenty cards..

But it's apparently not that simple, at least in the graphics world,
where seemingly it is impossible to take such a common-sensible approach
(in my mind) to defining a class, because (1) getting a "handle" on a
graphical object is an arcane event, a well-kept secret known only to
the initiated, and (2) you can't change how something is pictured except
through some difficult contortions involving the Paint event.

Feel free to straighten me out on what a "class" is and what "OOP" is.
Please let me know where the preceding approach is wrong, because it's
my best attempt at present to think in terms of OOP and in terms of
"classes." (I hope what I've said shows that I _am_ seriously
attempting to do my best to make some progress in understanding such
things.)

Barry Traver

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 16:02 (Wed, 16 Nov 2005 09:02:19 -0600)
From: Aaron Ballman
> OK. Let me see if I'm following this. If "g is a Graphics object,
> usually ... the one passed into the _Paint_ event for a Canvas or Window
> object" and "_Paint_ is an event that is called by the framework when
> it's time to repaint an item" and in that situation _Paint_ "gets passed
> a Graphics handle that all the drawing should happen on" and in those
> circumstances "you can take that Graphics object and use it when calling
> one of the _Draw_ methods," does that mean that you can only use one of
> the _Draw_ methods when a _Paint_ event for a Canvas or Window object
> has somehow been triggered (since that is that is "usually" how it is
> done)?

Not only -- you can get a Graphics object from a Picture for example,
and draw directly into a Picture object. But ultimately, if you want
this to show up on the screen, you should be doing it in the Paint event.

> If so, how to you trigger the Paint event (if that's required in order
> to be able to use g in one of the Draw methods)? If not - i.e., if the
> Paint event is only the "usual" way to get a meaningful value for g as a
> passed parameter and not the "only" way - then how else can we
> (figuratively speaking) get a "handle" on g?

You can trigger a Paint event by calling Refresh on what you want
painted (so you could call Canvas.Refresh, or Window.Refresh, etc).

> Or, to put it yet another way, how does one accomplish the simple act of
> drawing a particular card face up at a particular location?

Put the following code in the Window.Paint event:

someCardObject.DrawFaceUp( g, 25, 25 )

That'll draw the card at 25, 25 (relative to the window's upper left of
the client area).

HTH!

~Aaron
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 17:18 (Wed, 16 Nov 2005 11:18:52 -0500)
From: Barry Traver
Aaron Ballman wrote:

> Put the following code in the Window.Paint event:
> someCardObject.DrawFaceUp( g, 25, 25 )
> That'll draw the card at 25, 25 (relative to the window's upper left
> of the client area).
> HTH!

Thank you, thank you, thank you! It's working _great_, but there is
one unexpected bit of behavior (maybe two) taking place: (1) the new
graphic is being drawn _under_ what is already drawn there (in a sense
that's good, because I want to be able to draw cleanly overlapping
cards), when I would have expected it to be drawn _on top of_ what's
there, and (2) I seem to have created a clone of an already-existing
graphical object (because I have two Aces of Spades visible)..

Simple illustration coming up. To your War cards program, I added a
Pushbutton with this code in its Action event:

Dim I As Integer
DoGraphics = True
For I = 0 to 240 Step 20
MyRank = 0
MySuit = 3
MyX = I
MyY = 85
WarWindow.Refresh
MsgBox "Pause"
Next I
DoGraphics = False

(DoGraphics is a public Boolean, and MyRank, MySuit, MyX, and MyY are
all public Integers.)

Then I put this in the WarWindow.Paint event:

If DoGraphics Then
mPlayerCard.Rank = MyRank
mPlayerCard.Suit = MySuit
mPlayerCard.DrawFaceUp( g, MyX, MyY )
End If

Run the program, click once on the top of the stack (necessary so that
the mPlayerCard object is created), click on the PushButton, and click
repeatedly on the "OK" button on the MsgBox.

The Ace of Spades _does_ appear in the proper place, But (surprise!)
overlapping it are the two cards on the left (the bottom one of which
has also changed to the Ace of Spades, but that's another topic) and
even under the printed words "Opponent won!" (or, as the case may be,
"Player won!").

As you click repeatedly on the "OK" button on the MsgBox, the Ace of
Spades overlapped by the other two face-up cards moves cleanly to the
right, remaining _under_ both the other two cards and the printing, and
continues moving until it has completely passed also _under_ the stack
of cards on the right! There is no mess-up in the drawing (nothing
needs to be erased): it looks _exactly_ as if the one card were being
slid _under_ the other cards as it moves from left to right.

I think I can probably figure out myself why the Ace of Spades looks as
if it were cloned (there continues to be an Ace of Spades on the bottom
left of the original display), but I'm surprised that the new card
appears _under_ (not on top of) everything else that has previously been
drawn.

Is there an easy explanation of what is going on?

Barry Traver

P.S. I searched for the word "opaque" in the Language Reference, but
didn't turn up anything relevant. Is there some similar property here
that may be involved?

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 18:07 (Wed, 16 Nov 2005 11:07:53 -0600)
From: Aaron Ballman
> Dim I As Integer
> DoGraphics = True
> For I = 0 to 240 Step 20
> MyRank = 0
> MySuit = 3
> MyX = I
> MyY = 85
> WarWindow.Refresh
> MsgBox "Pause"
> Next I
> DoGraphics = False

What this code is going to do is put a bunch of aces of Spades all over
the window in a straight line.

> The Ace of Spades _does_ appear in the proper place, But (surprise!)
> overlapping it are the two cards on the left (the bottom one of which
> has also changed to the Ace of Spades, but that's another topic) and
> even under the printed words "Opponent won!" (or, as the case may be,
> "Player won!").

Because you're stepping by 20, and the card widths themselves may be
more, might be the reason why you're getting some sort of overlap.
However, it sounds to me like you're confused about the order of
drawing. When you paint something directly on to the window (which is
essentially what's happening here), the operations can become "stacked"
based on the order you draw things. If you draw Card 1 and then draw
Card 2, the second operation will occlude the first one (assuming their
bounds overlap) because the first one is already painted onto the window
and the second one paints over it. The same concept is true for
controls -- they have a z-ordering just like paint operations do. So
what is probably happening is that you're painting the card, and then a
StaticText "paints" its Text over the card.

> As you click repeatedly on the "OK" button on the MsgBox, the Ace of
> Spades overlapped by the other two face-up cards moves cleanly to the
> right, remaining _under_ both the other two cards and the printing, and
> continues moving until it has completely passed also _under_ the stack
> of cards on the right! There is no mess-up in the drawing (nothing
> needs to be erased): it looks _exactly_ as if the one card were being
> slid _under_ the other cards as it moves from left to right.

Because you're using MsgBox as a way to pause your application, you
cannot rely on anything you see. You're using MsgBox in the wrong way.
Try using App.SleepCurrentThread( 1000 ) for a 1-second pause instead.

HTH!

~Aaron
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: [Ann] Making a Card Game with Cards.dll
Date: 16.11.05 19:31 (Wed, 16 Nov 2005 13:31:14 -0500)
From: Barry Traver
Aaron Ballman wrote:

> What this code is going to do is put a bunch of aces of Spades all
> over the window in a straight line.
>
NO! It does NOT put "a bunch of aces of Spades all over the Window."
It puts ONLY (and never more than) TWO aces of Spades in the Window, one
to replace the card at the bottom left which doesn't ever move, and the
other which very neatly moves from left to right. (Maybe I didn't make
that clear because I used the word "overlap.")

To repeat, there are only TWO Aces of Spades, and one of them moves very
"neatly" from left to right. When it is drawn at a new position, the
Ace of Spades at the immediate previous position on the left is very
neatly erased.

> Because you're stepping by 20, and the card widths themselves may be
> more, might be the reason why you're getting some sort of overlap.

"Overlap" may not have been the best choice of words to describe it.
The new Ace of Spades, the one that moves, moves "under" the existing
graphics (the existing cards) in a very realistic way. You'd swear that
you were watching a film, with the same kind of two-dimentional
representation producing an amazing illusion of three-dimensional reality.

> However, it sounds to me like you're confused about the order of
> drawing. When you paint something directly on to the window (which is
> essentially what's happening here), the operations can become
> "stacked" based on the order you draw things. If you draw Card 1 and
> then draw Card 2, the second operation will occlude the first one
> (assuming their bounds overlap) because the first one is already
> painted onto the window and the second one paints over it. The same
> concept is true for controls -- they have a z-ordering just like paint
> operations do. So what is probably happening is that you're painting
> the card, and then a StaticText "paints" its Text over the card

I'm not sure exactly what you mean by "occlude," but if you mean
something that looks like what you might get when you do a "double
exposure" of a card moving to the right (see my P.S.), that is NOT what
is happening. (I would not have been surprised if that had hapened; in
fact, I would have expected it; but that is NOT what is happening.)
When the new card is placed at the new position, the card at the old
position not only is removed, but removed in such a fashion that the
graphics are not messed up in any way.

> .
>
>> As you click repeatedly on the "OK" button on the MsgBox, the Ace of
>> Spades overlapped by the other two face-up cards moves cleanly to the
>> right, remaining _under_ both the other two cards and the printing,
>> and continues moving until it has completely passed also _under_ the
>> stack of cards on the right! There is no mess-up in the drawing
>> (nothing needs to be erased): it looks _exactly_ as if the one card
>> were being slid _under_ the other cards as it moves from left to right.
>
> Because you're using MsgBox as a way to pause your application, you
> cannot rely on anything you see. You're using MsgBox in the wrong
> way. Try using App.SleepCurrentThread( 1000 ) for a 1-second pause
> instead.

I just tried it again, replacing the MsgBox "Pause" with
App.SleepCurrentThread( 1000 ), as you suggested, and apparently in this
particular situation it makes no difference. (Well, there is a _slight_
difference, in that if you watch very closely you can see a slight
flicker as the graphics are redrawn, BUT this does not take away from
the fact the effect produced is that the new moving Ace _is_ moving from
left to right, _leaving no traces behind it_.)

> HTH!

Your comments are _always_ helpful, even when I may not have expressed
myself clearly and you may or may not have understood exactly what it
was that I was trying to say.

Barry Traver

P.S. Maybe I should explain what I mean by "double exposure." Imaging
taking a picture of the three of diamonds. Then, without changing the
position of the camera or advancing the film, move the card slightly to
the right, and take another picture. The result is a picture of a card
that looks slightly wider than usual (perhaps with fuzzy edges) and that
contains six diamonds. Well, that is NOT what is happening in this
scenario. The film _is_ advanced for each new picture. There _are_ no
double exposures. There are never more than TWO Aces of Spades on the
screen at one time.

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>