Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 019: "Fun and Games"

http://www.craftanimations.com/ Though its quite expensive to ‘play around with’ just for laughs… Works directly in the viewport drive around over obsticals, skid, burnout w/e you like :).

1 Reply
(@dmc900)
Joined: 11 months ago

Posts: 0

Thank you so much! I’m sure this will provide me with 24 hours of very exciting entertainment!

Too bad there way to expensive!
But 24 hours will do me

Today is the deadline for the challenge!

I will be posting my efforts this evening.

Incidentally, TzMtN has just posted a tic tac toe game in the main maxscript forum here:
http://forums.cgsociety.org/showthread.php?f=98&t=640853

erilaz – Thanks for the tip

   I usually love mxs challenges, but never maneged to participate in one.
   This time I was unaware of the challenge completely until you tipped me.
   I hope I haven't disqualified myself from participating so I'll post my code
   and make it official:

 try destroyDialog TTTRollout catch ()
 rollout TTTRollout "TTT"
 (
 -- Local Variable Declerations
 ------------------------------------------
   
 	local dim = 120
 	local valArr
 	local testValArr
 	local sequence
 	local tickTest = false
 	local movesHistory
   
 -- User Interface
 ------------------------------------------
 
 	dropDownList ddlLevel "Level:" items:#("Beginner","Veteran","Expert","Imposible")
 	button bnNext "Next Turn" width:dim align:#center enabled:false
 	
 	button bn02 "" width:(dim/3) height:(dim/3) align:#center
 	button bn01 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x - dim/3,bn02.pos.y]
 	button bn03 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x + dim/3,bn02.pos.y]
 	button bn04 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x - dim/3,bn02.pos.y + dim/3]
 	button bn05 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x,bn02.pos.y + dim/3]
 	button bn06 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x + dim/3,bn02.pos.y + dim/3]
 	button bn07 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x - dim/3,bn02.pos.y + dim*2/3]
 	button bn08 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x,bn02.pos.y + dim*2/3]
 	button bn09 "" width:(dim/3) height:(dim/3) pos:[bn02.pos.x + dim/3,bn02.pos.y + dim*2/3]
 	
 	button bnUndo "Undo (0)" width:dim align:#center
 	button bnRestart "Restart" width:dim align:#center
 	
 	label lbWins "   Wins:" align:#left
 	label lbLosts "Losts:   " align:#right offset:[0,-18]
 	spinner spWins "" fieldWidth:40 align:#left type:#integer enabled:false
 	spinner spLosts "" fieldWidth:40 align:#right type:#integer offset:[0,-22] enabled:false
 	
 	timer tmEnd interval:100 active:false
 	
 -- Functions
 ------------------------------------------
 	
 	fn updateUI =
 	(
 		fn getLabel lin row =
 		(
 			local label = ""
 			if valArr[lin][row] > 0 then label = "X"
 			if valArr[lin][row] < 0 then label = "O"
 			label
 		)
 		
 		bn01.enabled = (bn01.caption =  getLabel 1 1).count == 0
 		bn02.enabled = (bn02.caption =  getLabel 1 2).count == 0
 		bn03.enabled = (bn03.caption =  getLabel 1 3).count == 0
 		bn04.enabled = (bn04.caption =  getLabel 2 1).count == 0
 		bn05.enabled = (bn05.caption =  getLabel 2 2).count == 0
 		bn06.enabled = (bn06.caption =  getLabel 2 3).count == 0
 		bn07.enabled = (bn07.caption =  getLabel 3 1).count == 0
 		bn08.enabled = (bn08.caption =  getLabel 3 2).count == 0
 		bn09.enabled = (bn09.caption =  getLabel 3 3).count == 0
 		
 		if bnRestart.caption != "Restart" then bnNext.enabled = false
 		bnUndo.enabled = movesHistory.count > 1
 		bnUndo.caption = "Undo (" + (movesHistory.count - 1) as string + ")"
 	)
 	
 	fn appendMovesHistory =
 	(
 		append movesHistory #()
 		for lin = 1 to 3 do (
 			append movesHistory[movesHistory.count] #()
 			for row = 1 to 3 do (
 				append movesHistory[movesHistory.count][lin] valArr[lin][row]
 			)
 		)
 	)
 	
 	fn testGameEnd vArr readOnly:false =
 	(
 		local test = 0
 		sequence = #()
 		for a = 1 to 3 do (
 			if vArr[a][1] == vArr[a][2] and vArr[a][1] == vArr[a][3] then
 			(
 				if vArr[a][1] > 0 then test = 1
 				if vArr[a][1] < 0 then test = -1
 				if vArr[a][1] != 0 then sequence = #([a,1],[a,2],[a,3])
 			)
 			
 			if vArr[1][a] == vArr[2][a] and vArr[1][a] == vArr[3][a] then
 			(
 				if vArr[1][a] > 0 then test = 1
 				if vArr[1][a] < 0 then test = -1
 				if vArr[1][a] != 0 then sequence = #([1,a],[2,a],[3,a])
 			)
 		) --end a loop
 		
 		if vArr[1][1] == vArr[2][2] and vArr[1][1] == vArr[3][3] then
 		(
 			if vArr[1][1] > 0 then test = 1
 			if vArr[1][1] < 0 then test = -1
 			if vArr[1][1] != 0 then sequence = #([1,1],[2,2],[3,3])
 		)
 		
 		if vArr[1][3] == vArr[2][2] and vArr[1][3] == vArr[3][1] then
 		(
 			if vArr[1][3] > 0 then test = 1
 			if vArr[1][3] < 0 then test = -1
 			if vArr[1][3] != 0 then sequence = #([1,3],[2,2],[3,1])
 		)
 		
 		if test == 0 then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if test == 0 and vArr[lin][row] == 0 then test = 2
 				)
 			)
 		)
 		
 		if not readOnly then (
 			case of
 			(
 				(test == 0):
 				(
 					bnRestart.caption = "Tie!"
 					movesHistory = #()
 				)
 				(test == 1):
 				(
 					bnRestart.caption = "You Win!"
 					spWins.value += 1
 					movesHistory = #()
 				)
 				(test == -1):
 				(
 					bnRestart.caption = "You Lose!"
 					spLosts.value += 1
 					movesHistory = #()
 				)
 				defalut:
 				(
 					bnRestart.caption = "Restart"
 				)
 			)
 			if sequence.count == 3 then tmEnd.active = true
 		)
 		
 		test
 	)
 	
 	fn setMatrix lin row val force:false =
 	(
 		if (not bnNext.enabled or force) and bnRestart.caption == "Restart" then (
 			valArr[lin][row] = val
 			bnNext.enabled = not bnNext.enabled
 			testGameEnd valArr
 			appendMovesHistory()
 			updateUI()
 		)
 	)
 	
 	fn calculateMove =
 	(
 		local posibleMoves = #()
 		local corners = #([1,1],[1,3],[3,1],[3,3])
 		local sides = #([1,2],[2,1],[2,3],[3,2])
 		
 		-- [0] Error posibility test:
 		-------------------------------
 		local errorTest = case ddlLevel.selection of (
 			1: true
 			2: random 1 3 == 2
 			3: random 1 9 == 5
 			4: false
 		)
 		
 		if errorTest then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if valArr[lin][row] == 0 then (
 						append posibleMoves [lin,row]
 						format "Error
"
 					)
 				)
 			)
 		)
 		
 		-- [1] Win posibility test:
 		--------------------------------
 		if posibleMoves.count == 0 then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if valArr[lin][row] == 0 then (
 						valArr[lin][row] = -1
 						if testGameEnd valArr readOnly:true == -1 then (
 							append posibleMoves [lin,row]
 							format "Win
"
 						)
 						valArr[lin][row] = 0
 					)
 				)
 			)
 		)
 		
 		-- [2] Block posibility test:
 		---------------------------------
 		if posibleMoves.count == 0 then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if valArr[lin][row] == 0 then (
 						valArr[lin][row] = 1
 						if testGameEnd valArr readOnly:true == 1 then (
 							append posibleMoves [lin,row]
 							format "Block
"
 						)
 						valArr[lin][row] = 0
 					)
 				)
 			)
 		)
 		
 		-- [3] Sandwich posibility test:
 		-----------------------------------
 		if posibleMoves.count == 0 then (
 			if valArr[2][2] == -1 then (
 				for c = 1 to corners.count where valArr[corners[c].x][corners[c].y] == 1 do (
 					if valArr[corners[5 - c].x][corners[5 - c].y] == 1 do (
 						for s in sides where valArr[s.x][s.y] == 0 do (
 							append posibleMoves s
 							format "Sandwich
"
 						)
 					)
 				)
 			)
 		)
 		
 		-- [4] Fork posibility test:
 		--------------------------------
 		if posibleMoves.count == 0 then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if valArr[lin][row] == 0 then (
 						valArr[lin][row] = -1
 						local winCount = 0
 						for lin2 = 1 to 3 do (
 							for row2 = 1 to 3 do (
 								if valArr[lin2][row2] == 0 then (
 									valArr[lin2][row2] = -1
 									if testGameEnd valArr readOnly:true == -1 then (
 										winCount += 1
 									)
 									valArr[lin2][row2] = 0
 								)
 							)
 						)
 						if winCount > 1 then (
 							append posibleMoves [lin,row]
 							format "Fork posibility
"
 						)
 						valArr[lin][row] = 0
 					)
 				)
 			)
 		)
 		
 		-- [5] Block Fork posibility test:
 		----------------------------------------
 		if posibleMoves.count == 0 then (
 			for lin = 1 to 3 do (
 				for row = 1 to 3 do (
 					if valArr[lin][row] == 0 then (
 						valArr[lin][row] = 1
 						local winCount = 0
 						for lin2 = 1 to 3 do (
 							for row2 = 1 to 3 do (
 								if valArr[lin2][row2] == 0 then (
 									valArr[lin2][row2] = 1
 									if testGameEnd valArr readOnly:true == 1 then (
 										winCount += 1
 									)
 									valArr[lin2][row2] = 0
 								)
 							)
 						)
 						if winCount > 1 then (
 							append posibleMoves [lin,row]
 							format "Block Fork posibility
"
 						)
 						valArr[lin][row] = 0
 					)
 				)
 			)
 		)
 		
 		-- [6] Empty Centre posibility test:
 		--------------------------------------------
 		if posibleMoves.count == 0 then (
 			if valArr[2][2] == 0 then (
 				append posibleMoves [2,2]
 				format "Empty Centre
"
 			)
 		)
 		
 		-- [7] Opposite Corner posibility test:
 		------------------------------------------------
 		if posibleMoves.count == 0 then (
 			for a = 1 to sides.count do (
 				if valArr[sides[a].x][sides[a].y] == 1 then (
 					b = 5 - a
 					if valArr[sides[b].x][sides[b].y] == 0 then (
 						append posibleMoves sides[b]
 						format "Opposite Corner
"
 					)
 				)
 			)
 		)
 		
 		-- [8] Empty Corner posibility test:
 		-----------------------------------------
 		if posibleMoves.count == 0 then (
 			for i in corners do (
 				if valArr[i.x][i.y] == 0 then (
 					append posibleMoves i
 					format "Empty Corner
"
 				)
 			)
 		)
 		
 		-- [9] Empty Side posibility test:
 		--------------------------------------------
 		if posibleMoves.count == 0 then (
 			for i in sides do (
 				if valArr[i.x][i.y] == 0 then (
 					append posibleMoves i
 					format "Empty Side
"
 				)
 			)
 		)
 		
 		-- Make a move:
 		---------------------
 		local newMove = posibleMoves[random 1 posibleMoves.count]
 		setMatrix newMove.x newMove.y -1 force:true
 	)
 	
 	fn nextTurn =
 	(
 		calculateMove()
 		updateUI()
 	)
 	
 	fn restartGame =
 	(
 		tmEnd.active = true
 		valArr = #(#(0,0,0),#(0,0,0),#(0,0,0))
 		movesHistory = #(#(#(0,0,0),#(0,0,0),#(0,0,0)))
 		bnRestart.caption = "Restart"
 		bnNext.enabled = false
 		updateUI()
 	)
 	
 	fn showWinner  =
 	(
 		if bnRestart.caption == "You Win!" or bnRestart.caption == "You Lose!" then (
 			local char = if bnRestart.caption == "You Win!" then "X" else "O"
 			
 			for i in sequence do (
 				if i == [1,1] then bn01.caption =  if tickTest then char else ""
 				if i == [1,2] then bn02.caption =  if tickTest then char else ""
 				if i == [1,3] then bn03.caption =  if tickTest then char else ""
 				if i == [2,1] then bn04.caption =  if tickTest then char else ""
 				if i == [2,2] then bn05.caption =  if tickTest then char else ""
 				if i == [2,3] then bn06.caption =  if tickTest then char else ""
 				if i == [3,1] then bn07.caption =  if tickTest then char else ""
 				if i == [3,2] then bn08.caption =  if tickTest then char else ""
 				if i == [3,3] then bn09.caption =  if tickTest then char else ""
 			)
 			
 			tickTest = not tickTest
 		)
 	)
 	
 	fn UndoMove =
 	(
 		deleteItem movesHistory movesHistory.count
 		valArr = movesHistory[movesHistory.count]
 		bnNext.enabled = not bnNext.enabled
 		updateUI()
 	)
 	
 	fn openDialog =
 	(
 		createDialog TTTRollout width:(dim + 25)
 	)
 	  
 	fn init =
 	(
 		restartGame()
 	)
   
 	fn done =
 	(
 		-- cleanup code
 		gc light:true
 	)
   
 -- Event Handlers
 ------------------------------------------
 	  
 	on bn01 pressed do setMatrix 1 1 1
 	on bn02 pressed do setMatrix 1 2 1
 	on bn03 pressed do setMatrix 1 3 1
 	on bn04 pressed do setMatrix 2 1 1
 	on bn05 pressed do setMatrix 2 2 1
 	on bn06 pressed do setMatrix 2 3 1
 	on bn07 pressed do setMatrix 3 1 1
 	on bn08 pressed do setMatrix 3 2 1
 	on bn09 pressed do setMatrix 3 3 1
 		
 	on bnRestart pressed do restartGame()
 	on bnUndo pressed do UndoMove()
 	on bnNext pressed do nextTurn()
 	
 	on tmEnd tick do showWinner()
 	
 	on TTTRollout open do init()
 	on TTTRollout close do done()
 
 ) -- end of rollout
 
 TTTRollout.openDialog()
      
