PDA

View Full Version : CgTalk Maxscript Challenge 019: "Fun and Games"


erilaz
04-09-2008, 11:58 PM
CgTalk Maxscript Challenge 019: "Fun and Games"

DESCRIPTION: Write a simple game with maxscript, either in the viewport or in a window.

DEADLINE: 10/06/2008

RULES:



Do NOT post your code until the deadline!
Code from scratch. Try not to use pre-exisitng functions or plugins.
Show your script references, if any (eg. Looking at another script to assist you).
You are encouraged to ask for help where needed, but try to do it on your own. The maxscript reference is an invaluable resource.
Post your final script inside [CODE] tags (located on your posting toolbar).
Post all code into THIS thread.
Post the max version you coded in, plus any maxscript extensions you used. (Thanks galagast!)
Try to finish the challenge in the proscribed time. There is no definite time limit.
NOTES: Designing and programming games present useful challenges that you will see in day to day scripting. Plus it's also fun to have something other than a tool running in 3ds Max. :)

Apologies for the long wait.

DaveWortley
04-11-2008, 09:37 AM
Oh i look forward to this! hehe, I think Jim Jagger made Pinball for max.

davestewart
05-04-2008, 03:01 PM
Awesome challenge!

Here's something I wrote last year, it took a good few hours, but definately under a day I think. Tested on max 8, will probably work in lower versions, no plugins used.



Use your mouse to play a variation on the classic arcade game 'Snake'!
The aim of the game is to shorten your body by eating power pills.
If you accidentally bump a pill with any part of your body except the head, your body gets longer.
If you run over your own body, your body gets longer.

http://www.keyframesandcode.com/resources/maxscript/Fun/MAXSnake/ui/MAXSnake.jpg

http://www.keyframesandcode.com/code/development/maxscript/maxsnake/

Lots of things I would like to add, but this'll do for now :)

Dave

dmak
05-06-2008, 10:36 PM
I've been waiting around for another maxscript challenge. This one looks like fun. Am new to game coding techniques so I'll probably make something real simple.

Dave, I just came across your site early off some google search and played your game. Very cool approach. A little more feedback when you do something right/wrong would be nice, but cool game none the less! Good work.

erilaz
05-06-2008, 11:40 PM
I've been waiting around for another maxscript challenge.

Yeah sorry. :blush:

Been really busy of late. Brain space has been small.

davestewart
05-07-2008, 11:18 AM
Hey Dan,
Thanks! Yup, always room for improvements. I really wanted to have the balls explode when you went through them, maybe with particles, maybe just geometry... but you have to draw the line somewhere! It really is too much fun :)

DaveWortley
05-07-2008, 01:18 PM
I'm designing a car racing game that doubles as an animation tool as it will record your movements. Not having much time to work on it though...

dmc900
05-25-2008, 12:06 PM
I'm designing a car racing game that doubles as an animation tool as it will record your movements. Not having much time to work on it though...

When I first checked out this thread about a week after it had posted I though of how awsome the concept of doing this in 3d max is!

I was achually thinking it would be great if someone could create a car rigging piece of max script where you could drive the car in real-time.

and after seeing your post I couldn't help but register and post here saying how amazing your idea is and how much I really want to see it and the idea of recording your movements is extremely amazing!

I'd love to be able to create a small map, add some opsticals and play it! Jumping over little rams and stuff, that'd be awsome!

If you or anyone else plans to create this please make me aware as I am so hyped up about this! This is something I'd love to play around with :)

I seriously hope it gets created! :)

dmc900
05-25-2008, 12:09 PM
Oh i look forward to this! hehe, I think Jim Jagger made Pinball for max.

sorry to, double post!
But since I haven't posted two validated posts, I cannot edit the last post I made!

anyways, I'm wondering if anyone has any links to that "3dmax" pinball game and any other games that you can use(play) in 3d max!

DaveWortley
05-26-2008, 12:14 PM
I managed to get the fundamentals of the car game working, could drive the thing forward and turn, the physics weren't correct, hadn't got round to controlling the speed propperly or linking turning with speed. But I have written the code before for an actionscript game in Flash.

