randomize background music for pygame project - python-3.x

I am trying to shuffle my background music in this very basic space invaders game. I just want it to randomly play a song from a list of 5 songs whenever the game starts or is restarted(I haven't added a restart button yet)I'm not getting any errors in the terminal but there is also nothing playing.
# background music
play_list = []
play_list.append("./toonz/toon1.mp3")
play_list.append("./toonz/toon2.mp3")
play_list.append("./toonz/toon3.mp3")
play_list.append("./toonz/toon4.mp3")
play_list.append("./toonz/toon5.mp3")
def play_toonz(play_list):
random.shuffle(play_list)
pygame.mixer.music.load(play_list[songNumber])
pygame.mixer.music.play(-1)
for num, song in enumerate(play_list):
if num == songNumber:
continue
mixer.music.queue(song)
Thinking I may have written the function incorrectly??

This code works for me:
import pygame
import random
pygame.mixer.init()
# background music
play_list = []
play_list.append(r"D:\MikeStuff\MP3\04-Zombie.mp3")
play_list.append(r"D:\MikeStuff\MP3\03 Invincible.mp3")
play_list.append(r"D:\MikeStuff\MP3\10. Kashmir.mp3")
play_list.append(r"D:\MikeStuff\MP3\11-fozzy-sos.mp3")
play_list.append(r"D:\MikeStuff\MP3\104-radiohead-creep.mp3")
songNumber = 1
def play_toonz(play_list):
random.shuffle(play_list)
pygame.mixer.music.load(play_list[songNumber])
pygame.mixer.music.play(10)
for num, song in enumerate(play_list):
if num == songNumber:
continue
pygame.mixer.music.queue(song)
play_toonz(play_list)
input("Press Enter to Exit....")

Related

Trying to make a can counter on a PI 4 in python, Strugging with code for two sensors running at the same time

So I work in the beverage industry and I decided to try and make a can counter using a Raspberry PI4. It needs to use two industrial sensors on the GPIO that detect the cans.
Full Disclosure I have just been googling most code and reading when I get errors in terminal to try and fix the issue. I have done some rudimentary C# and C++ programming doing PLC stuff but it's nothing like what i'm trying to do right now. Just some simple statements for conversions and formulas.
I have had it counting via the sensor on a very rudimentary code
import RPi.GPIO as GPIO
import time
GPIN = 16
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN, GPIO.IN)
counting = 0
while True:
while GPIO.input(GPIN) == 0:
time.sleep(0.1)
counting = counting + 1
print(counting)
while GPIO.input(GPIN) == 1:
time.sleep(0.1)
This counts in the terminal. It is of note I need to count the on and off state with a slight delay to keep accidental double counts from happening. I have even added in a GUI with guizero that makes it count in a window. although currently I cannot replicate that from what I remember working and i foolishly didn't save that as i was trying to get to the next stage, but the rough of it was instead of the print(counting) section in the above code I had the app.display() info.
Problem is I need it to count 2 sensors at the same time, one before the can rejector and one after. So I did some reading and figured I needed to run two (or maybe 3) loops at the same time. as I have 2 sensors that need a constant loop, plus it seems like a need another loop that runs and refreshes the GUI. I got turned into threading and have been trying to implement it as that seems like what I want but haven't been able to make heads or tails of it. I can get the GUI to display, but the sensors don't read. If I switch back to my simple code it counts away. Im having trouble meshing the two together.
import threading
from guizero import App, Text, PushButton
import RPi.GPIO as GPIO
import time
GPIN1 = 16
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN1, GPIO.IN)
GPIN2 = 15
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIN2, GPIO.IN)
counting1 = 0
counting2 = 0
counting3 = counting1 - counting2
def sensor1():
global counting1
while GPIO.input(GPIN1) == 0:
time.sleep(0.1)
counting1 = counting1 + 1
while GPIO.input(GPIN1) == 1:
time.sleep(0.1)
def sensor2():
global counting2
while GPIO.input(GPIN2) == 0:
time.sleep(0.1)
counting2 = counting2 + 1
while GPIO.input(GPIN2) == 1:
time.sleep(0.1)
x = threading.Thread(target=sensor1)
y = threading.Thread(target=sensor2)
x.start()
y.start()
while True:
app = App(title="Can Count")
message = Text(app, text="Total")
message = Text(app, text=(counting1))
message = Text(app, text="Rejected")
message = Text(app, text=(counting3))
app.display()
I'm just a bit stumped I'm sure my way isn't the best way to do this, any advice, tips or pointers in the right direction would be appreciated. I'm trying to crash course youtube python tutorials on the side but I am still coming up short.
It seems like I can get the display to show updates if i close the window via the x it restarts the window and shows the update but I have tried a few different things with guizero using a def text(): above that code and text.repeat(10, text) thinking this would redraw the screen but that doesn't work or breaks the gui or the code.
Also I know I call PushButton and don't use it, but the end goal will have a simple reset the counter button.. Just haven't got there yet.

