I’ve made a couple games with a board made from an image, displayed via a Canvas
object. Additional Image
or Link
objects are the loaded on top of the board image.
I’m trying to make the games responsive/adaptive to different screen sizes. I use JavaScript to find the displayed window size and during __init__
call a method based on the window size. Here’s an example:
def mobile_screen_dimensions(self):
flag_img_path="_/theme/green_check_mark_small.png" if self.player_color=="green" else "_/theme/blue_check_mark_small.png"
self.images = {
"board": URLMedia("_/theme/sequence_board_320.png"),
"flag": URLMedia(flag_img_path),
"green_chip": URLMedia("_/theme/chipGreen_border_small.png"),
"blue_chip": URLMedia("_/theme/chipBlue_border_small.png"),
}
self.IMAGE_WIDTH = 28
self.IMAGE_HEIGHT = 28
self.CANVAS_WIDTH = 288
self.CANVAS_HEIGHT = 288
self.canvas_size = self.CANVAS_WIDTH
self.canvas_1.height = self.CANVAS_HEIGHT
# code setting font sizes ...
Even so, I’m constantly playing with x
and y
locations to display flag
, green_chip
, and blue_chip
images where I want them to be in various screen sizes.
In my next game attempt I used an xypanel
for displaying the game board and other components:
class Form1(Form1Template):
def __init__(self, **properties):
global first_form_show # have to do this because we're changing value of variable; without global declaration Python thinks it's a local variable
# Set Form properties and Data Bindings.
self.init_components(**properties)
# Check screen width
_mobile_screen_width = 600
_tablet_screen_width = 850
window_size=window.innerWidth
mobile_screen = window_size <= _mobile_screen_width
tablet_screen = _mobile_screen_width < window_size <= _tablet_screen_width
desktop_screen = window_size > _tablet_screen_width
true_img_width,true_img_height=anvil.image.get_dimensions(URLMedia('_/theme/boggle_board.jpg'))
disp_mode="shrink_to_fit" if mobile_screen else "original_size"
board_img=Image(source='_/theme/boggle_board.jpg',display_mode=disp_mode)
self.xypanel = XYPanel(align='right')
self.xypanel.add_component(board_img,0,0)
if mobile_screen:
board_img.height=window_size*true_img_height/true_img_width
self.xypanel.height=board_img.height
# This is a row with textboxes and buttons
self.enter_word_row=self.make_enter_word_row(mobile_screen)
if mobile_screen:
self.grid_panel_1.add_component(self.xypanel,row=1,col_xs=0,width_xs=12)
self.grid_panel_1.add_component(self.enter_word_row, row=2, col_xs=0, width_xs=12)
self.grid_panel_1.add_component(self.lst_words,row=3,col_xs=0,width_xs=12)
elif tablet_screen:
self.grid_panel_1.add_component(self.xypanel,row=1,col_xs=0,width_xs=9)
self.grid_panel_1.add_component(self.lst_words,row=1,col_xs=8,width_xs=3)
self.grid_panel_1.add_component(self.enter_word_row, row=2, col_xs=0, width_xs=12)
elif desktop_screen:
self.grid_panel_1.add_component(self.xypanel, row=1, col_xs=0, width_xs=6)
self.grid_panel_1.add_component(self.lst_words, row=1, col_xs=6, width_xs=6)
self.grid_panel_1.add_component(self.enter_word_row, row=2, col_xs=0, width_xs=12)
This code works pretty well for adapting the display to different screens. The struggle comes while trying to display links where I want them on top of the image:
self.img_width=window_size if mobile_screen else true_img_width
self.img_height=board_img.height if mobile_screen else true_img_height
self.font_size=40 if mobile_screen else 50
self.make_board(board_number,self.img_width,self.img_height,self.font_size)
The make_board
method adds the links (which I’m referring to as “tiles”), from an array, via code including:
# Coordinates for link positions in grid:
x_positions = [0.08, 0.315, 0.55, 0.77]
y_positions = [0.01, 0.26, 0.52, 0.76]
for y in self.y_positions:
for x in self.x_positions:
link = self.create_link(tile_array.pop(), font_size )
self.link_array.append(link)
self.xypanel.add_component(link,x=x*img_width,y=y*img_height)
I’ve decided–like they say on informercials–there’s got to be a better way! … Is there? Maybe something involving relative sizes and positions? Different layout components? A magic wand?