Chapter 7, Listing 1

Listing 1: Card Script zu "Im Kerker des Grauens"

on OpenCard
  -- initTiles
  initKonstanten
  initGame
end openCard

on initGame
  global gTileArray, gTileKnown, gPlayer, gDone
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  global kHPos, kVPos, kHealthPos
  global kTop, kBottom, kLeft, kRight
  -- die Bildschirmausgabe stoppen
  lock screen
  play "IntroSound"
  -- Den done-Flag setzen
  put FALSE into gDone
  -- Wir "würfeln" die Anzahl der Räume aus
  put numberOfRooms() into numRooms
  repeat with i = 1 to kDungeonSizeH
    repeat with j = 1 to kDungeonSizeV
      -- erst einmal mauern wir das gesamte Dungeon zu
      put kWall into item j of line i of gTileArray
      -- und erklären alle Räume zu "nie gesehen
      put FALSE into item j of line i of gTileKnown
      put (i & ", " & j) into buttonName
      set the icon of cd button buttonName to kBlackTile
      set cursor to busy
    end repeat
  end repeat
  repeat with room = 1 to numRooms
    -- Erstelle Räume
    put 1 + random(5 - (numRooms DIV 2)) into hight
    put 1 + random(5 - (numRooms DIV 2)) into width
    put 1 + random(kDungeonSizeV - hight - 2) into item kTop¬
    of line room of roomRect
    put item kTop of line room of roomRect + hight¬
    into item kBottom of line room of roomRect
    put 1 + random(kDungeonSizeH - width - 2) into item kLeft¬
    of line room of roomRect
    put item kLeft of line room of roomRect + width¬
    into item kRight of line room of roomRect
    -- die Innenräume mit "leeren" Kacheln füllen:
    repeat with h = item kLeft of line room of roomRect¬
      to item kRight of line room of roomRect
      repeat with v = item kTop of line room of roomRect¬
        to item kBottom of line room of roomRect
        put kEmpty into item v of line h of gTileArray
      end repeat
    end repeat
  end repeat
  -- und jetzt die Korridore zwischen den Räumen
  repeat with room = 1 to numRooms - 1
    -- erst einmal zwei zufällige Punkt in room und room + 1 wählen
    put item kLeft of line room of roomRect¬
    + random(item kRight of line room of roomRect¬
    - item kLeft of line room of roomRect) into h1
    put item kTop of line room of roomRect¬
    + random(item kBottom of line room of roomRect¬
    - item kTop of line room of roomRect) into v1
    put item kLeft of line room + 1 of roomRect¬
    + random(item kRight of line room + 1 of roomRect¬
    - item kLeft of line room  + 1 of roomRect) into h2
    put item kTop of line room + 1 of roomRect¬
    + random(item kBottom of line room + 1 of roomRect¬
    - item kTop of line room + 1 of roomRect) into v2
    -- jetzt entlang der horizontalen Achse einen Weg suchen:
    if (h1 < h2) then
      repeat with h = h1 to h2
        put kEmpty into item v1 of line h of gTileArray
      end repeat
    else
      repeat with h = h2 to h1
        put kEmpty into item v1 of line h of gTileArray
      end repeat
    end if
    -- dann entlang der vertikalen Achse
    if (v1 < v2) then
      repeat with v = v1 to v2
        put kEmpty into item v of line h2 of gTileArray
      end repeat
    else
      repeat with v = v2 to v1
        put kEmpty into item v of line h2 of gTileArray
      end repeat
    end if
  end repeat
  -- jetzt bevölkern wir die Räume
  -- erst die Schätze (0 - 4 Geldhäufchen)
  put random(5) - 1 into numTreasures
  put 0 into i
  repeat while i < numTreasures
    put random(kDungeonSizeH) into h
    put random(kDungeonSizeV) into v
    if item v of line h of gTileArray = kEmpty then
      put kMoney into item v of line h of gTileArray
      add 1 to i
    end if
  end repeat
  -- dann die Trolle (1 - 5)
  put random(5) into numTrolle
  put 0 into i
  repeat while i < numTrolle
    put random(kDungeonSizeH) into h
    put random(kDungeonSizeV) into v
    if item v of line h of gTileArray = kEmpty then
      put kTroll into item v of line h of gTileArray
      add 1 to i
    end if
  end repeat
  -- den Ausgang
  put FALSE into gesetzt
  repeat until gesetzt = TRUE
    put random(kDungeonSizeH) into h
    put random(kDungeonSizeV) into v
    if item v of line h of gTileArray = kEmpty then
      put kExitPos into item v of line h of gTileArray
      put TRUE into gesetzt
    end if
  end repeat
  -- und zum Schluß unseren Hero
  put FALSE into gesetzt
  repeat until gesetzt = TRUE
    put random(kDungeonSizeH) into h
    put random(kDungeonSizeV) into v
    if item v of line h of gTileArray = kEmpty then
      put kPlayer into item v of line h of gTileArray
      -- seine Position und Gesundheit tragen wir ein
      put h into item kHPos of gPlayer
      put v into item kVPos of gPlayer
      put 5 into item kHealthPos of gPlayer
      put TRUE into gesetzt
    end if
  end repeat
  -- jetzt müssen wir noch die Umgebung unseres
  -- Helden sichtbar machen:
  showAroundPlayer
  -- den Bildschirm wieder freigeben
  unlock screen
