Update game scripts for new Python API

- Convert entity position access from tuple to x/y properties
- Update caption size property to font_size
- Fix grid boundary checks to use grid_size instead of exceptions
- Clean up demo timer on menu exit to prevent callbacks

These changes adapt the game scripts to work with the new standardized
Python API constructors and property names.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
John McCardle 2025-07-14 01:35:35 -04:00
parent 9c8d6c4591
commit a010e5fa96
3 changed files with 30 additions and 28 deletions

View File

@ -67,10 +67,10 @@ class COSEntity(): #mcrfpy.Entity): # Fake mcrfpy.Entity integration; engine bu
self.draw_pos = (tx, ty) self.draw_pos = (tx, ty)
for e in self.game.entities: for e in self.game.entities:
if e is self: continue if e is self: continue
if e.draw_pos == old_pos: e.ev_exit(self) if e.draw_pos.x == old_pos.x and e.draw_pos.y == old_pos.y: e.ev_exit(self)
for e in self.game.entities: for e in self.game.entities:
if e is self: continue if e is self: continue
if e.draw_pos == (tx, ty): e.ev_enter(self) if e.draw_pos.x == tx and e.draw_pos.y == ty: e.ev_enter(self)
def act(self): def act(self):
pass pass
@ -83,12 +83,12 @@ class COSEntity(): #mcrfpy.Entity): # Fake mcrfpy.Entity integration; engine bu
def try_move(self, dx, dy, test=False): def try_move(self, dx, dy, test=False):
x_max, y_max = self.grid.grid_size x_max, y_max = self.grid.grid_size
tx, ty = int(self.draw_pos[0] + dx), int(self.draw_pos[1] + dy) tx, ty = int(self.draw_pos.x + dx), int(self.draw_pos.y + dy)
#for e in iterable_entities(self.grid): #for e in iterable_entities(self.grid):
# sorting entities to test against the boulder instead of the button when they overlap. # sorting entities to test against the boulder instead of the button when they overlap.
for e in sorted(self.game.entities, key = lambda i: i.draw_order, reverse = True): for e in sorted(self.game.entities, key = lambda i: i.draw_order, reverse = True):
if e.draw_pos == (tx, ty): if e.draw_pos.x == tx and e.draw_pos.y == ty:
#print(f"bumping {e}") #print(f"bumping {e}")
return e.bump(self, dx, dy) return e.bump(self, dx, dy)
@ -106,7 +106,7 @@ class COSEntity(): #mcrfpy.Entity): # Fake mcrfpy.Entity integration; engine bu
return False return False
def _relative_move(self, dx, dy): def _relative_move(self, dx, dy):
tx, ty = int(self.draw_pos[0] + dx), int(self.draw_pos[1] + dy) tx, ty = int(self.draw_pos.x + dx), int(self.draw_pos.y + dy)
#self.draw_pos = (tx, ty) #self.draw_pos = (tx, ty)
self.do_move(tx, ty) self.do_move(tx, ty)
@ -181,7 +181,7 @@ class Equippable:
if self.zap_cooldown_remaining != 0: if self.zap_cooldown_remaining != 0:
print("zap is cooling down.") print("zap is cooling down.")
return False return False
fx, fy = caster.draw_pos fx, fy = caster.draw_pos.x, caster.draw_pos.y
x, y = int(fx), int (fy) x, y = int(fx), int (fy)
dist = lambda tx, ty: abs(int(tx) - x) + abs(int(ty) - y) dist = lambda tx, ty: abs(int(tx) - x) + abs(int(ty) - y)
targets = [] targets = []
@ -293,7 +293,7 @@ class PlayerEntity(COSEntity):
## TODO - find other entities to avoid spawning on top of ## TODO - find other entities to avoid spawning on top of
for spawn in spawn_points: for spawn in spawn_points:
for e in avoid or []: for e in avoid or []:
if e.draw_pos == spawn: break if e.draw_pos.x == spawn[0] and e.draw_pos.y == spawn[1]: break
else: else:
break break
self.draw_pos = spawn self.draw_pos = spawn
@ -314,9 +314,9 @@ class BoulderEntity(COSEntity):
elif type(other) == EnemyEntity: elif type(other) == EnemyEntity:
if not other.can_push: return False if not other.can_push: return False
#tx, ty = int(self.e.position[0] + dx), int(self.e.position[1] + dy) #tx, ty = int(self.e.position[0] + dx), int(self.e.position[1] + dy)
tx, ty = int(self.draw_pos[0] + dx), int(self.draw_pos[1] + dy) tx, ty = int(self.draw_pos.x + dx), int(self.draw_pos.y + dy)
# Is the boulder blocked the same direction as the bumper? If not, let's both move # Is the boulder blocked the same direction as the bumper? If not, let's both move
old_pos = int(self.draw_pos[0]), int(self.draw_pos[1]) old_pos = int(self.draw_pos.x), int(self.draw_pos.y)
if self.try_move(dx, dy, test=test): if self.try_move(dx, dy, test=test):
if not test: if not test:
other.do_move(*old_pos) other.do_move(*old_pos)
@ -342,7 +342,7 @@ class ButtonEntity(COSEntity):
# self.exit.unlock() # self.exit.unlock()
# TODO: unlock, and then lock again, when player steps on/off # TODO: unlock, and then lock again, when player steps on/off
if not test: if not test:
pos = int(self.draw_pos[0]), int(self.draw_pos[1]) pos = int(self.draw_pos.x), int(self.draw_pos.y)
other.do_move(*pos) other.do_move(*pos)
return True return True
@ -393,7 +393,7 @@ class EnemyEntity(COSEntity):
def bump(self, other, dx, dy, test=False): def bump(self, other, dx, dy, test=False):
if self.hp == 0: if self.hp == 0:
if not test: if not test:
old_pos = int(self.draw_pos[0]), int(self.draw_pos[1]) old_pos = int(self.draw_pos.x), int(self.draw_pos.y)
other.do_move(*old_pos) other.do_move(*old_pos)
return True return True
if type(other) == PlayerEntity: if type(other) == PlayerEntity:
@ -415,7 +415,7 @@ class EnemyEntity(COSEntity):
print("Ouch, my entire body!!") print("Ouch, my entire body!!")
self._entity.sprite_number = self.base_sprite + 246 self._entity.sprite_number = self.base_sprite + 246
self.hp = 0 self.hp = 0
old_pos = int(self.draw_pos[0]), int(self.draw_pos[1]) old_pos = int(self.draw_pos.x), int(self.draw_pos.y)
if not test: if not test:
other.do_move(*old_pos) other.do_move(*old_pos)
return True return True
@ -423,8 +423,8 @@ class EnemyEntity(COSEntity):
def act(self): def act(self):
if self.hp > 0: if self.hp > 0:
# if player nearby: attack # if player nearby: attack
x, y = self.draw_pos x, y = self.draw_pos.x, self.draw_pos.y
px, py = self.game.player.draw_pos px, py = self.game.player.draw_pos.x, self.game.player.draw_pos.y
for d in ((1, 0), (0, 1), (-1, 0), (1, 0)): for d in ((1, 0), (0, 1), (-1, 0), (1, 0)):
if int(x + d[0]) == int(px) and int(y + d[1]) == int(py): if int(x + d[0]) == int(px) and int(y + d[1]) == int(py):
self.try_move(*d) self.try_move(*d)

View File

@ -22,12 +22,13 @@ class TileInfo:
@staticmethod @staticmethod
def from_grid(grid, xy:tuple): def from_grid(grid, xy:tuple):
values = {} values = {}
x_max, y_max = grid.grid_size
for d in deltas: for d in deltas:
tx, ty = d[0] + xy[0], d[1] + xy[1] tx, ty = d[0] + xy[0], d[1] + xy[1]
try: if tx < 0 or tx >= x_max or ty < 0 or ty >= y_max:
values[d] = grid.at((tx, ty)).walkable
except ValueError:
values[d] = True values[d] = True
else:
values[d] = grid.at((tx, ty)).walkable
return TileInfo(values) return TileInfo(values)
@staticmethod @staticmethod
@ -70,10 +71,10 @@ def special_rule_verify(rule, grid, xy, unverified_tiles, pass_unverified=False)
tx, ty = xy[0] + dxy[0], xy[1] + dxy[1] tx, ty = xy[0] + dxy[0], xy[1] + dxy[1]
#print(f"Special rule: {cardinal} {allowed_tile} {type(allowed_tile)} -> ({tx}, {ty}) [{grid.at((tx, ty)).tilesprite}]{'*' if (tx, ty) in unverified_tiles else ''}") #print(f"Special rule: {cardinal} {allowed_tile} {type(allowed_tile)} -> ({tx}, {ty}) [{grid.at((tx, ty)).tilesprite}]{'*' if (tx, ty) in unverified_tiles else ''}")
if (tx, ty) in unverified_tiles and cardinal in "nsew": return pass_unverified if (tx, ty) in unverified_tiles and cardinal in "nsew": return pass_unverified
try: x_max, y_max = grid.grid_size
return grid.at((tx, ty)).tilesprite == allowed_tile if tx < 0 or tx >= x_max or ty < 0 or ty >= y_max:
except ValueError:
return False return False
return grid.at((tx, ty)).tilesprite == allowed_tile
import random import random
tile_of_last_resort = 431 tile_of_last_resort = 431

View File

