• Advertisement

Kivy Window Resizing Messes up Screen Formatting

Recommended Posts

I want to make it so the location and size of the buttons I use are changed to suit the background image when the screen is resized.

Here is my code so far:

Combines various .py files and
allows the game to run.
from kivy.app import App
from kivy.uix.image import Image
from kivy.config import Config
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout

class MainMenu(FloatLayout):
    def __init__(self, **kwargs):
        super(MainMenu, self).__init__(**kwargs)

        start_button = Button(pos=(25, 75),
                              size_hint=(.1, .1))

        load_button = Button(pos=(225, 75),
                             size_hint=(.1, .1))

        options_button = Button(pos=(425, 75),
                                size_hint=(.150, .1))

        quit_button = Button(pos=(708, 75),
                             size_hint=(.1, .1))

        background = Image(source="Main_Menu.png",
                           pos=(0, 0))


class BanditKing(App):
    def build(self):
        self.title = "Bandit King"
        self.icon = "Window_Icon.png"
        return MainMenu()

def main():
    Config.set("graphics", "width", "1600")
    Config.set("graphics", "height", "900")

if __name__ == "__main__":

Here is what it should always look like.



Here is what it does:


You might be able to tell the "Options" button is slightly off line with the other buttons. I would also like to know how to fix that.

Edited by RidiculousName

Share this post

Link to post
Share on other sites

I don't use Python but I will give you an answer that is pretty much universal. In C++ I do this in a number of ways, and it can depend on if I have objects within their own view, which keeps buttons spaced the same, or if I create new button views with different to account for different resolutions.

Just a basic example:

Assuming your screen is 800x600 and you have two buttons, each are 210x59 and positioned at (165, 270), and (425, 270) *Top left x,y. The first buttons top left point is at the 20.625% mark of the screen (left to right), and the second button is at the 53.125% mark of the screen for the x axis. The y will be at 45%. You get this calculation by taking the x or y and dividing into the width or height of the res. ie.

BUTTON 1 -> 165/800 = 0.20625, 270/600 = 0.45

BUTTON 2 -> 425/800 = 0.53125, 270/600 = 0.45

Now that you know the position % marks, you can resize with ratios.

If your screen res changes to 1024x600 you would just re-set the position of the buttons like so:

BUTTON1.x = 1024*0.20625 equals->211.20

BUTTON1.y = 600*0.45 equals -> 270

You'll see they have the same % -> 211.20/1024 = 0.20625 * 100 = 20.625%

This however will only re-position objects to contain the same x,y ratio when working in a different resolution, this will indeed add spacing between the objects unless you resize the width and height as well. This means you either have to be working with a high res image that you can scale down within the ratios evenly, or design different graphics for those off ratios.

The same principle can be applied like the above to generate width and height ratios. Let us take the width and height of the button which is 210x59. To get the ratio we do the same as we did for x, y.

210/800 = 0.2625 -> 26.25%

59/600 = 0.0983333333333333 -> 9.833333333333333%

Now since we didn't up the height on res change the graphic height would be the same.

You would now have to change the graphic width and height as follows to maintain the same ratio.

BUTTON1.width = 1024*0.2625 equals ->268.8

BUTTON1.height = 600*0.0983333333333333 equals -> rounds to 59

So on display 1 with 800x600 we have buttons as follows:

Button1 = 210x59 and positioned at (165, 270)

Button2 = 210x59 and positioned at (425, 270)

On display 2 with 1024*600 we have the buttons as follows:

So on display 1 with 800x600 we have buttons as follows:

Button1 = 268.8x59 and positioned at (211.2, 270)

Button2 = 268.8x59 and positioned at (544, 270)

The below screen shots will show they have the same ratios - ignore the gray borders I used a screen snip it tool - screen size is the green.




There are different methods such as using a view to draw your highest res graphics to, then scaling that view down which in turn scales all the graphics inside with the res change. You just need to account for the new width and height of your objects, especially for things like bounding box collision. You can also just make a variable which holds the ratio, and sets all your objects size based on that ratio to account for any changes. You'll only run into problems with this if you're not using even ratios when scaling because image width and height will not scale evenly.

I hope this helps, if you have more questions let me know.

Share this post

Link to post
Share on other sites
10 minutes ago, RidiculousName said:

Thank you!

I am still searching for how to get the window height/width while the game's running, but your post helped.

No problem! Like I said I don't know python or Kivy, but are you able to call something like:

currentSize = Window.size  ??

Is your screen width and height dynamic to a device? If you're dealing with just static sizes, you can always keep two variables that store the initial width and height values, and when you do a resolution change, just update it and use those variables to do ratio calculations.

Edited by Rutin

Share this post

Link to post
Share on other sites
1 hour ago, RidiculousName said:

I'm sure I can get it with something like that. I just haven't been able to find anything on it.

I might choose to just force the game to have one or two sizes.

This might be a good reference: https://kivy.org/docs/_modules/kivy/core/window.html

If you FIND keyword "size" you get the following:

I didn't look through everything but maybe:


def _set_system_size(self, size): self._size = size def _get_system_size(self): if self.softinput_mode == 'resize': return self._size[0], self._size[1] - self.keyboard_height return self._size system_size = AliasProperty( _get_system_size, _set_system_size, bind=('_size', )) '''Real size of the window ignoring rotation. .. versionadded:: 1.0.9 :attr:`system_size` is an :class:`~kivy.properties.AliasProperty`. ''' def _get_effective_size(self): '''On density=1 and non-ios displays, return system_size, else return scaled / rotated size. Used by MouseMotionEvent.update_graphics() and WindowBase.on_motion(). ''' w, h = self.system_size if platform == 'ios' or self._density != 1: w, h = self.size return w, h