end initGame

function numberOfRooms
  -- Anzahl der Räume liegt zwischen 3 und 6
  return 2 + random(4)
end numberOfRooms

on showAroundPlayer
  global gTileArray, gTileKnown, gPlayer
  global kHPos, kVPos, kHealthPos
  put item kHPos of gPlayer into playerH
  put item kVPos of gPlayer into playerV
  repeat with h = playerH - 1 to playerH + 1
    repeat with v = playerV - 1 to playerV + 1
      if ( (v > 0) AND (h > 0) ) then
        if item v of line h of gTileKnown = FALSE then
          put TRUE into item v of line h of gTileKnown
          drawTile h, v
        end if
      end if
    end repeat
  end repeat
end showAroundPlayer

on drawTile h, v
  global gTileArray, gTileKnown
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  if item v of line h of gTileKnown = TRUE then
    put item v of line h of gTileArray into tileStyle
    put (h & ", " & v) into buttonName
    if tileStyle = kEmpty then
      set the icon of cd button buttonName to kEmptyTile
    end if
    if tileStyle = kWall then
      set the icon of cd button buttonName to kWallTile
    end if
    if tileStyle = kMoney then
      set the icon of cd button buttonName to kMoneyTile
    end if
    if tileStyle = kTroll then
      set the icon of cd button buttonName to kTrollTile
    end if
    if tileStyle = kTempTroll then
      set the icon of cd button buttonName to kTrollTile
    end if
    if tileStyle = kExitPos then
      set the icon of cd button buttonName to kExitTile
    end if
    if tileStyle = kPlayer then
      set the icon of cd button buttonName to kPlayerTile
    end if
  end if
end drawTile

on moveTroll h, v
  global gTileArray, gTileKnown, gPlayer, gDone, gAlive
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  global kHPos, kVPos, kHealthPos
  global kDirTable
  put (h & ", " & v) into trollPosName
  -- Erst einmal die Position unseres Heros bestimmen
  put item kHPos of gPlayer into playerH
  put item kVPos of gPlayer into playerV
  put (playerH & ", " & playerV) into playerPosName
  -- Abstand bestimmen (City-Block-Abstand)
  put abs(h - playerH) + abs(v - playerV) into distance
  -- merkt der Troll irgend etwas?
  if (distance < random(15)) then
    -- der Troll bewegt sich auf unseren Helden zu
    if (h < playerH) then
      put h + 1 into newH
    else
      if (h > playerH) then
        put h - 1 into newH
      else
        put h into newH
      end if
    end if
    if (v < playerV) then
      put v + 1 into newV
    else
      if (v > playerV) then
        put v - 1 into newV
      else
        put v into newV
      end if
    end if
  else
    -- der Troll bewegt sich zufällig
    put random(8) into direction
    put h + (item kHPos of line direction of kDirTable)¬
    into newH
    put v + (item kVPos of line direction of kDirTable)¬
    into newV
  end if
  -- läuft der Troll auch nicht aus dem Spielfeld hinaus?
  if ( (newV > 0) AND (newH > 0) ) then
    if ( (newV <= kDungeonSizeV) AND (newH <= kDungeonSizeH) ) then
      put item newV of line newH of gTileArray into tileStyle
      if tileStyle = kEmpty then
        put kTempTroll into item newV of line newH of gTileArray
        put kEmpty into item v of line h of gTileArray
        drawTile newH, newV
        drawTile h, v
      end if
      if tileStyle = kPlayer then
        play "MonsterAttacks"
        -- Troll gewinnt Attacke?
        if random(10) > 5 then
          -- Troll gewinnt Attacke!!
          subtract 1 from item kHealthPos of gPlayer
          -- Lebt der Held noch?
          if (item kHealthPos of gPlayer) > 0 then
            -- Der Held überlebt
          else
            -- der Held stirbt
            play "HeroDied"
            put FALSE into gAlive
            exit moveTroll
          end if
        else
          -- der Troll stirbt
          play "MonsterDied"
          put kEmpty into item v of line h of gTileArray
          drawTile h, v
        end if
      end if
    end if
  end if
