Tutorial: Jewel Thief Action Game
Program a fun action game where your man must collect all the jewels in the scene without being touched by enemies.




Source Code
'-------------------------------------------------
' Source code for demo game: Jewel Thief
'   Original game concept & graphics: Paul Ligeski (1991)
'-------------------------------------------------
' Objects
DIM title, credit, barLevel, barScore, finalScore AS TEXT
DIM g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 AS IMAGE   ' Goodies
DIM e1, e2, e3, e4, e5 AS IMAGE  ' Enemies
DIM bg, bar, city, man, live1, live2, live3, live4 AS IMAGE
DIM black AS RECTANGLE
DIM button1, button2 AS BUTTON
' Variables
DIM stage AS INTEGER: stage = 0
DIM goodies AS INTEGER: goodies = 0  ' Goodies remaining
DIM score AS INTEGER: score = 0
DIM touched AS BOOLEAN: touched = false
DIM dead AS BOOLEAN: dead = false
DIM lives AS INTEGER: lives = 5      ' Lives remaining
DIM faceRight AS BOOLEAN: faceRight = true ' Facing right
DIM lastPos AS INTEGER: lastPos = 0  ' Last X position of player
' Settings
SET VOICE "sonia"
PIXELART
BGCOLOR #000000
' Start.
homeScreen
'----------------------------
' Display home screen.
'----------------------------
SUB homeScreen
  BGIMAGE "jewel_bg", "move-left", 4
  ' City
  city = IMAGE "jewel_city", (0, 640)  ' replace with an effect to move-in
  black = RECT (0, 318)-(640, 640), #000000
  MOVE city, (0, 210), 2000
  WAIT
  ' Title
  title = TEXT "Jewel Thief ", (_MIDDLEX, 60), "font7", 60, #FFFFFF, "type", 80
  credit = TEXT "Credits:\noriginal game by Paul Ligeski (1991)\nremake by D2Soft Technologies (2024)", (_MIDDLEX, 550), "default", 18, #ffffff, "fade-in", 1000
  VOICE "Jewel Thief"
  MUSIC "jazz_tune"
  WAIT
  ' Interface
  button1 = BUTTON "jewel_button1", "Start", (_MIDDLEX, 400), "font4", 30, #3C3C3C, "fade-in", 500
  ANIM button1, "scale", 100, 95, 1200
  ON CLICK button1, startGame
  ' Objects preparedness.
  man = IMAGE "jewel_man", (200, 200), "offscreen"
  DRAG man
  ON DRAG man, onManMoving
END SUB
'----------------------------
' Helpers
'----------------------------
SUB startGame
  clearHome
  WAIT
  addStatusBar
  nextLevel
END SUB
SUB clearHome
  SOUND "click"
  BGIMAGE ""
  HIDE button1 : HIDE black : HIDE city, "fade-out", 1000 : HIDE credit, "fade-out", 1000
  WAIT
  HIDE title, "fade-out", 500
END SUB
SUB addStatusBar
  bar = IMAGE "jewel_bar", (0, 600), "fade-in", 1000
  barLevel = TEXT "", (12, 606), "font4", 26, #3C3C3C, "fade-in", 1000
  barScore = TEXT "0", (475, 606), "font4", 26, #3C3C3C, "fade-in", 1000
  live1 = IMAGE "jewel_live", (345, 608), "fade-in", 1000
  live2 = IMAGE "jewel_live", (370, 608), "fade-in", 1000
  live3 = IMAGE "jewel_live", (395, 608), "fade-in", 1000
  live4 = IMAGE "jewel_live", (420, 608), "fade-in", 1000
END SUB
SUB onManMoving
  IF lastPos > POSX(man) THEN
    IF faceRight THEN : faceRight = false : MIRROR man : END IF
  ELSE
    IF NOT faceRight THEN : faceRight = true : MIRROR man : END IF
  END IF
  lastPos = POSX(man)
END SUB
SUB setPlayer
  MOVE man, (300, 200)
  TOP man
  SHOW man
END SUB
SUB activateLevel
  setPlayer
  WAIT
  animateEnemies
  WAIT
  startCollide
END IF
'----------------------------
' Level 1
'----------------------------
SUB level1
  title = TEXT "Level 1: Emerald ", (_MIDDLEX, 40), "font7", 50, #FFFFFF, "type", 40
  SET TEXT barLevel, "Emerald"
  IMAGE "jewel_goody1", (185, 610)
  SLEEP 400
  bg = IMAGE "jewel_bg_level1", (0, 78), "fade-in", 1000
  TOP title
  WAIT
  HIDE title, "fade-out", 400
  WAIT
  g1 = IMAGE "jewel_goody1", (RND(0, 620), RND(400, 580))
  g2 = IMAGE "jewel_goody1", (RND(0, 620), RND(400, 580))
  g3 = IMAGE "jewel_goody1", (RND(0, 620), RND(400, 580))
  g4 = IMAGE "jewel_goody1", (RND(0, 620), RND(400, 580))
  e1 = IMAGE "jewel_enemy1", (0, 0), "offscreen"
  e2 = IMAGE "jewel_enemy1", (0, 0), "offscreen"
  e3 = IMAGE "jewel_enemy1", (0, 0), "offscreen"
  goodies = 4
  activateLevel
