mirror of
https://github.com/pythonguis/pythonguis-examples.git
synced 2025-01-27 17:02:56 +08:00
solitaire: Add README.md
This commit is contained in:
parent
074c4c9970
commit
a165bbcf28
@ -30,8 +30,12 @@ found [on my site](http://martinfitzpatrick.name/tag/pyqt).
|
|||||||
1. [Currency converter](currency/) - "Doughnut" (PyQtGraph)
|
1. [Currency converter](currency/) - "Doughnut" (PyQtGraph)
|
||||||
1. [Solitaire](solitaire/) - "Ronery" (QGraphicsScene)
|
1. [Solitaire](solitaire/) - "Ronery" (QGraphicsScene)
|
||||||
|
|
||||||
# License
|
## License
|
||||||
|
|
||||||
All code is **licensed under an MIT license**. This allows you to re-use the code freely,
|
All code is **licensed under an MIT license**. This allows you to re-use the code freely,
|
||||||
remixed in both commercial and non-commercial projects. The only requirement is to
|
remixed in both commercial and non-commercial projects. The only requirement is to
|
||||||
include the same license when distributing.
|
include the same license when distributing.
|
||||||
|
|
||||||
|
## Other licenses
|
||||||
|
|
||||||
|
Icons used in the applications are by [Yusuke Kamiyaman](http://p.yusukekamiyamane.com/).
|
||||||
|
@ -6,16 +6,16 @@ ready made pictures of pie.
|
|||||||
Piecasso is a clone of the Paint programme from Windows 95 (ish) with a
|
Piecasso is a clone of the Paint programme from Windows 95 (ish) with a
|
||||||
few additions (and subtractions). The programme features standard
|
few additions (and subtractions). The programme features standard
|
||||||
tools including pen, brush, fill, spray can, eraser, text and a number of
|
tools including pen, brush, fill, spray can, eraser, text and a number of
|
||||||
shape drawing widgets.
|
shapes.
|
||||||
|
|
||||||
![Piecasso](screenshot-paint.png)
|
![Piecasso](screenshot-paint2.png)
|
||||||
|
|
||||||
You can copy from the image, with a custom shape,
|
You can copy from the image, with a custom shape,
|
||||||
although pasting + floating is not supported. The canvas is a fixed size
|
although pasting + floating is not supported. The canvas is a fixed size
|
||||||
and loaded images are adjusted to fit. A stamp tool is also included
|
and loaded images are adjusted to fit. A stamp tool is also included
|
||||||
which is pre-loaded with pictures of delicious pie.
|
which is pre-loaded with pictures of delicious pie.
|
||||||
|
|
||||||
![Piecasso](screenshot-paint2.png)
|
![Piecasso](screenshot-paint.png)
|
||||||
|
|
||||||
> If you think this example app is neat and want to learn more about
|
> If you think this example app is neat and want to learn more about
|
||||||
PyQt in general, [take a look at my ebook & online course
|
PyQt in general, [take a look at my ebook & online course
|
||||||
|
60
solitaire/README.md
Normal file
60
solitaire/README.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Ronery — A Solitaire game in PyQt
|
||||||
|
|
||||||
|
The classic card Solitaire (Klondike) game with a North Korean /
|
||||||
|
'Team America: World Police' twist. The game is otherwise identical,
|
||||||
|
offering the same options. Built with PyQt, it uses QGraphicsScene
|
||||||
|
to handle the play area.
|
||||||
|
|
||||||
|
![Ronery](screenshot-solitaire.png)
|
||||||
|
|
||||||
|
The classic Solitaire win-screen is also implemented, although since
|
||||||
|
the play canvas is not a bitmap it doesn't "fill up". It's still
|
||||||
|
sufficiently satisfying.
|
||||||
|
|
||||||
|
![Ronery](screenshot-solitaire2.png)
|
||||||
|
|
||||||
|
The configuration options allow for 3-draw and 1 draw styles, with 3, 5
|
||||||
|
or infinite rounds.
|
||||||
|
|
||||||
|
## Code notes
|
||||||
|
|
||||||
|
### Card handling
|
||||||
|
|
||||||
|
The approach I used here was to treat each place where cards can be placed
|
||||||
|
as a 'stack' object, which handles the cards it currently holds. Each stack
|
||||||
|
is responsible for the layout of the cards on it's pile.
|
||||||
|
|
||||||
|
A stack is also responsibly for accepting/rejecting an attempted drop of a
|
||||||
|
card on it. Some stacks, e.g. the deck + deal pile do not accept any drop.
|
||||||
|
Others, such as the finish piles, have specific rules.
|
||||||
|
|
||||||
|
In most cases there is no relationship between any cards on a stack, with
|
||||||
|
the exception of the 'in play' stacks along the bottom. Here cards have
|
||||||
|
a parent-child relationship, allowing multiple cards to be dragged at once.
|
||||||
|
|
||||||
|
### The end animation
|
||||||
|
|
||||||
|
The end-game was a bit weird to implement. Since it happens 'outside' of
|
||||||
|
game time the first thought was to have a self contained loop, using
|
||||||
|
`QApplication.processEvents` to tick over. But that's nasty.
|
||||||
|
|
||||||
|
Instead I used a timer, idle during play, which constantly pings an
|
||||||
|
animation step-forward endpoint. This moves cards (faking 'gravity', bouncing)
|
||||||
|
as well as re-stacking them once they're out of the play area.
|
||||||
|
Restacking uses the normal stacking code.
|
||||||
|
|
||||||
|
The final step was to block event handling, otherwise the cards could
|
||||||
|
still be grabbed while they bounced (and dropped). The easiest way to
|
||||||
|
achieve this was to simply place an event-capturing object over the entire
|
||||||
|
window.
|
||||||
|
|
||||||
|
## Other licenses
|
||||||
|
|
||||||
|
The card images were made from a [freely available set of PNGs](https://github.com/hayeah/playing-cards-assets)
|
||||||
|
which were themselves auto-generated from SVGs traced from actual cards(!).
|
||||||
|
The original card designs are out of copyright.
|
||||||
|
|
||||||
|
Note that the linked repository contains some custom art on ace cards which may still be copyrighted and so
|
||||||
|
was not used.
|
||||||
|
|
||||||
|
Icons used in the application are by [Yusuke Kamiyaman](http://p.yusukekamiyamane.com/).
|
@ -651,8 +651,8 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
if card.pos().x() < - CARD_DIMENSIONS.width():
|
if card.pos().x() < - CARD_DIMENSIONS.width():
|
||||||
card.vector = None
|
card.vector = None
|
||||||
drop = random.choice(self.drops)
|
# Put the card back where it started.
|
||||||
drop.add_card(card)
|
card.stack.add_card(card)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user