end moveTroll

on movePlayer h, v
  global gTileArray, gTileKnown, gPlayer, gDone, gAlive
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  global kHPos, kVPos, kHealthPos
  set cursor to watch
  lock screen
  put (h & ", " & v) into clickedButtonName
  -- Erst einmal die Position unseres Heros bestimmen
  put item kHPos of gPlayer into playerH
  put item kVPos of gPlayer into playerV
  put (playerH & ", " & playerV) into playerButtonName
  -- haben wir in ein Nachbarfeld geklickt?
  if (h >= (playerH - 1)) then
    if (h <= (playerH + 1)) then
      if (v >= (playerV - 1)) then
        if (v <= (playerV + 1)) then
          -- OK, wir sind da, was nun?
          put item v of line h of gTileArray into tileStyle
          if tileStyle = kEmpty then
            put kEmpty into item playerV of line playerH¬
            of gTileArray
            DrawTile playerH, playerV
            put kPlayer into item v of line h of gTileArray
            put h into item kHPos of gPlayer
            put v into item kVPos of gPlayer
            DrawTile h, v
          end if
          if tileStyle = kMoney then
            put kEmpty into item playerV of line playerH¬
            of gTileArray
            DrawTile playerH, playerV
            put kPlayer into item v of line h of gTileArray
            put h into item kHPos of gPlayer
            put v into item kVPos of gPlayer
            DrawTile h, v
            -- Hier können wir später die Punktzahl erhöhen
            play "GetMoney"
          end if
          if tileStyle = kWall then
            beep
          end if
          if tileStyle = kTroll then
            play "HeroAttacks"
            -- angreifen
            if (random(10) <= 5) then
              -- wir gewinnen!!!
              play "MonsterDied"
              -- und marschieren an den Platz des Monsters
              put kEmpty into item playerV of line playerH¬
              of gTileArray
              DrawTile playerH, playerV
              put kPlayer into item v of line h of gTileArray
              put h into item kHPos of gPlayer
              put v into item kVPos of gPlayer
              DrawTile h, v
            else
              -- war nix!
              subtract 1 from item kHealthPos of gPlayer
              -- Lebt der Held noch?
              if (item kHealthPos of gPlayer) > 0 then
                -- Der Held überlebt
              else
                -- der Held stirbt
                put FALSE into gAlive
                Play "HeroDied"
                exit movePlayer
              end if
            end if
          end if
          if tileStyle = kExitPos then
            -- Glückwunsch wir sind der Monsterhöhle entkommen
            play "ExitSound"
            put TRUE into gDone
          end if
        end if
      end if
    end if
  end if
  showAroundPlayer
  -- und jetzt die Trolle bewegen
  repeat with h = 1 to kDungeonSizeH
    repeat with v = 1 to kDungeonSizeV
      if item v of line h of gTileArray = kTroll then
        moveTroll h, v
      end if
    end repeat
  end repeat
  -- und in einer zweiten Schleife tempTroll durch Troll ersetzen
  repeat with h = 1 to kDungeonSizeH
    repeat with v = 1 to kDungeonSizeV
      if item v of line h of gTileArray = kTempTroll then
        put kTroll into item v of line h of gTileArray
      end if
    end repeat
  end repeat
  unlock screen
  set cursor to finger
