I am trying to create a game using livewires in which there are multiple levels. In each level, the screen will need to be a different size, so either I can create a new screen, or I can resize it. When I tried a new screen, like this (mcve):
from livewires import games
games.init(screen_width = 500, screen_height=100, fps = 50)
#dosomething
games.screen.quit()
games.init(screen_width = 100, screen_height=500, fps = 50)
games.screen.mainloop()
I get the error:
Traceback (most recent call last):
File "C:\Users\Fred\Desktop\game\main.py", line 6, in <module>
games.screen.mainloop()
File "C:\Users\Fred\Desktop\game\livewires\games.py", line 308, in mainloop
object._tick()
File "C:\Users\Fred\Desktop\game\livewires\games.py", line 503, in _tick
self.tick()
File "C:\Users\Fred\Desktop\game\livewires\games.py", line 776, in tick
self._after_death()
File "C:\Users\Fred\Desktop\game\main.py", line 5, in <module>
games.init(screen_width = 100, screen_height=500, fps = 50)
File "C:\Users\Fred\Desktop\game\livewires\games.py", line 884, in init
screen = Screen(screen_width, screen_height, fps)
File "C:\Users\Fred\Desktop\game\livewires\games.py", line 159, in __init__
raise GamesError("Cannot have more than on Screen object")
livewires.games.GamesError: Cannot have more than on Screen object
games.screen.width
and height
cannot be set (you can only get them), so I cannot do it like that, and when I change add line in livewires.games to reset the screen count to 0, I get an error in pygame instead.
Does anyone know of a way to resize, or else destroy and recreate the screen in livewires?
Note: I'm using Michael Dawsons edited version. Download for pygame and livewires used.
There is a way you can explore, by calling the method display.set_mode
from pygame, like in the Screen
class constructor (l. 165 in game.py from the package you provided)
games.init(screen_width = 500, screen_height=100, fps = 50)
#[...] level stuffs...
games.screen._width = 100 # this setup the width property directly in the screen
games.screen._height = 500 # this setup the height property
games.screen._display = pygame.display.set_mode((100, 500)) # this update the display
One drawback of this solution is that if you keep some living sprites during the screen change, they will not update correctly the erase method at display time, and this can leave some lines during the painting. To avoid that, you can call games.screen.clear()
or if you need a selective cleanup, you can use an overriden Sprite
class that can handle the correct method by calling screen.blit_and_dirty
.
class MySprite(games.Sprite):
def __init__(self, screen, *args, **kwargs):
self.screen = screen
super().__init__(*args, **kwargs)
def _erase(self):
"""
This method overrides the class method by using blit_and_dirty instead of blit_background
"""
self.screen.blit_and_dirty(self.screen._background, self._rect)
To use this class, you just have to inherit from it, and add the screen parameter :
class Ball(MySprite):
def __init__(self, screen):
super().__init__(screen, games.load_image('ball.png'), x=40, y=40, dx=2, dy=2)
def update(self):
if self.left<=0 or self.right>=self.screen.get_width():
self.dx*=-1
if self.top<=0 or self.bottom>=self.screen.get_height():
self.dy*=-1
And you can declare an instance like below :
games.init(screen_width = 500, screen_height=100, fps = 50)
games.screen.add(Ball(games.screen) )
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With