summaryrefslogtreecommitdiff
path: root/jeu-test/Lemmini/0.84/src/Game/Level.java
diff options
context:
space:
mode:
Diffstat (limited to 'jeu-test/Lemmini/0.84/src/Game/Level.java')
-rw-r--r--jeu-test/Lemmini/0.84/src/Game/Level.java346
1 files changed, 321 insertions, 25 deletions
diff --git a/jeu-test/Lemmini/0.84/src/Game/Level.java b/jeu-test/Lemmini/0.84/src/Game/Level.java
index 55e9cfb..977d965 100644
--- a/jeu-test/Lemmini/0.84/src/Game/Level.java
+++ b/jeu-test/Lemmini/0.84/src/Game/Level.java
@@ -461,6 +461,300 @@ public class Level {
return stencil;
}
+ public Stencil paintLevel(final BufferedImage bgImage, final Component cmp, final Stencil s , int choix) {
+ // flush all resources
+ sprObjFront = null;
+ sprObjBehind = null;
+ sprObjects = null;
+ entries = null;
+ System.gc();
+ // the screenBuffer should be big enough to hold the level
+ // returns stencil buffer;
+ int bgWidth = bgImage.getWidth();
+ int bgHeight = bgImage.getHeight();
+ // try to reuse old stencil
+ Stencil stencil;
+ if (s!= null && s.getWidth() == bgWidth && s.getHeight() == bgImage.getHeight()) {
+ s.clear();
+ stencil = s;
+ } else
+ stencil = new Stencil(bgWidth,bgImage.getHeight());
+ // paint terrain
+ for (int n = 0; n < terrain.size(); n++) {
+ Terrain t = terrain.get(n);
+ Image i = tiles[t.id];
+ int width = i.getWidth(null);
+ int height = i.getHeight(null);
+
+ int source[] = new int[width * height];
+ PixelGrabber pixelgrabber = new PixelGrabber(i, 0, 0, width,
+ height, source, 0, width);
+ try {
+ pixelgrabber.grabPixels();
+ } catch (InterruptedException interruptedexception) {}
+ int tx = t.xPos;
+ int ty = t.yPos;
+ boolean upsideDown = (t.modifier & Terrain.MODE_UPSIDE_DOWN) != 0;
+ boolean overwrite = (t.modifier & Terrain.MODE_NO_OVERWRITE) == 0;
+ boolean remove = (t.modifier & Terrain.MODE_REMOVE) != 0;
+ try {
+ for (int y = 0; y < height; y++) {
+ if (y + ty < 0 || y + ty >= bgHeight)
+ continue;
+ int yLineStencil = (y + ty) * bgWidth;
+ int yLine;
+ if (upsideDown)
+ yLine = (height - y - 1) * width;
+ else
+ yLine = y * width;
+ for (int x = 0; x < width; x++) {
+ if (x + tx < 0 || x + tx >= bgWidth)
+ continue;
+ int col = source[yLine + x];
+ // ignore transparent pixels
+ if ((col & 0xff000000) == 0)
+ continue;
+ boolean paint = false;
+ if (!overwrite) {
+ // don't overwrite -> only paint if background is transparent
+ if (stencil.get(yLineStencil + tx + x) == Stencil.MSK_EMPTY)
+ paint = true;
+ } else if (remove) {
+ bgImage.setRGB(x + tx, y + ty, 0 /*bgCol*/);
+ stencil.set(yLineStencil + tx + x, Stencil.MSK_EMPTY);
+ } else
+ paint = true;
+ if (paint) {
+ if(choix==3){
+ //System.out.println("couleur: "+x+" "+y+" = "+col);
+ bgImage.setRGB(x + tx, y + ty, -9400320);
+ }
+ // -28120
+ // -2064352
+ // -4173808
+ // -5752816
+ // -7331824
+ // -9400320
+ // -10485744
+ // -12054520
+ // -13022976
+ // -13697016
+ // -14655456
+ // -15716593
+ // -16289024
+
+ if (choix==0){
+ bgImage.setRGB(x + tx, y + ty, col);
+ }
+ stencil.set(yLineStencil + tx + x,Stencil.MSK_BRICK);
+ }
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ }
+ }
+
+ // now for the animated objects
+ ArrayList<SpriteObject> oCombined = new ArrayList<SpriteObject>(64);
+ ArrayList<SpriteObject> oBehind = new ArrayList<SpriteObject>(64);
+ ArrayList<SpriteObject> oFront = new ArrayList<SpriteObject>(4);
+ ArrayList<Entry> entry = new ArrayList<Entry>(4);
+ AffineTransform tx;
+ for (int n = 0; n < objects.size(); n++) {
+ try {
+ LvlObject o = objects.get(n);
+ //if (sprObjAvailable[o.id].animMode != Sprite.ANIM_NONE) {
+ SpriteObject spr = new SpriteObject(sprObjAvailable[o.id]);
+ spr.setX(o.xPos);
+ spr.setY(o.yPos);
+ // affine transform for flipping
+ tx = AffineTransform.getScaleInstance(1, -1);
+ tx.translate(0, -spr.getHeight());
+ AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ BufferedImage imgSpr;
+ // check for entries (ignore upside down entries)
+ if (spr.getType() == SpriteObject.Type.ENTRY && !o.upsideDown) {
+ Entry e = new Entry(o.xPos+spr.getWidth()/2, o.yPos);
+ e.id = oCombined.size();
+ entry.add(e);
+ spr.setAnimMode(Sprite.Animation.NONE);
+ }
+ // animated
+ boolean drawOnVis = o.paintMode == LvlObject.MODE_VIS_ON_TERRAIN;
+ boolean noOverwrite = o.paintMode == LvlObject.MODE_NO_OVERWRITE;
+ boolean inFront = (drawOnVis || !noOverwrite);
+ boolean drawFull = o.paintMode == LvlObject.MODE_FULL;
+
+ if (inFront)
+ oFront.add(spr);
+ else
+ oBehind.add(spr);
+ oCombined.add(spr);
+
+ // draw stencil (only for objects that are not upside down)
+ if (!o.upsideDown) {
+ for (int y = 0; y < spr.getHeight(); y++) {
+ if (y + spr.getY() < 0 || y + spr.getY() >= bgHeight)
+ continue;
+ int yLineStencil = (y + spr.getY()) * bgWidth;
+ for (int x = 0; x < spr.getWidth(); x++) {
+ //boolean pixOverdraw = false;
+ if (x + spr.getX() < 0 || x + spr.getX() >= bgWidth)
+ continue;
+ // manage collision mask
+ // now read stencil
+ int stencilVal;
+ stencilVal = stencil.get(yLineStencil + spr.getX()+ x);
+ // store object type in mask and idx in higher byte
+ if (/*paint &&*/ spr.getType() != SpriteObject.Type.ENTRY && spr.getType() != SpriteObject.Type.PASSIVE)
+ if ((spr.getMask(x,y) & 0xff000000) != 0) { // not transparent
+ // avoid two objects on the same stencil position
+ // overlap makes it impossible to delete pixels in objects (mask operations)
+ if (Stencil.getObjectID(stencilVal) == 0) {
+ stencil.or(yLineStencil + spr.getX() + x, spr.getMaskType() | Stencil.createObjectID(n));
+ } // else: overlap - erased later in object instance
+ }
+ }
+ }
+ }
+ // remove invisible pixels from all object frames that are "in front"
+ // for upside down objects, just create the upside down copy
+ if (o.upsideDown || inFront || (choix==3)) {
+ for (int frame = 0; frame < spr.getNumFrames(); frame++) {
+ imgSpr = ToolBox.createImage(spr.getWidth(),spr.getHeight(), Transparency.BITMASK);
+ // get flipped or normal version
+ if (o.upsideDown) {
+ // flip the image vertically
+ imgSpr = op.filter(spr.getImage(frame), imgSpr);
+ } else {
+ WritableRaster rImgSpr = imgSpr.getRaster();
+ rImgSpr.setRect(spr.getImage(frame).getRaster()); // just copy
+ }
+ // for "in front" objects the really drawn pixels have to be determined
+ if (inFront || (choix==3)) {
+ for (int y = 0; y < spr.getHeight(); y++) {
+ if (y + spr.getY() < 0 || y + spr.getY() >= bgHeight)
+ continue;
+ int yLineStencil = (y + spr.getY()) * bgWidth;
+ for (int x = 0; x < spr.getWidth(); x++) {
+ if (x + spr.getX() < 0 || x + spr.getX() >= bgWidth)
+ continue;
+ // now read stencil
+ int stencilVal = stencil.get(yLineStencil + spr.getX()+ x);
+ int stencilValMasked = stencilVal & Stencil.MSK_WALK_ON;
+ boolean paint =
+ drawFull || (stencilValMasked != 0 && drawOnVis) || (stencilValMasked == 0 && noOverwrite);
+ // hack for overlap:
+ int id = Stencil.getObjectID(stencilVal);
+ // check if a different interactive object was already entered at this pixel position
+ // however: exits must always be painted
+ // also: passive objects will always be painted
+ if ( inFront && spr.getType() != SpriteObject.Type.PASSIVE && spr.getType() != SpriteObject.Type.EXIT && id!=0 && id != n)
+ paint = false;
+ // sprite screenBuffer pixel
+ int imgCol = imgSpr.getRGB(x,y);
+ if ((imgCol & 0xff000000) == 0)
+ continue;
+ if ((!paint)||(choix==3)){
+ int ccc_temp=0;
+ if(choix==3){
+ // -28120
+ // -2064352
+ // -3100608
+ // -4173808
+ // -5210080
+ // -5752816
+ // -7331824
+ // -8376304
+ // -9400320
+ // -10485744
+ // -12054520
+ // -13022976
+ // -13697016
+ // -14655456
+ // -15716593
+ // -16289024
+ switch(stencilVal){
+ case 0 : // MSK_EMPTY
+ ccc_temp=0;
+ break;
+ case 32 : // MSK_NO_DIG_LEFT
+ ccc_temp=-28120;
+ break;
+ case 64 : // MSK_NO_DIG_RIGHT
+ ccc_temp=-2064352;
+ break;
+ case 128 : // MSK_TRAP_DROWN
+ ccc_temp=-15716593;
+ break;
+ case 256 : // MSK_TRAP_REPLACE
+ ccc_temp=-8376304;
+ break;
+ case 512 : // MSK_TRAP_DIE
+ ccc_temp=-13697016;
+ break;
+ case 1024 : // MSK_EXIT
+ ccc_temp=-7331824;
+ break;
+ default: break;
+ }
+ } else {
+ ccc_temp=imgCol;
+ }
+ imgSpr.setRGB(x,y,ccc_temp&0xffffff); // imgCol set transparent
+ }
+ }
+ }
+ }
+ //spr.img[frame].flush(); // will be overwritten -> flush data
+ spr.setImage(frame,imgSpr);
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ //System.out.println("Array out of bounds");
+ }
+ }
+
+ entries = new Entry[entry.size()];
+ entries = entry.toArray(entries);
+
+ // paint steel tiles into stencil
+ for (int n = 0; n < steel.size(); n++) {
+ Steel stl = steel.get(n);
+ int sx = stl.xPos;
+ int sy = stl.yPos;
+ for (int y = 0; y < stl.height; y++) {
+ if (y + sy < 0 || y + sy >= bgHeight)
+ continue;
+ int yLineStencil = (y + sy) * bgWidth;
+ for (int x = 0; x < stl.width; x++) {
+ if (x + sx < 0 || x + sx >= bgWidth)
+ continue;
+ int stencilVal = stencil.get(yLineStencil + x + sx);
+ // only allow steel on brick
+ if ((stencilVal & Stencil.MSK_BRICK) != 0) {
+ stencilVal &= ~Stencil.MSK_BRICK;
+ stencilVal |= Stencil.MSK_STEEL;
+ stencil.set(yLineStencil + x + sx, stencilVal);
+ }
+ }
+ }
+ }
+ // flush tiles
+ // if (tiles != null)
+ // for (int i=0; i < tiles.length; i++)
+ // tiles[i].flush();
+
+ sprObjects = new SpriteObject[oCombined.size()];
+ sprObjects = oCombined.toArray(sprObjects);
+ sprObjFront = new SpriteObject[oFront.size()];
+ sprObjFront = oFront.toArray(sprObjFront);
+ sprObjBehind = new SpriteObject[oBehind.size()];
+ sprObjBehind = oBehind.toArray(sprObjBehind);
+ System.gc();
+
+ return stencil;
+ }
/**
* Draw opaque objects behind background image.
@@ -475,8 +769,9 @@ public class Level {
try {
SpriteObject spr = sprObjBehind[n];
BufferedImage img = spr.getImage();
- if (spr.getX()+spr.getWidth() > xOfs && spr.getX() < xOfs+width)
+ if (spr.getX()+spr.getWidth() > xOfs && spr.getX() < xOfs+width){
g.drawImage(img,spr.getX()-xOfs,spr.getY(),null);
+ }
//spr.drawHidden(offImg,xOfsTemp);
} catch (ArrayIndexOutOfBoundsException ex) {}
}
@@ -496,8 +791,9 @@ public class Level {
try {
SpriteObject spr = sprObjFront[n];
BufferedImage img = spr.getImage();
- if (spr.getX()+spr.getWidth() > xOfs && spr.getX() < xOfs+width)
+ if (spr.getX()+spr.getWidth() > xOfs && spr.getX() < xOfs+width){
g.drawImage(img,spr.getX()-xOfs,spr.getY(),null);
+ }
} catch (ArrayIndexOutOfBoundsException ex) {}
}
}
@@ -577,18 +873,18 @@ public class Level {
break;
SpriteObject sprite = new SpriteObject(img, frames);
switch (anim) {
- case 0: // dont' animate
- sprite.setAnimMode(Sprite.Animation.NONE);
- break;
- case 1: // loop mode
- sprite.setAnimMode(Sprite.Animation.LOOP);
- break;
- case 2: // triggered animation - for the moment handle like loop
- sprite.setAnimMode(Sprite.Animation.TRIGGERED);
- break;
- case 3: // entry animation
- sprite.setAnimMode(Sprite.Animation.ONCE);
- break;
+ case 0: // dont' animate
+ sprite.setAnimMode(Sprite.Animation.NONE);
+ break;
+ case 1: // loop mode
+ sprite.setAnimMode(Sprite.Animation.LOOP);
+ break;
+ case 2: // triggered animation - for the moment handle like loop
+ sprite.setAnimMode(Sprite.Animation.TRIGGERED);
+ break;
+ case 3: // entry animation
+ sprite.setAnimMode(Sprite.Animation.ONCE);
+ break;
}
// get object type
int type = props.get("type_" + sIdx, -1);
@@ -596,17 +892,17 @@ public class Level {
break;
sprite.setType(SpriteObject.getType(type));
switch (sprite.getType()) {
- case EXIT:
- case NO_DIG_LEFT:
- case NO_DIG_RIGHT:
- case TRAP_DIE:
- case TRAP_REPLACE:
- case TRAP_DROWN:
- // load mask
- fName = "styles/"+set + "/" + set + "om_" + Integer.toString(idx)+ ".gif";
- img = Core.loadImage(tracker, fName);
- sprite.setMask(img);
- break;
+ case EXIT:
+ case NO_DIG_LEFT:
+ case NO_DIG_RIGHT:
+ case TRAP_DIE:
+ case TRAP_REPLACE:
+ case TRAP_DROWN:
+ // load mask
+ fName = "styles/"+set + "/" + set + "om_" + Integer.toString(idx)+ ".gif";
+ img = Core.loadImage(tracker, fName);
+ sprite.setMask(img);
+ break;
}
// get sound
int sound = props.get("sound_" + sIdx, -1);