Difference between revisions of "Maya Tetris"
Jump to navigation
Jump to search
(→wip) |
(No difference)
|
Latest revision as of 15:14, 8 September 2016
wip
proc string createText(string $string){
//creates a text object and merges it into a single shape
//returns object name
$textGrp = `group -n $string -em`;
string $textObj[] = `textCurves -t $string`;
delete $textObj[1];
string $subObjs[] = `listRelatives $textObj[0]`;
makeIdentity -a 1 $subObjs;
string $subShapes[] = `listRelatives $subObjs`;
$subShapes = `listRelatives -s $subShapes`;
parent -s -r $subShapes $textGrp;
delete $textObj[0];
return $textGrp;
}
proc string instanceCounter(int $digits){
//creates an updatable text counter using a particle + instance system, requires createText()
//returns particle system
$numbers = {"-","0","1","2","3","4","5","6","7","8","9"};
string $numberObj[]={};
string $objlist = "";
$textGrp = `group -em -n "digits_and_particleSystem"`;
setAttr($textGrp+".visibility") 0;
for($n in $numbers){
$object = createText($n);
parent $object $textGrp;
$objlist += " -object "+$object;
}
$pSystem = "particle";
for($i=0;$i<$digits;$i++){
$pSystem += " -p "+$i+" 0 0";
}
string $pobj[] = eval($pSystem);
addAttr -ln "index" -dt doubleArray $pobj[1];
string $instancerEval = "particleInstancer -addObject "+$objlist+" -cycle None -cycleStep 1 -cycleStepUnits Frames -levelOfDetail Geometry -rotationUnits Degrees -rotationOrder XYZ -n digitscounter -position worldPosition -age age -objectIndex index -visibility index "+$pobj[1];
string $particleInstanc = eval($instancerEval);
parent $pobj[0] $textGrp;
return $pobj[1];
}
proc updateCounter(string $particleShape,int $number, int $numberOfDigits){
//updates a counter created using instanceCounter()
$strN = string($number);
$strS = size($strN);
for($j = 0;$j<$numberOfDigits;$j++){
if($j<$strS){
$n = substring($strN,$strS-$j,$strS-$j);
particle -e -at "index" -id ($numberOfDigits-$j-1) -fv (float($n)+1) $particleShape;
}else{
particle -e -at "index" -id ($numberOfDigits-$j-1) -fv 0 $particleShape;
}
}
}
proc setCubeColor(string $cube){
// give a polygon cube random-ish colors on each face
constructionHistory -tgl off;
string $shapes[] = `listRelatives -s $cube`;
setAttr($shapes[0]+".displayColors") 1;
float $hue = rand(0,1);
for($i=0;$i<6;$i++){
float $hue2 = rand(-.07,.07);
$hue = (abs($hue2 + $hue))%1;
float $sat = rand(.6,.8);
float $value = rand(.6,.8);
float $color[] = `hsv_to_rgb <<$hue,$sat,$value>>`;
polyColorPerVertex -nun -rgb $color[0] $color[1] $color[2] ($cube+".f["+$i+"]");
}
constructionHistory -tgl on;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
proc setupTetrisControls(){
// set ups a bunch of objects that are parented in a way you can use the keyboard arrows ('pickwalk' function - eww) to travel through them
// a scriptjob will alway select the center 'neutral' object, like a joystick coming back to the center position
// object names will be hardcoded because I code like a monkey
if(`objExists "TetrisGroup"`) delete "TetrisGroup";
$nullGrp = `group -n "TetrisGroup" -em`;
$top = `spaceLocator -n "topCtrl"`;
setAttr($top[0]+".visibility",0);
spaceLocator -n "leftCtrl";
spaceLocator -n "rightCtrl";
spaceLocator -n "neutralCtrl";
parent "leftCtrl" "topCtrl";
parent "neutralCtrl" "topCtrl";
parent "rightCtrl" "topCtrl";
rename "neutralCtrlShape" "bottomCtrl";
$testObject = `polyCylinder -n "TestObject"`;
string $deleteCtrl = createText("delete");
$nullDeleteGrp = `group -n "DeleteGroup" -em`;
parent $nullDeleteGrp $nullGrp;
parent $deleteCtrl $nullDeleteGrp;
rename $deleteCtrl "deleteCtrl";
parent $top $nullGrp;
}
// global variables
global int $jobCtrl; // id of the scriptjob that will always select the neutral control defined by setupTetrisControls() - launches the ctrls() function
global int $jobLoop; // id of the scriptjob that will launch the loop() function
global float $startTime;
global float $previousSecond;
$startTime = `timerX`;
$previousSecond = `timerX -startTime $startTime`;
proc ctrls(){
// fires on any object selection in the scene, if it finds one of our control objects is selected, selects neutral one
// also kills scriptjobs if it finds
global int $jobCtrl;
global int $jobLoop;
global float $startTime;
global float $previousSecond;
string $sel[] = `ls -sl`;
select -r "neutralCtrl";
if($sel[0]=="deleteCtrl"){
evalDeferred("scriptJob -kill "+$jobCtrl+" -force");
scriptJob -kill $jobLoop -force;
delete "TetrisGroup";
//delete "deleteCtrl";
//delete "TestObject";
}else{
$c = $sel[0];
if($c=="topCtrl"){
setAttr("TestObject.rz") ((getAttr("TestObject.rz")+90)%360);
}
if($c=="leftCtrl"){
setAttr("TestObject.tx") (getAttr("TestObject.tx")-1);
}
if($c=="rightCtrl"){
setAttr("TestObject.tx") (getAttr("TestObject.tx")+1);
}
if($c=="bottomCtrl"){
$elapsedTime = `timerX -startTime $startTime`;
$previousSecond = $elapsedTime-1;
}
}
}
proc startTetris(){
//sets up ctrls, UI, game elements, and launches scriptjobs that actually start the game
global int $jobCtrl;
global int $jobLoop;
setupTetrisControls;
// actual script jobs
// one controls what happens on selection change
// the other one is the 'iterator', which controls the speed of the game
$jobCtrl = `scriptJob -e "SelectionChanged" "ctrls()" -protected`;
print $jobCtrl;
$jobLoop = `scriptJob -ie "loop(.2)" -protected`;
}
proc loop(float $speed){
//function that fires at every n millisecond, updates game
global float $startTime;
global float $previousSecond;
$elapsedTime = `timerX -startTime $startTime`;
if( ($previousSecond + $speed ) < $elapsedTime){
//print ("Total Time: "+$elapsedTime+"\n");
setAttr("TestObject.ty") ((getAttr("TestObject.ty")-1)%10);
testStuff();
//setAttr -type "string" annotationShape1.text $elapsedTime;
$previousSecond = $elapsedTime;
}else{
//empty cycle
//print($previousSecond+" "+$elapsedTime+"\n");
}
}
proc testStuff(){
for($i = 0;$i<50;$i++){
particle -e -at "index" -id (floor(rand(0,50))) -fv (floor(rand(0,8))) "particleShape1";
}
currentTime (`currentTime -q`);
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
setUpTetrisGrid(10,5);
proc setUpTetrisGrid(int $rows, int $cols){
// create particle system with an 'index' pp attr
string $p = "particle -n TetrisGridParticles";
global int $rows;
global int $cols;
global float $grid[];
float $pscale = 1.5;
for($i=0;$i<$rows;$i++){
for($j=0;$j<$cols;$j++){
$p+= "-p 0 "+($i*$pscale+$pscale/2)+" "+($j-$cols/2)*$pscale+ " ";
}
}
string $pSystem[] = eval($p);
setAttr ($pSystem[1]+".particleRenderType") 6; //streak mode no velocity = no streaks, I could hide particles too
addAttr -ln "index" -dt doubleArray $pSystem[1];
// create colored cubes to be instanced in particle system
string $objList = "";
for($i=0;$i<9;$i++){
string $pCube[] = `polyCube -w ($pscale*.98) -h ($pscale*.98) -d ($pscale*.98) -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 0`;
$objList += "-object \""+$pCube[0]+"\" ";
setCubeColor($pCube[0]);
setAttr($pCube[0]+".visibility") 0;
}
// create an instancer using the previous objects. '0' will be useless as it also maps visibility
string $particleInstanc = eval("particleInstancer -addObject "+$objList+"-cycle None -cycleStep 1 -cycleStepUnits Frames -levelOfDetail Geometry -rotationUnits Degrees -rotationOrder XYZ -position worldPosition -age age -objectIndex index -visibility index "+$pSystem[1]);
}
// available pieces in a big 7 * 4*4 array
global int $pieces[];
$pieces = {
0, 1, 0, 0, // #
0, 1, 0, 0, // #
0, 1, 0, 0, // #
0, 1, 0, 0, // #
0, 0, 0, 0, //
0, 1, 0, 0, // #
1, 1, 1, 0, // ###
0, 0, 0, 0, //
0, 0, 1, 0, // #
0, 0, 1, 0, // #
0, 1, 1, 0, // ##
0, 0, 0, 0, //
0, 1, 0, 0, // #
0, 1, 0, 0, // #
0, 1, 1, 0, // ##
0, 0, 0, 0, //
0, 0, 0, 0, //
0, 1, 1, 0, // ##
0, 1, 1, 0, // ##
0, 0, 0, 0, //
0, 0, 0, 0, //
0, 0, 1, 1, // ##
0, 1, 1, 0, // ##
0, 0, 0, 0, //
0, 0, 0, 0, //
0, 1, 1, 0, // ##
0, 0, 1, 1, // ##
0, 0, 0, 0 //
};
//return a random piece as 4*4 (16) array
proc int[] randomPiece(){
global int $pieces[];
$p = $pieces;
int $r = rand(7);
$r = $r * 16;
int $returnPiece[] = {
0, $p[$r+1 ], $p[$r+2 ], 0,
0, $p[$r+5 ], $p[$r+6 ], $p[$r+7 ],
$p[$r+8], $p[$r+9 ], $p[$r+10], $p[$r+11],
0, $p[$r+13], 0 , 0
};
return $returnPiece;
}
//print current piece to script editor
proc printPiece(int $p[]){
print("\n");
for($i=0;$i<4;$i++){
for($j=0;$j<4;$j++){
//print($i*4+$j);
print(($p[$i*4+$j]==1)?"#":".");
}
print("\n");
}
}
//rotate a 4*4 piece around its center:
//
// a b c d m i e a
// e f g h -> n j f b
// i j k l -> o k g c
// m n o p p l h d
//
proc int[] rotatePiece(int $p[]){
int $rotatedPiece[] = {$p[12],$p[8],$p[4],$p[0],$p[13],$p[9],$p[5],$p[1],$p[14],$p[10],$p[6],$p[2],$p[15],$p[11],$p[7],$p[3]}; //if 4x4 -> x=y, y=-x+3, clockwise rotation of matrix
return $rotatedPiece;
}
// int $pp[] = randomPiece();
// printPiece($pp);
// printPiece(rotatePiece(rotatePiece($pp)));
proc updateInstanceIndexesFromArray(string $particleShape,float $gridArray[]){
global int $rows;
global int $cols;
global float $grid[];
for($j = 0;$j<$rows;$j++){
for($i = 0;$i<$cols;$i++){
int $id = $j*$cols+$i;
particle -e -at "index" -id $id -fv ($grid[$id]) $particleShape;
}
}
currentTime (`currentTime -q`);
}
$grid = {};
$counter = -1;
$rows = 10;
$cols = 5;
for($i = 0;$i<$rows;$i++){
for($j = 0;$j<$cols;$j++){
$counter = $counter+1;
//$grid[$j*$cols+$i] = $counter+1+$i%2;
$grid[$counter] = $i%2*($i%3+1);
print($counter+1+$j%2+"\n");
}
}
updateInstanceIndexesFromArray("TetrisGridParticlesShape",$grid);