Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples does not work with kivy 2.1 #289

Open
stasalcatraz opened this issue Sep 24, 2022 · 5 comments
Open

Examples does not work with kivy 2.1 #289

stasalcatraz opened this issue Sep 24, 2022 · 5 comments

Comments

@stasalcatraz
Copy link

Can not run examples with kivy 2.1.0

Traceback (most recent call last):
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/src/kivent_test/examples/2_basic_app/./main.py", line 79, in
YourAppNameApp().run()
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/app.py", line 954, in run
self._run_prepare()
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/app.py", line 923, in _run_prepare
self.load_kv(filename=self.kv_file)
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/app.py", line 696, in load_kv
root = Builder.load_file(rfilename)
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/lang/builder.py", line 305, in load_file
return self.load_string(data, **kwargs)
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/lang/builder.py", line 405, in load_string
widget.apply_class_lang_rules(
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/uix/widget.py", line 470, in apply_class_lang_rules
Builder.apply(
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/lang/builder.py", line 540, in apply
self._apply_rule(
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/lang/builder.py", line 662, in _apply_rule
self._apply_rule(
File "/home/alcatraz/devel/python/alcatraz/myrpg-env/lib/python3.10/site-packages/kivy/lang/builder.py", line 659, in _apply_rule
widget.add_widget(child)
File "kivent_core/gameworld.pyx", line 610, in kivent_core.gameworld.GameWorld.add_widget
kivy.uix.widget.WidgetException: Cannot add <kivent_core.systems.position_systems.PositionSystem2D object at 0x7f37dab9b100>, it already has a parent 1.0

@jameslutt
Copy link

me too.

@jameslutt
Copy link

In the file "yourappname.kv" comment out -> #TestGame:
on line 6 will make it works.

@stasalcatraz
Copy link
Author

stasalcatraz commented Nov 10, 2022

In the file "yourappname.kv" comment out -> #TestGame: on line 6 will make it works.

Yes, because no TestGame widget and no gameworld is created. So example just does show empty Widget object as root widget. If you override the build() method of YourAppNameApp class and return new TestGame widget as root you've got the same error

@amstelchen
Copy link

So, I tried everything to get rid of the abovementioned WidgetException, rebuilt Kivy (both 2.1.0 and 2.2.0.dev0), rebuilt kivent_core, used older Python versions, without result. Is there any solution?

@AccelQuasarDragon
Copy link

I spent my whole morning on this. TL:DR;
one issue is building (cymunk doesnt build properly, rip)

this works on WSL (so on the ubuntu side), using vcxsrv to see the linux windows on Windows, .xlaunch file is here:

<?xml version="1.0" encoding="UTF-8"?>
<XLaunch WindowMode="MultiWindow" ClientMode="NoClient" LocalClient="False" Display="-1" LocalProgram="xcalc" RemoteProgram="xterm" RemotePassword="" PrivateKey="" RemoteHost="" RemoteUser="" XDMCPHost="" XDMCPBroadcast="False" XDMCPIndirect="False" Clipboard="True" ClipboardPrimary="True" ExtraParams="" Wgl="True" DisableAC="True" XDMCPTerminate="False"/>

  • step1: build kivy manually: https://kivy.org/doc/stable/gettingstarted/installation.html#from-source

  • step2: fix this using this:
    problem: error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: CANCEL (err 8)
    soln link: https://github.com/orgs/Homebrew/discussions/4069#discussioncomment-7987024
    soln: git config --global http.postBuffer 4096M

  • step 3: git clone kivent

  • step 4: poetry add cython (or pip install cython)

  • step 5: finally build kivent
    cd .../KivEnt/modules/core
    python setup.py build_ext install

  • step 6: only the base example without any system works.

  • debugging strategy I have been trying:
    u gotta keep recompiling the pyx and rebuilding kivent in KivEnt/modules/core using python setup.py build_ext install
    this will rebuild all the changes to gameworld.pyx

the issue lies when you add a system to the gameworld:

PositionSystem2D:
          system_id: 'position'
          gameworld: gameworld
          zones: ['general']
          size_of_component_block: 128

best guess: game systems are treated as kivy widgets and mess up the widget tree, hence the widget parent is a FLOAT, not even a widget as seen in this error: Cannot add <kivent_core.systems.position_systems.PositionSystem2D object at 0x7f37dab9b100>, it already has a parent 1.0

the original exception is here in gameworld.pyx:

raise WidgetException('Cannot add %r, it already has a parent %r'
                                  % (widget, parent))

THIS WORKS (but has a blank screen)

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.clock import Clock
from kivy.core.window import Window
from random import randint, choice, randrange
import kivent_core
from kivent_core.gameworld import GameWorld
from kivent_core.systems.position_systems import PositionSystem2D
from kivent_core.systems.renderers import Renderer
from kivent_core.systems.gamesystem import GameSystem
from kivent_core.managers.resource_managers import texture_manager
from kivy.properties import StringProperty, ObjectProperty
from kivy.factory import Factory
from kivent_core.managers.resource_managers import texture_manager
from os.path import dirname, join, abspath

texture_manager.load_atlas(join(dirname(dirname(abspath(__file__))), 'test', 'assets', 
    'stars.atlas'))

def lerp(v0, v1, t):
    return (1.-t)*v0 + t * v1

class FadingSystem(GameSystem):
    make_entity = ObjectProperty(None)
    
    def update(self, dt):
        entities = self.gameworld.entities
        for component in self.components:
            if component is not None:
                entity_id = component.entity_id
                entity = entities[entity_id]
                color_comp = entity.color
                component.current_time += dt
                current_time = component.current_time
                fade_out_start = component.fade_out_start
                time = component.time
                fade_out_time = time - fade_out_start
                if current_time >= time:
                    self.gameworld.remove_entity(entity_id)
                    self.make_entity()
                if current_time < fade_out_start:
                    color_comp.a = lerp(0., 255., 
                        current_time / fade_out_start)
                else:
                    color_comp.a = lerp(255., 0., 
                        (current_time - fade_out_start) / fade_out_time)


Factory.register('FadingSystem', cls=FadingSystem)


class TestGame(Widget):

    def init_game(self):
        self.setup_states()
        self.load_resources()
        self.set_state()
        self.draw_some_stuff()

    def load_resources(self):
        keys = ['star1', 'star2', 'star3', 'star_circle', 'star_square']
        self.model_keys = model_keys = []
        mk_a = model_keys.append
        model_manager = self.gameworld.model_manager
        load_textured_rectangle = model_manager.load_textured_rectangle
        for x in range(100):
            model_key = 'star_m_' + str(x)
            tex_key = choice(keys)
            wh = randrange(1., 7.)
            real_name = load_textured_rectangle(
                'vertex_format_4f', wh, wh, tex_key, model_key)
            mk_a((model_key, tex_key))

    def draw_some_stuff(self):
        init_entity = self.gameworld.init_entity
        for x in range(1000):
            self.draw_a_star()

    def draw_a_star(self):
        model_to_use = choice(self.model_keys)
        pos = randint(0, Window.width), randint(0, Window.height)
        fade_in = randrange(10., 15.)
        fade_out = randrange(10., 15.)
        create_dict = {
            'position': pos,
            'color': (255, 255, 255, 0),
            'renderer': {'texture': model_to_use[1], 
                'model_key': model_to_use[0]},
            'fade': {'time': fade_in + fade_out,
                'fade_out_start': fade_in, 
                'current_time': 0,},
        }
        ent = self.gameworld.init_entity(create_dict, ['position', 'color', 
            'renderer', 'fade'])

    def setup_states(self):
        self.gameworld.add_state(state_name='main', 
            systems_added=['renderer'],
            systems_removed=[], systems_paused=[],
            systems_unpaused=['renderer', 'fade'],
            screenmanager_screen='main')

    def set_state(self):
        self.gameworld.state = 'main'

class DebugPanel(Widget):
    fps = StringProperty(None)

    def __init__(self, **kwargs):
        super(DebugPanel, self).__init__(**kwargs)
        Clock.schedule_once(self.update_fps)

    def update_fps(self,dt):
        self.fps = str(int(Clock.get_fps()))
        Clock.schedule_once(self.update_fps, .05)


class YourAppNameApp(App):
    def build(self):
        Window.clearcolor = (0, 0, 0, 1.)


if __name__ == '__main__':
    YourAppNameApp().run()

#:import path os.path
#:import dirname os.path.dirname
#:import main __main__

TestGame:

<TestGame>:
    gameworld: gameworld
    GameWorld:
        id: gameworld
        gamescreenmanager: gamescreenmanager
        size_of_gameworld: 100*1024
        size_of_entity_block: 128
        system_count: 4
        size: root.size
        pos: root.pos
        zones: {'general': 10000}
        
    GameScreenManager:
        id: gamescreenmanager
        size: root.size
        pos: root.pos
        gameworld: gameworld


<GameScreenManager>:
    MainScreen:
        id: main_screen


<MainScreen@GameScreen>:
    name: 'main'
    FloatLayout:
        DebugPanel:
            size_hint: (.2, .1)
            pos_hint: {'x': .225, 'y': .025}


<DebugPanel>:
    Label:
        pos: root.pos
        size: root.size
        font_size: root.size[1]*.5
        halign: 'center'
        valign: 'middle'
        color: (1,1,1,1)
        text: 'FPS: ' + root.fps if root.fps != None else 'FPS:'

so does this (also black screen)

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
import kivent_core

class TestGame(Widget):
    def on_kv_post(self, *args):
        self.gameworld.init_gameworld([], callback=self.init_game)

    def init_game(self):
        self.setup_states()
        self.set_state()

    def setup_states(self):
        self.gameworld.add_state(state_name='main',
            systems_added=[],
            systems_removed=[], systems_paused=[],
            systems_unpaused=[],
            screenmanager_screen='main')

    def set_state(self):
        self.gameworld.state = 'main'

class YourAppNameApp(App):
    def build(self):
        pass

if __name__ == '__main__':
    YourAppNameApp().run()
#:kivy 1.11.0

TestGame:

<TestGame>:
    gameworld: gameworld
    GameWorld:
        id: gameworld
        gamescreenmanager: gamescreenmanager
        size_of_gameworld: 100*1024
        size_of_entity_block: 128
        system_count: 2
        zones: {'general': 10000}
    GameScreenManager:
        id: gamescreenmanager
        size: root.size
        pos: root.pos
        gameworld: gameworld
        GameScreen:
            name: 'main'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants