244 lines
11 KiB
Python
244 lines
11 KiB
Python
# =============================================================================
|
|
# Fishing Mini-Project - Main Game File (OUTLINE ONLY)
|
|
# =============================================================================
|
|
# This file is a STRUCTURAL OUTLINE: function signatures + descriptive comments.
|
|
# The actual implementation will be written by the project author (human).
|
|
#
|
|
# Engine: cmu_graphics | Pattern: MVC (Model-View-Controller)
|
|
# Data: creatures.tsv (tab-separated database at repo root)
|
|
# Save: save.json (persistent progress in the script directory)
|
|
# =============================================================================
|
|
|
|
from cmu_graphics import *
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 1: DATA LOADING / FILE I/O
|
|
# -----------------------------------------------------------------------------
|
|
# Helpers that read from and write to disk. Kept separate from game logic so
|
|
# the data source (TSV path, save path) can change without touching gameplay.
|
|
# =============================================================================
|
|
|
|
def loadCreatures(path):
|
|
# Read creatures.tsv (tab-separated) and parse it into a usable structure.
|
|
# Suggested return: a list of dicts, one per creature, with keys matching
|
|
# the header row: name, description, price, sprite-file, difficulty,
|
|
# length, weight. Convert numeric columns (price, difficulty, length,
|
|
# weight) from strings to int/float here; leave missing fields as sensible
|
|
# defaults so partially-filled rows (like the current TSV) don't crash.
|
|
pass
|
|
|
|
|
|
def loadSave(path):
|
|
# Load save.json and return the player's saved state (money, owned baits,
|
|
# owned upgrades, current bait, caught log, etc.). If the file is missing
|
|
# or unreadable, return a fresh default-state dict so a first-time player
|
|
# starts cleanly. This is the only place that reads the save file.
|
|
pass
|
|
|
|
|
|
def writeSave(path, saveState):
|
|
# Serialize the current player state to save.json. Call this at key moments
|
|
# (after a sale, after a purchase, on quit) so progress persists between
|
|
# sessions. Keep the written structure identical to what loadSave expects.
|
|
pass
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 2: MODEL - STATE SETUP & GAME DATA
|
|
# -----------------------------------------------------------------------------
|
|
# Everything that initializes and holds game state on the cmu_graphics `app`.
|
|
# No drawing and no event handling here - just state.
|
|
# =============================================================================
|
|
|
|
def onAppStart(app):
|
|
# cmu_graphics entry point. Initialize ALL app.* state here:
|
|
# - window/layout constants (width, height, dock/water/grass regions)
|
|
# - app.creatures (from loadCreatures)
|
|
# - app.save (from loadSave) and derived player values
|
|
# - app.scene (which screen is active: 'dock', 'shop', 'catch', ...)
|
|
# - fishing state (idle / waiting-for-bite / skill-check / result)
|
|
# - skill-check state placeholders (cursor angle, bars, speed, result)
|
|
# - app.stepsPerSecond for the game loop cadence
|
|
# Delegates to the smaller setup helpers below to keep this readable.
|
|
pass
|
|
|
|
|
|
def resetFishingState(app):
|
|
# Return the fishing cycle to its starting "idle" point so a new cast can
|
|
# begin. Clears any active skill-check data, the pending random bite timer,
|
|
# and the currently-hooked creature. Called at startup and after each catch
|
|
# is resolved/dismissed.
|
|
pass
|
|
|
|
|
|
def pickRandomCreature(app):
|
|
# Choose which creature the player hooks on this cast. Selection is filtered
|
|
# by the current bait (bait gates which difficulty tiers are available) and
|
|
# weighted toward easier creatures, while still giving rarer/harder ones a
|
|
# real chance (per the spec's "skewed toward easier but still fun" goal).
|
|
# Returns the chosen creature record (one entry from app.creatures).
|
|
pass
|
|
|
|
|
|
def startSkillCheck(app, creature):
|
|
# Configure a new skill check based on the hooked creature's difficulty.
|
|
# Difficulty maps to: cursor rotation speed, number of target bars, and
|
|
# bar length/width. Also apply any owned upgrades that modify these values
|
|
# (e.g. slower cursor, wider bars, extra forgiveness). Stores the resulting
|
|
# parameters on app for the controller/view to use.
|
|
pass
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 3: CONTROLLER - GAME LOOP & INPUT HANDLING
|
|
# -----------------------------------------------------------------------------
|
|
# cmu_graphics event hooks. These advance state and route input; they should
|
|
# call Model helpers rather than contain heavy logic themselves.
|
|
# =============================================================================
|
|
|
|
def onStep(app):
|
|
# Runs every time step (the game loop / "controller tick").
|
|
# Responsibilities depend on the current fishing phase:
|
|
# - waiting-for-bite: count down the random timer; when it elapses, pick a
|
|
# creature and transition into the skill check.
|
|
# - skill-check: advance the cursor's angle around the circle each step.
|
|
# - otherwise (idle, viewing a catch, in shop): do nothing time-based.
|
|
pass
|
|
|
|
|
|
def onMousePress(app, mouseX, mouseY):
|
|
# Primary input router. Behavior depends on app.scene / fishing phase:
|
|
# - dock idle: clicking starts a cast (begin waiting-for-bite).
|
|
# - skill-check active: register the click as a timing attempt and
|
|
# evaluate it via checkSkillHit.
|
|
# - catch popup showing: dismiss the popup and reset fishing.
|
|
# - shop / UI sprites clicked: open the shop or trigger that UI action.
|
|
# Keep this as dispatch only - defer the real work to helper functions.
|
|
pass
|
|
|
|
|
|
def onKeyPress(app, key):
|
|
# Optional keyboard controls. Candidates: a key to cast/reel as an
|
|
# alternative to clicking, a key to open/close the shop, or a debug/reset
|
|
# key during development. Remove if you decide the game is mouse-only.
|
|
pass
|
|
|
|
|
|
def checkSkillHit(app):
|
|
# Evaluate a skill-check click: is the cursor's current angle inside one of
|
|
# the active target bars? Decide hit vs miss. Define the multi-bar flow here
|
|
# (e.g. must the player clear every bar, or is one good hit enough?) and
|
|
# advance or fail the skill check accordingly. On full success, mark the
|
|
# creature as caught and move to the catch-display phase; on failure, end
|
|
# the cast without a catch.
|
|
pass
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 4: SHOP / ECONOMY LOGIC
|
|
# -----------------------------------------------------------------------------
|
|
# Buying/selling and the rogue-like upgrade system. Pure state changes that the
|
|
# controller invokes; no drawing here.
|
|
# =============================================================================
|
|
|
|
def sellCreature(app, creature):
|
|
# Add the creature's market value to the player's money. Value scales with
|
|
# difficulty (harder creatures pay more, per the spec). Persist the updated
|
|
# money via writeSave. Decide here whether selling is automatic on catch or
|
|
# a deliberate action in the shop/market.
|
|
pass
|
|
|
|
|
|
def buyUpgrade(app, upgradeId):
|
|
# Attempt to purchase an upgrade. Check the player can afford it and doesn't
|
|
# already own it; if valid, deduct money, record ownership in app.save, and
|
|
# persist. Upgrades modify the skill check (cursor speed, bar size/count,
|
|
# extra attempts, etc.) and are read back in startSkillCheck.
|
|
pass
|
|
|
|
|
|
def buyBaitLicense(app, baitId):
|
|
# Purchase a one-time license for a bait tier. Once owned, the player can
|
|
# freely switch to that bait at no further cost (switching handled by
|
|
# setActiveBait). Bait determines which creatures are reachable in
|
|
# pickRandomCreature. Deduct money, record ownership, persist.
|
|
pass
|
|
|
|
|
|
def setActiveBait(app, baitId):
|
|
# Switch the currently-equipped bait to any bait the player already owns a
|
|
# license for. Free action. Updates app state so the next cast's creature
|
|
# pool reflects the new bait. Reject the switch if the bait isn't owned.
|
|
pass
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 5: VIEW - DRAWING
|
|
# -----------------------------------------------------------------------------
|
|
# redrawAll + per-scene draw helpers. These ONLY read state and draw; they must
|
|
# never mutate app state. Composed top-down so redrawAll stays legible.
|
|
# =============================================================================
|
|
|
|
def redrawAll(app):
|
|
# Master draw routine. Draw the persistent world first (background, grass,
|
|
# water, dock, player), then layer the active scene/phase on top:
|
|
# - the shop UI, or
|
|
# - the active skill-check overlay, or
|
|
# - the catch-display popup.
|
|
# Delegates each piece to the helpers below.
|
|
pass
|
|
|
|
|
|
def drawBackground(app):
|
|
# Draw the static scene layout from the spec: grass behind, the dock, and
|
|
# the lake occupying the bottom ~1/3 of the screen (blue water, optional
|
|
# wave patterns). This is the backdrop present in every scene.
|
|
pass
|
|
|
|
|
|
def drawPlayerAndRod(app):
|
|
# Draw the character sprite seated at the end of the dock with the fishing
|
|
# rod. When a cast is active, draw the line and the bobber dropping onto the
|
|
# water surface. Reflects the current fishing phase visually.
|
|
pass
|
|
|
|
|
|
def drawShopEntities(app):
|
|
# Draw the clickable shop/UI sprites standing on the grass (per the spec).
|
|
# Positions here must line up with the hit-testing done in onMousePress so
|
|
# clicks land on the right entity.
|
|
pass
|
|
|
|
|
|
def drawSkillCheck(app):
|
|
# Draw the active skill-check overlay: the circle, the target bars placed
|
|
# around it (count/length from difficulty), and the rotating cursor at its
|
|
# current angle. Optionally show which bars are already cleared. Read-only.
|
|
pass
|
|
|
|
|
|
def drawCatchDisplay(app):
|
|
# Draw the "you caught it!" popup: the creature's sprite coming out of the
|
|
# water, plus its name, description, and stats (length, weight, value).
|
|
# Stays up until dismissed by a click (handled in onMousePress). Read-only.
|
|
pass
|
|
|
|
|
|
def drawHud(app):
|
|
# Draw the persistent heads-up display: current money, equipped bait, and
|
|
# any brief status/instruction text ("click to cast", etc.). Overlaid on
|
|
# every scene so the player always sees their core stats.
|
|
pass
|
|
|
|
|
|
# =============================================================================
|
|
# SECTION 6: PROGRAM ENTRY
|
|
# -----------------------------------------------------------------------------
|
|
def main():
|
|
# Start the cmu_graphics app (runApp with the chosen window dimensions).
|
|
pass
|
|
|
|
|
|
main()
|