├── .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 | 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 | 14 | 15 | 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 | 64 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 93 | 94 | 95 | 96 | 114 | 115 | 116 | 135 | 136 | 137 | 156 | 157 | 158 | 177 | 178 | 179 | 198 | 199 | 200 | 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 | 247 | 248 | 1500476902364 249 | 254 | 255 | 1511218806844 256 | 261 | 262 | 1518040675020 263 | 268 | 269 | 1524172379199 270 | 275 | 278 | 279 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 298 | 299 | 300 | 301 | 302 | 303 | 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 | --------------------------------------------------------------------------------