end movePlayer

---
-- Alle Mausklicks, die nicht vom Panic-Button abgefangen werden,
-- landen hier:
--
on mouseUp
  global gDone, gAlive
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  repeat with h = 1 to kDungeonSizeH
    repeat with v = 1 to kDungeonSizeV
      put (h & ", " & v) into buttonName
      if the clickLoc is within the rect of cd button buttonName then
        movePlayer h, v
      end if
    end repeat
  end repeat
  if gAlive = FALSE then
    go next
    exit mouseUp
  end if
  if gDone = TRUE then
    initGame
  end if
end mouseUp


--  Hier einige nützliche Konstanten:
on initKonstanten
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  global kHPos, kVPos, kHealthPos
  global kTop, kBottom, kLeft, kRight
  global kDirTable, gAlive
  -- Höhe und Breite der Spielfläche
  put 16 into kDungeonSizeH
  put 10 into kDungeonSizeV
  -- Tile-Größe
  put 32 into kTileSize
  -- Konstanten für die möglichen Zustände der einzelnen
  -- Spielquadrate
  put 0 into kEmpty
  put 1 into kWall
  put 2 into kPlayer
  put 3 into kTroll
  put 4 into kTempTroll
  put 5 into kMoney
  put 6 into kExitPos
  -- Konstanten für die Icons der einzelnen Tiles
  put 128 into kPlayerTile
  put 129 into kEmptyTile
  put 130 into kTrollTile
  put 131 into kMoneyTile
  put 132 into kWallTile
  put 133 into kExitTile
  put 134 into kBlackTile
  -- Konstanten für die zusammengesetzten Datentypen
  -- der Spieler
  put 1 into kHPos
  put 2 into kVPos
  put 3 into kHealthPos
  -- der Rechtecke
  put 1 into kTop
  put 2 into kBottom
  put 3 into kLeft
  put 4 into kRight
  -- Richtungs-Array
  put  0 into item 1 of line 1 of kDirTable
  put  1 into item 2 of line 1 of kDirTable
  put -1 into item 1 of line 2 of kDirTable
  put  1 into item 2 of line 2 of kDirTable
  put -1 into item 1 of line 3 of kDirTable
  put  0 into item 2 of line 3 of kDirTable
  put -1 into item 1 of line 4 of kDirTable
  put -1 into item 2 of line 4 of kDirTable
  put  0 into item 1 of line 5 of kDirTable
  put -1 into item 2 of line 5 of kDirTable
  put  1 into item 1 of line 6 of kDirTable
  put -1 into item 2 of line 6 of kDirTable
  put  1 into item 1 of line 7 of kDirTable
  put  0 into item 2 of line 7 of kDirTable
  put  1 into item 1 of line 8 of kDirTable
  put  1 into item 2 of line 8 of kDirTable
  put TRUE into gAlive
end initKonstanten

--
-- wird nur einmal aufgerufen, um die Karte zu initialisieren
--
on initTiles
  global gTileArray, gTileKnown
  global kDungeonSizeH, kDungeonSizeV, kTileSize
  global kEmpty, kWall, kPlayer, kTroll, kTempTroll, kMoney, kExitPos
  global kPlayerTile, kEmptyTile, kTrollTile, kMoneyTile, kWallTile
  global kExitTile, kBlackTile
  global kHPos, kVPos, kHealthPos
  global kTop, kBottom, kLeft, kRight
  -- lock screen
  repeat with i = 1 to kDungeonSizeH
    repeat with j = 1 to kDungeonSizeV
      put (i*kTileSize) - (kTileSize DIV 2) into item 1 of tileLoc
      put (j*kTileSize) - (kTileSize DIV 2) into item 2 of tileLoc
      doMenu "New Button"
      set the style of card Button "New Button" to transparent
      set the height of card Button "New Button" to kTileSize
      set the width of card Button "New Button" to kTileSize
      set the Icon of card Button "New Button" to kBlackTile
      set showName of card Button "New Button" to FALSE
      show card Button "New Button" at tileLoc
      set the name of card Button "New Button" to i & ", " & j
    end repeat
  end repeat
  -- unlock screen
  choose browse tool
end initTiles

© 1997 by Jörg Kantel
Zurück zum Inhaltsverzeichnis