Fishy-Feed Lab ============== This lab will be a step by step guide to create a minigame where you feed some worms to a fish. When the fishy is all fed and happy, you win! .. figure:: ../images/fishy-feed.webp :align: center Fishy-Feed Game .. warning:: Overfeeding your actual fish can be fatal. Please refer to the food instructions label for the proper amounts to feed your fish. Required Files -------------- - :doc:`pygame-template` - :download:`fishGreen.png <../images/fishGreen.png>` - :download:`wormPink.png <../images/wormPink.png>` Steps ----- 1. Import the ``fishGreen.png`` image. Store the image in a variable called ``fish_img``. Ensure that it is in the same directory as this Python file, or be sure to reference the filepath properly. **Never load images in the game loop**. Do this before the loop. 2. Create a ``fish_rect`` variable by extracting the ``Rect`` object from the ``fish_img`` using the ``.get_rect()`` method. 3. Set the ``.center`` property of the ``fish_rect`` to the center of the screen. 4. ``.blit`` the ``fish_img`` onto the ``screen``. Remember, you have to use the ``fish_rect`` 's ``.topleft`` coordinate, or the hitbox (the ``fish_rect``) and the image will be at different locations on the screen. 5. The fish looks like... a fish out of water. Change the ``screen.fill()`` color to ``(212, 241, 249)``. 6. Import the ``wormPink.png`` file and store it in a variable claled ``worm_img``. 7. Create a ``worm_rect`` variable and extract the ``Rect`` object from the ``worm_img`` `Surface``. Set the ``worm_rect`` center to (400, 50). 8. ``.blit`` the ``worm_img`` to the screen at the ``worm_rect.topleft`` position. 9. Mr. Wormy is a little too big. Let's apply a transform (scale) to the worm to make it 33% the original size. Do this befor eyou extract the rect into the ``worm_rect`` variable. 10. Next, set up a ``worms_fed`` variable and set it to ``0``. This will keep track of how many worms we have fed our fishy. 11. Get pygame to display some text showing the value of the ``worms_fed`` variable. Because this will change, it needs to be rendered in the game-loop. The text will simply be in teh format ``"Worms fed: {worms_fed}"``. Don't forget to ``pygame.font.init()``, then load a font, then you can render the text, then you can blit the text to the screen. Blit it to (0, 0). 12. Create a ``MOUSEBUTTONDOWN`` event that will just increace the score (``worms_fed``) by ``1`` every time you click. Just for testing purposes. Verify that the score text is updating. 13. Modify the mouse down event to only increase when you actually click on the ``worm_rect``. Use the ``.collidepoint`` method for this using ``event.pos``. 14. Modify the event again so that if the worm is clicked, we can give it a new location. Use ``random.randrange`` for this and use the screen width and height as the maximum. 15. Let's add the ability to drag the worm around. We want to be able to drop him on the fish. See a previous tutorial on how to drag if you need more hints. Create a ``dragging_worm`` variable and set it to ``False``. 16. In the "Game updates" section of the game loop, put some code like "if dragging worm is True, then set the worm_rect center to the mouse position". Again, the dragging tutorial will help out with this. 17. Manually set the ``dragging_worm`` variable to ``True`` to verify that the worm is stuck to the mouse position when it is ``True``. 18. Set ``dragging_worm`` back to ``False``. 19. In the ``MOUSEBUTTONDOWN`` event, comment out the score and the repositioning of the worm for now. Then, if the ``event.pos`` is on the worm, then we need to set dragging to ``True``. When you click the worm, it should stick to the mouse, but you won't be able to get rid of it, for now. 20. Create a ``MOUSEBUTTONUP`` event that will set the dragging variable to ``False``. Now when you release the worm, it should not stick to the mouse anymore, but drop where you let go. 21. Move the commented code from #19 concerning the score and the repositioning of the worm into the "Game updates" section of the game loop. You want to run this code if the ``worm_rect`` collides with the ``fish_rect``. Now if you move the worm to the fish, it will automatically eat it. 22. You may notice if you don't let go of the mouse, the dragging variable won't be set to ``False``. You can set it to False when the score goes up, too. Improvements ------------ - When the fish is fed 5 worms, show some text saying ``"You Win!"``. - Sometimes the worm spawns on the fish for free points. Use a while loop to ensure the worm spawns away from the fish. While the worm and fish are colliding, give the worm a new x and y coordinate. You can also use ``fish_rect.inflate(...)`` to add a buffer zone around the fish. - Get the fishy to move back and forth. When it moves right, flip the image. - Modify the code so you must drop the worm on the fish in order to score a point (rather than the fish simply coming into contact with it). - The hit-boxes for the worm and fish are a little off. See if you can narrow them down. It might help to draw a rect after you draw the image to see where the hitbox actually is and how large it is.