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

A bug of scrolling #354

Open
ruichen0 opened this issue Sep 21, 2022 · 12 comments
Open

A bug of scrolling #354

ruichen0 opened this issue Sep 21, 2022 · 12 comments

Comments

@ruichen0
Copy link

ruichen0 commented Sep 21, 2022

When I use set_focus to scrolling the layer, A bug emerged:

File "C:\Python\Python39\lib\site-packages\cocos\layer\scrolling.py", line 448, in set_focus layer.set_view(childs_scroll_x, childs_scroll_y, w, h, 
File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 885, in set_view self._update_sprite_set() 
File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 1966, in _update_sprite_set self._sprites[cell] = pyglet.sprite.Sprite(image, x=int(cx), y=int(cy), 
File "C:\Python\Python39\lib\site-packages\pyglet\sprite.py", line 241, in __init__ self._texture = img.get_texture() File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 835, in get_texture self._current_texture = self.create_texture(Texture, rectangle, force_rectangle)
File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 827, in create_texture self.blit_to_texture(texture.target, texture.level,
File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 995, in blit_to_texture glTexSubImage2D(target, level,
File "C:\Python\Python39\lib\site-packages\pyglet\gl\lib.py", line 107, in errcheck raise GLException(msg) pyglet.gl.lib.GLException: b'\xce\xde\xd0\xa7\xd6\xb5'

and the window crashed.
This is my code:
`vx = (self.keys[key.D] - self.keys[key.A]) * self.MOVE_SPEED
vy = (self.keys[key.W] - self.keys[key.S]) * self.MOVE_SPEED

dx = vx * dt
dy = vy * dt

new = self.get_rect()

new.x += dx
new.y += dy

self.scroller.set_focus(new.x, new.y)`

Can I know how to fix it?
Thank you in advance.

@ccanepa
Copy link
Contributor

ccanepa commented Sep 21, 2022

missing '()' in new_position = self.get_rect ?

'new_position' is not used, should be 'new' ?

hard to say

@ruichen0
Copy link
Author

Yes, new_position is new. I accidentally removed get_rect parentheses on Github. It's actually parentheses there.

@ccanepa
Copy link
Contributor

ccanepa commented Sep 22, 2022

Yes, new_position is new. I accidentally removed get_rect parentheses on Github. It's actually parentheses there.

Please always use copy and paste from code as exercised to github issue to quote code, not free type it.

The bytes in pyglet.gl.lib.GLException: b'\xce\xde\xd0\xa7\xd6\xb5' should translate to text under your locale, or the locale the openGL drivers choose.

You should provide a translation for that to see what error is diagnosing openGL.

b'\xce\xde\xd0\xa7\xd6\xb5'.decode(zzz) should give clear text in your locale for the correct zzz, then you should translate to english.

Anyway, I suspect there's not enough context here to diagnose the problem.

@ruichen0
Copy link
Author

ruichen0 commented Sep 23, 2022

When I change set_focus(new.x, 0) or set_focus(0, new.y), the window didn't crashed. I also tried set_focus(new.x, new.y / 2) and
set_focus(new.x / 2, new.y), at the beginning the window is not crashed, but when I try to move to some place, it's crashed. I don't know if this is useful or not.

This is my complete code:

    class role(actor):
        def __init__(self, image, pos, maplayer):
            super(Role, self).__init__(image, pos, maplayer)

         def on_enter(self):
            super(Role, self).on_enter()

            self.scroller = self.get_ancestor(ScrollingManager)
            self.keys = key.KeyStateHandler()

            director.window.push_handlers(self.keys)

        def update_(self, dt):
            self.update_position(dt)

        def update_position(self, dt):
            vx = (self.keys[key.D] - self.keys[key.A]) * self.MOVE_SPEED
            vy = (self.keys[key.W] - self.keys[key.S]) * self.MOVE_SPEED

            dx = vx * dt
            dy = vy * dt

            new = self.get_rect()

            new.x += dx
            new.y += dy

            self.scroller.set_focus(new.x, new.y)

actor:

class Actor(Sprite, RectMapCollider):
    def __init__(self, image, pos, maplayer):
        Sprite.__init__(self, image)
        RectMapCollider.__init__(self)

        x, y = pos
        self.position = Vector2(x, y)
        self.cshape = AARectShape(self.position, self.width / 2, self.height / 2)

        self.maplayer = maplayer

    def update_position(self, new_pos):
        x, y = new_pos
        self.position = Vector2(x, y)
        self.cshape.center = self.position

Thank you for your help.

@ccanepa
Copy link
Contributor

ccanepa commented Sep 23, 2022

  • possible problem: dt can be big when the scene starts to run, maybe you can
    if dt > 0.1: dt = 0.1
  • not enough context: what is Role?
  • what was the openGL error?
  • use triple backticks when quoting blocks of code in Github, and set the lang. Example: hit 'edit' in ypur prev comment to see the raw post

@ruichen0
Copy link
Author

The Role context is added in the last comment now.
the openGL error:

File "D:\cocos2d游戏demo\source\game_scene\role.py", line 36, in update_
    self.update_position(dt)
  File "D:\cocos2d游戏demo\source\game_scene\role.py", line 74, in update_position
    self.scroller.set_focus(new.x, new.y)
  File "C:\Python\Python39\lib\site-packages\cocos\layer\scrolling.py", line 448, in set_focus
    layer.set_view(childs_scroll_x, childs_scroll_y, w, h,
  File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 885, in set_view
    self._update_sprite_set()
  File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 1966, in _update_sprite_set
    self._sprites[cell] = pyglet.sprite.Sprite(image, x=int(cx), y=int(cy),
  File "C:\Python\Python39\lib\site-packages\pyglet\sprite.py", line 241, in __init__
    self._texture = img.get_texture()
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 835, in get_texture
    self._current_texture = self.create_texture(Texture, rectangle, force_rectangle)
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 827, in create_texture
    self.blit_to_texture(texture.target, texture.level,
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 995, in blit_to_texture
    glTexSubImage2D(target, level,
  File "C:\Python\Python39\lib\site-packages\pyglet\gl\lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'\xce\xde\xd0\xa7\xd6\xb5'

Can I know how to fix it? Thank you.

@ccanepa
Copy link
Contributor

ccanepa commented Sep 24, 2022

The Role context is added in the last comment now.
the openGL error:

File "D:\cocos2d游戏demo\source\game_scene\role.py", line 36, in update_
    self.update_position(dt)
...
  File "C:\Python\Python39\lib\site-packages\pyglet\gl\lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'\xce\xde\xd0\xa7\xd6\xb5'

No, that was the python traceback.

The openGL error is b'\xce\xde\xd0\xa7\xd6\xb5', which is text in some encoding.

Being so short it is probably writed in some ideogram / pictorial language.

To see as text you must decode it; if it were Greek you would try
b'\xce\xde\xd0\xa7\xd6\xb5'.decode("cp737")

It is not Greek.

Well, try with decoders that will suit your Windows 's language, look available decoders at
https://docs.python.org/3/library/codecs.html#standard-encodings


Anyway, your code does multiple inheritance and composition with complex classes, it will be hard to debug.

As a vague guess I suspect some missing initialization, methods name colission, problems related to inheritance of properties, ...

@ruichen0
Copy link
Author

ruichen0 commented Sep 25, 2022

I really appreciate your help.
b'\xce\xde\xd0\xa7\xd6\xb5' shows "invalid value" when I decode.
I create a simple class to replace complicated Role's set_focus.
The new class:

from cocos.sprite import Sprite
from cocos.euclid import Vector2

from source.common.image import Image      # the source of all images


class Focus(Sprite):
    def __init__(self, pos):
        Sprite.__init__(self, image=Image.focus)        # A transparent picture

        x, y = pos
        self.position = Vector2(x, y)

    def on_enter(self):
        super(Focus, self).on_enter()

        self.scroller = self.get_ancestor(ScrollingManager)

    def update_(self, new_pos):
        self.update_position(new_pos)

    def update_position(self, new_pos):
        self.position = new_pos

        new = self.get_rect()

        self.scroller.set_focus(new.x, new.y)```

The code to invoke Focus:
```from cocos.layer import ScrollableLayer

from source.game_scene.assassin import Assassin
from source.game_scene.using import Using


class Game_Layer(ScrollableLayer):
    def __init__(self, *args):
        super(Game_Layer, self).__init__()

        self.background_map = args[0]
        self.objects_map = args[2]
        self.fore_map = args[1]

        self.creates()

    def creates(self):
        player = self.objects_map.match(label="start point")[0]
        self.role = Assassin(player.position, self.fore_map)
        self.player_focus = Using(self.role.position)
        self.add(self.role, z=50)
        self.add(self.player_using, z=0)

    def on_enter(self):
        super(Game_Layer, self).on_enter()
        self.schedule(self.update)

    def update(self, dt):
        self.role.update_(dt)
        self.player_focus.update_(self.role.position)

But when I try to move, the window crashed just like before.
The bug:

Traceback (most recent call last):
  File "D:\cocos2d游戏demo\source\main.py", line 17, in <module>
    run_game()
  File "D:\cocos2d游戏demo\source\main.py", line 12, in run_game
    director.run(Menu_Scene())
  File "C:\Python\Python39\lib\site-packages\cocos\director.py", line 384, in run
    event_loop.run()
  File "C:\Python\Python39\lib\site-packages\pyglet\app\base.py", line 169, in run
    timeout = self.idle()
  File "C:\Python\Python39\lib\site-packages\pyglet\app\base.py", line 239, in idle
    redraw_all = self.clock.call_scheduled_functions(dt)
  File "C:\Python\Python39\lib\site-packages\pyglet\clock.py", line 255, in call_scheduled_functions
    item.func(dt, *item.args, **item.kwargs)
  File "D:\cocos2d游戏demo\source\game_scene\game_layer.py", line 34, in update
    self.player_using.update_(self.role.position)
  File "D:\cocos2d游戏demo\source\game_scene\using.py", line 22, in update_
    self.update_position(new_pos)
  File "D:\cocos2d游戏demo\source\game_scene\using.py", line 30, in update_position
    self.scroller.set_focus(new.x, new.y)
  File "C:\Python\Python39\lib\site-packages\cocos\layer\scrolling.py", line 448, in set_focus
    layer.set_view(childs_scroll_x, childs_scroll_y, w, h,
  File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 885, in set_view
    self._update_sprite_set()
  File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 1966, in _update_sprite_set
    self._sprites[cell] = pyglet.sprite.Sprite(image, x=int(cx), y=int(cy),
  File "C:\Python\Python39\lib\site-packages\pyglet\sprite.py", line 241, in __init__
    self._texture = img.get_texture()
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 835, in get_texture
    self._current_texture = self.create_texture(Texture, rectangle, force_rectangle)
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 827, in create_texture
    self.blit_to_texture(texture.target, texture.level,
  File "C:\Python\Python39\lib\site-packages\pyglet\image\__init__.py", line 995, in blit_to_texture
    glTexSubImage2D(target, level,
  File "C:\Python\Python39\lib\site-packages\pyglet\gl\lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'\xce\xde\xd0\xa7\xd6\xb5'

Now I know it's not Actor's and Role's problem, but I still don't know why there's a bug.
May I know how to fix it?
Thank you.

@ccanepa
Copy link
Contributor

ccanepa commented Sep 25, 2022

Lets see:

  • the traceback's last two lines tells that openGL got an invalid value when doing a blit to texture
  • goint up the traceback,
    File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 885, in set_view self._update_sprite_set()
    the code in coco's tile.py for MapLayer was trying to create sprites for tiles that are now visible
  • So, this method may directly or not sending bad data to the blitter. let's look at it
       def set_view(self, x, y, w, h, viewport_x=0, viewport_y=0):
          # invoked by ScrollingManager.set_focus()
          super(MapLayer, self).set_view(x, y, w, h, viewport_x, viewport_y)
          self._update_sprite_set()
    • the super is ScrollableLayer, and his set_view does not ring any bells
    • self.update_sprite_set() calls self.get_visible_cells(), and attempts to create a sprite for each cell, wich for some cell will traceback
    • so self.get_visible_cells() is providing bad data
    • self.get_visible_cells() calls RectMap.get_in_region(self, left, bottom, right, top) which will return the cells that overlaps the intersection between the rect ( left, bottom, right, top) and the rect defined by the RectMap image
    • from this high level description seems that even if ( left, bottom, right, top) are wrong, the method will only returns cells covering the image, which could not traceback.
    • This only leaves two options for the problem
      • The self.tw or self.th, which give the width and height of image in tiles are wrong, which can come from
        • somehow the load map ends bad -> you can check by loading the map into one of the cocos test scripts and moving the player
        • the tw and th was rewrited to wrong values -> lookup the values on loading then in RectMap.get_in_region assert that they have the same value
      • the implementation for the intersection is bad -> add asserts in RectMap.get_in_region
          top = min(len(self.cells[0]), ceil(float(top - oy) / self.th))
          assert 0 <= int(left) < self.tw
          assert 0 <= int(right) < self.tw
          assert 0 <= int(bottom) < self.th
          assert 0 <= int(top) < self.th

@ruichen0
Copy link
Author

ruichen0 commented Dec 4, 2022

Hi @ccanepa , sorry to reply so late.

I first tried to add the code in RectMap.get_in_region, then I did nothing and the window has crashed. There's the bug:

File "C:\Python\Python39\lib\site-packages\cocos\director.py", line 384, in run event_loop.run() File "C:\Python\Python39\lib\site-packages\pyglet\app\base.py", line 169, in run timeout = self.idle() File "C:\Python\Python39\lib\site-packages\pyglet\app\base.py", line 239, in idle redraw_all = self.clock.call_scheduled_functions(dt) File "C:\Python\Python39\lib\site-packages\pyglet\clock.py", line 255, in call_scheduled_functions item.func(dt, *item.args, **item.kwargs) File "D:\aCocos2dGame\source\game_scene\game_layer.py", line 34, in update self.player_using.update_(self.role.position) File "D:\aCocos2dGame\source\game_scene\using.py", line 22, in update_ self.update_position(new_pos) File "D:\aCocos2dGame\source\game_scene\using.py", line 29, in update_position self.scroller.set_focus(new.x, new.y) File "C:\Python\Python39\lib\site-packages\cocos\layer\scrolling.py", line 448, in set_focus layer.set_view(childs_scroll_x, childs_scroll_y, w, h, File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 885, in set_view self._update_sprite_set() File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 951, in _update_sprite_set for cell in self.get_visible_cells(): File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 897, in get_visible_cells return self.get_in_region(x, y, x + w, y + h) File "C:\Python\Python39\lib\site-packages\cocos\tiles.py", line 1097, in get_in_region assert 0 <= int(left) < self.tw AssertionError

May I know how to fix it? Thank you.

@ruichen0
Copy link
Author

I download a project which with a tilemap can load well. But when I use the map in my project, it still crashed. the cocos is the same version, I think it's the code's problem, not the tliemap. May I know how to fix it? Thank you.

@ruichen0
Copy link
Author

Hi @ccanepa , may I know whether you get chance to check my comment? Thanks.

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

2 participants