Space Invaders - Overview

Platform: 3ds Max 2008+ (MAXScript)
Status: Released
Address: www.GeoffSamuel.com/Scrip_Files.php?proj=5


This is an example of a game running completely in MAXScript.

Code

--Classic space invaders in 3d max
--Creator: Geoffrey Samuel
--Contact E-mail: Geoff@GeoffSamuel.com
--Contact Website: www.GeoffSamuel.com

--script wirten, tested and designed by Geoffrey Samuel, all rights reserved 2008.

--KNOW BUGS:   
--      *Script returns a game_setup = undefined at first launch   
--          SOLOUTION: Close down rollout and re-run script
--      *Script tries to access deleted scene objects when the exit button is pressed and then the start button (ends up crashing max) 
--          SOLOUTION: Dont do it. close down rollout and re-run script


fn define_varibals = (
global game_has_started = false
global alien_move_dir = "Right"
global level = 1
global shot=#()
global boxpos
global score= 0
global alien_shots_to_be_deleted =#()
global alien_ship_to_be_deleted =#()
global shots_to_be_deleted =#()
global Shoot_HOLDUP = "1"
global Alien_shot = #()
global Player_level = 0
global level_up_timer_on = true
global timer_wait = 1
global lifes = 3
)
fn game_setup =(
    ------------------------------------------------------BLOCKS
global  blocks = #()
    --Set up blocks
    blocks[1] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[-156.227,-86.4469,0.2]
    blocks[2] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[-110.727,-86.4469,0.2]
    blocks[3] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[-65.2271,-86.4469,0.2]
    blocks[4] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[-19.7271,-86.4469,0.2]
    blocks[5] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[25.7729,-86.4469,0.2]
    blocks[6] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[71.2729,-86.4469,0.2]
    blocks[7] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[116.773,-86.4469,0.2]
    blocks[8] = Rectangle length:30.4029 width:18.315 cornerRadius:0 pos:[162.273,-86.4469,0.2]
   
    for n = 1 to 8 do (
        blocks[n].wirecolor = green

convertTo blocks[n]  (Editable_Poly)
            addModifier blocks[n]  (shell innerAmount:0 outerAmount:0.5)
    addModifier blocks[n] (subdivide manualUpdate:1 size:35)
)
    ------------------------------------------------------PLAYER
--makes a new varibal to hold the LINE (SPLINE) data
global Player_ship = line()
--converts the line to a editable spline so vertexs (knots) can be added
convertToSplineShape(Player_ship)
--adds a new spline section to the line
 addNewSpline Player_ship
 --creates the outline of the player ship
addKnot Player_ship 1 #corner #curve [-29.487,-120.004,0]
addKnot Player_ship 1 #corner #curve [-29.487,-129.853,0]
addKnot Player_ship 1 #corner #curve [-0.549,-129.853,0]
addKnot Player_ship 1 #corner #curve [-0.601,-119.94,0]
addKnot Player_ship 1 #corner #curve [-10.031,-119.94,0]
addKnot Player_ship 1 #corner #curve [-10.031,-116.761,0]
addKnot Player_ship 1 #corner #curve [-13.131,-116.761,0]
addKnot Player_ship 1 #corner #curve [-13.131,-114.103,0]
addKnot Player_ship 1 #corner #curve [-16.428,-114.103,0]
addKnot Player_ship 1 #corner #curve [-16.428,-116.667,0]
addKnot Player_ship 1 #corner #curve [-19.963,-116.667,0]
addKnot Player_ship 1 #corner #curve [-19.963,-119.963,0]
--closes the spline off so it keeps looping
close Player_ship 1
--updates the shape so it can be displayed in the viewport
updateShape(Player_ship)
--gives the player ship that classic green colour
Player_ship.wirecolor = green

-- center the player ship
CenterPivot Player_ship
--select it to apply an edit mesh and a subdeive to it
convertTo Player_ship   (Editable_Poly)
    addModifier Player_ship  (subdivide manualUpdate:1 size:35)
--positon the ship where it should start from
Player_ship.pos = [0,-127.463,0]

global orignal_shot = (Rectangle length:12.0879 width:1.4652 cornerRadius:0 pos:Player_ship.pos wirecolor:WHITE)
convertTo orignal_shot    (Editable_Poly)
    addModifier orignal_shot  (shell innerAmount:0 outerAmount:1)
    addModifier orignal_shot  (subdivide manualUpdate:1 size:35)
orignal_shot.pos = [727.694,-559.594,0]





--makes a new varibal to hold the LINE (SPLINE) data
global alien_shot_orginal = line()
--converts the line to a editable spline so vertexs (knots) can be added
convertToSplineShape(alien_shot_orginal)
--adds a new spline section to the line
 addNewSpline alien_shot_orginal
 --creates the outline of the alien shot
addKnot alien_shot_orginal 1 #corner #curve [-111.647,13.54,0]
addKnot alien_shot_orginal 1 #corner #curve [-106.363,13.54,0]
addKnot alien_shot_orginal 1 #corner #curve [-110.212,6.756,0]
addKnot alien_shot_orginal 1 #corner #curve [-104.928,5.908,0]
addKnot alien_shot_orginal 1 #corner #curve [-109.69,-3.486,0]
addKnot alien_shot_orginal 1 #corner #curve [-113.539,-3.42,0]
addKnot alien_shot_orginal 1 #corner #curve [-110.077,3.311,0]
addKnot alien_shot_orginal 1 #corner #curve [-115.27,4.688,0]
--closes the spline off so it keeps looping
close alien_shot_orginal 1
--updates the shape so it can be displayed in the viewport
updateShape(alien_shot_orginal)
--gives the alien shot a yellow colour
alien_shot_orginal.wirecolor = Yellow
-- center the alien shot
CenterPivot alien_shot_orginal
--select it to apply an edit mesh and a subdeive to it
convertTo alien_shot_orginal   (Editable_Poly)
addModifier alien_shot_orginal (shell innerAmount:0 outerAmount:1)
    addModifier alien_shot_orginal  (subdivide manualUpdate:1 size:35)
--positon the ship where it should start from
alien_shot_orginal.pos =  [827.694,-459.594,0]

hide alien_shot_orginal




    ------------------------------------------------------GUI parts
    --LIVES
    --copy the low res player ship for the lives indicators
global life_1 = instance Player_ship
global life_2 = instance Player_ship
global life_3 = instance Player_ship
--position the lives indicators where they should be
life_1.pos = [95.95,134.28,0]
life_2.pos = [131.973,134.28,0]
life_3.pos = [168.756,134.28,0]
--gives the lives ship that classic green colour
life_1.wirecolor = green
life_2.wirecolor = green
life_3.wirecolor = green

--Lives text
Lives_text = text size:29.21 pos:[44.157,126.741,0] Text: "LIVES" Wirecolor: White font: "OCR A Extended" kerning: -3.84
    convertTo Lives_text  (Editable_Poly)
       
--Score text (word score)
        score_text = text size:29.21 pos:[-158.072,126.741,0] Text: "SCORE" Wirecolor: White font: "OCR A Extended" kerning: -3.84
    convertTo score_text  (Editable_Poly)
       
--Player Score text
        global player_score_text = text size:29.21 pos:[-88.109,126.741,0] Text: "0" Wirecolor: green font: "OCR A Extended" kerning: -3.84



)
fn create_aliens = (
        ------------------------------------------------------SPACE INVADERS
    -------make the aliens

    --makes a new varibal to hold the LINE (SPLINE) data
alien_ship = line()
--converts the line to a editable spline so vertexs (knots) can be added
convertToSplineShape(alien_ship)
--adds a new spline section to the line
 addNewSpline alien_ship
 --creates the outline of the player ship
addKnot alien_ship 1 #corner #curve [-158.681,121.033,0]
addKnot alien_ship 1 #smooth #curve [-167.002,108.471,0]
addKnot alien_ship 1 #corner #curve [-163.279,107.176,0]
addKnot alien_ship 1 #corner #curve [-167.002,100.992,0]
addKnot alien_ship 1 #corner #curve [-166.614,100.992,0]
addKnot alien_ship 1 #corner #curve [-162.761,107.047,0]
addKnot alien_ship 1 #corner #curve [-160.624,107.111,0]
addKnot alien_ship 1 #corner #curve [-162.016,104.456,0]
addKnot alien_ship 1 #corner #curve [-161.369,104.456,0]
addKnot alien_ship 1 #corner #curve [-159.912,107.047,0]
addKnot alien_ship 1 #corner #curve [-157.45,107.047,0]
addKnot alien_ship 1 #corner #curve [-155.993,104.456,0]
addKnot alien_ship 1 #corner #curve [-155.346,104.456,0]
addKnot alien_ship 1 #corner #curve [-156.738,107.111,0]
addKnot alien_ship 1 #corner #curve [-154.601,107.047,0]
addKnot alien_ship 1 #corner #curve [-150.748,100.992,0]
addKnot alien_ship 1 #corner #curve [-150.36,100.992,0]
addKnot alien_ship 1 #corner #curve [-154.083,107.176,0]
addKnot alien_ship 1 #smooth  #curve [-150.36,108.471,0]

--closes the spline off so it keeps looping
close alien_ship 1
--updates the shape so it can be displayed in the viewport
updateShape(alien_ship)
--gives the player ship that classic green colour
alien_ship.wirecolor = white

-- center the player ship
CenterPivot alien_ship
--select it to apply an edit mesh and a subdeive to it
convertTo alien_ship    (Editable_Poly)
addModifier alien_ship   (subdivide manualUpdate:1 size:35)


--positon the ship where it should start from
alien_ship.pos = [-163.361,111.534,0]
    ------populate the alien side
    global alien_ships_array = #()
    for side = 0 to 4 do (
        num_side = side * 11
        for top = 0 to 10 do (
            num = num_side+top+1
        alien_ships_array[num] = instance alien_ship
    alien_ships_array[num].wirecolor = color 255 255 255
            move alien_ships_array[num] [(top*26.5326),(side*-22.2702),0]
   
    )
   
)
delete alien_ship
)
fn game_exit = (
    viewport.ResetAllViews()
    mybox = box()
    togo = max select all
    if togo != undefined then (
    delete $
    )
)
fn  alient_check_dir = (
   
    if alien_ships_array[1].pos.x > -77.976 then (
        for p = 1 to alien_ships_array.count do (
        move alien_ships_array[p] [0,-22.2702,0]
        )
        alien_move_dir = "Left"
        level += 0.025
    )
        if alien_ships_array[1].pos.x < -189.617 then (
        for p = 1 to alien_ships_array.count do (
        move alien_ships_array[p] [0,-11.1351,0]
        )
        alien_move_dir = "Right"
        level += 0.025
    )
)
fn  aliens_move= (
    --move left
    if alien_move_dir == "Right" do(
    for p = 1 to alien_ships_array.count do (
        move alien_ships_array[p] [level*2,0,0]
    ))
    --move right
        if alien_move_dir == "Left" do(
    for p = 1 to alien_ships_array.count do (
        move alien_ships_array[p] [-level*2,0,0]
    ))
)
fn shooting = (
    if Shoot_HOLDUP =="1" do (
        append shot (instance orignal_shot)
        Shoot_HOLDUP="0"
        )
)
tool moveplayer  (
    on freeMove do(
        Player_ship.pos.x = worldPoint.x
        if  Player_ship.pos.x > 185.357 do (
    Player_ship.pos.x =185.356)
    if  Player_ship.pos.x < -186.598 do (
    Player_ship.pos.x =-186.597)

    )
    on mouseMove  clickno do (
    Player_ship.pos.x = worldPoint.x
        if  Player_ship.pos.x > 185.357 do (
    Player_ship.pos.x =185.356)
    if  Player_ship.pos.x < -186.598 do (
    Player_ship.pos.x =-186.597)
            orignal_shot.pos = Player_ship.pos
    hide orignal_shot
)
    on mousePoint click do(

 shooting()
       
    if mButton do  batchFloater.pos = boxpos

))
fn wall_shot_detection shot_num = (
   
    for b = 1 to blocks.count do (
            if (distance shot[shot_num]     blocks[b]) < 15  then (
                    global nVertsBefore = blocks[b].mesh.numVerts
                    global nVertsAfter = (blocks[b]- shot[shot_num]).numverts
                    if nVertsBefore==nVertsAfter then(

                    )else (
                        --print "collision"
                        append shots_to_be_deleted shot_num     )
                )
            )
)
fn alien_shot_detection shot_num= (
        for p = 1 to alien_ships_array.count do (
            if (distance shot[shot_num]     alien_ships_array[p]) < 20 then (
                    global nVertsBefore = shot[shot_num].mesh.numVerts
                    global nVertsAfter = ( shot[shot_num] - alien_ships_array[p]).numverts
                    if nVertsBefore!=nVertsAfter then(
                        --print "no collision"
                    )
                    else
                    (
                    --print "collision"
                        if p==1 then (
                            hide alien_ships_array[p]
                   
                            score+=10          
                            append shots_to_be_deleted shot_num 
                        )
                        else
                        (
                            append alien_ship_to_be_deleted p
               
                            print number_of_aliens_killed
                            score+=10          
                            append shots_to_be_deleted shot_num        
                           
                        exit
                        )
                    )
            )
        )
)
fn alien_shooting = (
    ship_to_shoot = (random 2 alien_ships_array.count)
    alien_shot_orginal.pos = alien_ships_array[ship_to_shoot].pos
    append  Alien_shot (instance alien_shot_orginal)
)
fn ALIEN_wall_shot_detection= (
        for p = 1 to Alien_shot.count do (
    for b = 1 to blocks.count do (
            if (distance Alien_shot[p]  blocks[b]) < 8  then (
                    global nVertsBefore = blocks[b].mesh.numVerts
                    global nVertsAfter = (blocks[b] - Alien_shot[p]).numverts
                    if nVertsBefore==nVertsAfter then(
    append alien_shots_to_be_deleted p 
                    )else (
                        print "collision"
                        --append alien_shots_to_be_deleted p       
                        )
                )
            )
)
)
fn ALIEN_shot_to_player_detection = (
        for p = 1 to Alien_shot.count do (
            if (distance Alien_shot[p] Player_ship) < 20 then (
                    global nVertsBefore = Alien_shot[p].mesh.numVerts
                    global nVertsAfter = ( Alien_shot[p] - Player_ship).numverts
                    if nVertsBefore!=nVertsAfter then(
                        --print "no collision"
                    )
                    else
                    (
                        append alien_shots_to_be_deleted p
                        lose_life()
                    )
            )
        )
)
fn lose_life = (
   
    lifes -=1
    if lifes == 2 do hide life_3
    if lifes == 1 do hide life_2
    if lifes == 0 do hide life_1
    if lifes < 0 do gameover()
)
fn gameover = (
    game_has_started = false
    global gameover_text = text size:69.0 kerning:0 leading:0 pos:[3.11355,-14.8352,50] text: "GAME OVER"
 convertTo gameover_text   (Editable_Poly)
    batchFloater.pos = boxpos
)
fn level_up = (
    level_up_timer_on = true
create_aliens()
number_of_aliens_killed =0
level +=0.1
Player_level +=1
    Player_level_string = "LEVEL " + Player_level as string
global level_text = text size:100 kerning:0 leading:0 pos:[3.11355,-14.8352,50] text: Player_level_string
 convertTo level_text   (Editable_Poly)
)
rollout Batch_Converter "SPACE INVADERS" width:200 height:80
(
    button Start "START" pos:[13,6] width:179 height:22
    button exit_button "EXIT" pos:[7,32] width:189 height:41
   
    timer Level_up_timer "Timer" pos:[94,67] width:24 height:24 interval: 2000
    timer Shoot_HOLDUP_timer "Timer" pos:[94,67] width:24 height:24 interval: 250
    timer shoot_timer "Timer" pos:[94,67] width:24 height:24 interval: 40
    timer player_timer "Timer" pos:[94,67] width:24 height:24 interval: 40
    timer alients_timer "Timer" pos:[94,67] width:24 height:24 interval: 40
    timer score_timer "Timer" pos:[94,67] width:24 height:24 interval: 150
    timer alien_shoot_timer "Timer" pos:[94,67] width:24 height:24 interval: 500
    on Shoot_HOLDUP_timer tick do
    (
        Shoot_HOLDUP = "1"
    )
   
    on alien_shoot_timer tick do
    (
        if game_has_started == true then (
    alien_shooting()
        )
    )
    on Level_up_timer tick do
    (
        if level_up_timer_on == true do (
            timer_wait += 1
            if timer_wait == 2 do (
                level_up_timer_on = False
                delete level_text
                timer_wait = 0
            )
        )
    )
   
        on score_timer tick do
    (          
        if game_has_started == true then (
        player_score_text.text = (score as string)
           
            if alien_ships_array.count<=1 do (
                level_up()
       
           
            )   
        )
    )
    on player_timer tick do
    (   
        if game_has_started == true then (
            startTool  moveplayer
            stopTool moveplayer
        )
        else (stopTool moveplayer)
    )
   
    on shoot_timer tick do
    (   
            if game_has_started == true then (
               
            alien_ship_to_be_deleted =#()
            shots_to_be_deleted =#()   
            alien_shots_to_be_deleted =#()
               
               
                ALIEN_shot_to_player_detection()
               
                for r=1 to shot.count do (
                   
                alien_shot_detection r
                wall_shot_detection r   
            )
            for q=1 to alien_shots_to_be_deleted.count do (
                if Alien_shot[alien_shots_to_be_deleted[q]] != undefined do(
                delete Alien_shot[alien_shots_to_be_deleted[q]]
                deleteItem Alien_shot alien_shots_to_be_deleted[q]
            ))
           
            alien_shots_to_be_deleted =#()
            ALIEN_wall_shot_detection()
           
            for q=1 to alien_shots_to_be_deleted.count do (
                if Alien_shot[alien_shots_to_be_deleted[q]] != undefined do(
                delete Alien_shot[alien_shots_to_be_deleted[q]]
                deleteItem Alien_shot alien_shots_to_be_deleted[q]
            ))
           
                alien_shots_to_be_deleted =#()
            for r=1 to Alien_shot.count do (
                    if Alien_shot[r].pos.y < -178.815 then (
                    append alien_shots_to_be_deleted r     
                )
            )   
            for q=1 to alien_shots_to_be_deleted.count do (
                if Alien_shot[alien_shots_to_be_deleted[q]] != undefined do(
                delete Alien_shot[alien_shots_to_be_deleted[q]]
                deleteItem Alien_shot alien_shots_to_be_deleted[q]
            ))
           

            for p=1 to alien_ship_to_be_deleted.count do (
                if alien_ships_array[alien_ship_to_be_deleted[p]] != undefined do(
                delete alien_ships_array[alien_ship_to_be_deleted[p]]
                deleteItem alien_ships_array alien_ship_to_be_deleted[p]
            ))
           
           
            for y=1 to shots_to_be_deleted.count  do (
                if shot[shots_to_be_deleted[y]] != undefined do(
                delete shot[shots_to_be_deleted[y]]
                deleteItem shot shots_to_be_deleted[y]
                )
            )
           
            shots_to_be_deleted =#()
            for r=1 to shot.count do (
                wall_shot_detection r   
            )
                for y=1 to shots_to_be_deleted.count  do (
                    if shots_to_be_deleted[y] != undefined do(
                delete shot[shots_to_be_deleted[y]]
                deleteItem shot shots_to_be_deleted[y]
            )       )
           
           
            shots_to_be_deleted =#()
            for r=1 to shot.count do (
                    if shot[r].pos.y > 155.49 then (
                    append shots_to_be_deleted r       
                )
            )      
            for y=1 to shots_to_be_deleted.count  do (
                delete shot[shots_to_be_deleted[y]]
                deleteItem shot shots_to_be_deleted[y]
            )
           
            for s=1 to shot.count do (
                move shot[s] [0,10,0]
                shot[s].wirecolor = WHITE
            )
                for j=1 to Alien_shot.count do (
                move Alien_shot[j] [0,-10,0]
                Alien_shot[j].wirecolor = YELLOW
            )
            )
        )
   

    on alients_timer tick do
    (
        if game_has_started == true then (
            alient_check_dir()
            aliens_move()
       
        )
    )

fn game_start = (
    game_exit()
    define_varibals()
    viewport.setLayout #layout_1
    viewport.setType #view_top
    viewport.SetRenderLevel  #smoothhighlights
    viewport.setGridVisibility  #all false
    DisableSceneRedraw()
    game_setup()
    clearSelection()
    EnableSceneRedraw()
    ResetXForm Player_ship
    game_has_started = true
)
   
    on Start pressed do
    (
        game_start()
        boxpos = batchFloater.pos
        batchFloater.pos = [1301,447]
        level_up()
    )
   
    on exit_button pressed do
    (
        game_has_started = false
        stopTool  moveplayer
        game_exit()
    )
)

function MakerolloutFloat =
(
    global batchFloater = newRolloutFloater "space invaders" 220 109
    addRollout Batch_Converter batchFloater rolledup:false
)
 MakerolloutFloat()

Script Download

The script can be downloaded here