@ -87,7 +87,7 @@ class Crypt:
# Side Bar (inventory, level info) config # Side Bar (inventory, level info) config
self.level_caption = mcrfpy.Caption((5,5), "Level: 1", font, fill_color=(255, 255, 255)) self.level_caption = mcrfpy.Caption((5,5), "Level: 1", font, fill_color=(255, 255, 255))
self.level_caption.size = 26 self.level_caption.font_size = 26
self.level_caption.outline = 3 self.level_caption.outline = 3
self.level_caption.outline_color = (0, 0, 0) self.level_caption.outline_color = (0, 0, 0)
self.sidebar.children.append(self.level_caption) self.sidebar.children.append(self.level_caption)
@ -103,7 +103,7 @@ class Crypt:
mcrfpy.Caption((25, 130 + 95 * i), "x", font, fill_color=(255, 255, 255)) for i in range(5) mcrfpy.Caption((25, 130 + 95 * i), "x", font, fill_color=(255, 255, 255)) for i in range(5)
] ]
for i in self.inv_captions: for i in self.inv_captions:
i.size = 16 i.font_size = 16
self.sidebar.children.append(i) self.sidebar.children.append(i)
liminal_void = mcrfpy.Grid(1, 1, t, (0, 0), (16, 16)) liminal_void = mcrfpy.Grid(1, 1, t, (0, 0), (16, 16))
@ -382,7 +382,7 @@ class Crypt:
def pull_boulder_search(self): def pull_boulder_search(self):
for dx, dy in ( (0, -1), (-1, 0), (1, 0), (0, 1) ): for dx, dy in ( (0, -1), (-1, 0), (1, 0), (0, 1) ):
for e in self.entities: for e in self.entities:
if e.draw_pos != (self.player.draw_pos[0] + dx, self.player.draw_pos[1] + dy): continue if e.draw_pos.x != self.player.draw_pos.x + dx or e.draw_pos.y != self.player.draw_pos.y + dy: continue
if type(e) == ce.BoulderEntity: if type(e) == ce.BoulderEntity:
self.pull_boulder_move((dx, dy), e) self.pull_boulder_move((dx, dy), e)
return self.enemy_turn() return self.enemy_turn()
@ -395,7 +395,7 @@ class Crypt:
if self.player.try_move(-p[0], -p[1], test=True): if self.player.try_move(-p[0], -p[1], test=True):
old_pos = self.player.draw_pos old_pos = self.player.draw_pos
self.player.try_move(-p[0], -p[1]) self.player.try_move(-p[0], -p[1])
target_boulder.do_move(*old_pos) target_boulder.do_move(old_pos.x, old_pos.y)
def swap_level(self, new_level, spawn_point): def swap_level(self, new_level, spawn_point):
self.level = new_level self.level = new_level
@ -451,7 +451,7 @@ class SweetButton:
# main button caption # main button caption
self.caption = mcrfpy.Caption((40, 3), caption, font, fill_color=font_color) self.caption = mcrfpy.Caption((40, 3), caption, font, fill_color=font_color)
self.caption.size = font_size self.caption.font_size = font_size
self.caption.outline_color=font_outline_color self.caption.outline_color=font_outline_color
self.caption.outline=font_outline_width self.caption.outline=font_outline_width
self.main_button.children.append(self.caption) self.main_button.children.append(self.caption)
@ -548,20 +548,20 @@ class MainMenu:
# title text # title text
drop_shadow = mcrfpy.Caption((150, 10), "Crypt Of Sokoban", font, fill_color=(96, 96, 96), outline_color=(192, 0, 0)) drop_shadow = mcrfpy.Caption((150, 10), "Crypt Of Sokoban", font, fill_color=(96, 96, 96), outline_color=(192, 0, 0))
drop_shadow.outline = 3 drop_shadow.outline = 3
drop_shadow.size = 64 drop_shadow.font_size = 64
components.append( components.append(
drop_shadow drop_shadow
) )
title_txt = mcrfpy.Caption((158, 18), "Crypt Of Sokoban", font, fill_color=(255, 255, 255)) title_txt = mcrfpy.Caption((158, 18), "Crypt Of Sokoban", font, fill_color=(255, 255, 255))
title_txt.size = 64 title_txt.font_size = 64
components.append( components.append(
title_txt title_txt
) )
# toast: text over the demo grid that fades out on a timer # toast: text over the demo grid that fades out on a timer
self.toast = mcrfpy.Caption((150, 400), "", font, fill_color=(0, 0, 0)) self.toast = mcrfpy.Caption((150, 400), "", font, fill_color=(0, 0, 0))
self.toast.size = 28 self.toast.font_size = 28
self.toast.outline = 2 self.toast.outline = 2
self.toast.outline_color = (255, 255, 255) self.toast.outline_color = (255, 255, 255)
self.toast_event = None self.toast_event = None
@ -626,6 +626,7 @@ class MainMenu:
def play(self, sweet_btn, args): def play(self, sweet_btn, args):
#if args[3] == "start": return # DRAMATIC on release action! #if args[3] == "start": return # DRAMATIC on release action!
if args[3] == "end": return if args[3] == "end": return
mcrfpy.delTimer("demo_motion") # Clean up the demo timer
self.crypt = Crypt() self.crypt = Crypt()
#mcrfpy.setScene("play") #mcrfpy.setScene("play")
self.crypt.start() self.crypt.start()