package ddddbb.game; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Vector; import ddddbb.comb.DLocation; import ddddbb.comb.DOp; import ddddbb.comb.DSignedAxis; import ddddbb.game.Settings.GameStatus; import ddddbb.gen.SelArray; import ddddbb.gui.ViewScreen; import ddddbb.math.Camera4dParallel; import ddddbb.math.D4Tupel; import ddddbb.math.Point; import ddddbb.math.Point2d; import ddddbb.math.Point4d; import ddddbb.sound.SoundEnum; public class Level extends Scene4d { public final SelArray<GameStatus> gameStatus; // public Vector<Facet> allFacets = new Vector<Facet>(); public String name; public Compound goal; public ViewScreen viewScreen; public D4Tupel cursor = new D4Tupel(0,0,0,0); //public BoolModel showGoal; public Level(final Settings ss) { super(ss); gameStatus = ss.gameStatus; } private void propagateGameStatus() { if (goal == null) { gameStatus.setSel(Settings.GameStatus.NONE); return; } if (compounds.size() == 1) { if (DOp.motionEqual(goal.locations,compounds.sel().locations)) { gameStatus.setSel(Settings.GameStatus.REACHED); } else { gameStatus.setSel(Settings.GameStatus.MISSED); } return; } if (!DOp.motionContained(compounds.sel().locations,goal.locations)) { gameStatus.setSel(Settings.GameStatus.MISSED); return; } if (gameStatus.sel() != Settings.GameStatus.PENDING ) { gameStatus.setSel(Settings.GameStatus.PENDING); } } private void setGoal(int[][] c) { goal = new Compound(c); } public void changeObjective(Objective objective) { setGoal(objective.goal); setCompounds(objective.compounds); propagateGameStatus(); } // public Compound getSelected() { // return (Compound)compounds.getSelectedObject(); // } // public boolean move(D4Tupel t) { // return move(t.x1,t.x2,t.x3,t.x4); // } public boolean transSelected(DSignedAxis v) { if ( compounds.selInt() == -1 ) { return false; } Compound compound = compounds.sel(); compound.translate(v); if (isOverlapping()) { compound.translate(new DSignedAxis(-v.human())); SoundEnum.BARRINGCOMPOUND.play(); return false; } compounds.changed(); SoundEnum.MOVINGCOMPOUND.play(); return true; } public ActionListener transSelectedA(final int direc) { return new ActionListener() { public void actionPerformed(ActionEvent e) { transSelected(new DSignedAxis(direc)); } }; } public boolean rotSelected(int v, int w) { if ( compounds.selInt() == -1 ) { return false; } Compound compound = compounds.sel(); compound.rotate(v,w); if (isOverlapping()) { compound.rotate(w,v); SoundEnum.BARRINGCOMPOUND.play(); return false; } if (camera4d instanceof Camera4dParallel) { //for other cases visibility is set in paint method //for programming lazyness set new visibility of *all* compounds updateFacing(); } compounds.changed(); SoundEnum.ROTATINGCOMPOUND.play(); return true; } public ActionListener rotSelectedA(final int a1, final int a2) { return new ActionListener() { public void actionPerformed(ActionEvent e) { rotSelected(a1-1, a2-1); } }; } private boolean isOverlapping() { int[][][] cs = new int[compounds.size()][][]; for (int i=0;i<cs.length;i++) { cs[i]=compounds.get(i).locations; } return DOp.intersecting(cs); } private Vector<Compound> combinables(Compound c0) { Vector<Compound> res = new Vector<Compound>(); for (Compound c : compounds) { if (c0!=c && DOp.d3adjacent(c.locations,c0.locations)) { res.add(c); } } return res; } private void combine(Compound c0,Vector<Compound> cs) { compounds.notify = false; c0.combine(cs); for (Compound c : cs) { compounds.remove(c); } c0.setBaryCenter(); updateFaces3d(compounds); updateFacing(); compounds.notify = true; } public void combine() { Compound c0 = compounds.sel(); Vector<Compound> bordering = combinables(c0); if ( compounds.size() != 1 && bordering.size() > 0 ) { combine(c0,bordering); SoundEnum.SNAPPINGCOMPOUNDS.play(); //the redraw from a normal changed() does not suffice, thats why we force it viewScreen.paint(viewScreen.getGraphics()); } propagateGameStatus(); } public ActionListener combineAction = new ActionListener() { public void actionPerformed(ActionEvent e) { combine(); } }; public static final Point4d[][] unitVector4d = new Point4d[][] { new Point4d[] { new Point4d(1,0,0,0), new Point4d(0,1,0,0), new Point4d(0,0,1,0), new Point4d(0,0,0,1) }, new Point4d[] { new Point4d( -1, 0, 0, 0 ), new Point4d( 0, -1, 0, 0 ), new Point4d( 0, 0, -1, 0 ), new Point4d( 0, 0, 0, -1 ) } }; public void BoundaryCuboid3d(Point a,Point b) { for (Compound c: compounds) for (DLocation v : c.getAllFaces()[0]) { for (int i=0;i<3;i++) { if ( v.p3.x[i] < a.x[i]) { a.x[i] = v.p3.x[i]; } if ( v.p3.x[i] > b.x[i]) { b.x[i] = v.p3.x[i]; } } } } public void BoundaryCuboid2d(Point2d a,Point2d b) { a.x1 = Double.MAX_VALUE; a.x2 = Double.MAX_VALUE; b.x1 = Double.MIN_VALUE; b.x2 = Double.MIN_VALUE; for (Compound c: compounds) for (DLocation v : c.getAllFaces()[0]) { if ( v.p2l.x1 < a.x1) { a.x1 = v.p2l.x1; } if ( v.p2l.x2 < a.x2) { a.x2 = v.p2l.x2; } if ( v.p2r.x1 < a.x1) { a.x1 = v.p2r.x1; } if ( v.p2r.x2 < a.x2) { a.x2 = v.p2r.x2; } if ( v.p2l.x1 > b.x1) { b.x1 = v.p2l.x1; } if ( v.p2l.x2 > b.x2) { b.x2 = v.p2l.x2; } if ( v.p2r.x1 > b.x1) { b.x1 = v.p2r.x1; } if ( v.p2r.x2 > b.x2) { b.x2 = v.p2r.x2; } } } public Objective asObjective() { int[][][] cmpnds = new int[compounds.size()][][]; for (int i=0;i<cmpnds.length;i++) { cmpnds[i] = compounds.get(i).locations; } return new Objective(ss.objectives.sel().name + " modified",goal.locations,cmpnds); } // public void paint(D3Graphics g3) { // if (showGoal.isSelected()) { // Vector<Compound> v = new Vector<Compound>(); // v.add(goal); // updateFaces3d(v); // paintScene(g3,v); // updateFaces3d(compounds); // } // else { paintScene(g3,compounds); } // } public void stateChanged() { changed(); } }