By the way, this code has a new undo feature in it!

Written in Max 2008 by the way.

Here are my references:
[ http://en.wikipedia.org/wiki/Tic-tac-toe ]( http://en.wikipedia.org/wiki/Tic-tac-toe) 
[ http://www.wikihow.com/Win-at-Tic-Tac-Toe ]( http://www.wikihow.com/Win-at-Tic-Tac-Toe) 

Thanks to PEN and ZeBoxx2 for their help!

  Cheers, Matan.

Not a work of genius, this is a simple replication of the classic puzzle toy. The fun stuff was the dynamic parenting, which is still a bit funny. Uncomment the line near the bottom for 1-click 90 degree rotation.


-------------------------------------------------------------
-- SCRIPT: 	"Cube Puzzle"
-- VERSION 	1.0a
-- AUTHOR: 	Martin Brennand
-- DATE: 	28/05/2008
-- NOTES: 	Simple Rubiks cube.  Not quite right yet. :)
--
--FAULTS: The event trigger causes some irregularity in 
--			  the parenting of the cubes, so rotation can be
--			   skewed.
-------------------------------------------------------------


(
	tempObj = 0
	cubeArray = 0
	spinners = 0
	rot = eulerangles 0 0 0
	
	fn createCube mat=
	(
		local idx = 1
		local cubeArray = #()
		startPos = [-20,-20,-20]
		for l = 1 to 3 do
		(
			for d = 1 to 3 do
			(
				for w = 1 to 3 do
				(
					cubeName = "cube_"+(idx as string)
					cubeArray[idx] = box name:cubeName width:10 height:10 length:10
					centerPivot cubeArray[idx]
					cubeArray[idx].pos = startPos + [l*10,d*10,w*10]
					addModifier (cubeArray[idx]) (Edit_Poly())
					cubeArray[idx].isFrozen = true
					cubeArray[idx].showFrozenInGray  = false
					
					idx +=1
				)
			)
		)
		selection =  cubeArray
		selection.Material = mat
		return cubeArray
	)

	fn createMaterials =
	(
		local materialArray = #()
		local mColours = #(red,green,blue,yellow,orange,black)
		for i = 1 to 6 do
		(
			materialArray[i] = standardMaterial diffuse:mColours[i]
		)
		multiMat = multiMaterial numsubs:6
		multiMat.materialList = materialArray
		
		return multiMat
	)


	fn createSpinners cubes=
	(
		local spinnerArray = #()
		for i = 1 to 3 do
		(
			spinnerArray[i] = circle radius: 25 
			if ( mod i 3 )== 0 then
			(
				spinnerArray[i].pos += [0,0,10]
			)
				if ( mod i 2 )== 0 then
			(
				spinnerArray[i].pos += [0,0,-10]
			)
		)
		for i = 4 to 6 do
		(
			spinnerArray[i] = circle radius: 25 
			rot = (eulerangles 0 90 0) 
			spinnerArray[i].rotation =  rot
			
			if ( mod i 3 )== 0 then
			(
				spinnerArray[i].pos += [10,0,0]
			)
				if ( mod i 4 )== 0 then
			(
				spinnerArray[i].pos += [-10,0,0]
			)
		)
		for i = 7 to 9 do
		(
			spinnerArray[i] = circle radius: 25 
			rot = (eulerangles 90 0 0) 
			spinnerArray[i].rotation =  rot	
			if ( mod i 3 )== 0 then
			(
				spinnerArray[i].pos += [0,10,0]
			)
				if ( mod i 2 )== 0 then
			(
				spinnerArray[i].pos += [0,-10,0]
			)
		)
		
		return spinnerArray
		
	)
	
	fn randomiseSpinners spinnerArr = 
	(
		numSpins = random 50 100
		spinnerCount = spinnerArr.count
		
		for i = 1 to numSpins do
		(
			select spinnerArr[(random 1 spinnerCount)]
			in coordsys local rotate selection (angleaxis 90 [0, 0 ,1])
		)
	)
	
	rollout cubePuzzle "cubey puzzley" width:79 height:73
	(
		button quitBtn "Quit" pos:[23,44] width:35 height:21
		button spinButton "Shuffle" pos:[18,13] width:49 height:21
		on cubePuzzle open do
		(
			print "Dialog Init"
		)
		on cubePuzzle close do
		(
			deleteAllChangeHandlers  id:#spinnerRotate
			delete cubeArray
			delete spinners
			print "Dialog Closed"
		)
		on quitBtn pressed do
		(
			DestroyDialog cubePuzzle
		)
		on spinButton pressed do
		(
			randomiseSpinners(spinners)
		)
	)
--------------------------------------------------------------------------------------		
--------------------------------------------------------------------------------------		
	--create the objects
	multiMat = createMaterials()
	cubeArray = createCube(multiMat)
	spinners = createSpinners(cubeArray)

	--start the game cycle
	createDialog cubePuzzle		
	when select spinners change id:#spinnerRotate obj  do
	(
		if obj != tempObj then --don't parent more than once per selection!
		(
			for item in obj.children do (deleteItem obj.children item) --clear the children from the spinner
					
			spinnerTransform = obj.transform.position
			rotationGroup = #()
			for i = 1 to cubeArray.count do
			(
				if (intersects cubeArray[i] obj) then 
				(
					append rotationGroup cubeArray[i]
				)
			)
			rotationGroup.parent = obj
			tempObj = obj
		)
		--in coordsys local rotate selection (angleaxis 90 [0, 0 ,1]) --one-click rotation
	)	
	
)

Hey Erilaz,
I couldn’t get your game to work!

-- Error occurred in <handler>()
--  Frame:
--   spinnerTransform: [0,10,0]
--   Obj: $Circle09
--   rotationGroup: #($cube_7, $cube_8, $cube_9, $cube_16, $cube_17, $cube_18, $cube_25, $cube_26, $cube_27)
>> MAXScript Change Handler Exception: -- No ""rotate"" function for undefined <<


??

1 Reply
(@erilaz)
Joined: 11 months ago

Posts: 0

Hmm… odd. What version of max are you using? I’ve been coding and testing in 2009. I assume this happens when you click shuffle, or does it happen immediately?

Great work on the snake game, although i’m finding it a bit hard to control!

OK, Here’s MaxSnake. Lots of potential here for a killer game I think. I especially enjoyed:
[ul]
[li]The mouse interaction[/li][li]Having the segments follow in a chain-like fashion[/li][li]Having functions called “KillPill” and “EatPill” heh heh[/li][/ul]

-- Script:		MAXSnake!
 -- Author:		Dave Stewart
 -- Release:		0.5
 -- MaxVersion:	Tested on 8, will probably work on lower versions quite happily.
 -- Date:		June 6th 2007
 
 -- Description:	Use your mouse to play a variation on the classic Snake game!
 
 -- Instructions:The aim of teh game is to survive as long as possible, or shorten your
 --				body by eating power pills. If you accidentally bump a pill without 
 --				eating it your body gets longer. If you ru over your own body, your
 -- 				body gets longer. Have fun!
 
 -- To do:		Scoring, finish bumpy board (and animate it) probably tinker with gameplay, finish the bumpy course.
 
 clearListener()
 try (destroydialog roMAXSnake); catch(err)
 
 rollout roMAXSnake "MAXSnake!" width:160 height:40
 (
 	local arrSegs		= #()
 	local arrPills		= #()
 	local arrObjs		= #()
 	
 	local segCount		= 15
 	local timerInterval	= 10
 	local mouseObj
 	local createPills, eatPill, cleanup
 	
 	local isColliding	= false
 	local counter		= 0
 	local counterMax	= 20
 	
 	local boardSize		= 3000
 	local boardIsBumpy	= false
 	
 	local vptLayout		= viewport.getLayout()
 	
 	Timer tmr1 "Timer" pos:[8,40] width:24 height:24 interval:100
 	checkButton ckbTimer "Active" pos:[8,8] width:72 height:24 checked:true
 	button btnRestart "Restart" pos:[80,8] width:74 height:24
 	
 	fn planeLineIntersect planePoint planeNormal linePoint lineVector =
 		(
 		local lineVector	= normalize lineVector
 		local d1			= dot (planePoint - linePoint) planeNormal
 		local d2			= dot lineVector planeNormal
 		if abs d2 < 0.0000000754 then
 			(
 			if abs d1 > 0.0000000754 then 0 else -1
 			)
 		else(
 			linePoint + ( (d1/d2) * lineVector )
 			)
 		)
 
 	fn moveToSurface src trg =
 		( 
 		r1	= ray (src.pos + [0,0,10000]) [0,0,-1] 
 		r2	= intersectRay trg r1
 		z	= if r2 == undefined then 0 else r2.pos.z
 		src.pos.z = z
 		)
 	
 
 	fn getMousePos =
 		(
 		local p	= mouse.pos
 		local r	= mapScreenToWorldRay p
 		local p3 = planeLineIntersect [0,0,0] [0,0,1] r.pos r.dir
 		p3
 		)
 
 
 	function addSegment trgObj: col: =
 		(
 		-- create
 			local obj		= box()
 			if col == unsupplied do col = red
 			obj.wirecolor	= col
 			obj.pivot		= obj.center
 
 		-- store object
 			append arrSegs obj
 			
 		-- lookat
 			if trgObj == unsupplied do trgObj = arrSegs[arrSegs.count]
 			obj.target		= trgObj
 			obj
 		)
 
 	function removeSegment =
 		(
 		-- object
 			local obj = arrSegs[arrSegs.count]
 		-- create a dummy target, or else 2 nodes get deleted!
 			local d = dummy ishidden:true
 			obj.target = d
 		-- kill objects
 			delete obj
 			arrSegs.count = arrSegs.count - 1
 		)
 
 	function setup =
 		(
 		-- new scene
 			delete objects
 		
 		-- create target
 			mouseObj = point()
 			append arrObjs mouseObj
 			hide mouseObj
 
 		-- create objects
 			local obj, trgObj = mouseObj
 			for i = 1 to segCount do
 				(
 				trgObj		= addSegment trgObj:trgObj
 				trgObj.pos	= [0, -i * 30, 0]
 				)
 			arrSegs[1].wirecolor = black
 				
 		-- gameboard
 			local mat = standardmaterial name:"Gameboard"
 			local map = mat.diffuseMap = Bricks()
 			map.coords.V_Tiling = 2
 			map.coords.U_Tiling = 2
 			showtexturemap mat map on
 			
 			local p = plane width:boardSize length:boardSize pos:[0,0,-10] material:mat name:"Gameboard" wirecolor:black lengthsegs:30 widthsegs:30
 			
 			if boardIsBumpy == true do
 				(
 				p.lengthsegs	= 50
 				p.widthsegs		= 50
 				
 				addModifier p (NoiseModifier())
 				n				= p.modifiers[1]
 				n.strength		= [0,0,100]
 				n.scale			= 300
 				)
 			
 			
 			--converttopoly p
 			append arrObjs p
 			
 			when select $Gameboard changes do deselect $Gameboard
 				
 		-- camera
 			local c		= freecamera ishidden:true
 			c.pos		= [0,-300,200]
 			rotate c (angleaxis 70 [1,0,0])
 			c.fov		= 80
 			c.parent	= arrSegs[1]
 			append arrObjs c
 			--hide c
 			
 		-- lights
 			local l1	= omnilight pos: [-2000,2000,-100] multiplier:1.0 color:white ishidden:true
 			local l2	= omnilight pos: [2000,-2000,-100] multiplier:0.5 color:(color 150 150 255) ishidden:true
 			append arrObjs l1
 			append arrObjs l2
 			
 			local spot	= freespot pos: [0,-100,300] hotspot:50 falloff:120 ishidden:true
 			rotate spot (angleaxis 35 [1,0,0])
 			spot.parent	= arrSegs[1]
 			append arrObjs spot
 
 		-- viewports
 			viewport.setLayout #layout_3vl --#layout_2v
 			
 			viewport.activeViewport = 1
 			viewport.setType #view_top
 			viewport.SetRenderLevel #flat
 			viewport.setGridVisibility 1 false
 			
 			viewport.activeViewport = 2
 			viewport.setType #view_persp_user
 			viewport.setTM (matrix3 [0.713251,-0.532976,0.455204] [0.700909,0.54236,-0.463219] [0,0.649448,0.760406] [-24.3243,333.06,-4051.52])
 			viewport.SetRenderLevel #smoothhighlights
 			viewport.setGridVisibility 2 false
 			
 			viewport.activeViewport = 3
 			viewport.setType #view_camera
 			viewport.SetRenderLevel #smoothhighlights
 			viewport.setGridVisibility 3 false
 			
 			max tool zoomextents all
 			
 		-- new pill
 			createPills 10
 			
 		-- start
 			tmr1.active = false
 			ckbTimer.checked = tmr1.active = queryBox "Start game!?"
 		)
 		
 	function follow trg src strict:true =
 		(
 		local p		= trg.pos - src.pos
 		local np	= normalize p
 		local mp
 
 		local d		= distance [0,0,0] p
 		local fd	= src.height * 2
 
 		--format "%
" p
 		if d > fd do
 			(
 			if strict then
 				(
 				mp		= p - np * fd
 				--mp		= np * fd
 				src.pos	+= mp
 				)
 			else(
 				mp		= np * fd
 				src.pos	+= mp
 				)
 			)
 		)
 		
 	function animateObjects =
 		(
 		-- mouse
 			mouseObj.pos	= getMousePos()
 
 		-- move
 			follow mouseObj arrSegs[1] strict:false
 			--if boardIsBumpy == true do moveToSurface arrSegs[1] $Gameboard
 			for i = 1 to arrSegs.count - 1 do
 				(
 				local trgObj = arrSegs[i]
 				local srcObj = arrSegs[i + 1]
 				if isValidNode srcObj do
 					(
 					follow trgObj srcObj
 					if boardIsBumpy == true do moveToSurface srcObj $Gameboard
 					)
 				)
 				
 		)
 		
 	function killPill pill =
 		(
 		deleteItem arrPills (findItem arrPills pill)
 		delete pill
 		
 		)
 		
 	function eatPill pill =
 		(
 		removeSegment()
 		killPill pill
 		createPills 2
 		)
 		
 	function createPills n =
 		(
 		for i = 1 to n do
 			(
 			local s		= sphere()
 			local v		= boardSize * 0.4
 			s.pos		= random [-v, -v, 0] [v, v, 0]
 			s.wirecolor	= white
 			append arrPills s
 			if boardIsBumpy == true do
 				(
 				moveToSurface s $Gameboard
 				s.pos.z += s.radius
 				)
 			)
 		)
 		
 	function checkPills =
 		(
 		local endLoop = false
 		
 		for pill in arrPills do
 			(
 			-- eat!
 				if intersects pill arrSegs[1] do
 					(
 					eatPill pill
 					exit
 					)
 				
 			-- hit!
 				for i = 2 to arrSegs.count do
 					(
 					if intersects arrSegs[i] pill do
 						(
 						addSegment col:orange
 						addSegment col:orange
 						killPill pill
 						createPills 2
 						endLoop = true
 						exit
 						)
 					/*
 					*/
 					)
 			if endLoop do exit
 			)
 		)
 		
 	function checkReinstateCollisions =
 		(
 		if isColliding == true do
 			(
 			counter += 1
 			if counter == counterMax do
 				(
 				isColliding = false
 				counter = 0
 				)
 			)
 		)
 		
 	function checkCollisions =
 		(
 		local n = 1
 		for i = 1 to arrSegs.count do
 			(
 			for j = n to arrSegs.count do
 				(
 				--format "% % %
" i j n
 				if i == j do continue
 				if (distance arrSegs[i] arrSegs[j]) < arrSegs[i].width do
 					(
 					addSegment col:yellow
 					addSegment col:yellow
 					--print arrSegs[i]
 					--print arrSegs[j]
 					isColliding = true
 					exit
 					)
 				if isColliding do exit
 				)
 			if isColliding do exit
 			n += 1
 			)
 		)
 		
 	function checkBounds =
 		(
 		/*
 		*/
 		local p = arrSegs[1].pos
 		if p.x > $gameboard.max.x OR p.x < $gameboard.min.x OR p.y > $gameboard.max.y OR p.y < $gameboard.min.y do
 			(
 			messagebox "You went out of bounds!"
 			cleanup()
 			setup()
 			)
 		)
 		
 	function checkSegs =
 		(
 		if arrSegs.count == 1 do
 			(
 			messagebox "Well done! You ate enough pills!"
 			cleanup()
 			setup()
 			)
 		)
 		
 	function cleanup = 
 		(
 		tmr1.active = false
 		delete mouseObj
 		for seg in arrSegs do
 			(
 			try(delete seg);catch(err)
 			)
 		for pill in arrPills do
 			(
 			try(delete pill);catch(err)
 			)
 		for obj in arrObjs do
 			(
 			try(delete obj);catch(err)
 			)
 			
 		arrSegs		= #()
 		arrPills	= #()
 		arrObjs		= #()
 		
 		SetUIColor 41 (GetDefaultUIColor 41)
 
 		)
 	
 	
 	
 	
 	on roMAXSnake open	do
 		(
 		SetUIColor 41 [0,0,0]
 		colorMan.repaintUI #repaintAll
 		setup()
 		)
 	on roMAXSnake close do
 		(
 		cleanup()
 		colorMan.repaintUI #repaintAll
 		viewport.setLayout vptLayout
 		)
 		
 	on ckbTimer changed state do tmr1.active = state
 	on tmr1 tick do
 		(
 		animateObjects()
 		checkPills()
 		checkCollisions()
 		checkReinstateCollisions()
 		checkBounds()
 		checkSegs()
 		)
 	on btnRestart pressed do
 		(
 		cleanup()
 		setup()
 		)
 )
 
 createdialog roMAXSnake
 

rubik’s cube works here in 2009 as well; cute
One thing you may wish to consider is the transform locks, so that a given ‘twist’ control can only rotate around its appropriate axis

Hey Martin,
Not happy in max 9, but happy in 2008!

It would be great if you would animate the turns, using a timer. The flick is a bit sudden for me.

Glad you like the snake game, and yes, it can be a bit hard to control!

The trick is to put your mouse on the spot on the board you want to travel to (in any viewport) as it’s projecting a ray there, then I’m doing some trig to get the direction.

Great challenge, I’m glad I could take part this time

ok, i discided to write a space invaders game for max. works in max 2008
few bugs in it:
*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

 
--Classic space invaders in 3d max
--Creator: Geoffrey Samuel
--Contact E-mail: Geoff@GeoffSamuel.com
--Contact Website: [www.GeoffSamuel.com]( http://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,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,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()
 
)
)
 
 
 
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()
)
)
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
)
function MakerolloutFloat = 
(
global batchFloater = newRolloutFloater "space invaders" 220 109
addRollout Batch_Converter batchFloater rolledup:false
)
MakerolloutFloat()
 
 
 

references:

  • the maxscript reference
  • The collion detection theroy from a post here on CGSociety

Excellent work Geoff! That’s loads of fun

Page 2 / 3