include, plotscr.hsd include, scancode.hsi global variable(1, armada) global variable(2, playing) global variable(3, direction) global variable(4, movespeed) global variable(5, walktoggle) global variable(6, shooter) global variable(7, friendly bullets) global variable(8, cannon charge) global variable(9, start speed) global variable(10, enemy bullets) global variable(11, enemy fire rate) global variable(12, score) plotscript, space invadeOHRs, begin suspend player create armada create shooter create bullet layers start timer scripts setup score playing := true while(playing) do( update game wait(1) ) cleanup all game over end script, cleanup all, begin # Free all slices and reset their globals to zero free slice(armada) armada := 0 free slice(shooter) shooter := 0 free slice(friendly bullets) friendly bullets := 0 free slice(enemy bullets) enemy bullets := 0 # Cancel the timers stop timer(0) stop timer(1) # Hide the score string hide string(1) end script, start timer scripts, begin set timer(0, 1, 3, @update walktoggle) set timer(1, 1, 4, @reload cannon) end script, create shooter, begin shooter := load walkabout sprite(10) realign slice(shooter, edge:center, edge:bottom, edge:center, edge:bottom) end script, create armada, begin if(armada) then( set slice x(armada, 0) set slice y(armada, 0) )else( armada := create container ) variable(sl, row, col) for(row, 0, 3) do( for(col, 0, 7) do( sl := load walkabout sprite(2 + col) set parent(sl, armada) set sprite frame(sl, 4) place sprite(sl, col * 25, row * 25) ) ) refit armada direction := 1 start speed += 1 movespeed := start speed enemy fire rate += 1 end script, create bullet layers, begin friendly bullets := create container(320, 200) enemy bullets := create container(320, 200) end script, setup score, begin show string at(1, 0, 0) $1="" append number(1, score) end script, update game, begin user input move armada update each enemy update shooter update bullets end script, user input, begin if(key is pressed(key:ESC)) then( playing := false ) if(key is pressed(key:left)) then( set slice x(shooter, slice x(shooter) -- 4) ) if(key is pressed(key:right)) then( set slice x(shooter, slice x(shooter) + 4) ) if(keyval(key:space)>>1) then( fire bullet ) end script, move armada, begin set slice x(armada, slice x(armada) + (movespeed * direction)) if(direction==1) then( if(not(slice contains(sprite layer, armada))) then( clamp slice(armada, sprite layer) play sound(0) direction := direction * -1 set slice y(armada, slice y(armada) + 4) ) )else( if(not(slice contains(sprite layer,armada))) then( clamp slice(armada, sprite layer) play sound(0) direction := direction * -1 movespeed += 1 set slice y(armada, slice y(armada) + 4) ) ) if(slice y(armada) + slice height(armada) >> slice height(sprite layer)) then( shooter dies ) end script, update each enemy, begin variable(enemy) enemy := first child(armada) if(not(enemy)) then(create armada, exit script) while(enemy) do( set sprite frame(enemy, 4 + walktoggle) if(slice collide(enemy, shooter)) then(shooter dies) if(random(0,999) << enemy fire rate) then(enemy fire bullet(enemy)) enemy := next sibling(enemy) ) end script, update shooter, begin set sprite frame(shooter, walktoggle) end script, update bullets, begin update friendly bullets update enemy bullets end script, update friendly bullets, begin variable(bullet, delete) bullet := first child(friendly bullets) while(bullet) do( delete := false set slice y(bullet, slice y(bullet) -- 8) if(check for friendly bullet hit(bullet)) then(delete := bullet) if(slice collide(bullet, sprite layer) == false) then(delete := bullet) bullet := next sibling(bullet) if(delete) then(free slice(delete)) ) end script, check for friendly bullet hit, bullet, begin variable(enemy) enemy := first child(armada) while(enemy) do( if(slice contains(enemy, bullet)) then( free slice(enemy) play sound(3) refit armada score += move speed * enemy fire rate $1="" append number(1, score) exit returning(true) ) enemy := next sibling(enemy) ) exit returning(false) end script, update enemy bullets, begin variable(bullet, delete) bullet := first child(enemy bullets) while(bullet) do( delete := false set slice y(bullet, slice y(bullet) + 5) if(slice contains(shooter, bullet)) then( shooter dies exit script ) if(not(slice collide(bullet, sprite layer))) then(delete := bullet) bullet := next sibling(bullet) if(delete) then(free slice(delete)) ) end script, fire bullet, begin if(cannon charge == false) then(exit script) variable(bullet) bullet := create rect(4, 8) set parent(bullet, friendly bullets) set horiz anchor(bullet, edge:center) set vert anchor(bullet, edge:center) set rect fgcol(bullet, 0) set rect bgcol(bullet, 15) set rect border(bullet, -1) set slice x(bullet, slice screen x(shooter)) set slice y(bullet, slice screen y(shooter) -- slice height(shooter)) cannon charge := false play sound(2) end script, enemy fire bullet, enemy, begin variable(bullet) bullet := create rect(4, 8) set parent(bullet, enemy bullets) set horiz anchor(bullet, edge:center) set vert anchor(bullet, edge:center) set rect fgcol(bullet, 0) set rect bgcol(bullet, 12) set rect border(bullet, -1) set slice x(bullet, slice screen x(enemy) + slice width(enemy) / 2) set slice y(bullet, slice screen y(enemy) + slice height(enemy)) play sound(2) end script, update walktoggle, begin walktoggle := walktoggle, xor, 1 play sound(1) set timer(0, 1, 3, @update walktoggle) end script, reload cannon, begin cannon charge := true set timer(1, 1, 5, @reload cannon) end script, refit armada, begin variable(sl, x1, y1, x2, y2, diffx, diffy) x1 := 99999 y1 := 99999 x2 := -99999 y2 := -99999 # Find the new boundaries sl := first child(armada) while(sl) do( if(slice screen x(sl) << x1) then(x1 := slice screen x(sl)) if(slice screen y(sl) << y1) then(y1 := slice screen y(sl)) if(slice screen x(sl) + slice width(sl) >> x2) then(x2 := slice screen x(sl) + slice width(sl)) if(slice screen y(sl) + slice height(sl) >> y2) then(y2 := slice screen y(sl) + slice height(sl)) sl := next sibling(sl) ) # Readjust container diffx := x1 -- slice screen x(armada) diffy := y1 -- slice screen y(armada) set slice screen x(armada, x1) set slice screen y(armada, y1) set slice width(armada, x2 -- x1) set slice height(armada, y2 -- y1) sl := first child(armada) # Readjust children while(sl) do( set slice x(sl, slice x(sl) -- diffx) set slice y(sl, slice y(sl) -- diffy) sl := next sibling(sl) ) end script, shooter dies, begin $0="GAME OVER" center string at(0, 160, 100) playing := false while(key is pressed(key:space)) do(wait) end