END SUB
'----------------------------
' Level 2
'----------------------------
SUB level2
  title = TEXT "Level 2: Opal ", (_MIDDLEX, 40), "font7", 50, #FFFFFF, "type", 40
  SET TEXT barLevel, "Opal"
  IMAGE "jewel_goody2", (205, 610)
  SLEEP 400
  bg = IMAGE "jewel_bg_level2", (0, 78), "fade-in", 1000
  TOP title
  WAIT
  HIDE title, "fade-out", 400
  WAIT
  g1 = IMAGE "jewel_goody2", (RND(0, 620), RND(400, 580))
  g2 = IMAGE "jewel_goody2", (RND(0, 620), RND(400, 580))
  g3 = IMAGE "jewel_goody2", (RND(0, 620), RND(400, 580))
  g4 = IMAGE "jewel_goody2", (RND(0, 620), RND(400, 580))
  g5 = IMAGE "jewel_goody2", (RND(0, 620), RND(400, 580))
  e1 = IMAGE "jewel_enemy2", (0, 0), "offscreen"
  e2 = IMAGE "jewel_enemy2", (0, 0), "offscreen"
  e3 = IMAGE "jewel_enemy2", (0, 0), "offscreen"
  e4 = IMAGE "jewel_enemy2", (0, 0), "offscreen"
  goodies = 5
  activateLevel
END SUB
'----------------------------
' Level 3
'----------------------------
SUB level3
  title = TEXT "Level 3: Sapphire ", (_MIDDLEX, 40), "font7", 50, #FFFFFF, "type", 40
  SET TEXT barLevel, "Sapphire"
  IMAGE "jewel_goody3", (222, 610)
  SLEEP 400
  bg = IMAGE "jewel_bg_level3", (0, 78), "fade-in", 1000
  TOP title
  WAIT
  HIDE title, "fade-out", 400
  WAIT
  g1 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g2 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g3 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g4 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g5 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g6 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g7 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  g8 = IMAGE "jewel_goody3", (RND(0, 620), RND(400, 580))
  e1 = IMAGE "jewel_enemy3", (0, 0), "offscreen"
  e2 = IMAGE "jewel_enemy3", (0, 0), "offscreen"
  e3 = IMAGE "jewel_enemy3", (0, 0), "offscreen"
  e4 = IMAGE "jewel_enemy3", (0, 0), "offscreen"
  goodies = 8
  activateLevel
END SUB
'----------------------------
' Level 4
'----------------------------
SUB level4
  title = TEXT "Level 4: Garnet ", (_MIDDLEX, 40), "font7", 50, #FFFFFF, "type", 40
  SET TEXT barLevel, "Garnet"
  IMAGE "jewel_goody4", (244, 610)
  SLEEP 400
  bg = IMAGE "jewel_bg_level3", (0, 78), "fade-in", 1000
  TOP title
  WAIT
  HIDE title, "fade-out", 400
  WAIT
  g1 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g2 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g3 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g4 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g5 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g6 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g7 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g8 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g9 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  g10 = IMAGE "jewel_goody4", (RND(0, 620), RND(400, 580))
  e1 = IMAGE "jewel_enemy4", (0, 0), "offscreen"
  e2 = IMAGE "jewel_enemy4", (0, 0), "offscreen"
  e3 = IMAGE "jewel_enemy4", (0, 0), "offscreen"
  e4 = IMAGE "jewel_enemy4", (0, 0), "offscreen"
  e5 = IMAGE "jewel_enemy4", (0, 0), "offscreen"
  goodies = 10
  activateLevel
END SUB
'----------------------------
' Level 5
'----------------------------
SUB level5
  title = TEXT "Level 5: Pearl ", (_MIDDLEX, 40), "font7", 50, #FFFFFF, "type", 40
  SET TEXT barLevel, "Pearl"
  IMAGE "jewel_goody5", (264, 610)
  SLEEP 400
  bg = IMAGE "jewel_bg_level5", (0, 78), "fade-in", 1000
  TOP title
  WAIT
  HIDE title, "fade-out", 400
  WAIT
  g1 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g2 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g3 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g4 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g5 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g6 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g7 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g8 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g9 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  g10 = IMAGE "jewel_goody5", (RND(0, 620), RND(400, 580))
  e1 = IMAGE "jewel_enemy5", (0, 0), "offscreen"
  e2 = IMAGE "jewel_enemy5", (0, 0), "offscreen"
  e3 = IMAGE "jewel_enemy5", (0, 0), "offscreen"
  e4 = IMAGE "jewel_enemy5", (0, 0), "offscreen"
  e5 = IMAGE "jewel_enemy5", (0, 0), "offscreen"
  goodies = 10
  activateLevel
