00001 import javax.microedition.lcdui.*;
00002 import javax.microedition.m3g.*;
00003 import java.util.*;
00004
00005
00009 public class TicTacCanvas extends Canvas {
00010
00012 private Graphics3D graphics3d;
00014 private Camera camera;
00016 private Light light;
00017
00019 private float angle = 0.0f;
00021 private float angleIcon = 0.0f;
00022
00024 private Background background = new Background();
00025
00027 private Mesh mTorus=null;
00028 private Mesh mCross=null;
00029 private Mesh mPlateau=null;
00030 private Mesh mSelect=null;
00031
00033 CompositingMode compModeAlpha=new CompositingMode();
00034 CompositingMode compModeOpaque=new CompositingMode();
00035
00037 Transform camTransform = new Transform();
00038 Transform viewTransform = new Transform();
00039 Transform caseTransform = new Transform();
00040 Transform tmpTransform = new Transform();
00041
00042
00044 private int plateau[][][];
00045
00047 private int curZ=0;
00048 private int curZTrans=0;
00049
00051 private int curX=0;
00052 private int curXTrans=0;
00053
00055 private int curY=0;
00056 private int curYTrans=0;
00057
00058
00060 private int playerNum=0;
00061
00063 TicTacCom com;
00064
00066 TicTacMain main;
00067
00069 boolean waitToPlay=false;
00070
00072 boolean victory=false;
00074 boolean defeat=false;
00076 boolean nullMatch=false;
00078 private int nbCoups=0;
00080 private int maxCoups=27;
00081
00082
00089 public TicTacCanvas(TicTacMain m, int pn, TicTacCom c) {
00090 playerNum=pn;
00091 com=c;
00092 main=m;
00093
00094
00095 setCommandListener(new CommandListener() {
00096 public void commandAction(Command c, Displayable d) {
00097 if (c.getCommandType() == Command.EXIT)
00098 TicTacMain.quitApp();
00099 else if(c.getCommandType() == Command.ITEM)
00100 main.restartApp();
00101
00102 }
00103
00104 });
00105
00106 try { init();}
00107 catch(Exception e) { e.printStackTrace();}
00108 }
00109
00110
00117 private void init() throws Exception {
00118
00120 addCommand(new Command("Exit", Command.EXIT, 1));
00121 addCommand(new Command("Restart", Command.ITEM, 1));
00122
00123 graphics3d = Graphics3D.getInstance();
00124
00125 camera = new Camera();
00126 camera.setPerspective( 60.0f,
00127 (float)getWidth()/ (float)getHeight(),
00128 1.0f,
00129 1000.0f );
00130
00131 light = new Light();
00132 light.setColor(0xffffff);
00133 light.setIntensity(1.25f);
00134
00135
00136
00137
00138 background.setColor(0xDDEEDD);
00139
00140 Object3D roots[]=Loader.load("/TicTac7.m3g");
00141 Group tGroup=(Group)roots[0];
00142
00143 for(int i=0; i<tGroup.getChildCount(); i++)
00144 if(tGroup.getChild(i).getUserID()==100){
00145 mTorus=(Mesh)tGroup.getChild(i);
00146 }else if(tGroup.getChild(i).getUserID()==101){
00147 mCross=(Mesh)tGroup.getChild(i);
00148 }else if(tGroup.getChild(i).getUserID()==102){
00149 mPlateau=(Mesh)tGroup.getChild(i);
00150 }else if(tGroup.getChild(i).getUserID()==103){
00151 mSelect=(Mesh)tGroup.getChild(i);
00152 }
00153
00154 mTorus.setAlphaFactor(0.3f);
00155 mCross.setAlphaFactor(0.3f);
00156 compModeAlpha.setBlending(CompositingMode.ALPHA);
00157
00158 compModeOpaque.setBlending(CompositingMode.REPLACE);
00159
00160
00161 plateau=new int[3][3][3];
00162
00163
00164 if(playerNum==1)
00165 waitToPlay=false;
00166 else{
00167 waitToPlay=true;
00168 com.receive();
00169 }
00170
00171
00172 camTransform.postTranslate(0.0f, 0.0f, 30.0f);
00173 graphics3d.setCamera(camera, camTransform);
00174
00175
00176 graphics3d.resetLights();
00177 graphics3d.addLight(light, camTransform);
00178
00179 }
00180
00185 protected void drawTorus(Transform transform){
00186 tmpTransform.set(transform);
00187 tmpTransform.postRotate(90.0f, 1.0f, 0.0f, 0.0f);
00188 graphics3d.render(mTorus, tmpTransform);
00189 }
00190
00195 protected void drawCross(Transform transform){
00196 tmpTransform.set(transform);
00197 tmpTransform.postRotate(45.0f, 0.0f, 1.0f, 0.0f);
00198 graphics3d.render(mCross, tmpTransform);
00199 }
00200
00205 protected void drawSelect(Transform transform){
00206 tmpTransform.set(transform);
00207 tmpTransform.postScale(0.9f, 0.9f, 0.9f);
00208 graphics3d.render(mSelect, tmpTransform);
00209 }
00210
00217 protected void paint(Graphics g) {
00218 graphics3d.bindTarget(g, true,
00219 Graphics3D.DITHER |
00220 Graphics3D.TRUE_COLOR);
00221 graphics3d.clear(background);
00222
00223
00224 if(waitToPlay && com.newReceivedData){
00225 int []t=com.getReceivedData();
00226 plateau[t[1]][t[2]][t[3]]=t[0];
00227 nbCoups++;
00228
00229
00230 waitToPlay=false;
00231
00232 if(gagne(t[0], t[1], t[2], t[3])){
00233 defeat=true;
00234 waitToPlay=true;
00235 }else if(nbCoups==maxCoups)
00236 nullMatch=true;
00237 }
00238
00239
00240 if(curZTrans < curZ*10)
00241 curZTrans+=1;
00242 else if(curZTrans > curZ*10)
00243 curZTrans-=1;
00244
00245 if(curXTrans < curX*10)
00246 curXTrans+=1;
00247 else if(curXTrans > curX*10)
00248 curXTrans-=1;
00249
00250
00251
00252 if(!waitToPlay)
00253 angleIcon+=5.0f;
00254
00255 tmpTransform.setIdentity();
00256 tmpTransform.postTranslate(11.0f, 15.0f, -0.01f);
00257 tmpTransform.postScale(0.1f, 0.1f, 0.1f);
00258 tmpTransform.postRotate(angleIcon, 1.0f, 1.0f, 1.0f );
00259
00260 if( playerNum==1){
00261 mTorus.getAppearance(0).setCompositingMode(compModeOpaque);
00262 drawTorus(tmpTransform);
00263 }else if( playerNum==2){
00264 mCross.getAppearance(0).setCompositingMode(compModeOpaque);
00265 drawCross(tmpTransform);
00266 }
00267
00268
00269
00270
00271 angle += 1.0f;
00272 viewTransform.setIdentity();
00273 viewTransform.postTranslate(0.0f, 0.0f, -200.0f);
00274 viewTransform.postRotate((curZTrans*1.80f)+10.0f, 1.0f, 0.0f, 0.0f);
00275 viewTransform.postRotate(( (20-curXTrans)*2.0f)-20.0f, 0.0f, 1.0f, 0.0f);
00276
00277
00278 for(int j=0; j<3; j++)
00279 for(int k=0; k<3; k++)
00280 for(int i=0; i<3; i++){
00281 caseTransform.set(viewTransform);
00282 caseTransform.postTranslate( (i-1)*60.0f, (k-1)*50.0f, (j-1)*60.0f );
00283 if(k==curZ){
00284 caseTransform.postScale(1.3f, 1.3f, 1.3f);
00285 mTorus.getAppearance(0).setCompositingMode(compModeOpaque);
00286 mCross.getAppearance(0).setCompositingMode(compModeOpaque);
00287 }else{
00288 caseTransform.postScale(1.2f, 1.2f, 1.2f);
00289 mTorus.getAppearance(0).setCompositingMode(compModeAlpha);
00290 mCross.getAppearance(0).setCompositingMode(compModeAlpha);
00291 }
00292
00293 if( plateau[i][j][k]==1)
00294 drawTorus(caseTransform);
00295 else if( plateau[i][j][k]==2)
00296 drawCross(caseTransform);
00297
00298 if(i==curX && j==curY && k==curZ)
00299 drawSelect(caseTransform);
00300
00301 }
00302
00303
00304
00305 graphics3d.render(mPlateau, viewTransform);
00306 graphics3d.releaseTarget();
00307
00308
00309 if(waitToPlay && !com.newReceivedData){
00310 g.setColor(0xFF6611);
00311 g.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE ));
00312
00313 g.drawString("L'autre joueur joue...", getWidth()/2, getHeight()/2 - 10,
00314 Graphics.HCENTER | Graphics.BASELINE);
00315 }else if(victory){
00316 g.setColor(0xFF1111);
00317 g.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE ));
00318
00319 g.drawString("Victoire !!! :-)", getWidth()/2, getHeight()/2 - 10,
00320 Graphics.HCENTER | Graphics.BASELINE);
00321 }else if(defeat){
00322 g.setColor(0xFF1111);
00323 g.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE ));
00324
00325 g.drawString("Perdu ! :-(", getWidth()/2, getHeight()/2 - 10,
00326 Graphics.HCENTER | Graphics.BASELINE);
00327 }else if(nullMatch){
00328 g.setColor(0xFF1111);
00329 g.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE ));
00330
00331 g.drawString("Match nul !", getWidth()/2, getHeight()/2 - 10,
00332 Graphics.HCENTER | Graphics.BASELINE);
00333 }
00334
00335 }
00336
00341 protected void keyPressed(int keyCode) {
00342 if(!waitToPlay && !victory && !defeat && !nullMatch)
00343 switch(this.getGameAction(keyCode)) {
00344
00345
00346 case Canvas.GAME_C :
00347 if(curZ<2)
00348 curZ++;
00349 break;
00350 case Canvas.GAME_A :
00351 if(curZ>0)
00352 curZ--;
00353 break;
00354
00355 case Canvas.RIGHT :
00356 if(curX<2)
00357 curX++;
00358 break;
00359 case Canvas.LEFT :
00360 if(curX>0)
00361 curX--;
00362 break;
00363
00364
00365 case Canvas.UP :
00366 if(curY<2)
00367 curY++;
00368 break;
00369 case Canvas.DOWN :
00370 if(curY>0)
00371 curY--;
00372 break;
00373
00374 case Canvas.FIRE:
00375 if(plateau[curX][curY][curZ]==0){
00376 plateau[curX][curY][curZ]=playerNum;
00377 nbCoups++;
00378
00379 repaint();
00380
00381 com.send(playerNum, curX, curY, curZ);
00382
00383 if(gagne(playerNum, curX, curY, curZ))
00384 victory=true;
00385 else if(nbCoups==maxCoups)
00386 nullMatch=true;
00387 else
00388 com.receive();
00389
00390 waitToPlay=true;
00391 }
00392
00393 break;
00394
00395 }
00396
00397 }
00398
00399
00407 int getCase(int x, int y, int z){
00408 if(x<0 || y<0 || z<0 || x>2 || y>2 || z>2)
00409 return 0;
00410 else
00411 return plateau[x][y][z];
00412 }
00413
00422 boolean gagne(int p, int x, int y, int z){
00423 for(int i=-1; i<2; i++)
00424 for(int j=-1; j<2; j++)
00425 for(int k=-1; k<2; k++)
00426 if( !(i==0 && j==0 && k==0) ){
00427 if( (getCase(x+i, y+j, z+k)==p) && ( (getCase(x+i*2, y+j*2, z+k*2)==p) || (getCase(x-i, y-j, z-k)==p) ) ){
00428 return true;
00429 }
00430 }
00431
00432
00433 return false;
00434
00435 }
00436 }