Pause Function Ursina - Python - python

I'm trying to do a pause menu for my game in Ursina Engine and I can't fount informatino how the function pause() works or how to do it.
Can someone help me?

Pausing is already implemented in ursina. Just set application.paused to True or False. application.pause() and application.resume() does the same.
from ursina import *
app = Ursina()
# Make a simple game so we have something to test with
from ursina.prefabs.first_person_controller import FirstPersonController
player = FirstPersonController(gravity=0, model='cube', color=color.azure)
camera.z = -10
ground = Entity(model='plane', texture='grass', scale=10)
# Create an Entity for handling pausing an unpausing.
# Make sure to set ignore_paused to True so the pause handler itself can still recieve input while the game is paused.
pause_handler = Entity(ignore_paused=True)
pause_text = Text('PAUSED', origin=(0,0), scale=2, enabled=False) # Make a Text saying "PAUSED" just to make it clear when it's paused.
def pause_handler_input(key):
if key == 'escape':
application.paused = not application.paused # Pause/unpause the game.
pause_text.enabled = application.paused # Also toggle "PAUSED" graphic.
pause_handler.input = pause_handler_input # Assign the input function to the pause handler.
app.run()

Related

My program crashes after i hold the w key to move the turtle for too long in the turtle library

The code is as follows:
import turtle
width = 400
length = 300
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("x")
drawer = turtle.Turtle()
drawer.speed(3)
drawer.begin_fill()
drawer.color("blue", "yellow")
def drawern():
drawer.seth(90)
drawer.fd(1)
def drawerw():
drawer.seth(180)
drawer.fd(1)
def drawers():
drawer.seth(270)
drawer.fd(1)
def drawere():
drawer.seth(0)
drawer.fd(1)
wn.onkeypress(drawern, "w")
wn.onkeypress(drawerw, "a")
wn.onkeypress(drawers, "s")
wn.onkeypress(drawere, "d")
wn.listen()
wn.mainloop()
It gives a stack overflow error. Does anyone know why this issue persists? It doesn't happen when i let go of it once in a while.
I believe the stack overflow error is due to repeated assigning of angle to the stack. To prevent this, you can introduce a debounce. We will name our debounce as move.
A debounce, in simple terms, is fail-safe to prevent an event for triggering again and again while keeping the rest of the code running.
Define the variable in global space:
move = False
As for the function:
def drawern():
global move #To let the function know the variable is from global scope
if not move: #The key is pressed first time
drawer.seth(90)
move = True #Sets our debounce to True, it will not activate until the key is released
drawer.fd(1)
wn.onkeypress(drawern, "w")
We need to have another function with an event to reset our debounce:
def reset_db():
global move
move = False #Resets the debounce, referencing the key has been released
wn.onkeyrelease(reset_db, "w") #Connects the event
I have demonstrated for w key here only. You can duplicate it for the rest of the keys too.

Ursina EditorCamera() toggle

this is the code I have used to toggle between having an EditorCamera in Ursina and turning it off:
from ursina import *
app = Ursina()
def input(key):
if key == 'd':
editor_camera.enabled = False
if key == 'e':
editor_camera.enabled = True
editor_camera = EditorCamera(enabled = False)
cube = Entity(model = "cube", texture = "brick") # just to see if it works
app.run()
When applied on its own like this, it works fine but when I apply the same logic to a much larger project, when enabling the camera (press e) everything just disappears and when I disable the camera (press d), it all reappears. Is there something I'm missing? Any help is appreciated.
After #pokepetter's answer, I figured out a new solution, just replace your code with this one:
from ursina import *
app = Ursina()
def input(key):
if key == 'd':
editor_camera.ignore = True
if key == 'e':
editor_camera.ignore = False
editor_camera = EditorCamera()
cube = Entity(model = "cube", texture = "brick")
app.run()
From editor_camera.py:
def on_disable(self):
camera.editor_position = camera.position
camera.parent = camera.org_parent
camera.position = camera.org_position
camera.rotation = camera.org_rotation
So when you disable it, it will put the camera back to it's original position, which can be useful when making, you know, an editor.
If you simply want to stop the editor camera's code from running, I recommend setting editor_camera.ignore = True and update and input code will stop running, but on_disable won't get called.
Alternatively you could do editor_camera.on_disable = None or just reset the position and rotation manually.

Trying to do animation but the program would close before it

I'm a beginner and was wondering if there was any way to finish the current animation before the program closes. Here is the sample of the code:
if playerHealth <= 0: # If the player dies
expl = Explosion(hit.rect.center, 'lg')
all_sprites.add(expl) # Show animation of him blowing up
running = False # End the game
Basically the running = False code would run before the animation(expl) starts. Is there a better way of showing this animation fully?
This sounds like a case for using a callback function. Pygame's animation class has the on_finished property which is intended to be assigned to a callback. The callback would be called once the animation is finished playing and would stop the game. Here's an example Explosion class.
class Explosion:
def __init__(self, rect, size, cb_func):
self.animate_explosion(cb_func)
...
def animate_explosion(self, cb_func):
# start animation here
...
# when animation finishes
self.on_finished = cb_func()
And then within your game logic you have something like the following:
def callback():
running = False
if playerHealth <= 0: # If the player dies
expl = Explosion(hit.rect.center, 'lg', callback())
all_sprites.add(expl) # Show animation of him blowing up
Probably You need more modifications, but one of them is:
if playerHealth <= 0 and not blowing_up_animation_started: # If the player dies
expl = Explosion(hit.rect.center, 'lg')
all_sprites.add(expl) # Show animation of him blowing up
blowing_up_animation_started = True
blowing_up_animation_finished = False
if blowing_up_animation_finished:
running = False # End the game