END SUB
'----------------------------
' Generic level functions
'----------------------------
SUB nextLevel
  stage = stage + 1
  IF stage = 1 THEN
    level1
    WAIT
    MUSIC "short_jazz_bip"
    VOICE "Go!"
  END IF
  IF stage = 2 THEN
    level2
  END IF
  IF stage = 3 THEN
    level3
  END IF
  IF stage = 4 THEN
    level4
  END IF
  IF stage = 5 THEN
    level5
  END IF
  IF stage = 6 THEN
    gameOver ' End of levels.
  END IF
END SUB
SUB clearLevel
  HIDE man
  HIDE e1 : HIDE e2 : HIDE e3 : HIDE e4 : HIDE e5
  HIDE g1 : HIDE g2 : HIDE g3 : HIDE g4 : HIDE g5 : HIDE g6 : HIDE g7 : HIDE g8 : HIDE g9 : HIDE g10
  HIDE bg, "fade-out", 400
END SUB
'----------------------------
' Set detection and animations
'----------------------------
SUB startCollide
  ' Collision with gems
  ON COLLIDE g1, man, pickup, 1
  ON COLLIDE g2, man, pickup, 1
  ON COLLIDE g3, man, pickup, 1
  ON COLLIDE g4, man, pickup, 1
  ON COLLIDE g5, man, pickup, 1
  ON COLLIDE g6, man, pickup, 1
  ON COLLIDE g7, man, pickup, 1
  ON COLLIDE g8, man, pickup, 1
  ON COLLIDE g9, man, pickup, 1
  ON COLLIDE g10, man, pickup, 1
  ' Collision with enemies
  ON COLLIDE e1, man, hurt
  ON COLLIDE e2, man, hurt
  ON COLLIDE e3, man, hurt
  ON COLLIDE e4, man, hurt
  ON COLLIDE e5, man, hurt
END SUB
SUB animateEnemies
  ANIM e1, "yoyo", (RND(0, 620), RND(320, 560))-(RND(0, 620), RND(320, 560)), RND(600, 2000)
  ANIM e2, "yoyo", (RND(0, 620), RND(320, 560))-(RND(0, 620), RND(320, 560)), RND(600, 2000)
  ANIM e3, "yoyo", (RND(0, 620), RND(320, 560))-(RND(0, 620), RND(320, 560)), RND(600, 2000)
  ANIM e4, "yoyo", (RND(0, 620), RND(320, 560))-(RND(0, 620), RND(320, 560)), RND(600, 2000)
  ANIM e5, "yoyo", (RND(0, 620), RND(320, 560))-(RND(0, 620), RND(320, 560)), RND(600, 2000)
END SUB
'----------------------------
' Animate enemies
'----------------------------
SUB hurt
  IF NOT touched AND NOT dead THEN
    touched = true
    lives = lives - 1
    SOUND "slap"
    ANIM man, "BLINK", 200, 4  ' 4 set a short period of invicibility.
    IF lives = 4 THEN
      HIDE live4, "fade-out", 400
    END IF
    IF lives = 3 THEN
      HIDE live3, "fade-out", 400
    END IF
    IF lives = 2 THEN
      HIDE live2, "fade-out", 400
    END IF
    IF lives = 1 THEN
      HIDE live1, "fade-out", 400
    END IF
    IF lives = 0 THEN
      dead = true
      gameOver
    END IF
    WAIT
    touched = false
  END IF
END SUB
'----------------------------
' Picking up goodies.
'----------------------------
SUB pickup
  HIDE _OBJECT ' Hide gem
  SOUND "pop", "no-wait"
  goodies = goodies - 1
  score = score + 100
  SET TEXT barScore, STR(score)
  IF goodies = 0 THEN
    stageDone
  END IF
END SUB
SUB stageDone
  IF NOT dead THEN
    clearLevel
    SOUND "applause", "no-wait"
    WAIT
    nextLevel
  END IF
END SUB
'----------------------------
' Game over
'----------------------------
SUB gameOver
  clearLevel
  WAIT
  title = TEXT "Game Over", (_MIDDLEX, 100), "font7", 50, #FFFFFF, "type", 80
  MUSIC "game_over"
  WAIT
  finalScore = TEXT "Your final score: " + STR(score), (_MIDDLEX, 250), "default", 40, #ffffff, "fade-in", 1000
  SLEEP 2000
  button2 = BUTTON "jewel_button1", "OK", (_MIDDLEX, 400), "font4", 30, #3C3C3C, "fade-in", 500
  ANIM button2, "scale", 100, 95, 1200
  ON CLICK button2, restartGame
END SUB
SUB restartGame
  RELOAD
END SUB
        
Go back to list of Tutorials.