With the assistance I got here, and assurance here, I’ve created a two player game, with the game’s state saved in a data table (state of the game board, card deck, two hands, and whose turn it is; one row, 5 cells).
A player’s turn happens when the screen is touched/clicked, triggering the mouse down event. This event is where changes to the board, hand, etc. are processed and sent to the data table on the server.
To keep everything synced between the players, a timer starts a method that pulls in the current state data and updates players’ UI’s.
I think every once in awhile the update
function starts before the canvas_1_mouse_down
function has finished executing. This causes issues sometimes re: the data; hands (string lists) end up being updated twice. So, I want to be sure the two methods are never operating at the same time.
I tried setting self.timer_1.interval=0
at the beginning of canvas_1_mouse_down
, to turn off the timer, and then setting the timer’s interval back at the end of the method. I still had issues.
Then I tried adding a flag, self.is_mouse_down
, setting it to True
at the beginning of canvas_1_mouse_down
, and False
at the end of the method. Meanwhile, the update
method begins with
if not self.is_mouse_down:
This combination helped. I had fewer issues, but not none.
Finally, I tried adding a flag, self.is_updating
, setting it to True
at the beginning of update
, and False
at the end of the method. Meanwhile, the canvas_1_mouse_down
method begins with if not self.is_updating
This combination seems to have eliminated the problem. However, unless I set the timer interval to ~5 seconds I run into issues sometimes where a player’s touch/click isn’t initially recognized, i.e., you have to click a few times to make a move. I assume the update function’s blocking the mouse down event.
Do you think my reasoning is sound? Is there something better I should do to address the issue?
For completeness, here’s some of the code (I can explain methods, if necessary):
def update(self):
if not self.is_mouse_down:
self.is_updating = True
with anvil.server.no_loading_indicator:
game_state = anvil.server.call('update')
if game_state is None:
return
if self.player_color=="green":
if game_state['GreenHand']!=self.hand:
self.hand = anvil.server.call('get_hand',"green")
if self.player_color=="blue":
if game_state['BlueHand']!=self.hand:
self.hand = anvil.server.call('get_hand',"blue")
if game_state['Board'] != self.model:
self.model = game_state['Board']
if game_state['IsGreenTurn']!=self.is_green_turn:
self.is_green_turn = game_state['IsGreenTurn']
self.display_turn_message()
self.update_hand_display(self.hand)
self.canvas_1_reset()
self.is_updating = False
canvas_1_mouse_down
is lengthy. It processes the effects of tapping/clicking the canvas (game board) in various spots, changing local variables, updating the display, and calling methods on the server to update values in the data table. It ends this way:
anvil.server.call_s('save_board',self.model)
self.canvas_1_reset()
# On the server, add new card to hand, update hand (and deck) in data table
anvil.server.call_s('update_hand',self.player_color,self.hand)
# Get updated hand to display
self.hand = anvil.server.call_s('get_hand',self.player_color)
self.update_hand_display(self.hand)
self.change_player() # updates data table re: whose turn it is
self.timer_1.interval=constants.TIMER_INTERVAL
self.is_mouse_down=False