how do I let my program know and respond to a key being pressed

I am thirteen years old, and I am learning to code. I think that I am doing quite well, however, I have hit a massive roadblock.
I am trying to program some sort of advanced Etch a sketch game, and with the general coding, I can do it.
like:
if the player says 'forward' + number:
go forward by that number.
that all works and it can draw shapes and everything, and rub out and change color even.
But what I am trying to do, is make my program respond to going forward when the button 'w' 'a' 's' or 'd' buttons are pressed, then without clicking enter, have it immediately have a turtle move by 40 pixels up, down, left or right.
I am using a platform called Trinket.io and so far it is proving very useful to code on. but whenever I find a website that says, 'this should work!' it doesn't. or it is only a snippet of code, or whatever the problem is, the program won't respond when I click w a s or d.
On Trinket.io, when you open up a pygame trinket it gives you two example games that both work on w a s d movement. I have tried to take some code form that, and modify it so it will print some text 'you clicked a' or 'you clicked w'. This hasn't worked either.
By the way, all of this testing has been done on a completely different trinket so various bits of code in the Etch a sketch prodject can't be the problem.
from time import *
import pygame
pygame.init()
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
while True: # main game loop
for event in pygame.event.get(): # event handling loop
if event.type == K_DOWN:
print('key down')
elif event.key == K_UP:
print('key up')
this piece of code is as close as I think I have gotten so far to my goal as it produces no error messages, it just doesn't work or do anything.
Try putting your event handling loop in a different thread so it can run with your game:
from time import *
import pygame
import _thread
pygame.init()
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
def controller():
while True: # main game loop
for event in pygame.event.get(): # event handling loop
if event.type == K_DOWN:
print('key down')
elif event.key == K_UP:
print('key up')
_thread.start_new_thread(controller)
Your controller should be running parallel with your game, This means that the rest of your game will also have to be put into it's own thread
.
See this for more info on threading: https://www.tutorialspoint.com/python3/python_multithreading.htm

Why does tkinter sometimes work without mainloop in Python 3?

Here's code for a little game. You're supposed to hit buttons that say 'click' to score points and avoid hitting buttons that say 'clack' or 'cluck' which cause you to lose points. The first weird thing is that the program works fine under IDLE even though it doesn't include a call to mainloop. The second is that it stops working if we add the following line at the bottom:
input('Hit enter to continue')
No game window appears, even after we hit enter. Adding a different line at the end like
print('hello')
does not have this effect.
Can anyone explain to me what's going on? I know that GUI programs used to run under IDLE's own mainloop, but that was a long time ago in Python 2 and definitely wasn't generally true under Python 3, at least last time I checked.
from tkinter import *
import random
score = 0
root = Tk()
scoreFrame = Frame(root)
scoreFrame.pack(expand = YES, fill = BOTH)
scoreLabel = Label(scoreFrame)
scoreLabel.pack()
def showScore():
scoreLabel['text'] = 'Score: {0}'.format(score)
scoreLabel.pack()
clickFrame = Frame(root)
clickFrame.pack(side = BOTTOM, expand = YES, fill = BOTH)
def changeLabels():
for button in buttons:
button['text'] = random.choice(['click', 'clack', 'cluck'])
button['bg'] = buttonDefaultColor
root.after(1500, changeLabels)
def makeButton():
button = Button(clickFrame)
def cmd():
global score
if button['bg'] == buttonDefaultColor:
if button['text'] == 'click':
score += 10
button['bg'] = 'light green'
else:
score -= 10
button['bg'] = 'light yellow'
button['command'] = cmd
button.pack(side = LEFT, expand = YES, fill = BOTH)
return button
buttons = [makeButton() for i in range(5)]
buttonDefaultColor = buttons[0]['bg']
changeLabels()
showScore()
Added: The first three comments all suggest that IDLE is running the event loop for me, making mainloop unnecessary but (1) I remember clearly when this suddenly stopped being true some years back (not that IDLE stopped running mainloop, but that GUI programs running under it did not need to run mainloop themselves) and (2) no one has explained why the input statement at the end breaks the program.