How to play music continuously in pyglet

me and my friend are working on a game and we want our music to loop as long as the game is running. Help please there seems to be no function to put music on repeat
In current versions of pyglet, you should use a SourceGroup, setting the loop attribute to True. You can then queue it into a Player to play it:
snd = pyglet.media.load('sound.wav')
looper = pyglet.media.SourceGroup(snd.audio_format, None)
looper.loop = True
looper.queue(snd)
p = pyglet.media.Player()
p.queue(looper)
p.play()
Not sure if there's a more compact way of doing this but it seems to work...
To make a sound play in a loop, you can use a Player:
# create a player and queue the song
player = pyglet.media.Player()
sound = pyglet.media.load('lines.mp3')
player.queue(sound)
# keep playing for as long as the app is running (or you tell it to stop):
player.eos_action = pyglet.media.SourceGroup.loop
player.play()
To play more background sounds simultaneously, just start up another player for each of the sounds, with the same EOS_LOOP "eos_action" setting as above for each of them.
For playing continuously you can use this code
This will allow you to play files from your root directory
import pyglet
from pyglet.window import key
import glob
window = pyglet.window.Window(1280, 720, "Python Player", resizable=True)
window.set_minimum_size(400,300)
songs=glob.glob("*.wav")
player=pyglet.media.Player()
#window.event
def on_key_press(symbol, modifiers):
if symbol == key.ENTER:
print("A key was pressed")
#window.event
def on_draw():
global player
for i in range(len(songs)):
source=pyglet.resource.media(songs[i])
player.queue(source)
player.play()
pyglet.app.run()
this works for me
myplayer = pyglet.media.Player()
Path = "c:/path/to/youraudio.mp3"
source = pyglet.media.load(filename=source, streaming=False)
myplayer.queue(self.slowCaseSongSource)
myplayer.eos_action = 'loop'
this might be irrelevant:
import pyglet
import time
import random
#WARNING: You have to download your own sounds and define them like this:
#sound_1 = pyglet.resource.media("sound_file.wav", streaming=False)
#replacing "sound_file" with your own file.
# Add the sound variables here
BACKGROUND_OPTIONS = ()
player = pyglet.media.Player()
def play_background_sound():
global player
player.queue(random.choice(BACKGROUND_OPTIONS))
player.play()
# This is optional; it's just a function that keeps the player filled so there aren't any breaks.
def queue_sounds():
global player
while True:
player.queue(random.choice(BACKGROUND_OPTIONS))
time.sleep(60) # change this if the background music you have is shorter than 3 minutes
threading.Thread(target=queue_sounds).start()

Right way to continuously update color of Tkinter Canvas item

I am trying to figure out how to change a rectangle's color continuously, with a second between each change. Right now I have this simple function which makes a window with a square above a button, that changes the color of the square after every button click:
def junk():
def random_color():
red = int(random.random()*256)
green = int(random.random()*256)
blue = int(random.random()*256)
return '#' + ('{:0>#02X}'*3).format(red,green,blue)
def change_color():
c.itemconfig(r, fill=random_color())
x = Tkinter.Tk()
c = Tkinter.Canvas(master=x)
c['width'] = 400; c['height'] = 400
r = c.create_rectangle(0,0,400,400)
b = Tkinter.Button(master=x, command=change_color)
b['text'] = 'change color'
c.pack(); b.pack(); x.mainloop()
What I want is to be able to click once, and then have the colors change automatically. I know I want to use a CheckButton instead of a Button for this, so that one click will start the loop, and and the next click will stop it.
Also, this is not how I am structuring my "real" code, this is how I am testing from the IDLE shell. Defining the helper functions inside the junk function makes it easy to get at all the relevant code at once, without having the bloat of a full class. So please don't give me comments on style, this is quick and dirty on purpose.
TL;DR I'm not sure how to get a continuous loop running to change the color, while being able to start and stop the loop with a button click.
I figured it out. Before I show my solution, I want to correct a mistaken statement I made above: I don't to use a Checkbutton to make this work. I can make a normal button into a toggle button by changing the 'relief' option of the button. Here is my solution:
def junk():
def color_poll():
global alarm
c.itemconfig(r, fill=random_color())
if keep_going:
alarm = c.after(1000, color_poll)
def change_color():
global keep_going, alarm
if not keep_going:
keep_going = True
b['text']='STOP';b['fg']='red';b['relief']=Tkinter.SUNKEN
color_poll()
else:
keep_going = False; c.after_cancel(alarm); alarm = None
b['text']='GO';b['fg']='green';b['relief']=Tkinter.RAISED
x = Tkinter.Tk()
c = Tkinter.Canvas(master=x)
c['width'] = 400; c['height'] = 400
r = c.create_rectangle(0,0,400,400)
global keep_going, alarm
keep_going = False; alarm = None
b = Tkinter.Button(master=x, command=change_color)
b['text'] = 'GO';b['fg']='green';b['font']='Arial 16';b['relief']=Tkinter.RAISED
c.pack(); b.pack(); x.mainloop()
I'm using the same random_color function, but I moved it out because it out of the junk function because it didn't need to be there.

Categories

Resources