├── .gitignore
├── .idea
├── Pygame_Functions.iml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── LICENSE
├── README.md
├── demos
├── Agent (Animation Demo).py
├── DrawingShapes.py
├── KeyCodes.py
├── Moon Lander (Sprites demo).py
├── Moon Lander 2 (with text label).py
├── ResizeDemo.py
├── RocketDemo.py
├── RocketDemo2.py
├── RocketDemo3.py
├── RocketDemo4.py
├── __pycache__
│ └── pygame_functions.cpython-311.pyc
├── animationDemo2.py
├── buttonDemo.py
├── flipDemo.py
├── images
│ ├── Jurassic.jpg
│ ├── agent1.png
│ ├── agent2.png
│ ├── agent3.png
│ ├── agent4.png
│ ├── agent5.png
│ ├── agent6.png
│ ├── agent7.png
│ ├── agent8.png
│ ├── agentpunch1.png
│ ├── agentpunch2.png
│ ├── asteroid.png
│ ├── button1.png
│ ├── button2.png
│ ├── corridor.png
│ ├── dungeonFloor.png
│ ├── dungeonFloor1.png
│ ├── dungeonFloor2.png
│ ├── dungeonFloor3.png
│ ├── dungeonFloor4.png
│ ├── greendot.png
│ ├── lander.png
│ ├── landerCrash.png
│ ├── links.gif
│ ├── moonSurface.jpg
│ ├── redasteroid.png
│ ├── rocket1.png
│ ├── rocket2a.png
│ ├── rocket2b.png
│ ├── smalllinks.gif
│ └── stars.png
├── multilineLabel.py
├── pygame_functions.py
├── robotron.py
├── scrollDemo.py
├── sounds
│ └── Rocket-SoundBible.wav
└── textDemo.py
└── pygame_functions.py
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/launch.json
2 | demos/__pycache__/pygame_functions.cpython-37.pyc
3 | demos/__pycache__/pygame_functions.cpython-38.pyc
4 |
--------------------------------------------------------------------------------
/.idea/Pygame_Functions.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 | screensize
27 | setbackgr
28 | updatedispl
29 | clears
30 | update
31 | setba
32 | pygame.surface
33 | setsp
34 | addimage
35 | bl
36 | blit
37 | framnes
38 | fr
39 | frames
40 | spriteshee
41 | make
42 | settiles
43 | scrollba
44 | makesprite
45 | setback
46 | changeImage
47 | setbackgroun
48 | endwait
49 | pause
50 | movesprite
51 | changesprite
52 | mak
53 | scroll
54 | keptr
55 | keypress
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | 1483193307379
243 |
244 |
245 | 1483193307379
246 |
247 |
248 | 1500476902364
249 |
250 |
251 |
252 | 1500476902364
253 |
254 |
255 | 1511218806844
256 |
257 |
258 |
259 | 1511218806844
260 |
261 |
262 | 1518040675020
263 |
264 |
265 |
266 | 1518040675020
267 |
268 |
269 | 1524172379199
270 |
271 |
272 |
273 | 1524172379199
274 |
275 |
276 |
277 |
278 |
279 |
280 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pygame_functions
2 |
3 | This is a set of functions to make using Pygame easier.
4 |
5 | Check out the wiki at https://github.com/StevePaget/Pygame_Functions/wiki
6 |
7 | See video tutorials at https://www.youtube.com/playlist?list=PLeOSHd3t9lzKr4O3A3Q7OZyf8QwyCALyn
8 |
9 | Please raise issues or request new features at https://github.com/StevePaget/Pygame_Functions/issues
10 |
--------------------------------------------------------------------------------
/demos/Agent (Animation Demo).py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 |
4 | screenSize(500,245)
5 | setBackgroundImage("images/corridor.png") # A background image always sits behind the sprites
6 |
7 | agent = makeSprite("images/agent7.png") # We create the sprite with the default image
8 | addSpriteImage(agent, "images/agent8.png") # Add extra images. They are stored in the Sprite object
9 | addSpriteImage(agent, "images/agent1.png") # but not displayed yet
10 | addSpriteImage(agent, "images/agent2.png")
11 | addSpriteImage(agent, "images/agent3.png")
12 | addSpriteImage(agent, "images/agent4.png")
13 | addSpriteImage(agent, "images/agent5.png")
14 | addSpriteImage(agent, "images/agent6.png") # See the alternative way of doing this with a Sprite Sheet
15 |
16 | agentX = 200 # Set the X position on the screen
17 | agentImage = 0 # This lets us track the current animation frame for the agent
18 | moveSprite(agent, agentX, 120)
19 | showSprite(agent)
20 | nextFrame = clock() # This lets us schedule the time for the next animation frame using the internal clock
21 |
22 | while True:
23 |
24 | if keyPressed("right"):
25 | if clock() > nextFrame: # It is time for the next animation frame
26 | agentImage +=1 # Move the animation on by one frame
27 | if agentImage > 7: # We have 8 frames, so loop round to the start
28 | agentImage = 0
29 | changeSpriteImage(agent, agentImage)
30 | nextFrame = clock() + 60 #schedule the next frame 60 milliseconds from now
31 |
32 | agentX +=7 # Change the position for the sprite
33 | if agentX>500: # If reached the edge, loop round the screen
34 | agentX=-20
35 |
36 | moveSprite(agent, agentX, 120) # Actually move the sprite
37 |
38 | else:
39 | agentImage = 0 # If the key is not being pressed, switch back to "standing" frame
40 | changeSpriteImage(agent, agentImage)
41 |
42 | tick(30) #The movement runs at 30 frames per second, even though the agent image is only changed every 60ms
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/demos/DrawingShapes.py:
--------------------------------------------------------------------------------
1 | # Demonstration of using draw commands to draw simple shapes using pygame_functions.
2 |
3 | from pygame_functions import *
4 |
5 | screenSize(400,400) # Create a window of 400 pixels square
6 | setBackgroundColour("white")
7 |
8 | drawEllipse(200,200,350,350,"lightblue")
9 |
10 | drawRect(100,100,200,200,"darkgreen", 3)
11 |
12 | drawTriangle(150,150,180,150,165,180,"red") # You can use an HTML color name
13 |
14 | drawTriangle(220,150,250,150,235,180,[255,100,50]) # or use an RGB colour definition
15 |
16 | drawPolygon([ (110,250) , (290,250) , (280,220), (120,220) ], "sienna" ) # note the pairs of coordinates within the point list.
17 |
18 |
19 |
20 | endWait()
--------------------------------------------------------------------------------
/demos/KeyCodes.py:
--------------------------------------------------------------------------------
1 | #Displays key codes on screen to aid key identification. Esc to quit
2 |
3 | from pygame_functions import *
4 |
5 | screenSize(300,100)
6 |
7 | infoLabel = makeLabel("Key Code:", 20, 50,10,"white")
8 | showLabel(infoLabel)
9 |
10 | while True:
11 | key = waitPress()
12 | changeLabel(infoLabel,"Key Code: " + str(key))
13 | if key==27:
14 | break
15 | pause(1000, False)
16 |
--------------------------------------------------------------------------------
/demos/Moon Lander (Sprites demo).py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 | screenSize(750,750)
4 | setBackgroundImage("images/stars.png")
5 | setIcon("images/lander.png")
6 | setWindowTitle("Moon Lander")
7 |
8 | surface = makeSprite("images/moonSurface.jpg") # create the sprite object
9 | moveSprite(surface, 0, 650) # move it into position. It is not visible yet
10 | showSprite(surface) # display it
11 |
12 | lander = makeSprite("images/lander.png") # create the sprite object
13 | addSpriteImage(lander,"images/landerCrash.png") # add the crashed image
14 | moveSprite(lander, 280, 0) # move it into position. It is not visible yet
15 | showSprite(lander) # display it
16 |
17 |
18 | ypos = 0
19 | yspeed = 0
20 | upthrust = 0
21 |
22 | while True:
23 | if keyPressed("up"): # check the Wiki for a list of keys that are recognised
24 | upthrust = 2
25 | else:
26 | upthrust = 0
27 |
28 | ypos += yspeed
29 | moveSprite(lander, 280, ypos)
30 | yspeed += 1 - upthrust # add a bit of acceleration due to gravity
31 |
32 |
33 | if touching(lander, surface):
34 | ypos = 650 - 150 # place the lander on the surface
35 | if yspeed > 10:
36 | changeSpriteImage(lander, 1)
37 | yspeed = 0 # stop the movement
38 | pause(1000)
39 | break
40 | tick(30)
41 |
42 | endWait()
43 | print("done")
44 |
--------------------------------------------------------------------------------
/demos/Moon Lander 2 (with text label).py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 | screenSize(750,750)
4 | setBackgroundImage("images/stars.png")
5 |
6 |
7 | surface = makeSprite("images/moonSurface.jpg") # create the sprite object
8 | moveSprite(surface, 0, 650) # move it into position. It is not visible yet
9 | showSprite(surface) # display it
10 |
11 | lander = makeSprite("images/lander.png") # create the sprite object
12 | addSpriteImage(lander,"images/landerCrash.png") # add the crashed image
13 | moveSprite(lander, 280, 0) # move it into position. It is not visible yet
14 | showSprite(lander) # display it
15 |
16 | fuelColour = "yellow"
17 | fuelLabel = makeLabel("Fuel: 50", 28, 10, 10, fuelColour)
18 | showLabel(fuelLabel)
19 |
20 | ypos = 0
21 | yspeed = 0
22 | upthrust = 0
23 | fuel = 50
24 |
25 | while True:
26 | if keyPressed("up") and fuel > 0: # only allow thrust if some fuel exists
27 | upthrust = 2
28 | fuel = fuel - 1 # remove some fuel
29 | if fuel < 10:
30 | fuelColour = "red" # Warning for low fuel
31 |
32 | changeLabel(fuelLabel,"Fuel: " + str(int(fuel)), fuelColour) # Update the label
33 | else:
34 | upthrust = 0
35 |
36 | ypos += yspeed
37 | moveSprite(lander, 280, ypos)
38 | yspeed += 1 - upthrust # add a bit of acceleration due to gravity
39 |
40 |
41 | if touching(lander, surface):
42 | ypos = 650 - 150 # place the lander on the surface
43 | if yspeed > 10:
44 | changeSpriteImage(lander,1)
45 | yspeed = 0 # stop the movement
46 | break
47 |
48 |
49 | tick(30)
50 |
51 |
52 |
--------------------------------------------------------------------------------
/demos/ResizeDemo.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 | screenSize(1000, 750)
4 | setBackgroundImage("images/stars.png")
5 |
6 | rocket = makeSprite("images/rocket1.png")
7 | moveSprite(rocket,500,300)
8 |
9 | showSprite(rocket)
10 |
11 | scale = 10
12 | scaleChange = 10
13 | angle = 0
14 |
15 | while True:
16 | angle +=5
17 | scale += scaleChange
18 | transformSprite(rocket, angle, scale/100)
19 | if scale > 300:
20 | scaleChange = -10
21 | elif scale <20:
22 | scaleChange = 10
23 | pause(20)
24 |
25 | endWait()
26 |
--------------------------------------------------------------------------------
/demos/RocketDemo.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 | screenSize(1000, 750)
4 | setBackgroundImage("images/stars.png")
5 |
6 | rocket = makeSprite("images/rocket1.png")
7 | addSpriteImage(rocket,"images/rocket2a.png")
8 |
9 |
10 | xPos = 500
11 | yPos = 320
12 | xSpeed = 0
13 | ySpeed = 0
14 | moveSprite(rocket, xPos, yPos)
15 | showSprite(rocket)
16 |
17 | while True:
18 | if keyPressed("up"):
19 | changeSpriteImage(rocket,1)
20 | transformSprite(rocket, 0,1)
21 | ySpeed -= 2
22 |
23 | elif keyPressed("down"):
24 | changeSpriteImage(rocket,1)
25 | transformSprite(rocket, 180,1)
26 | ySpeed += 2
27 |
28 | elif keyPressed("right"):
29 | changeSpriteImage(rocket,1)
30 | transformSprite(rocket, 90,1)
31 | xSpeed += 2
32 |
33 | elif keyPressed("left"):
34 | changeSpriteImage(rocket,1)
35 | transformSprite(rocket, -90,1)
36 | xSpeed -= 2
37 |
38 | else:
39 | changeSpriteImage(rocket,0)
40 |
41 | xPos += xSpeed
42 | if xPos > 960:
43 | xPos = -100
44 | elif xPos < -100:
45 | xPos = 960
46 |
47 | yPos += ySpeed
48 | if yPos > 700:
49 | yPos = -100
50 | elif yPos < -100:
51 | yPos = 700
52 |
53 | moveSprite(rocket, xPos, yPos)
54 |
55 | tick(30)
56 |
57 | endWait()
58 |
--------------------------------------------------------------------------------
/demos/RocketDemo2.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 | import math
3 |
4 | screenSize(1000, 750)
5 | setBackgroundImage("images/stars.png")
6 |
7 | rocket = makeSprite("images/rocket1.png")
8 | addSpriteImage(rocket,"images/rocket2a.png")
9 | addSpriteImage(rocket,"images/rocket2b.png")
10 |
11 | thrustSound = makeSound("sounds/Rocket-SoundBible.wav")
12 |
13 |
14 | xPos = 500
15 | yPos = 320
16 | xSpeed = 0
17 | ySpeed = 0
18 | angle=0
19 | thrustAmount = 0.5
20 | moveSprite(rocket, xPos, yPos,True)
21 | showSprite(rocket)
22 | thrustFrame = 1
23 | nextframe = clock()
24 |
25 | while True:
26 | if keyPressed("left"):
27 | angle = angle - 5
28 |
29 | transformSprite(rocket, angle, 1)
30 |
31 | elif keyPressed("right"):
32 | angle = angle +5
33 | transformSprite(rocket, angle, 1)
34 |
35 | if keyPressed("up"):
36 | if clock() > nextframe:
37 | nextframe = clock() + 200
38 | if thrustFrame == 1:
39 | changeSpriteImage(rocket,1)
40 | thrustFrame=2
41 | else:
42 | changeSpriteImage(rocket,2)
43 | thrustFrame=1
44 | # use Trigonometry to convert the thrust into 2 components, x and y
45 | xSpeed += math.sin(math.radians(angle)) * thrustAmount
46 | ySpeed -= math.cos(math.radians(angle)) * thrustAmount
47 | playSound(thrustSound)
48 |
49 | else:
50 | changeSpriteImage(rocket,0)
51 | stopSound(thrustSound)
52 |
53 | xPos += xSpeed
54 | if xPos > 1000:
55 | xPos = 0
56 | elif xPos < 0:
57 | xPos = 1000
58 |
59 | yPos += ySpeed
60 | if yPos > 750:
61 | yPos = 0
62 | elif yPos < 0:
63 | yPos = 750
64 |
65 | moveSprite(rocket, xPos, yPos,True)
66 | tick(30)
67 |
68 | endWait()
69 |
--------------------------------------------------------------------------------
/demos/RocketDemo3.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 | import math, random
3 |
4 | screenSize(1000, 750)
5 | setBackgroundImage("images/stars.png")
6 |
7 | rocket = makeSprite("images/rocket1.png")
8 | addSpriteImage(rocket,"images/rocket2a.png")
9 | addSpriteImage(rocket,"images/rocket2b.png")
10 | thrustSound = makeSound("sounds/Rocket-SoundBible.wav")
11 |
12 |
13 | # we will store our asteroid sprites in a list
14 | asteroids = []
15 | for x in range(5):
16 | thisAsteroid = makeSprite("images/asteroid.png")
17 | # we will also add an alternative image to each sprite
18 | addSpriteImage(thisAsteroid, "images/redasteroid.png")
19 | # we will give each asteroid a random x position and a random y position
20 | # we will use dot notation to store this position *inside* the Sprite object
21 | thisAsteroid.x = random.randint(0,1000)
22 | thisAsteroid.y = random.randint(0,750)
23 | moveSprite(thisAsteroid, thisAsteroid.x, thisAsteroid.y)
24 | #also, store a random x speed and random y speed inside each asteroid Sprite
25 | thisAsteroid.xspeed = random.randint(-5,5)
26 | thisAsteroid.yspeed = random.randint(-5,5)
27 | showSprite(thisAsteroid)
28 | #now add this asteroid to the list
29 | asteroids.append(thisAsteroid)
30 |
31 | xPos = 500
32 | yPos = 320
33 | xSpeed = 0
34 | ySpeed = 0
35 | angle=0
36 | thrustAmount = 0.5
37 | moveSprite(rocket, xPos, yPos,True)
38 | showSprite(rocket)
39 | thrustFrame = 1
40 | nextframe = clock()
41 |
42 | while True:
43 | if keyPressed("left"):
44 | angle = angle - 5
45 |
46 | transformSprite(rocket,angle,1)
47 |
48 | elif keyPressed("right"):
49 | angle = angle +5
50 | transformSprite(rocket, angle, 1)
51 |
52 | if keyPressed("h"):
53 | hideAll()
54 |
55 | if keyPressed("u"):
56 | unhideAll()
57 |
58 |
59 | if keyPressed("up"):
60 | if clock() > nextframe:
61 | nextframe = clock() + 200
62 | if thrustFrame == 1:
63 | changeSpriteImage(rocket,1)
64 | thrustFrame=2
65 | else:
66 | changeSpriteImage(rocket,2)
67 | thrustFrame=1
68 | # use Trigonometry to convert the thrust into 2 components, x and y
69 | xSpeed += math.sin(math.radians(angle)) * thrustAmount
70 | ySpeed -= math.cos(math.radians(angle)) * thrustAmount
71 | playSound(thrustSound)
72 |
73 | else:
74 | changeSpriteImage(rocket,0)
75 | stopSound(thrustSound)
76 |
77 | xPos += xSpeed
78 | if xPos > 1000:
79 | xPos = 0
80 | elif xPos < 0:
81 | xPos = 1000
82 |
83 | yPos += ySpeed
84 | if yPos > 750:
85 | yPos = 0
86 | elif yPos < 0:
87 | yPos = 750
88 |
89 | moveSprite(rocket, xPos, yPos,True)
90 |
91 | # now we will move all the asteroids by their speeds
92 | for thisAsteroid in asteroids:
93 | thisAsteroid.x += thisAsteroid.xspeed
94 | if thisAsteroid.x > 1000:
95 | thisAsteroid.x = 0
96 | elif thisAsteroid.x < 0:
97 | thisAsteroid.x = 1000
98 |
99 | thisAsteroid.y += thisAsteroid.yspeed
100 | if thisAsteroid.y > 750:
101 | thisAsteroid.y = 0
102 | elif thisAsteroid.y < 0:
103 | thisAsteroid.y = 750
104 |
105 | moveSprite(thisAsteroid, thisAsteroid.x, thisAsteroid.y)
106 |
107 | # now we will grab a list of all the sprites that are currently touching the rocket
108 | hitAsteroids = allTouching(rocket)
109 | # and change the image of each one
110 | for thisHitAsteroid in hitAsteroids:
111 | changeSpriteImage(thisHitAsteroid,1)
112 |
113 | tick(30)
114 |
115 | endWait()
116 |
--------------------------------------------------------------------------------
/demos/RocketDemo4.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 | import math, random
3 |
4 | # This version is used to demonstrate the more efficient use of setAutoUpdate and updateDisplay
5 | # when displaying many sprites.
6 | # for mor info, see https://www.youtube.com/watch?v=SA0F6Huj9dg
7 |
8 |
9 |
10 | screenSize(1000, 750)
11 | setBackgroundImage("images/stars.png")
12 |
13 | setAutoUpdate(False)
14 |
15 | rocket = makeSprite("images/rocket1.png")
16 | addSpriteImage(rocket,"images/rocket2a.png")
17 | addSpriteImage(rocket,"images/rocket2b.png")
18 | thrustSound = makeSound("sounds/Rocket-SoundBible.wav")
19 | fpsDisplay = makeLabel("FPS:",30,10,10,"white")
20 | showLabel(fpsDisplay)
21 |
22 | # we will store our asteroid sprites in a list
23 | asteroids = []
24 | for x in range(500):
25 | thisAsteroid = makeSprite("images/asteroid.png")
26 | # we will also add an alternative image to each sprite
27 | addSpriteImage(thisAsteroid, "images/redasteroid.png")
28 | # we will give each asteroid a random x position and a random y position
29 | # we will use dot notation to store this position *inside* the Sprite object
30 | thisAsteroid.x = random.randint(0,1000)
31 | thisAsteroid.y = random.randint(0,750)
32 | moveSprite(thisAsteroid, thisAsteroid.x, thisAsteroid.y)
33 | #also, store a random x speed and random y speed inside each asteroid Sprite
34 | thisAsteroid.xspeed = random.randint(-5,5)
35 | thisAsteroid.yspeed = random.randint(-5,5)
36 | showSprite(thisAsteroid)
37 | #now add this asteroid to the list
38 | asteroids.append(thisAsteroid)
39 |
40 | xPos = 500
41 | yPos = 320
42 | xSpeed = 0
43 | ySpeed = 0
44 | angle=0
45 | thrustAmount = 0.3
46 | moveSprite(rocket, xPos, yPos,True)
47 | showSprite(rocket)
48 | thrustFrame = 1
49 | nextframe = clock()
50 |
51 | while True:
52 | if keyPressed("left"):
53 | angle = angle - 5
54 |
55 | transformSprite(rocket,angle,1)
56 |
57 | elif keyPressed("right"):
58 | angle = angle +5
59 | transformSprite(rocket, angle, 1)
60 |
61 | if keyPressed("h"):
62 | hideAll()
63 |
64 | if keyPressed("u"):
65 | unhideAll()
66 |
67 |
68 | if keyPressed("up"):
69 | if clock() > nextframe:
70 | nextframe = clock() + 200
71 | if thrustFrame == 1:
72 | changeSpriteImage(rocket,1)
73 | thrustFrame=2
74 | else:
75 | changeSpriteImage(rocket,2)
76 | thrustFrame=1
77 | # use Trigonometry to convert the thrust into 2 components, x and y
78 | xSpeed += math.sin(math.radians(angle)) * thrustAmount
79 | ySpeed -= math.cos(math.radians(angle)) * thrustAmount
80 | playSound(thrustSound)
81 |
82 | else:
83 | changeSpriteImage(rocket,0)
84 | stopSound(thrustSound)
85 |
86 | xPos += xSpeed
87 | if xPos > 1000:
88 | xPos = 0
89 | elif xPos < 0:
90 | xPos = 1000
91 |
92 | yPos += ySpeed
93 | if yPos > 750:
94 | yPos = 0
95 | elif yPos < 0:
96 | yPos = 750
97 |
98 | moveSprite(rocket, xPos, yPos,True)
99 |
100 | # now we will move all the asteroids by their speeds
101 | for thisAsteroid in asteroids:
102 | thisAsteroid.x += thisAsteroid.xspeed
103 | if thisAsteroid.x > 1000:
104 | thisAsteroid.x = 0
105 | elif thisAsteroid.x < 0:
106 | thisAsteroid.x = 1000
107 |
108 | thisAsteroid.y += thisAsteroid.yspeed
109 | if thisAsteroid.y > 750:
110 | thisAsteroid.y = 0
111 | elif thisAsteroid.y < 0:
112 | thisAsteroid.y = 750
113 |
114 | moveSprite(thisAsteroid, thisAsteroid.x, thisAsteroid.y)
115 |
116 | # now we will grab a list of all the sprites that are currently touching the rocket
117 | hitAsteroids = allTouching(rocket)
118 | # and change the image of each one
119 | for thisHitAsteroid in hitAsteroids:
120 | changeSpriteImage(thisHitAsteroid,1)
121 |
122 | fps= tick(60)
123 | changeLabel(fpsDisplay, "FPS: {0}".format(str(round(fps, 2))))
124 | updateDisplay()
125 |
126 | endWait()
127 |
--------------------------------------------------------------------------------
/demos/__pycache__/pygame_functions.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/__pycache__/pygame_functions.cpython-311.pyc
--------------------------------------------------------------------------------
/demos/animationDemo2.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 |
4 | screenSize(600,600)
5 | setBackgroundColour("pink")
6 | testSprite = makeSprite("images/links.gif", 32) # links.gif contains 32 separate frames of animation.
7 |
8 | moveSprite(testSprite,300,300,True)
9 | showSprite(testSprite)
10 |
11 | nextFrame = clock()
12 | frame = 0
13 | while True:
14 | if clock() > nextFrame: # We only animate our character every 80ms.
15 | frame = (frame+1)%8 # There are 8 frames of animation in each direction
16 | nextFrame += 80 # so the modulus 8 allows it to loop
17 |
18 | if keyPressed("num6"):
19 | changeSpriteImage(testSprite, 0*8+frame) # 0*8 because right animations are the 0th set in the sprite sheet
20 |
21 | elif keyPressed("num2"):
22 | changeSpriteImage(testSprite, 1*8+frame) # down facing animations are the 1st set
23 |
24 | elif keyPressed("num4"):
25 | changeSpriteImage(testSprite, 2*8+frame) # and so on
26 |
27 | elif keyPressed("num8"):
28 | changeSpriteImage(testSprite, 3*8+frame)
29 |
30 | else:
31 | changeSpriteImage(testSprite, 1 * 8 + 5) # the static facing front look
32 |
33 | tick(120)
34 |
35 | endWait()
36 |
--------------------------------------------------------------------------------
/demos/buttonDemo.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 |
4 | screenSize(500,500)
5 | textlabel = makeLabel("Welcome", 22,200,50,"white", font="impact")
6 | showLabel(textlabel)
7 |
8 | b1 = makeSprite("images/button1.png")
9 | moveSprite(b1, 200,150)
10 | b2 = makeSprite("images/button2.png")
11 | moveSprite(b2, 200,200)
12 | showSprite(b1)
13 | showSprite(b2)
14 |
15 | def clicked1():
16 | changeLabel(textlabel,"Clicked Button 1")
17 |
18 | def clicked2():
19 | changeLabel(textlabel,"Clicked Button 2")
20 |
21 | while True:
22 | if spriteClicked(b1):
23 | clicked1()
24 | elif spriteClicked(b2):
25 | clicked2()
26 | tick(30)
27 |
28 |
29 | endWait()
--------------------------------------------------------------------------------
/demos/flipDemo.py:
--------------------------------------------------------------------------------
1 | # Demo of the flip parameters for transformSprite
2 | # Use direction keys to flip horizontally or vertically
3 | # Use space key to rotate
4 |
5 | from pygame_functions import *
6 |
7 | screenSize(1024, 768)
8 | jurassic = makeSprite("images/Jurassic.jpg")
9 | showSprite(jurassic)
10 |
11 | angle = 0
12 | hflip = False
13 | vflip = False
14 |
15 | while True:
16 | if keyPressed("space"):
17 | angle +=4
18 | if keyPressed("left") or keyPressed("right"):
19 | hflip = True
20 | else:
21 | hflip = False
22 | if keyPressed("up") or keyPressed("down"):
23 | vflip = True
24 | else:
25 | vflip = False
26 | transformSprite(jurassic, angle, 1, hflip, vflip)
27 | tick(30)
28 |
29 | endWait()
30 |
--------------------------------------------------------------------------------
/demos/images/Jurassic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/Jurassic.jpg
--------------------------------------------------------------------------------
/demos/images/agent1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent1.png
--------------------------------------------------------------------------------
/demos/images/agent2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent2.png
--------------------------------------------------------------------------------
/demos/images/agent3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent3.png
--------------------------------------------------------------------------------
/demos/images/agent4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent4.png
--------------------------------------------------------------------------------
/demos/images/agent5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent5.png
--------------------------------------------------------------------------------
/demos/images/agent6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent6.png
--------------------------------------------------------------------------------
/demos/images/agent7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent7.png
--------------------------------------------------------------------------------
/demos/images/agent8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agent8.png
--------------------------------------------------------------------------------
/demos/images/agentpunch1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agentpunch1.png
--------------------------------------------------------------------------------
/demos/images/agentpunch2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/agentpunch2.png
--------------------------------------------------------------------------------
/demos/images/asteroid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/asteroid.png
--------------------------------------------------------------------------------
/demos/images/button1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/button1.png
--------------------------------------------------------------------------------
/demos/images/button2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/button2.png
--------------------------------------------------------------------------------
/demos/images/corridor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/corridor.png
--------------------------------------------------------------------------------
/demos/images/dungeonFloor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/dungeonFloor.png
--------------------------------------------------------------------------------
/demos/images/dungeonFloor1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/dungeonFloor1.png
--------------------------------------------------------------------------------
/demos/images/dungeonFloor2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/dungeonFloor2.png
--------------------------------------------------------------------------------
/demos/images/dungeonFloor3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/dungeonFloor3.png
--------------------------------------------------------------------------------
/demos/images/dungeonFloor4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/dungeonFloor4.png
--------------------------------------------------------------------------------
/demos/images/greendot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/greendot.png
--------------------------------------------------------------------------------
/demos/images/lander.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/lander.png
--------------------------------------------------------------------------------
/demos/images/landerCrash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/landerCrash.png
--------------------------------------------------------------------------------
/demos/images/links.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/links.gif
--------------------------------------------------------------------------------
/demos/images/moonSurface.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/moonSurface.jpg
--------------------------------------------------------------------------------
/demos/images/redasteroid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/redasteroid.png
--------------------------------------------------------------------------------
/demos/images/rocket1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/rocket1.png
--------------------------------------------------------------------------------
/demos/images/rocket2a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/rocket2a.png
--------------------------------------------------------------------------------
/demos/images/rocket2b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/rocket2b.png
--------------------------------------------------------------------------------
/demos/images/smalllinks.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/smalllinks.gif
--------------------------------------------------------------------------------
/demos/images/stars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/images/stars.png
--------------------------------------------------------------------------------
/demos/multilineLabel.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 | import random
3 | screenSize(800,800)
4 | setBackgroundColour("white")
5 |
6 | text = "Hello"
7 | xpos = 10
8 | multiLineLabel = makeLabel(text, 27, xpos, 10, "black", "Times")
9 | showLabel(multiLineLabel)
10 |
11 | inputBox = makeTextBox(10, 760, 200, 0)
12 | showTextBox(inputBox)
13 |
14 |
15 | for x in range (26):
16 | newText = textBoxInput(inputBox)
17 | text += "
" + newText
18 | changeLabel(multiLineLabel,text, "black",random.choice(["blue","red","green","yellow",[255,90,90],[255,255,255]]))
19 | moveLabel(multiLineLabel,xpos+(x*20),10)
20 |
21 |
22 | endWait()
23 |
--------------------------------------------------------------------------------
/demos/pygame_functions.py:
--------------------------------------------------------------------------------
1 | # pygame_functions
2 |
3 | # Documentation at www.github.com/stevepaget/pygame_functions
4 | # Report bugs at https://github.com/StevePaget/Pygame_Functions/issues
5 |
6 |
7 | import pygame, sys, os
8 |
9 | from pathlib import Path
10 | DIR = Path(__file__).parent.absolute()
11 | DIR = f'{DIR}'.replace('\\','/')
12 | os.chdir(DIR)
13 |
14 |
15 | pygame.mixer.pre_init(44100, -16, 2, 512)
16 | pygame.init()
17 | pygame.mixer.init()
18 | spriteGroup = pygame.sprite.LayeredUpdates()
19 | textboxGroup = pygame.sprite.OrderedUpdates()
20 | gameClock = pygame.time.Clock()
21 | musicPaused = False
22 | hiddenSprites = pygame.sprite.OrderedUpdates()
23 | screenRefresh = True
24 | background = None
25 |
26 | keydict = {"space": pygame.K_SPACE, "esc": pygame.K_ESCAPE, "up": pygame.K_UP, "down": pygame.K_DOWN,
27 | "left": pygame.K_LEFT, "right": pygame.K_RIGHT, "return": pygame.K_RETURN,
28 | "a": pygame.K_a,
29 | "b": pygame.K_b,
30 | "c": pygame.K_c,
31 | "d": pygame.K_d,
32 | "e": pygame.K_e,
33 | "f": pygame.K_f,
34 | "g": pygame.K_g,
35 | "h": pygame.K_h,
36 | "i": pygame.K_i,
37 | "j": pygame.K_j,
38 | "k": pygame.K_k,
39 | "l": pygame.K_l,
40 | "m": pygame.K_m,
41 | "n": pygame.K_n,
42 | "o": pygame.K_o,
43 | "p": pygame.K_p,
44 | "q": pygame.K_q,
45 | "r": pygame.K_r,
46 | "s": pygame.K_s,
47 | "t": pygame.K_t,
48 | "u": pygame.K_u,
49 | "v": pygame.K_v,
50 | "w": pygame.K_w,
51 | "x": pygame.K_x,
52 | "y": pygame.K_y,
53 | "z": pygame.K_z,
54 | "1": pygame.K_1,
55 | "2": pygame.K_2,
56 | "3": pygame.K_3,
57 | "4": pygame.K_4,
58 | "5": pygame.K_5,
59 | "6": pygame.K_6,
60 | "7": pygame.K_7,
61 | "8": pygame.K_8,
62 | "9": pygame.K_9,
63 | "0": pygame.K_0,
64 | "num0": pygame.K_KP0,
65 | "num1": pygame.K_KP1,
66 | "num2": pygame.K_KP2,
67 | "num3": pygame.K_KP3,
68 | "num4": pygame.K_KP4,
69 | "num5": pygame.K_KP5,
70 | "num6": pygame.K_KP6,
71 | "num7": pygame.K_KP7,
72 | "num8": pygame.K_KP8,
73 | "num9": pygame.K_KP9}
74 | screen = ""
75 |
76 |
77 | class Background():
78 | def __init__(self):
79 | self.colour = pygame.Color("black")
80 |
81 | def setTiles(self, tiles):
82 | if type(tiles) is str:
83 | self.tiles = [[loadImage(tiles)]]
84 | elif type(tiles[0]) is str:
85 | self.tiles = [[loadImage(i) for i in tiles]]
86 | else:
87 | self.tiles = [[loadImage(i) for i in row] for row in tiles]
88 | self.stagePosX = 0
89 | self.stagePosY = 0
90 | self.tileWidth = self.tiles[0][0].get_width()
91 | self.tileHeight = self.tiles[0][0].get_height()
92 | screen.blit(self.tiles[0][0], [0, 0])
93 | self.surface = screen.copy()
94 |
95 | def scroll(self, x, y):
96 | self.stagePosX -= x
97 | self.stagePosY -= y
98 | col = (self.stagePosX % (self.tileWidth * len(self.tiles[0]))) // self.tileWidth
99 | xOff = (0 - self.stagePosX % self.tileWidth)
100 | row = (self.stagePosY % (self.tileHeight * len(self.tiles))) // self.tileHeight
101 | yOff = (0 - self.stagePosY % self.tileHeight)
102 |
103 | col2 = ((self.stagePosX + self.tileWidth) % (self.tileWidth * len(self.tiles[0]))) // self.tileWidth
104 | row2 = ((self.stagePosY + self.tileHeight) % (self.tileHeight * len(self.tiles))) // self.tileHeight
105 | screen.blit(self.tiles[row][col], [xOff, yOff])
106 | screen.blit(self.tiles[row][col2], [xOff + self.tileWidth, yOff])
107 | screen.blit(self.tiles[row2][col], [xOff, yOff + self.tileHeight])
108 | screen.blit(self.tiles[row2][col2], [xOff + self.tileWidth, yOff + self.tileHeight])
109 |
110 | self.surface = screen.copy()
111 |
112 | def setColour(self, colour):
113 | self.colour = parseColour(colour)
114 | screen.fill(self.colour)
115 | pygame.display.update()
116 | self.surface = screen.copy()
117 |
118 |
119 | class newSprite(pygame.sprite.Sprite):
120 | def __init__(self, filename, frames=1, altDims = None):
121 | pygame.sprite.Sprite.__init__(self)
122 | self.images = []
123 | img = loadImage(filename)
124 | if altDims:
125 | img = pygame.transform.scale(img, (altDims[0]*frames, altDims[1]))
126 | self.originalWidth = img.get_width() // frames
127 | self.originalHeight = img.get_height()
128 | frameSurf = pygame.Surface((self.originalWidth, self.originalHeight), pygame.SRCALPHA, 32)
129 | x = 0
130 | for frameNo in range(frames):
131 | frameSurf = pygame.Surface((self.originalWidth, self.originalHeight), pygame.SRCALPHA, 32)
132 | frameSurf.blit(img, (x, 0))
133 | self.images.append(frameSurf.copy())
134 | x -= self.originalWidth
135 | self.image = pygame.Surface.copy(self.images[0])
136 |
137 | self.currentImage = 0
138 | self.rect = self.image.get_rect()
139 | self.rect.topleft = (0, 0)
140 | self.mask = pygame.mask.from_surface(self.image)
141 | self.angle = 0
142 | self.scale = 1
143 |
144 | def addImage(self, filename):
145 | self.images.append(loadImage(filename))
146 |
147 | def move(self, xpos, ypos, centre=False):
148 | if centre:
149 | self.rect.center = [xpos, ypos]
150 | else:
151 | self.rect.topleft = [xpos, ypos]
152 |
153 | def changeImage(self, index):
154 | self.currentImage = index
155 | if self.angle == 0 and self.scale == 1:
156 | self.image = self.images[index]
157 | else:
158 | self.image = pygame.transform.rotozoom(self.images[self.currentImage], -self.angle, self.scale)
159 | oldcenter = self.rect.center
160 | self.rect = self.image.get_rect()
161 | originalRect = self.images[self.currentImage].get_rect()
162 | self.originalWidth = originalRect.width
163 | self.originalHeight = originalRect.height
164 | self.rect.center = oldcenter
165 | self.mask = pygame.mask.from_surface(self.image)
166 | if screenRefresh:
167 | updateDisplay()
168 |
169 |
170 | class newTextBox(pygame.sprite.Sprite):
171 | def __init__(self, text, xpos, ypos, width, case, maxLength, fontSize):
172 | pygame.sprite.Sprite.__init__(self)
173 | self.text = ""
174 | self.width = width
175 | self.initialText = text
176 | self.case = case
177 | self.maxLength = maxLength
178 | self.boxSize = int(fontSize * 1.7)
179 | self.image = pygame.Surface((width, self.boxSize))
180 | self.image.fill((255, 255, 255))
181 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, width - 1, self.boxSize - 1], 2)
182 | self.rect = self.image.get_rect()
183 | self.fontFace = pygame.font.match_font("Arial")
184 | self.fontColour = pygame.Color("black")
185 | self.initialColour = (180, 180, 180)
186 | self.font = pygame.font.Font(self.fontFace, fontSize)
187 | self.rect.topleft = [xpos, ypos]
188 | newSurface = self.font.render(self.initialText, True, self.initialColour)
189 | self.image.blit(newSurface, [10, 5])
190 |
191 | def update(self, keyevent):
192 | key = keyevent.key
193 | unicode = keyevent.unicode
194 | if (31 < key < 127 or 255 < key < 266) and (
195 | self.maxLength == 0 or len(self.text) < self.maxLength): # only printable characters
196 | if keyevent.mod in (1, 2) and self.case == 1 and key >= 97 and key <= 122:
197 | # force lowercase letters
198 | self.text += chr(key)
199 | elif keyevent.mod == 0 and self.case == 2 and key >= 97 and key <= 122:
200 | self.text += chr(key - 32)
201 | else:
202 | # use the unicode char
203 | self.text += unicode
204 |
205 | elif key == 8:
206 | # backspace. repeat until clear
207 | keys = pygame.key.get_pressed()
208 | nexttime = pygame.time.get_ticks() + 200
209 | deleting = True
210 | while deleting:
211 | keys = pygame.key.get_pressed()
212 | if keys[pygame.K_BACKSPACE]:
213 | thistime = pygame.time.get_ticks()
214 | if thistime > nexttime:
215 | self.text = self.text[0:len(self.text) - 1]
216 | self.image.fill((255, 255, 255))
217 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
218 | newSurface = self.font.render(self.text, True, self.fontColour)
219 | self.image.blit(newSurface, [10, 5])
220 | updateDisplay()
221 | nexttime = thistime + 50
222 | pygame.event.clear()
223 | else:
224 | deleting = False
225 |
226 | self.image.fill((255, 255, 255))
227 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
228 | newSurface = self.font.render(self.text, True, self.fontColour)
229 | self.image.blit(newSurface, [10, 5])
230 | if screenRefresh:
231 | updateDisplay()
232 |
233 | def move(self, xpos, ypos, centre=False):
234 | if centre:
235 | self.rect.topleft = [xpos, ypos]
236 | else:
237 | self.rect.center = [xpos, ypos]
238 |
239 | def clear(self):
240 | self.image.fill((255, 255, 255))
241 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
242 | newSurface = self.font.render(self.initialText, True, self.initialColour)
243 | self.image.blit(newSurface, [10, 5])
244 | if screenRefresh:
245 | updateDisplay()
246 |
247 |
248 | class newLabel(pygame.sprite.Sprite):
249 | def __init__(self, text, fontSize, font, fontColour, xpos, ypos, background):
250 | pygame.sprite.Sprite.__init__(self)
251 | self.text = text
252 | self.fontColour = parseColour(fontColour)
253 | self.fontFace = pygame.font.match_font(font)
254 | self.fontSize = fontSize
255 | self.background = background
256 | self.font = pygame.font.Font(self.fontFace, self.fontSize)
257 | self.renderText()
258 | self.rect.topleft = [xpos, ypos]
259 |
260 | def update(self, newText, fontColour, background):
261 | self.text = newText
262 | if fontColour:
263 | self.fontColour = parseColour(fontColour)
264 | if background:
265 | self.background = parseColour(background)
266 |
267 | oldTopLeft = self.rect.topleft
268 | self.renderText()
269 | self.rect.topleft = oldTopLeft
270 | if screenRefresh:
271 | updateDisplay()
272 |
273 | def renderText(self):
274 | lineSurfaces = []
275 | textLines = self.text.split("
")
276 | maxWidth = 0
277 | maxHeight = 0
278 | for line in textLines:
279 | lineSurfaces.append(self.font.render(line, True, self.fontColour))
280 | thisRect = lineSurfaces[-1].get_rect()
281 | if thisRect.width > maxWidth:
282 | maxWidth = thisRect.width
283 | if thisRect.height > maxHeight:
284 | maxHeight = thisRect.height
285 | self.image = pygame.Surface((maxWidth, (self.fontSize + 1) * len(textLines) + 5), pygame.SRCALPHA, 32)
286 | self.image.convert_alpha()
287 | if self.background != "clear":
288 | self.image.fill(parseColour(self.background))
289 | linePos = 0
290 | for lineSurface in lineSurfaces:
291 | self.image.blit(lineSurface, [0, linePos])
292 | linePos += self.fontSize + 1
293 | self.rect = self.image.get_rect()
294 |
295 |
296 | def loadImage(fileName, useColorKey=False):
297 | if os.path.isfile(fileName):
298 | image = pygame.image.load(fileName)
299 | image = image.convert_alpha()
300 | # Return the image
301 | return image
302 | else:
303 | raise Exception(f"Error loading image: {fileName} – Check filename and path?")
304 |
305 |
306 | def screenSize(sizex, sizey, xpos=None, ypos=None, fullscreen=False):
307 | global screen
308 | global background
309 | if xpos != None and ypos != None:
310 | os.environ['SDL_VIDEO_WINDOW_POS'] = f"{xpos}, {ypos + 50}"
311 | else:
312 | windowInfo = pygame.display.Info()
313 | monitorWidth = windowInfo.current_w
314 | monitorHeight = windowInfo.current_h
315 | os.environ['SDL_VIDEO_WINDOW_POS'] = f"{(monitorWidth - sizex) // 2}, {(monitorHeight - sizey) // 2}"
316 | if fullscreen:
317 | screen = pygame.display.set_mode([sizex, sizey], pygame.FULLSCREEN)
318 | else:
319 | screen = pygame.display.set_mode([sizex, sizey])
320 | background = Background()
321 | screen.fill(background.colour)
322 | pygame.display.set_caption("Graphics Window")
323 | background.surface = screen.copy()
324 | pygame.display.update()
325 | return screen
326 |
327 |
328 |
329 | def moveSprite(sprite, x, y, centre=False):
330 | sprite.move(x, y, centre)
331 | if screenRefresh:
332 | updateDisplay()
333 |
334 |
335 | def rotateSprite(sprite, angle):
336 | print("rotateSprite has been deprecated. Please use transformSprite")
337 | transformSprite(sprite, angle, 1)
338 |
339 |
340 | def transformSprite(sprite, angle, scale, hflip=False, vflip=False):
341 | oldmiddle = sprite.rect.center
342 | if hflip or vflip:
343 | tempImage = pygame.transform.flip(sprite.images[sprite.currentImage], hflip, vflip)
344 | else:
345 | tempImage = sprite.images[sprite.currentImage]
346 | if angle != 0 or scale != 1:
347 | sprite.angle = angle
348 | sprite.scale = scale
349 | tempImage = pygame.transform.rotozoom(tempImage, -angle, scale)
350 | sprite.image = tempImage
351 | sprite.rect = sprite.image.get_rect()
352 | sprite.rect.center = oldmiddle
353 | sprite.mask = pygame.mask.from_surface(sprite.image)
354 | if screenRefresh:
355 | updateDisplay()
356 |
357 |
358 | def killSprite(sprite):
359 | sprite.kill()
360 | if screenRefresh:
361 | updateDisplay()
362 |
363 |
364 | def setBackgroundColour(colour):
365 | background.setColour(colour)
366 | if screenRefresh:
367 | updateDisplay()
368 |
369 |
370 | def setBackgroundImage(img):
371 | global background
372 | background.setTiles(img)
373 | if screenRefresh:
374 | updateDisplay()
375 |
376 |
377 | def hideSprite(sprite):
378 | hiddenSprites.add(sprite)
379 | spriteGroup.remove(sprite)
380 | if screenRefresh:
381 | updateDisplay()
382 |
383 |
384 | def hideAll():
385 | hiddenSprites.add(spriteGroup.sprites())
386 | spriteGroup.empty()
387 | if screenRefresh:
388 | updateDisplay()
389 |
390 |
391 | def unhideAll():
392 | spriteGroup.add(hiddenSprites.sprites())
393 | hiddenSprites.empty()
394 | if screenRefresh:
395 | updateDisplay()
396 |
397 |
398 | def showSprite(sprite, layer=None):
399 | spriteGroup.add(sprite, layer= layer)
400 | if screenRefresh:
401 | updateDisplay()
402 |
403 |
404 | def makeSprite(filename, frames=1, altDims = None):
405 | thisSprite = newSprite(filename, frames, altDims)
406 | return thisSprite
407 |
408 |
409 | def addSpriteImage(sprite, image):
410 | sprite.addImage(image)
411 |
412 |
413 | def changeSpriteImage(sprite, index):
414 | sprite.changeImage(index)
415 |
416 | def changeLayer(sprite, layer):
417 | spriteGroup.change_layer(sprite, layer)
418 |
419 | def nextSpriteImage(sprite):
420 | sprite.currentImage += 1
421 | if sprite.currentImage > len(sprite.images) - 1:
422 | sprite.currentImage = 0
423 | sprite.changeImage(sprite.currentImage)
424 |
425 |
426 | def prevSpriteImage(sprite):
427 | sprite.currentImage -= 1
428 | if sprite.currentImage < 0:
429 | sprite.currentImage = len(sprite.images) - 1
430 | sprite.changeImage(sprite.currentImage)
431 |
432 |
433 | def makeImage(filename):
434 | return loadImage(filename)
435 |
436 |
437 | def touching(sprite1, sprite2):
438 | collided = pygame.sprite.collide_mask(sprite1, sprite2)
439 | return collided
440 |
441 |
442 | def allTouching(spritename):
443 | if spriteGroup.has(spritename):
444 | collisions = pygame.sprite.spritecollide(spritename, spriteGroup, False, collided=pygame.sprite.collide_mask)
445 | collisions.remove(spritename)
446 | return collisions
447 | else:
448 | return []
449 |
450 |
451 | def pause(milliseconds, allowEsc=True):
452 | keys = pygame.key.get_pressed()
453 | current_time = pygame.time.get_ticks()
454 | waittime = current_time + milliseconds
455 | updateDisplay()
456 | while not (current_time > waittime or (keys[pygame.K_ESCAPE] and allowEsc)):
457 | pygame.event.clear()
458 | keys = pygame.key.get_pressed()
459 | if (keys[pygame.K_ESCAPE] and allowEsc):
460 | pygame.quit()
461 | sys.exit()
462 | current_time = pygame.time.get_ticks()
463 |
464 |
465 | def drawRect(xpos, ypos, width, height, colour, linewidth=0):
466 | global bgSurface
467 | colour = parseColour(colour)
468 | thisrect = pygame.draw.rect(screen, colour, [xpos, ypos, width, height], linewidth)
469 | if screenRefresh:
470 | pygame.display.update(thisrect)
471 |
472 |
473 | def drawLine(x1, y1, x2, y2, colour, linewidth=1):
474 | global bgSurface
475 | colour = parseColour(colour)
476 | thisrect = pygame.draw.line(screen, colour, (x1, y1), (x2, y2), linewidth)
477 | if screenRefresh:
478 | pygame.display.update(thisrect)
479 |
480 |
481 | def drawPolygon(pointlist, colour, linewidth=0):
482 | global bgSurface
483 | colour = parseColour(colour)
484 | thisrect = pygame.draw.polygon(screen, colour, pointlist, linewidth)
485 | if screenRefresh:
486 | pygame.display.update(thisrect)
487 |
488 |
489 | def drawEllipse(centreX, centreY, width, height, colour, linewidth=0):
490 | global bgSurface
491 | colour = parseColour(colour)
492 | thisrect = pygame.Rect(centreX - width / 2, centreY - height / 2, width, height)
493 | pygame.draw.ellipse(screen, colour, thisrect, linewidth)
494 | if screenRefresh:
495 | pygame.display.update(thisrect)
496 |
497 |
498 | def drawTriangle(x1, y1, x2, y2, x3, y3, colour, linewidth=0):
499 | global bgSurface
500 | colour = parseColour(colour)
501 | thisrect = pygame.draw.polygon(screen, colour, [(x1, y1), (x2, y2), (x3, y3)], linewidth)
502 | if screenRefresh:
503 | pygame.display.update(thisrect)
504 |
505 |
506 | def clearShapes():
507 | global background
508 | screen.blit(background.surface, [0, 0])
509 | if screenRefresh:
510 | updateDisplay()
511 |
512 |
513 | def updateShapes():
514 | pygame.display.update()
515 |
516 |
517 | def end():
518 | pygame.quit()
519 |
520 |
521 | def makeSound(filename):
522 | pygame.mixer.init()
523 | thissound = pygame.mixer.Sound(filename)
524 |
525 | return thissound
526 |
527 |
528 | def playSound(sound, loops=0):
529 | sound.play(loops)
530 |
531 |
532 | def stopSound(sound):
533 | sound.stop()
534 |
535 |
536 | def playSoundAndWait(sound):
537 | sound.play()
538 | while pygame.mixer.get_busy():
539 | # pause
540 | pause(10)
541 |
542 |
543 | def makeMusic(filename):
544 | pygame.mixer.music.load(filename)
545 |
546 |
547 | def playMusic(loops=0):
548 | global musicPaused
549 | if musicPaused:
550 | pygame.mixer.music.unpause()
551 | else:
552 | pygame.mixer.music.play(loops)
553 | musicPaused = False
554 |
555 |
556 | def stopMusic():
557 | pygame.mixer.music.stop()
558 |
559 |
560 | def pauseMusic():
561 | global musicPaused
562 | pygame.mixer.music.pause()
563 | musicPaused = True
564 |
565 |
566 | def rewindMusic():
567 | pygame.mixer.music.rewind()
568 |
569 |
570 | def endWait():
571 | updateDisplay()
572 | print("Press ESC to quit")
573 | waiting = True
574 | while waiting:
575 | for event in pygame.event.get():
576 | if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == keydict["esc"]):
577 | waiting = False
578 | pygame.quit()
579 | sys.exit()
580 |
581 |
582 |
583 | def keyPressed(keyCheck=""):
584 | global keydict
585 | keys = pygame.key.get_pressed()
586 | if sum(keys) > 0:
587 | if keyCheck == "" or keys[keydict[keyCheck.lower()]]:
588 | return True
589 | return False
590 |
591 |
592 | def makeLabel(text, fontSize, xpos, ypos, fontColour='black', font='Arial', background="clear"):
593 | # make a text sprite
594 | thisText = newLabel(text, fontSize, font, fontColour, xpos, ypos, background)
595 | return thisText
596 |
597 |
598 | def moveLabel(sprite, x, y):
599 | sprite.rect.topleft = [x, y]
600 | if screenRefresh:
601 | updateDisplay()
602 |
603 |
604 | def changeLabel(textObject, newText, fontColour=None, background=None):
605 | textObject.update(newText, fontColour, background)
606 | # updateDisplay()
607 |
608 |
609 | def waitPress():
610 | pygame.event.clear()
611 | keypressed = False
612 | thisevent = pygame.event.wait()
613 | while thisevent.type != pygame.KEYDOWN:
614 | thisevent = pygame.event.wait()
615 | return thisevent.key
616 |
617 |
618 | def makeTextBox(xpos, ypos, width, case=0, startingText="Please type here", maxLength=0, fontSize=22):
619 | thisTextBox = newTextBox(startingText, xpos, ypos, width, case, maxLength, fontSize)
620 | textboxGroup.add(thisTextBox)
621 | return thisTextBox
622 |
623 |
624 | def textBoxInput(textbox, functionToCall=None, args=[]):
625 | # starts grabbing key inputs, putting into textbox until enter pressed
626 | global keydict
627 | textbox.text = ""
628 | returnVal = None
629 | while True:
630 | updateDisplay()
631 | if functionToCall:
632 | returnVal = functionToCall(*args)
633 | for event in pygame.event.get():
634 | if event.type == pygame.KEYDOWN:
635 | if event.key == pygame.K_RETURN:
636 | textbox.clear()
637 | if returnVal:
638 | return textbox.text, returnVal
639 | else:
640 | return textbox.text
641 | elif event.key == pygame.K_ESCAPE:
642 | pygame.quit()
643 | sys.exit()
644 | else:
645 | textbox.update(event)
646 | elif event.type == pygame.QUIT:
647 | pygame.quit()
648 | sys.exit()
649 |
650 |
651 | def clock():
652 | current_time = pygame.time.get_ticks()
653 | return current_time
654 |
655 |
656 | def tick(fps):
657 | for event in pygame.event.get():
658 | if (event.type == pygame.KEYDOWN and event.key == keydict["esc"]) or event.type == pygame.QUIT:
659 | pygame.quit()
660 | sys.exit()
661 | gameClock.tick(fps)
662 | return gameClock.get_fps()
663 |
664 |
665 | def showLabel(labelName):
666 | textboxGroup.add(labelName)
667 | if screenRefresh:
668 | updateDisplay()
669 |
670 |
671 | def hideLabel(labelName):
672 | textboxGroup.remove(labelName)
673 | if screenRefresh:
674 | updateDisplay()
675 |
676 |
677 | def showTextBox(textBoxName):
678 | textboxGroup.add(textBoxName)
679 | if screenRefresh:
680 | updateDisplay()
681 |
682 |
683 | def hideTextBox(textBoxName):
684 | textboxGroup.remove(textBoxName)
685 | if screenRefresh:
686 | updateDisplay()
687 |
688 |
689 | def updateDisplay():
690 | global background
691 | spriteRects = spriteGroup.draw(screen)
692 | textboxRects = textboxGroup.draw(screen)
693 | pygame.display.update()
694 | keys = pygame.key.get_pressed()
695 | if (keys[pygame.K_ESCAPE]):
696 | pygame.quit()
697 | sys.exit()
698 | spriteGroup.clear(screen, background.surface)
699 | textboxGroup.clear(screen, background.surface)
700 |
701 |
702 | def mousePressed():
703 | #pygame.event.clear()
704 | mouseState = pygame.mouse.get_pressed()
705 | if mouseState[0]:
706 | return True
707 | else:
708 | return False
709 |
710 |
711 | def spriteClicked(sprite):
712 | mouseState = pygame.mouse.get_pressed()
713 | if not mouseState[0]:
714 | return False # not pressed
715 | pos = pygame.mouse.get_pos()
716 | if sprite.rect.collidepoint(pos):
717 | return True
718 | else:
719 | return False
720 |
721 |
722 | def parseColour(colour):
723 | if type(colour) == str:
724 | # check to see if valid colour
725 | return pygame.Color(colour)
726 | else:
727 | colourRGB = pygame.Color("white")
728 | colourRGB.r = colour[0]
729 | colourRGB.g = colour[1]
730 | colourRGB.b = colour[2]
731 | return colourRGB
732 |
733 |
734 | def mouseX():
735 | x = pygame.mouse.get_pos()
736 | return x[0]
737 |
738 |
739 | def mouseY():
740 | y = pygame.mouse.get_pos()
741 | return y[1]
742 |
743 |
744 | def scrollBackground(x, y):
745 | global background
746 | background.scroll(x, y)
747 |
748 |
749 | def setAutoUpdate(val):
750 | global screenRefresh
751 | screenRefresh = val
752 |
753 | def setIcon(iconfile):
754 | gameicon = pygame.image.load(iconfile)
755 | pygame.display.set_icon(gameicon)
756 |
757 | def setWindowTitle(string):
758 | pygame.display.set_caption(string)
759 |
760 |
761 | if __name__ == "__main__":
762 | print("pygame_functions is not designed to be run directly.\n" \
763 | "See the wiki at https://github.com/StevePaget/Pygame_Functions/wiki/Getting-Started for more information.")
764 |
--------------------------------------------------------------------------------
/demos/robotron.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 | setAutoUpdate(False)
4 |
5 |
6 | class Player():
7 | def __init__(self):
8 | self.xpos = 400
9 | self.ypos = 400
10 | self.speed = 3
11 | self.health = 100
12 | self.xdir = 0
13 | self.ydir = 0
14 | self.currentWeapon = 0
15 | self.sprite = makeSprite("images/smalllinks.gif",32)
16 | showSprite(self.sprite)
17 | self.frame = 0
18 | self.timeOfNextFrame = clock()
19 | self.lastBulletTime = clock()
20 |
21 | def move(self):
22 | if clock() > self.timeOfNextFrame: # We only animate our character every 80ms.
23 | self.frame = (self.frame + 1) % 8 # There are 8 frames of animation in each direction
24 | self.timeOfNextFrame += 80 # so the modulus 8 allows it to loop
25 |
26 | if keyPressed("left"):
27 | self.xpos -= self.speed
28 | changeSpriteImage(self.sprite, 2*8+self.frame)
29 | self.xdir = -1
30 | elif keyPressed("right"):
31 | self.xpos += self.speed
32 | changeSpriteImage(self.sprite, 0*8+self.frame)
33 | self.xdir = 1
34 | else:
35 | self.xdir = 0
36 |
37 | if keyPressed("up"):
38 | self.ypos -= self.speed
39 | changeSpriteImage(self.sprite, 3*8+self.frame)
40 | self.ydir = -1
41 | elif keyPressed("down"):
42 | self.ypos += self.speed
43 | changeSpriteImage(self.sprite, 1*8+self.frame)
44 | self.ydir = 1
45 | else:
46 | self.ydir = 0
47 |
48 | moveSprite(self.sprite, self.xpos, self.ypos)
49 |
50 | def update(self):
51 | self.move()
52 | if keyPressed("space"):
53 | if clock() > self.lastBulletTime + 30:
54 | # add a new bullet to the list of bullets
55 | if self.xdir != 0 or self.ydir != 0:
56 | bullets.append(Projectile(self.xpos + 20, self.ypos + 20, self.xdir * 10, self.ydir * 10, 0))
57 | self.lastBulletTime = clock()
58 |
59 |
60 | class Projectile():
61 | def __init__(self, xpos, ypos, xspeed, yspeed, damage):
62 | self.xpos = xpos
63 | self.ypos = ypos
64 | self.xspeed = xspeed
65 | self.yspeed = yspeed
66 |
67 | self.sprite = makeSprite("images/greendot.png")
68 | self.move()
69 | showSprite(self.sprite)
70 |
71 | def move(self):
72 | self.xpos += self.xspeed
73 | self.ypos += self.yspeed
74 | if self.xpos < 0 or self.xpos > 800 or self.ypos < 0 or self.ypos > 800:
75 | return False
76 | moveSprite(self.sprite, self.xpos, self.ypos)
77 | return True
78 |
79 |
80 | screenSize(800, 800)
81 | setBackgroundColour([10,40,40])
82 | p = Player()
83 | bullets = [] # make an empty list of bullets
84 | while True:
85 | p.update()
86 | for bullet in bullets: # ask each bullet in the list to move
87 | if bullet.move() == False:
88 | hideSprite(bullet.sprite)
89 | bullets.remove(bullet)
90 | updateDisplay()
91 | tick(60)
92 | endWait()
93 |
94 |
--------------------------------------------------------------------------------
/demos/scrollDemo.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 |
3 |
4 | screenSize(600,600)
5 | setAutoUpdate(False)
6 |
7 |
8 | setBackgroundImage( [ ["images/dungeonFloor1.png", "images/dungeonFloor2.png"] ,
9 | ["images/dungeonFloor3.png", "images/dungeonFloor4.png"] ])
10 |
11 |
12 | testSprite = makeSprite("images/links.gif",32) # links.gif contains 32 separate frames of animation. Sizes are automatically calculated.
13 |
14 | moveSprite(testSprite,300,300,True)
15 |
16 | showSprite(testSprite)
17 |
18 | nextFrame = clock()
19 | frame=0
20 | while True:
21 | if clock() > nextFrame: # We only animate our character every 80ms.
22 | frame = (frame+1)%8 # There are 8 frames of animation in each direction
23 | nextFrame += 80 # so the modulus 8 allows it to loop
24 |
25 | if keyPressed("right"):
26 | changeSpriteImage(testSprite, 0*8+frame) # 0*8 because right animations are the 0th set in the sprite sheet
27 | scrollBackground(-5,0) # The player is moving right, so we scroll the background left
28 |
29 | elif keyPressed("down"):
30 | changeSpriteImage(testSprite, 1*8+frame) # down facing animations are the 1st set
31 | scrollBackground(0, -5)
32 |
33 | elif keyPressed("left"):
34 | changeSpriteImage(testSprite, 2*8+frame) # and so on
35 | scrollBackground(5,0)
36 |
37 | elif keyPressed("up"):
38 | changeSpriteImage(testSprite,3*8+frame)
39 | scrollBackground(0,5)
40 |
41 | else:
42 | changeSpriteImage(testSprite, 1 * 8 + 5) # the static facing front look
43 |
44 | updateDisplay()
45 | tick(120)
46 |
47 | endWait()
48 |
--------------------------------------------------------------------------------
/demos/sounds/Rocket-SoundBible.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StevePaget/Pygame_Functions/84728e6e6a1b768895dbf6bddc61430e67d767de/demos/sounds/Rocket-SoundBible.wav
--------------------------------------------------------------------------------
/demos/textDemo.py:
--------------------------------------------------------------------------------
1 | from pygame_functions import *
2 | import random
3 | screenSize(800,800)
4 |
5 | # This demo shows you the textBox (for easy typed input) and the label (for text output)
6 |
7 |
8 | instructionLabel = makeLabel("Please enter a word", 40, 10, 10, "blue", "Agency FB", "yellow")
9 | showLabel(instructionLabel)
10 |
11 | wordBox = makeTextBox(10, 80, 300, 0, "Enter text here", 15, 24)
12 | showTextBox(wordBox)
13 | entry = textBoxInput(wordBox)
14 |
15 |
16 | wordlabel = makeLabel(entry, 30, random.randint(1,700), random.randint(50,700), "red")
17 | showLabel(wordlabel)
18 |
19 | pause(1000)
20 | moveLabel(wordlabel, 300,300)
21 |
22 |
23 | wordlabel = makeLabel(entry, 30, random.randint(1,700), random.randint(50,700), "red")
24 | showLabel(wordlabel)
25 |
26 | pause(1000)
27 | hideLabel(wordlabel)
28 |
29 |
30 | endWait()
31 |
--------------------------------------------------------------------------------
/pygame_functions.py:
--------------------------------------------------------------------------------
1 | # pygame_functions
2 |
3 | # Documentation at www.github.com/stevepaget/pygame_functions
4 | # Report bugs at https://github.com/StevePaget/Pygame_Functions/issues
5 |
6 |
7 | import pygame, sys, os
8 |
9 | from pathlib import Path
10 | DIR = Path(__file__).parent.absolute()
11 | DIR = f'{DIR}'.replace('\\','/')
12 | os.chdir(DIR)
13 |
14 |
15 | pygame.mixer.pre_init(44100, -16, 2, 512)
16 | pygame.init()
17 | pygame.mixer.init()
18 | spriteGroup = pygame.sprite.LayeredUpdates()
19 | textboxGroup = pygame.sprite.OrderedUpdates()
20 | gameClock = pygame.time.Clock()
21 | musicPaused = False
22 | hiddenSprites = pygame.sprite.OrderedUpdates()
23 | screenRefresh = True
24 | background = None
25 |
26 | keydict = {"space": pygame.K_SPACE, "esc": pygame.K_ESCAPE, "up": pygame.K_UP, "down": pygame.K_DOWN,
27 | "left": pygame.K_LEFT, "right": pygame.K_RIGHT, "return": pygame.K_RETURN,
28 | "a": pygame.K_a,
29 | "b": pygame.K_b,
30 | "c": pygame.K_c,
31 | "d": pygame.K_d,
32 | "e": pygame.K_e,
33 | "f": pygame.K_f,
34 | "g": pygame.K_g,
35 | "h": pygame.K_h,
36 | "i": pygame.K_i,
37 | "j": pygame.K_j,
38 | "k": pygame.K_k,
39 | "l": pygame.K_l,
40 | "m": pygame.K_m,
41 | "n": pygame.K_n,
42 | "o": pygame.K_o,
43 | "p": pygame.K_p,
44 | "q": pygame.K_q,
45 | "r": pygame.K_r,
46 | "s": pygame.K_s,
47 | "t": pygame.K_t,
48 | "u": pygame.K_u,
49 | "v": pygame.K_v,
50 | "w": pygame.K_w,
51 | "x": pygame.K_x,
52 | "y": pygame.K_y,
53 | "z": pygame.K_z,
54 | "1": pygame.K_1,
55 | "2": pygame.K_2,
56 | "3": pygame.K_3,
57 | "4": pygame.K_4,
58 | "5": pygame.K_5,
59 | "6": pygame.K_6,
60 | "7": pygame.K_7,
61 | "8": pygame.K_8,
62 | "9": pygame.K_9,
63 | "0": pygame.K_0,
64 | "num0": pygame.K_KP0,
65 | "num1": pygame.K_KP1,
66 | "num2": pygame.K_KP2,
67 | "num3": pygame.K_KP3,
68 | "num4": pygame.K_KP4,
69 | "num5": pygame.K_KP5,
70 | "num6": pygame.K_KP6,
71 | "num7": pygame.K_KP7,
72 | "num8": pygame.K_KP8,
73 | "num9": pygame.K_KP9}
74 | screen = ""
75 |
76 |
77 | class Background():
78 | def __init__(self):
79 | self.colour = pygame.Color("black")
80 |
81 | def setTiles(self, tiles):
82 | if type(tiles) is str:
83 | self.tiles = [[loadImage(tiles)]]
84 | elif type(tiles[0]) is str:
85 | self.tiles = [[loadImage(i) for i in tiles]]
86 | else:
87 | self.tiles = [[loadImage(i) for i in row] for row in tiles]
88 | self.stagePosX = 0
89 | self.stagePosY = 0
90 | self.tileWidth = self.tiles[0][0].get_width()
91 | self.tileHeight = self.tiles[0][0].get_height()
92 | screen.blit(self.tiles[0][0], [0, 0])
93 | self.surface = screen.copy()
94 |
95 | def scroll(self, x, y):
96 | self.stagePosX -= x
97 | self.stagePosY -= y
98 | col = (self.stagePosX % (self.tileWidth * len(self.tiles[0]))) // self.tileWidth
99 | xOff = (0 - self.stagePosX % self.tileWidth)
100 | row = (self.stagePosY % (self.tileHeight * len(self.tiles))) // self.tileHeight
101 | yOff = (0 - self.stagePosY % self.tileHeight)
102 |
103 | col2 = ((self.stagePosX + self.tileWidth) % (self.tileWidth * len(self.tiles[0]))) // self.tileWidth
104 | row2 = ((self.stagePosY + self.tileHeight) % (self.tileHeight * len(self.tiles))) // self.tileHeight
105 | screen.blit(self.tiles[row][col], [xOff, yOff])
106 | screen.blit(self.tiles[row][col2], [xOff + self.tileWidth, yOff])
107 | screen.blit(self.tiles[row2][col], [xOff, yOff + self.tileHeight])
108 | screen.blit(self.tiles[row2][col2], [xOff + self.tileWidth, yOff + self.tileHeight])
109 |
110 | self.surface = screen.copy()
111 |
112 | def setColour(self, colour):
113 | self.colour = parseColour(colour)
114 | screen.fill(self.colour)
115 | pygame.display.update()
116 | self.surface = screen.copy()
117 |
118 |
119 | class newSprite(pygame.sprite.Sprite):
120 | def __init__(self, filename, frames=1, altDims = None):
121 | pygame.sprite.Sprite.__init__(self)
122 | self.images = []
123 | img = loadImage(filename)
124 | if altDims:
125 | img = pygame.transform.scale(img, (altDims[0]*frames, altDims[1]))
126 | self.originalWidth = img.get_width() // frames
127 | self.originalHeight = img.get_height()
128 | frameSurf = pygame.Surface((self.originalWidth, self.originalHeight), pygame.SRCALPHA, 32)
129 | x = 0
130 | for frameNo in range(frames):
131 | frameSurf = pygame.Surface((self.originalWidth, self.originalHeight), pygame.SRCALPHA, 32)
132 | frameSurf.blit(img, (x, 0))
133 | self.images.append(frameSurf.copy())
134 | x -= self.originalWidth
135 | self.image = pygame.Surface.copy(self.images[0])
136 |
137 | self.currentImage = 0
138 | self.rect = self.image.get_rect()
139 | self.rect.topleft = (0, 0)
140 | self.mask = pygame.mask.from_surface(self.image)
141 | self.angle = 0
142 | self.scale = 1
143 |
144 | def addImage(self, filename):
145 | self.images.append(loadImage(filename))
146 |
147 | def move(self, xpos, ypos, centre=False):
148 | if centre:
149 | self.rect.center = [xpos, ypos]
150 | else:
151 | self.rect.topleft = [xpos, ypos]
152 |
153 | def changeImage(self, index):
154 | self.currentImage = index
155 | if self.angle == 0 and self.scale == 1:
156 | self.image = self.images[index]
157 | else:
158 | self.image = pygame.transform.rotozoom(self.images[self.currentImage], -self.angle, self.scale)
159 | oldcenter = self.rect.center
160 | self.rect = self.image.get_rect()
161 | originalRect = self.images[self.currentImage].get_rect()
162 | self.originalWidth = originalRect.width
163 | self.originalHeight = originalRect.height
164 | self.rect.center = oldcenter
165 | self.mask = pygame.mask.from_surface(self.image)
166 | if screenRefresh:
167 | updateDisplay()
168 |
169 |
170 | class newTextBox(pygame.sprite.Sprite):
171 | def __init__(self, text, xpos, ypos, width, case, maxLength, fontSize):
172 | pygame.sprite.Sprite.__init__(self)
173 | self.text = ""
174 | self.width = width
175 | self.initialText = text
176 | self.case = case
177 | self.maxLength = maxLength
178 | self.boxSize = int(fontSize * 1.7)
179 | self.image = pygame.Surface((width, self.boxSize))
180 | self.image.fill((255, 255, 255))
181 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, width - 1, self.boxSize - 1], 2)
182 | self.rect = self.image.get_rect()
183 | self.fontFace = pygame.font.match_font("Arial")
184 | self.fontColour = pygame.Color("black")
185 | self.initialColour = (180, 180, 180)
186 | self.font = pygame.font.Font(self.fontFace, fontSize)
187 | self.rect.topleft = [xpos, ypos]
188 | newSurface = self.font.render(self.initialText, True, self.initialColour)
189 | self.image.blit(newSurface, [10, 5])
190 |
191 | def update(self, keyevent):
192 | key = keyevent.key
193 | unicode = keyevent.unicode
194 | if (31 < key < 127 or 255 < key < 266) and (
195 | self.maxLength == 0 or len(self.text) < self.maxLength): # only printable characters
196 | if keyevent.mod in (1, 2) and self.case == 1 and key >= 97 and key <= 122:
197 | # force lowercase letters
198 | self.text += chr(key)
199 | elif keyevent.mod == 0 and self.case == 2 and key >= 97 and key <= 122:
200 | self.text += chr(key - 32)
201 | else:
202 | # use the unicode char
203 | self.text += unicode
204 |
205 | elif key == 8:
206 | # backspace. repeat until clear
207 | keys = pygame.key.get_pressed()
208 | nexttime = pygame.time.get_ticks() + 200
209 | deleting = True
210 | while deleting:
211 | keys = pygame.key.get_pressed()
212 | if keys[pygame.K_BACKSPACE]:
213 | thistime = pygame.time.get_ticks()
214 | if thistime > nexttime:
215 | self.text = self.text[0:len(self.text) - 1]
216 | self.image.fill((255, 255, 255))
217 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
218 | newSurface = self.font.render(self.text, True, self.fontColour)
219 | self.image.blit(newSurface, [10, 5])
220 | updateDisplay()
221 | nexttime = thistime + 50
222 | pygame.event.clear()
223 | else:
224 | deleting = False
225 |
226 | self.image.fill((255, 255, 255))
227 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
228 | newSurface = self.font.render(self.text, True, self.fontColour)
229 | self.image.blit(newSurface, [10, 5])
230 | if screenRefresh:
231 | updateDisplay()
232 |
233 | def move(self, xpos, ypos, centre=False):
234 | if centre:
235 | self.rect.topleft = [xpos, ypos]
236 | else:
237 | self.rect.center = [xpos, ypos]
238 |
239 | def clear(self):
240 | self.image.fill((255, 255, 255))
241 | pygame.draw.rect(self.image, (0, 0, 0), [0, 0, self.width - 1, self.boxSize - 1], 2)
242 | newSurface = self.font.render(self.initialText, True, self.initialColour)
243 | self.image.blit(newSurface, [10, 5])
244 | if screenRefresh:
245 | updateDisplay()
246 |
247 |
248 | class newLabel(pygame.sprite.Sprite):
249 | def __init__(self, text, fontSize, font, fontColour, xpos, ypos, background):
250 | pygame.sprite.Sprite.__init__(self)
251 | self.text = text
252 | self.fontColour = parseColour(fontColour)
253 | self.fontFace = pygame.font.match_font(font)
254 | self.fontSize = fontSize
255 | self.background = background
256 | self.font = pygame.font.Font(self.fontFace, self.fontSize)
257 | self.renderText()
258 | self.rect.topleft = [xpos, ypos]
259 |
260 | def update(self, newText, fontColour, background):
261 | self.text = newText
262 | if fontColour:
263 | self.fontColour = parseColour(fontColour)
264 | if background:
265 | self.background = parseColour(background)
266 |
267 | oldTopLeft = self.rect.topleft
268 | self.renderText()
269 | self.rect.topleft = oldTopLeft
270 | if screenRefresh:
271 | updateDisplay()
272 |
273 | def renderText(self):
274 | lineSurfaces = []
275 | textLines = self.text.split("
")
276 | maxWidth = 0
277 | maxHeight = 0
278 | for line in textLines:
279 | lineSurfaces.append(self.font.render(line, True, self.fontColour))
280 | thisRect = lineSurfaces[-1].get_rect()
281 | if thisRect.width > maxWidth:
282 | maxWidth = thisRect.width
283 | if thisRect.height > maxHeight:
284 | maxHeight = thisRect.height
285 | self.image = pygame.Surface((maxWidth, (self.fontSize + 1) * len(textLines) + 5), pygame.SRCALPHA, 32)
286 | self.image.convert_alpha()
287 | if self.background != "clear":
288 | self.image.fill(parseColour(self.background))
289 | linePos = 0
290 | for lineSurface in lineSurfaces:
291 | self.image.blit(lineSurface, [0, linePos])
292 | linePos += self.fontSize + 1
293 | self.rect = self.image.get_rect()
294 |
295 |
296 | def loadImage(fileName, useColorKey=False):
297 | if os.path.isfile(fileName):
298 | image = pygame.image.load(fileName)
299 | image = image.convert_alpha()
300 | # Return the image
301 | return image
302 | else:
303 | raise Exception(f"Error loading image: {fileName} – Check filename and path?")
304 |
305 |
306 | def screenSize(sizex, sizey, xpos=None, ypos=None, fullscreen=False):
307 | global screen
308 | global background
309 | if xpos != None and ypos != None:
310 | os.environ['SDL_VIDEO_WINDOW_POS'] = f"{xpos}, {ypos + 50}"
311 | else:
312 | windowInfo = pygame.display.Info()
313 | monitorWidth = windowInfo.current_w
314 | monitorHeight = windowInfo.current_h
315 | os.environ['SDL_VIDEO_WINDOW_POS'] = f"{(monitorWidth - sizex) // 2}, {(monitorHeight - sizey) // 2}"
316 | if fullscreen:
317 | screen = pygame.display.set_mode([sizex, sizey], pygame.FULLSCREEN)
318 | else:
319 | screen = pygame.display.set_mode([sizex, sizey])
320 | background = Background()
321 | screen.fill(background.colour)
322 | pygame.display.set_caption("Graphics Window")
323 | background.surface = screen.copy()
324 | pygame.display.update()
325 | return screen
326 |
327 |
328 |
329 | def moveSprite(sprite, x, y, centre=False):
330 | sprite.move(x, y, centre)
331 | if screenRefresh:
332 | updateDisplay()
333 |
334 |
335 | def rotateSprite(sprite, angle):
336 | print("rotateSprite has been deprecated. Please use transformSprite")
337 | transformSprite(sprite, angle, 1)
338 |
339 |
340 | def transformSprite(sprite, angle, scale, hflip=False, vflip=False):
341 | oldmiddle = sprite.rect.center
342 | if hflip or vflip:
343 | tempImage = pygame.transform.flip(sprite.images[sprite.currentImage], hflip, vflip)
344 | else:
345 | tempImage = sprite.images[sprite.currentImage]
346 | if angle != 0 or scale != 1:
347 | sprite.angle = angle
348 | sprite.scale = scale
349 | tempImage = pygame.transform.rotozoom(tempImage, -angle, scale)
350 | sprite.image = tempImage
351 | sprite.rect = sprite.image.get_rect()
352 | sprite.rect.center = oldmiddle
353 | sprite.mask = pygame.mask.from_surface(sprite.image)
354 | if screenRefresh:
355 | updateDisplay()
356 |
357 |
358 | def killSprite(sprite):
359 | sprite.kill()
360 | if screenRefresh:
361 | updateDisplay()
362 |
363 |
364 | def setBackgroundColour(colour):
365 | background.setColour(colour)
366 | if screenRefresh:
367 | updateDisplay()
368 |
369 |
370 | def setBackgroundImage(img):
371 | global background
372 | background.setTiles(img)
373 | if screenRefresh:
374 | updateDisplay()
375 |
376 |
377 | def hideSprite(sprite):
378 | hiddenSprites.add(sprite)
379 | spriteGroup.remove(sprite)
380 | if screenRefresh:
381 | updateDisplay()
382 |
383 |
384 | def hideAll():
385 | hiddenSprites.add(spriteGroup.sprites())
386 | spriteGroup.empty()
387 | if screenRefresh:
388 | updateDisplay()
389 |
390 |
391 | def unhideAll():
392 | spriteGroup.add(hiddenSprites.sprites())
393 | hiddenSprites.empty()
394 | if screenRefresh:
395 | updateDisplay()
396 |
397 |
398 | def showSprite(sprite, layer=None):
399 | spriteGroup.add(sprite, layer= layer)
400 | if screenRefresh:
401 | updateDisplay()
402 |
403 |
404 | def makeSprite(filename, frames=1, altDims = None):
405 | thisSprite = newSprite(filename, frames, altDims)
406 | return thisSprite
407 |
408 |
409 | def addSpriteImage(sprite, image):
410 | sprite.addImage(image)
411 |
412 |
413 | def changeSpriteImage(sprite, index):
414 | sprite.changeImage(index)
415 |
416 | def changeLayer(sprite, layer):
417 | spriteGroup.change_layer(sprite, layer)
418 |
419 | def nextSpriteImage(sprite):
420 | sprite.currentImage += 1
421 | if sprite.currentImage > len(sprite.images) - 1:
422 | sprite.currentImage = 0
423 | sprite.changeImage(sprite.currentImage)
424 |
425 |
426 | def prevSpriteImage(sprite):
427 | sprite.currentImage -= 1
428 | if sprite.currentImage < 0:
429 | sprite.currentImage = len(sprite.images) - 1
430 | sprite.changeImage(sprite.currentImage)
431 |
432 |
433 | def makeImage(filename):
434 | return loadImage(filename)
435 |
436 |
437 | def touching(sprite1, sprite2):
438 | collided = pygame.sprite.collide_mask(sprite1, sprite2)
439 | return collided
440 |
441 |
442 | def allTouching(spritename):
443 | if spriteGroup.has(spritename):
444 | collisions = pygame.sprite.spritecollide(spritename, spriteGroup, False, collided=pygame.sprite.collide_mask)
445 | collisions.remove(spritename)
446 | return collisions
447 | else:
448 | return []
449 |
450 |
451 | def pause(milliseconds, allowEsc=True):
452 | keys = pygame.key.get_pressed()
453 | current_time = pygame.time.get_ticks()
454 | waittime = current_time + milliseconds
455 | updateDisplay()
456 | while not (current_time > waittime or (keys[pygame.K_ESCAPE] and allowEsc)):
457 | pygame.event.clear()
458 | keys = pygame.key.get_pressed()
459 | if (keys[pygame.K_ESCAPE] and allowEsc):
460 | pygame.quit()
461 | sys.exit()
462 | current_time = pygame.time.get_ticks()
463 |
464 |
465 | def drawRect(xpos, ypos, width, height, colour, linewidth=0):
466 | global bgSurface
467 | colour = parseColour(colour)
468 | thisrect = pygame.draw.rect(screen, colour, [xpos, ypos, width, height], linewidth)
469 | if screenRefresh:
470 | pygame.display.update(thisrect)
471 |
472 |
473 | def drawLine(x1, y1, x2, y2, colour, linewidth=1):
474 | global bgSurface
475 | colour = parseColour(colour)
476 | thisrect = pygame.draw.line(screen, colour, (x1, y1), (x2, y2), linewidth)
477 | if screenRefresh:
478 | pygame.display.update(thisrect)
479 |
480 |
481 | def drawPolygon(pointlist, colour, linewidth=0):
482 | global bgSurface
483 | colour = parseColour(colour)
484 | thisrect = pygame.draw.polygon(screen, colour, pointlist, linewidth)
485 | if screenRefresh:
486 | pygame.display.update(thisrect)
487 |
488 |
489 | def drawEllipse(centreX, centreY, width, height, colour, linewidth=0):
490 | global bgSurface
491 | colour = parseColour(colour)
492 | thisrect = pygame.Rect(centreX - width / 2, centreY - height / 2, width, height)
493 | pygame.draw.ellipse(screen, colour, thisrect, linewidth)
494 | if screenRefresh:
495 | pygame.display.update(thisrect)
496 |
497 |
498 | def drawTriangle(x1, y1, x2, y2, x3, y3, colour, linewidth=0):
499 | global bgSurface
500 | colour = parseColour(colour)
501 | thisrect = pygame.draw.polygon(screen, colour, [(x1, y1), (x2, y2), (x3, y3)], linewidth)
502 | if screenRefresh:
503 | pygame.display.update(thisrect)
504 |
505 |
506 | def clearShapes():
507 | global background
508 | screen.blit(background.surface, [0, 0])
509 | if screenRefresh:
510 | updateDisplay()
511 |
512 |
513 | def updateShapes():
514 | pygame.display.update()
515 |
516 |
517 | def end():
518 | pygame.quit()
519 |
520 |
521 | def makeSound(filename):
522 | pygame.mixer.init()
523 | thissound = pygame.mixer.Sound(filename)
524 |
525 | return thissound
526 |
527 |
528 | def playSound(sound, loops=0):
529 | sound.play(loops)
530 |
531 |
532 | def stopSound(sound):
533 | sound.stop()
534 |
535 |
536 | def playSoundAndWait(sound):
537 | sound.play()
538 | while pygame.mixer.get_busy():
539 | # pause
540 | pause(10)
541 |
542 |
543 | def makeMusic(filename):
544 | pygame.mixer.music.load(filename)
545 |
546 |
547 | def playMusic(loops=0):
548 | global musicPaused
549 | if musicPaused:
550 | pygame.mixer.music.unpause()
551 | else:
552 | pygame.mixer.music.play(loops)
553 | musicPaused = False
554 |
555 |
556 | def stopMusic():
557 | pygame.mixer.music.stop()
558 |
559 |
560 | def pauseMusic():
561 | global musicPaused
562 | pygame.mixer.music.pause()
563 | musicPaused = True
564 |
565 |
566 | def rewindMusic():
567 | pygame.mixer.music.rewind()
568 |
569 |
570 | def endWait():
571 | updateDisplay()
572 | print("Press ESC to quit")
573 | waiting = True
574 | while waiting:
575 | for event in pygame.event.get():
576 | if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == keydict["esc"]):
577 | waiting = False
578 | pygame.quit()
579 | sys.exit()
580 |
581 |
582 |
583 | def keyPressed(keyCheck=""):
584 | global keydict
585 | keys = pygame.key.get_pressed()
586 | if sum(keys) > 0:
587 | if keyCheck == "" or keys[keydict[keyCheck.lower()]]:
588 | return True
589 | return False
590 |
591 |
592 | def makeLabel(text, fontSize, xpos, ypos, fontColour='black', font='Arial', background="clear"):
593 | # make a text sprite
594 | thisText = newLabel(text, fontSize, font, fontColour, xpos, ypos, background)
595 | return thisText
596 |
597 |
598 | def moveLabel(sprite, x, y):
599 | sprite.rect.topleft = [x, y]
600 | if screenRefresh:
601 | updateDisplay()
602 |
603 |
604 | def changeLabel(textObject, newText, fontColour=None, background=None):
605 | textObject.update(newText, fontColour, background)
606 | # updateDisplay()
607 |
608 |
609 | def waitPress():
610 | pygame.event.clear()
611 | keypressed = False
612 | thisevent = pygame.event.wait()
613 | while thisevent.type != pygame.KEYDOWN:
614 | thisevent = pygame.event.wait()
615 | return thisevent.key
616 |
617 |
618 | def makeTextBox(xpos, ypos, width, case=0, startingText="Please type here", maxLength=0, fontSize=22):
619 | thisTextBox = newTextBox(startingText, xpos, ypos, width, case, maxLength, fontSize)
620 | textboxGroup.add(thisTextBox)
621 | return thisTextBox
622 |
623 |
624 | def textBoxInput(textbox, functionToCall=None, args=[]):
625 | # starts grabbing key inputs, putting into textbox until enter pressed
626 | global keydict
627 | textbox.text = ""
628 | returnVal = None
629 | while True:
630 | updateDisplay()
631 | if functionToCall:
632 | returnVal = functionToCall(*args)
633 | for event in pygame.event.get():
634 | if event.type == pygame.KEYDOWN:
635 | if event.key == pygame.K_RETURN:
636 | textbox.clear()
637 | if returnVal:
638 | return textbox.text, returnVal
639 | else:
640 | return textbox.text
641 | elif event.key == pygame.K_ESCAPE:
642 | pygame.quit()
643 | sys.exit()
644 | else:
645 | textbox.update(event)
646 | elif event.type == pygame.QUIT:
647 | pygame.quit()
648 | sys.exit()
649 |
650 |
651 | def clock():
652 | current_time = pygame.time.get_ticks()
653 | return current_time
654 |
655 |
656 | def tick(fps):
657 | for event in pygame.event.get():
658 | if (event.type == pygame.KEYDOWN and event.key == keydict["esc"]) or event.type == pygame.QUIT:
659 | pygame.quit()
660 | sys.exit()
661 | gameClock.tick(fps)
662 | return gameClock.get_fps()
663 |
664 |
665 | def showLabel(labelName):
666 | textboxGroup.add(labelName)
667 | if screenRefresh:
668 | updateDisplay()
669 |
670 |
671 | def hideLabel(labelName):
672 | textboxGroup.remove(labelName)
673 | if screenRefresh:
674 | updateDisplay()
675 |
676 |
677 | def showTextBox(textBoxName):
678 | textboxGroup.add(textBoxName)
679 | if screenRefresh:
680 | updateDisplay()
681 |
682 |
683 | def hideTextBox(textBoxName):
684 | textboxGroup.remove(textBoxName)
685 | if screenRefresh:
686 | updateDisplay()
687 |
688 |
689 | def updateDisplay():
690 | global background
691 | spriteRects = spriteGroup.draw(screen)
692 | textboxRects = textboxGroup.draw(screen)
693 | pygame.display.update()
694 | keys = pygame.key.get_pressed()
695 | if (keys[pygame.K_ESCAPE]):
696 | pygame.quit()
697 | sys.exit()
698 | spriteGroup.clear(screen, background.surface)
699 | textboxGroup.clear(screen, background.surface)
700 |
701 |
702 | def mousePressed():
703 | #pygame.event.clear()
704 | mouseState = pygame.mouse.get_pressed()
705 | if mouseState[0]:
706 | return True
707 | else:
708 | return False
709 |
710 |
711 | def spriteClicked(sprite):
712 | mouseState = pygame.mouse.get_pressed()
713 | if not mouseState[0]:
714 | return False # not pressed
715 | pos = pygame.mouse.get_pos()
716 | if sprite.rect.collidepoint(pos):
717 | return True
718 | else:
719 | return False
720 |
721 |
722 | def parseColour(colour):
723 | if type(colour) == str:
724 | # check to see if valid colour
725 | return pygame.Color(colour)
726 | else:
727 | colourRGB = pygame.Color("white")
728 | colourRGB.r = colour[0]
729 | colourRGB.g = colour[1]
730 | colourRGB.b = colour[2]
731 | return colourRGB
732 |
733 |
734 | def mouseX():
735 | x = pygame.mouse.get_pos()
736 | return x[0]
737 |
738 |
739 | def mouseY():
740 | y = pygame.mouse.get_pos()
741 | return y[1]
742 |
743 |
744 | def scrollBackground(x, y):
745 | global background
746 | background.scroll(x, y)
747 |
748 |
749 | def setAutoUpdate(val):
750 | global screenRefresh
751 | screenRefresh = val
752 |
753 | def setIcon(iconfile):
754 | gameicon = pygame.image.load(iconfile)
755 | pygame.display.set_icon(gameicon)
756 |
757 | def setWindowTitle(string):
758 | pygame.display.set_caption(string)
759 |
760 |
761 | if __name__ == "__main__":
762 | print("pygame_functions is not designed to be run directly.\n" \
763 | "See the wiki at https://github.com/StevePaget/Pygame_Functions/wiki/Getting-Started for more information.")
764 |
--------------------------------------------------------------------------------