Mp3 Player using python 2.7 and pyglet on Ubuntu

I am trying to make an mp3 player in python using pyglet and I want to display the current song name that is playing. I tried to use SourceInfo class, but I don't know how it works
pyglet.media.SourceInfo.title doesn't show anything. Could you please help me?
Thanks
First all all, make sure you got AvBin installed!
Otherwise you won't be able to play much other than wav files.
Remember that this is just a rough mock up of what you need.
Build on it, scrap it.. But this is a start.
import pyglet
pyglet.options['audio'] = ('pulse', 'alsa')
window = pyglet.window.Window(width=800, height=600)
player=pyglet.media.Player()
# == Queue more tracks,
# the label will update automatically
player.queue( pyglet.media.load('./Downloads/music/Pendulum - Hold Your Color.mp3', streaming=True) )
player.volume=0.3
# window is the variable 'window' from earlier.
#window.event
def on_draw():
window.clear()
if player.playing:
label = pyglet.text.Label('{artist} - {song}'.format(**{'artist' : player.source.info.author.decode('UTF-8'),
'song' : player.source.info.title.decode('UTF-8')}),
font_size=36,
x=window.width//2, y=window.height//2, # same here, window on line 6
anchor_x='center', anchor_y='center')
else:
label = pyglet.text.Label('Music paused!', font_size=36, x=window.width//2, y=window.height//2, anchor_x='center', anchor_y='center')
label.draw()
window.flip() # This is overkill but ensures proper rendering at all times.
#window.event
def on_key_press(symbol, modifiers):
# Up and Down controls the volume for instance
if symbol == pyglet.window.key.UP:
player.volume = player.volume+0.1
elif symbol == pyglet.window.key.DOWN:
player.volume = player.volume-0.1
# Any key really will start/pause the playback
elif player.playing:
player.pause()
else:
player.play()
pyglet.app.run()

mouse click events on a saved video using opencv and python

I want to draw a rectangle in a saved video. While drawing the rectangle,the video must freeze. I am successful in drawing a rectangle on a image,but I don't know how to do the same on a saved video using opencv and python.
I was in need of a ROI selection mechanism using opencv and I finally figured how to implement it.
The implementation can be found here (opencvdragrect). It uses opencv 3.1.0 and Python 2.7
For a saved video till the time you don't read another frame and display it, the video is considered as paused.
In terms of how to add it to a paused video (frame), this code below might help.
import cv2
import selectinwindow
wName = "select region"
video = cv2.VideoCapture(videoPath)
while(video.isOpened()):
# Read frame
ret, RGB = video.read()
frameCounter += 1
if frameCounter == 1 : # you can pause any frame you like
rectI = selectinwindow.dragRect
selectinwindow.init(rectI, I, wName, I.shape[1], I.shape[0])
cv2.namedWindow(wName)
cv2.setMouseCallback(wName, selectinwindow.dragrect, rectI)
while True:
# display the image
cv2.imshow(wName, rectI.image)
key = cv2.waitKey(1) & 0xFF
# if returnflag is set break
# this loop and run the video
if rectI.returnflag == True:
break
box = [rectI.outRect.x,rectI.outRect.y,rectI.outRect.w,rectI.outRect.h]
# process the video
# ...
# ...
In the (opencvdragrect) library you use double-click to stop the rectangle selection process and continue with video.
Hope this helps.

Resources