I'm guessing your answer will be found in the above link.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Snaked
      Im working in this project for 1 year .... mostly i develop a tool and databases for make the different maps and now i'm doing the client for play the game
      Tell me if you like it......
      this is a capture of how is viewing atm

    • By RoKabium Games
      Another one of our new UI for #screenshotsaturday. This is the inventory screen for showing what animal fossils you have collected so far. #gamedev #indiedev #sama
    • By Dave Haylett
      Hi everyone. I need some help with my project. It's a 2D-graphics-heavy WPF front-end app written in C#, which talks to two Access 2000 databases (yes I know, it's all I've got). It will be distributed freely on the internet, and so will be being used by Windows users of various installations/versions of Windows, Office, etc.
      One of the two databases (let's call it A), is intended to be read-only, and will be distributed with the app. It has half a dozen relational tables which I as the developer have populated, and is connected to in the app via OleDB Jet 4 with SQL querying the data now and then as the user uses the front-end. The database will be replaced whenever I release an update to the app.
      Database B is read/write, and contains end-user preferences, for example when they favourite something in my front-end, a Favourites table in here gets appended to. This database is not distributed with my app, and should not be overwritten, as it will lose user prefs, etc. and annoy my users.
      Whenever my app is run by a user, during initialisation database A will suck in the user data from database B (using simple SQL SELECT * INTO...), so that all the tables can be joined together by the SQL in database A (to include user prefs/favourites in SQL queries), and whenever the user favourites something, a record is created both in A (for the short-term session) and B (permanently). Database B isn't just about holding favourites, there is other user data in here as well, so there are 3 or 4 tables in B.
      So far, this is all working fine and I'm happy...
      Unfortunately my app is currently 32-bit, and it now needs to break the 32-bit memory barrier what with the size and volume of the graphics I'm pulling in (using the HDD is not really an option, as different graphics are needed kind of instantly and the hard disc would be being hosed and the app dog-slow otherwise, I suspect even off an SSD).
      I'm using VS2015, and switching to 64-bit will probably fix the memory problem, but it breaks Jet 4.0. I'm sure this is old news to most of you.
      To try to keep with 32-bit (and Jet4) but get the memory I need I've tried the -largeaddressaware toggle, and I've tried the editbin suggestion, but I just can't get these solutions to work in VS2015 no matter how hard I try. Are these definitely 100% solutions to 2gb memory limit in 32-bit applications? Should they always work? Am I dumb in being unable to get this to work?
      So otherwise I'm resigned to migrating to 64-bit, and having to get around the database issue, not the memory issue.
      My users will be using a variety of Windows versions (probably 7 and 10), and I'm sure various versions of Office, and so my solution for querying my two Access databases needs to be pretty open if possible.
      Googling has suggested I switch from JET4 to ACE12, but this is apparently requiring me to uninstall Office 2000 and install a 64-bit version (which I don't have), so I can't use it, and I suspect any users who also have an old version of Office installed won't be able to use it either?
      Googling has also suggested I use MS SQL Server. This sounds fine if there's such a thing as a "lite" local version which can manage database access, but I still need to somehow get the data from the databases (A.mdb and B.mdb) into the SQL Server each time the users fire up my app.
      The only solution I can think of at the minute, is to export all the tables from database A into CSVs every time I update the data in there, and have the app import them in a lame way, and also convert database B into some crappy text file which gets written to whenever the user changes a preference. I'd much rather use SQL to do all this if possible, as when the user browses around the app, queries involving joining several tables in A are regularly created and executed to adjust the user's experience/return search results/etc.
      So to summarise my misery, is there either an easy reliable way for me to keep with 32-bit/Jet4 and be able to address >2gb. Or is there instead an easy reliable way for me to switch to 64-bit and successfully query two Access databases without requiring all my users to have 64-bit Office installed?
      Thanks for reading and I hope someone can help.
    • By Alexander Winter
        Jumpaï is a game about creating platformer levels and playing them online with everyone. Will you become the most popular level maker or will you be a speedrunner holding world records on everyone's levels? More into casual play? No problems! You can happily play through the giant level database or chill at people's hub. Meet new people, make new friends, learn to master the game by asking pros or ask for people's favorite tricks on level making.  

      Unlike other games of its genre, Jumpaï is about playing levels with everyone in real time. You have the fun to see how other people are playing and get to realize you are not the only one failing that jump!

      The game is currently into development and still have lots to do. I am looking for people willing to help how they can. Developer? Graphist? Play tester? Sound designer? Game designer? I'm welcoming everyone. The project is so big I have a lot of work to do in all areas. Server backend, UI/UX, Game networking, Gameplay and even the website some day. As you can see from the default buttons, the game has been made with LibGDX. 

      If you plan to take an important role into the development of the game, we will discuss how you will get paid once the game generates money. Note that I'm not working on the game full-time. I'm studying full-time and working on it is a hobby. It's been 14 months since it started.

      So, are you interested? If so join me on my discord https://discord.gg/dwRTNCG and I'll answer all your questions.

      Additionnal screenshots:

    • By Kevin Pudlo
      Airlock 22 is seeking a Sprite Artist to help create the art and animations for a video game we are developing. Artwork is currently just placeholders done by myself until we can get someone with much more experience to help out!
      - Create Sprites that the Engineering team will be able to bring into the game under production. 
      - Assist with Sprite animations if it is something you are comfortable with. 
      - Collaborate with other team members to develop artwork for current and future projects.
      - Ability to work independently 
      - Ability to focus while working remotely 
      - You are able to create your artwork in a well-lit environment
      - Experience with Sprite Animation 
      - A very creative mind 
      - Excited to help build a studio from the ground up.
      Please contact me at kevin@airlock22.co
  • Advertisement