Using IDLE, I have written an interactive python program using pygame and saved it as file Songboard01.py. I use IDLE's run command or f5 to run the script. The user responds initially to the IDLE shell, which asks a startup question, after which all the responses are mouse clicks on the pygame screen. In addition to game play, the screen allows the user to click on alternatives such as (1) 'Quit', (2) 'Instructions', (3) 'Credits', (4) 'Solutions', and (5) 'Play again'. The first three work fine, and the game is able to pick up without a problem after (2) or (3). It is 'Play again' that has me stumped.
This function:
def new_game():
done = True # closes pygame while-loop
pygame.quit()
import Songboard01.py
will start the game over with the startup question in the IDLE shell, but it only works once. If the user tries to get a new game a second time, the error message ends:
File "/Users/anobium/Desktop/SongBoard/Songboard01.py", line 314, in new_game
import Songboard01.py
ModuleNotFoundError: No module named 'Songboard01.py'; 'Songboard01' is not a package
A python program cannot import itself, and using the import function will raise an error. Also, you shouldn't put a ".py" at the end of a package name. I recommend putting your main game loop and putting a break if the user chooses (1), (2), (3), or (4). Put a continue if the user chooses (5). Your game will go back to the start if the user chooses (5).
Sample code:
#do your imports
import pygame #and all other needed modules
#Make classes or setup the game
while True:
#Do all of the game stuff
#Ok now make the buttons
#if button = 1 or 2 or 3 or 4:
break
#else if button = 5:
continue
Related
I'm learning python with the book python crash course , i wrote the code for the game alien invasion , but it is not working , when i write "import sys" , the word sys is underscore and the program opens up the screen for like a millisecond and then it closes itself, i look for an answer in this site and YouTube and i haven't been able to find a solution, can anyone help? thanks in advance.
I'm using vs code on Linux mint.
this is what i wrote so far:
from settings import Settings
from ship import Ship
import sys
class AlienInvasion:
"""overall class to manage game assets and behavior"""
def __init__(self):
""" initialize the game and creates game resources"""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
def run_game(self):
"""start the main loop for the game."""
while True:
self._check_events()
#whatch for keyboard and mouse events .
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
#redraw the screen during each pass through the loop.
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
#make the most recently drawn screen visible.
pygame.display.flip()
if __name__ == '__main__':
#make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
It looks like there's probably an error being thrown somewhere in your script that is causing the program to stop running, and as such, close the terminal as soon as it is opened. In my experience, this only happens when you execute the script from a file browser UI by double-clicking it.
To fix this, try running the program from somewhere that will stay open, even when the program is terminated, like, for example, the built-in terminal in vscode (you can reveal by going to view > terminal). To run the program, then simply run the command:
python path/to/my/script.py
If it causes an error, you will then be able to see it printed nicely, without the terminal closing.
On another note, importing sys has nothing to do with this problem. The reason it is highlighted by pylance is that you have imported it, but then you haven't used it anywhere (for example calling a function like sys.exit()), so it thinks that the line is unnecessary. It will go away once you use the sys module somewhere else in the script.
According to your error content, I think this is caused by the fact that the file is not found, meanwhile sys is not used in your code.
Here are some reasons caused "FileNotFoundError", you could confirm one by one:
1. File name and file type
The wrong file name was inserted into the code. Please carefully check the document name.
2. Escape of Python string
In the string of file, the address string information similar to C:\user\desktop will be involved, which conflicts with the escape function in Python string, such as \n representing line feed. Use r"C:\User\Desktop" or C:\\User\\Desktop to avoid Python escaping strings.
3. Relative path problem
Generally, it is not recommended to use. In the process of Python running, the relative path is the folder that the process points to when running, and the folder is used as the file tree of the root node, that is, if you open the file by using the relative path, you can only access the file under its root node.
You could use the methods os.path.abspath() and os.path.abspath('..') provided in the OS library to view and change the absolute path where Python runs.
4. Python runtime location
If it is such a problem, you can add the following code to the head of the file:
import sys
sys.path.append("../your/target/path/")
try pip install os-sys and pip install syspath
enter link description here
I'm currently building a python code to play Blackjack where I need to be able to call certain functions uppon keypress without necessarily being in the terminal. I found this keyboard module which helped but I came across this issue.
def hit_or_stand(deck,hand):
global playing
print ("\nWould you like to Hit or Stand? Enter 'h' or 's'")
if keyboard.is_pressed('h'):
hit(deck,hand)
if keyboard.is_pressed('s'):
print("Player stands. Dealer is playing.")
playing = False
Let me explain what this function does as I don't want to overload everyone with the entire code. Essentially this function is called in a loop until the player decides to hit s which declares playing as False and therefore stopping the loop. If the player hits h then the hit function is called which draws a card. The player can draw as many cards.
My problem right now is that this code doesn't wait for user keypress. It loops extremely fast repeating it. I only want it to loop after either h or s is pressed.
I tried using keyboard.wait('h') on the line above the first if but then this doesn't allow the user to press s and therefore declare playing as False.
What I'm looking for is something along the lines of keyboard.wait('h'or's') but I know this does not work.
Thank you for your help. I am using python 3.7.9
EDIT: Keyboard Module I am referring too:
https://pypi.org/project/keyboard/
Use keyboard.read_key() to wait for any input.
If it's not h or s ,read_key again.
import keyboard
def mywait():
keyboard.read_key()
def my_function():
print("Hello")
def my_exit():
quit()
keyboard.add_hotkey("p", my_function)
keyboard.add_hotkey("esc", my_exit)
while True:
mywait()
Gets error when I click the exit (X) button:
Failed to execute script pong
How can I close the turtle game by clicking the exit button with no error?
Getting errors from turtle when you close the window is highly indicative of not playing by the rules event-wise. Typically it's due to a while True: loop instead of using timer events. A properly event-drive turtle program should reach the mainloop statement (or one of its equivalents) and allow events to run the show. If you want specifics, provide your code as part of your question.
The error in the terminal must be due to the the while True: loop that most beginners like me use. Closing the window abruptly stops the process while the while True: loop was still going on. So, in order to avoid this error you can define a function
#Function
def quit():
global running
running = False
#Keybinding
screen.onkeypress(quit, "q")
#Main game loop
while running:
...
#update events
...
I'm building a headless soundboard using Raspberry Pi, and as such need a way to launch the script I'm using on boot. The program was edited and tested using the default editor Pi shot up, Thonny, and everything seems to run as intended. The buttons I'm using all play the sounds I expect them to, no issues.
I went ahead and edited rc.local to run the script as soon as the Pi boots (specifically, I added sudo python /filepath/soundboard.py & above exit 0), which it does. It seems to run identically to the way it did using Thonny, but sound cuts off after about 5 seconds, even if no buttons are pressed. When I run it directly through the command line, the same issue occurs.
The code here has been compressed, as there is more than one button, but they all use the same line.
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
while True:
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
As far as I can tell, the while loop continues to run the program, but pressing buttons does nothing. Also, since adding the loop, the code dumps a Traceback, showing the error
gpiozero.exc.GPIOPinInUse: pin 8 is already in use by <gpiozero.Button objext on pin GPIO8, pull_up=True, is_active=False>
which might have something to do with my issue? btn_0 isn't the only button to have two functions assigned to it, but the only one to throw up this error, no matter what pin I use. The error doesn't appear if I remove the loop from the code.
You create btn_0 in an infinit while loop again and again. In the second iteration btn_0 is probably the first button that is created again. But pin 8 (which should be used for the button) has been assigned to the old instance of btn_0 in the last iteration.
You should move the glob.glob statement and the button initialization outside of the While loop. If the while loop is necessary to keep you program running place it below the initialization code and iterate over nop ore pause statements (whatever works).
If pygame.init starts it own looped thread you do not need a while loop at the end at all.
I don't know anything about pygame, so the last statement is just a guess.
Example:
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
while True:
nop
Is there a way to program a function that takes user input without requesting it? For example, during a game of tic-tac-toe, the user could press "Q" at any time and the program would close?
There are a few ways to do this, and they are all different.
If your game is a terminal application using curses, you would catch the q when you call getch(), and then raise SystemExit or simply break out of your while loop that many curses applications use.
Using tkinter or another GUI library, you would bind a key press event to your Frame widget that holds the tic-tac-toe board.
Assuming you are just printing the board out (I have a basic Tic-Tac-Toe game that does that), during input you could close it (even though you specifically asked otherwise):
user_option = input("Enter a space to move to, or 'Q' to quit: ")
try:
if user_option.lower() == 'q': # makes everything lowercase so it is easier to handle
import sys
sys.exit("Game Terminated.")
except TypeError:
# other code
I'm not sure how the player chooses to move, so I used try and except. In my Tic-Tac-Toe game, I have the user input an integer, which corresponds to a space on the board.
Or, you can just have the user press Ctrl+C which is the automatic KeyBoardInterrupt in Python (ends the program).