Early tests suggest that if you were only driving the car on a flat course then you could get some nice realistic handling going and have autokey running and record your movements.

I'm sure someone else has done it before though, I was just seeing if I could do it.

dmc900
05-26-2008, 12:27 PM
I managed to get the fundamentals of the car game working, could drive the thing forward and turn, the physics weren't correct, hadn't got round to controlling the speed propperly or linking turning with speed. But I have written the code before for an actionscript game in Flash.

Early tests suggest that if you were only driving the car on a flat course then you could get some nice realistic handling going and have autokey running and record your movements.

I'm sure someone else has done it before though, I was just seeing if I could do it.

I haven't seen it done before, however I have seen car rigging plugins such as Newplugins Vehicle Studio and the demo was preety good but you cannot control the car in real time and record your movments, it all worked a little like reactor so you cannot see what's happening until you process everything (which is fairly annoying).

Do you have any working maxscript code, I've love to try it out! :cool:

erilaz
05-26-2008, 01:05 PM
I should have my pointless game up next week if I can work out how to dynamically shift parenting in a when construct (http://forums.cgsociety.org/showthread.php?f=98&t=635509).:argh:

erilaz
05-27-2008, 02:42 PM
I'm pretty much done. I'll wait until the deadline next week to post my code.:D

erilaz
06-02-2008, 11:38 PM
A week to go!

Just out of interest, who is actually working on something? I've got three different ones in the works right now. :D

decapitator
06-03-2008, 07:02 AM
...
I was achually thinking it would be great if someone could create a car rigging piece of max script where you could drive the car in real-time.

...

If you or anyone else plans to create this please make me aware as I am so hyped up about this! This is something I'd love to play around with :)

I seriously hope it gets created! :)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 :).

dmc900
06-03-2008, 09:27 AM
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 :).

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 :)

erilaz
06-10-2008, 04:35 AM
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

MatanH
06-10-2008, 06:18 AM
erilaz - Thanks for the tip :thumbsup:

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\n"
)
)
)
)

-- [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\n"
)
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\n"
)
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\n"
)
)
)
)
)

-- [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\n"
)
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\n"
)
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\n"
)
)

-- [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\n"
)
)
)
)

-- [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\n"
)
)
)

-- [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\n"
)
)
)

-- 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://www.wikihow.com/Win-at-Tic-Tac-Toe

Thanks to PEN and ZeBoxx2 for their help!

Cheers, Matan.

erilaz
06-10-2008, 09:51 AM
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
)

)

davestewart
06-10-2008, 10:50 AM
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 <<




??

davestewart
06-10-2008, 10:51 AM
OK, Here's MaxSnake. Lots of potential here for a killer game I think. I especially enjoyed:

The mouse interaction
Having the segments follow in a chain-like fashion
Having functions called "KillPill" and "EatPill" heh heh

-- 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 "%\n" 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 "% % %\n" 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

erilaz
06-10-2008, 01:15 PM
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 <<




??

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! :D

ZeBoxx2
06-10-2008, 01:58 PM
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

davestewart
06-10-2008, 02:38 PM
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 :)

jifman
06-10-2008, 03:51 PM
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

davestewart
06-10-2008, 04:47 PM
Excellent work Geoff! That's loads of fun :)

erilaz
06-10-2008, 06:59 PM
Thanks for the comments guys! Glad to see I wasn't going insane and it's a an earlier version of max. I could probably fix it to be compatible.

As for transform locks, I had considered it, as well as doing the 90-degree spin rather than just a shift, but time and inclination got in the way. :P

I've actually made two more games, but i'm still tweaking them. Once still crashes max right now.:D

davestewart
06-10-2008, 08:19 PM
One still crashes max right now.:D

The "Work Out Why Max Is Continually Crashing" Game.

I love it!! Did it take you long to write? LOL ;)

erilaz
06-10-2008, 11:48 PM
The "Work Out Why Max Is Continually Crashing" Game.

I love it!! Did it take you long to write? LOL ;)

Considering how much it crashed, a heck of a long time! :D

CGTalk Moderation
06-10-2008, 11:48 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.