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.
Related
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()
My problem is that when I change the content of the variable "XO" inside the if statement, the one in the condition of the If statement becomes undefined.
from ursina import *
import time
app = Ursina()
window.title = "Game"
window.borderless = False
window.exit_button_visible = False
XO = "X"
class Tile(Button):
def __init__(self, position = (-5, -5, 0), texture = "assets/tile.png"):
super().__init__(
parent = scene,
model = "quad",
color = color.lime,
position = position,
texture = texture
)
def input(self, key):
if self.hovered:
if key == "left mouse down":
if XO == "X":
Tile(position = self.position, texture = "assets/tile_x")
XO = "O"
else:
Tile(position = self.position, texture = "assets/tile_0")
XO = "X"
time.sleep(.005)
destroy(self)
for x in range(3):
for y in range(3):
block = Tile((x-1, y-1))
app.run()
The biggest issue here is that you seem to be trying to reference a global variable inside of a some inner context. In general, this is not encouraged for a lot of reasons. One of the biggest in my opinion is that global code is difficult to maintain. Instead, I would encourage you refactor your code so that all of your code resides inside of a class, and work on encapsulating your code.
That being said, sometimes it is necessary to use the global scope. In order to do that, you simply use the global keyword before the name of the variable you want global scope for. In your case, you would simple do global XO at the start of your input function.
I've been searching for an answer for two hours now. What I am trying to accomplish in kivy is this:
import time
clear = "\033[2J\033[1;1f"
print("""
################################
##this should display an image##
################################""")
time.sleep(1)
print(clear)
print("""
#####################################
##this should display another image##
#####################################""")
It is the beginning of a program I already got ready, but not as a real Desktop Application as if it would be with kivy.
The program begins with showing an image, pausing for a second, then not showing an image before initiating the main menu with buttons and so on (not important).
This is what I have so far (not working) :
class Intro(FloatLayout):
connection = Image(source='connection.png')
noconnection = Image(source='noconnection.png')
checkloop = True
def check_connection(self, dt):
url='http://www.google.com/'
timeout=5
connected.stop()
noconnection.stop()
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
_ = requests.get(url, timeout=timeout)
connected.play()
self.add_widget(self.connection)
Clock.schedule_once(self.remove_widget(self.connection), 1)
checkloop = False
except requests.ConnectionError:
noconnection.play()
self.add_widget(self.noconnection)
self.remove_widget(self.noconnection)
txtinput = TextInput(text='ConnectionError. Enter to try again...')
except smtplib.SMTPConnectError:
noconnection.play()
img = Image(source='noconnection.png')
self.add_widget(self.noconnection)
self.remove_widget(self.noconnection)
txtinput = TextInput(text='SMTPConnectError. Enter to try again...')
class I41(App):
def build(self):
self.icon = 'riseicon.png'
self.title = '41'
intro = Intro()
Clock.schedule_once(intro.check_connection)
print("DONE")
What am I doing wrong still?
I hope you guys can help me! First questions asked on stackoverflow!
In your check_connection() method you have many return statements. Note that the documentation. says:
return leaves the current function
So anything after a return is encountered will not be executed, and any other code in the method will be stopped (like a while loop).
A fix is to call the code that you want executed after return using a call to Clock.schedle_once() .
Here is a simple example of how to do that:
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
class MyFloatLayout(FloatLayout):
img = Image(source='connection.png')
checkloop = True
def showImage(self, dt):
self.add_widget(self.img)
# other code here, like connecting to Google
if self.checkloop:
# continue loop
Clock.schedule_once(self.deleteImage, 1)
def deleteImage(self, dt):
self.remove_widget(self.img)
if self.checkloop:
# continue loop
Clock.schedule_once(self.showImage, 1)
class I41(App):
def build(self):
self.icon = 'riseicon.png'
self.title = '41'
root = MyFloatLayout()
# start image loop
Clock.schedule_once(root.showImage)
return root
I41().run()
The loop is stopped by setting checkloop to False in MyFloatLayout.
I am trying to build a simple media tool in Pyglet, which requires a seek feature. Files are loaded, paused, and then told to seek to a specific time; however, the file does not seek when Player.seek() is called. Below is the test code I am using:
import os
import pyglet
from os.path import abspath, isfile
def loadsong(filename):
# check for file
print("Attempting to load "+filename)
filename = abspath(filename)
if not ( isfile(filename) ):
raise Exception(filename+" not found.")
# create a player for this file
song = pyglet.media.load(filename)
source = song.play()
source.eos_action = source.EOS_LOOP
source.pause()
return source
music = loadsong("test.mp3")
music.seek(57)
music.play()
pyglet.app.run()
What am I doing wrong here? I am using Python 3.5.2, Pyglet 1.2 alpha 1, and AVBin 11 alpha 4.
First of all, the error you're getting is quite important.
But I'll assume it's a Segmentation fault (core dumped) on the row:
music.seek(12)
Another quick note, fix your indentation! You're using 3 spaces and whether you are a space guy or a tab guy - 3 spaces is just odd -
The reason for you getting a segmentation fault when trying to seek is most likely because of AVbin, it's an old (and dead afaik) project.
I hacked together something more similar to a music player and here's an example on how you can use Seek with wav files:
import pyglet
from pyglet.gl import *
from os.path import abspath, isfile
pyglet.options['audio'] = ('pulseaudio', 'alsa', 'openal', 'silent')
pyglet.have_avbin=False
key = pyglet.window.key
def loadsong(filename):
# check for file
filename = abspath(filename)
# create a player for this file
player = pyglet.media.Player()
player.queue(pyglet.media.load(filename, streaming=False))
#player.play()
#song.eos_action = song.EOS_LOOP
#song.pause()
return player
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(300, 300, fullscreen = False)
self.alive = 1
self.player = loadsong('./test.wav')
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
elif symbol == key.SPACE:
if self.player.playing:
self.player.pause()
else:
self.player.play()
elif symbol == key.RIGHT:
print('Skipping to:',self.player.time+2)
self.player.source.seek(self.player.time+2)
elif symbol == key.LEFT:
print('Rewinding to:',self.player.time-2)
self.player.source.seek(self.player.time-2)
def render(self):
self.clear()
#source = pyglet.text.Label(str(self.player.source.info.title.decode('UTF-8')), x=20, y=300-30)
volume = pyglet.text.Label(str(self.player.volume*100)+'% volume', x=20, y=40)
p_time = pyglet.text.Label(str(self.player.time), x=20, y=20)
#source.draw()
volume.draw()
p_time.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
x = main()
x.run()
A few important notes:
pyglet.have_avbin=False
This will turn off AVbin completely, there is probably a way to turn it off for individual sources.. But since I rarely play around with it I honestly have no idea of how to.. So off it goes :)
Secondly:
streaming=False
On the media.load() call is quite important, otherwise you might get weird artifacts in your sound and or no sound at all. I got instance to a super high pitched scratching noise that almost made me deaf without that flag.
Other than that, the code is quite straight forward.
self.player.source.seek(<time>)
Is called on the player object that is a instance of pyglet.media.Player(). And it works brilliantly.
Another work-around would be to manually install AVbin 7 which appears to be working better, but I'm reluctant to install it on this machine just for testing purposes.. But the overall info i've gathered over the years is that that old library works better with Mp3 files.
Please ensure Player.playing is True before invoking Player.seek().
In the end of loadsong() function, you invoked the pause() that will set the Player.playing to False.
you could try:
music.play()
music.seek(57)
instead of:
music.seek(57)
music.play()
The following example uses pyglet 1.5.6, the seek() function works on my macbook pro, but negative on my windows 10:
import pyglet
from pyglet.window import key
source = pyglet.media.load(VIDEO_FILE_PATH)
fmt = source.video_format
player = pyglet.media.Player()
player.queue(source)
player.play()
window = pyglet.window.Window(width=fmt.width, height=fmt.height)
#window.event
def on_draw():
player.get_texture().blit(0, 0)
#window.event
def on_key_press(symbol, modifiers):
if symbol == key.LEFT:
player.seek(player.time - 3.5)
elif symbol == key.RIGHT:
player.seek(player.time + 3.5)
elif symbol == key.SPACE:
if player.playing:
player.pause()
else:
player.play()
pyglet.app.run()
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.