Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2012
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.91 KB | None | 0 0
  1. package slicktests.lighting;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.Random;
  6.  
  7. import org.lwjgl.opengl.GL11;
  8. import org.lwjgl.opengl.GL14;
  9. import org.newdawn.slick.AppGameContainer;
  10. import org.newdawn.slick.BasicGame;
  11. import org.newdawn.slick.Color;
  12. import org.newdawn.slick.GameContainer;
  13. import org.newdawn.slick.Graphics;
  14. import org.newdawn.slick.Image;
  15. import org.newdawn.slick.Input;
  16. import org.newdawn.slick.SlickException;
  17.  
  18. /**
  19.  * davedes' Tutorials
  20.  * Alpha Map Lighting
  21.  * http://slick.cokeandcode.com/wiki/doku.php?id=alpha_maps
  22.  *
  23.  * @author davedes
  24.  */
  25. public class LightingTestAlpha extends BasicGame {
  26.  
  27.     //number of tiles in our simple horizontal sprite sheet
  28.     public static final int TILE_COUNT = 5;
  29.  
  30.     //width/height of tile in pixels
  31.     public static final int TILE_SIZE = 40;
  32.  
  33.     //size of alpha map (for use with sprite sheet)
  34.     public static final int ALPHA_MAP_SIZE = 256;
  35.  
  36.     //space after tile, before next tile
  37.     public static final int TILE_SPACING = 2;
  38.  
  39.     //the "sprite sheet" or texture atlas image
  40.     private Image spriteSheet;
  41.  
  42.     //the sub-images of our sprite sheet
  43.     private Image[] tileSprites;
  44.  
  45.     //our 2D map array
  46.     private Image[][] tileMap;
  47.  
  48.     //map size in tiles
  49.     private int mapWidth, mapHeight;
  50.  
  51.     //our alpha map image; just a feathered black circle on a transparent background
  52.     private Image alphaMap, player;
  53.     private Image offscreen, lightsImage;
  54.     private Graphics offscreenGraphics, lightsGraphics;
  55.  
  56.     private Random random = new Random();
  57.  
  58.     //our lights
  59.     private List<Light> lights = new ArrayList<Light>();
  60.  
  61.     //a timer used for simple light scaling effect
  62.     private long elapsed;
  63.  
  64.     //a shared instance of Color so we don't need to create a new one each frame
  65.     private Color sharedColor = new Color(1f, 1f, 1f, 1f);
  66.  
  67.     /** Describes a single point light. */
  68.     public static class Light {
  69.         /** The position of the light */
  70.         float x, y;
  71.         /** The RGB tint of the light, alpha is ignored */
  72.         Color tint;
  73.         /** The alpha value of the light, default 1.0 (100%) */
  74.         float alpha;
  75.         /** The amount to scale the light (use 1.0 for default size). */
  76.         private float scale;
  77.         //original scale
  78.         private float scaleOrig;
  79.  
  80.         public Light(float x, float y, float scale, Color tint) {
  81.             this.x = x;
  82.             this.y = y;
  83.             this.scale = scaleOrig = scale;
  84.             this.alpha = 1f;
  85.             this.tint = tint;
  86.         }
  87.  
  88.         public Light(float x, float y, float scale) {
  89.             this(x, y, scale, Color.white);
  90.         }
  91.  
  92.         public void update(float time) {
  93.             //effect: scale the light slowly using a sin func
  94.             scale = scaleOrig + 1f + .5f*(float)Math.sin(time);
  95.         }
  96.     }
  97.  
  98.     public LightingTestAlpha() {
  99.         super("Alpha Map Lighting");
  100.     }
  101.  
  102.     public void init(GameContainer container) throws SlickException {
  103. //      container.setVSync(true);
  104. //      container.setTargetFrameRate(60);
  105.  
  106.         //To reduce texture binds, our alpha map and tilesheet will be in the same texture
  107.         //Most games will implement their own SpriteSheet class, but for simplicity's sake:
  108.             //map tiles are in a horizontal row starting at (0, 0)
  109.             //alpha map is located below the tiles, at (0, TILE_SIZE+TILE_SPACING)
  110.         spriteSheet = new Image("res/lighting/lighting_sprites_inv.png", false, Image.FILTER_NEAREST);
  111.  
  112.         //grab the tiles
  113.         tileSprites = new Image[TILE_COUNT];
  114.         for (int i = 0; i < tileSprites.length; i++) {
  115.             tileSprites[i] = spriteSheet.getSubImage(i * (TILE_SIZE + TILE_SPACING), 0, TILE_SIZE, TILE_SIZE);
  116.         }
  117.        
  118.         player = spriteSheet.getSubImage(0, 301, 29, 40);
  119.  
  120.         //grab the alpha map
  121.         alphaMap = spriteSheet.getSubImage(0, TILE_SIZE + TILE_SPACING, ALPHA_MAP_SIZE, ALPHA_MAP_SIZE);
  122.  
  123.         //randomize our map
  124.         randomizeMap(container);
  125.  
  126.         //reset the lighting
  127.         resetLights(container);
  128.        
  129.         //our offscreen image
  130.         offscreen = Image.createOffscreenImage(container.getWidth(), container.getHeight());
  131.         offscreenGraphics = offscreen.getGraphics();
  132.        
  133.         //our lights image
  134.         lightsImage = Image.createOffscreenImage(container.getWidth(), container.getHeight());
  135.         lightsGraphics = lightsImage.getGraphics();
  136.     }
  137.  
  138.     Image randomTile() {
  139.         int r = random.nextInt(100);
  140.         if (r < 5)
  141.             return tileSprites[1 + random.nextInt(4) ];
  142.         else
  143.             return tileSprites[0];
  144.     }
  145.  
  146.     void randomizeMap(GameContainer container) {
  147.         // create the map
  148.         mapWidth = container.getWidth() / TILE_SIZE + 1;
  149.         mapHeight = container.getHeight() / TILE_SIZE + 1;
  150.         tileMap = new Image[mapWidth][mapHeight];
  151.         for (int x = 0; x < mapWidth; x++) {
  152.             for (int y = 0; y < mapHeight; y++) {
  153.                 tileMap[x][y] = randomTile();
  154.             }
  155.         }
  156.     }
  157.  
  158.     public void resetLights(GameContainer container) {
  159.         //clear the lights and add a new one with default scale
  160.         lights.clear();
  161.         lights.add(new Light(container.getInput().getMouseX(), container.getInput().getMouseY(), 1f));
  162.     }
  163.    
  164.     public void render(GameContainer container, Graphics g)
  165.             throws SlickException {
  166.         //---- First render our lights to a single image
  167.         //technically we only need to do this whenever the lights change
  168.         Graphics.setCurrent(lightsGraphics);
  169.        
  170.         //1. clear the light image background to black
  171.         lightsGraphics.setBackground(Color.black);
  172.         lightsGraphics.clear();
  173.        
  174.         //2. set up GL blending to avoid any transparency loss
  175.         GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA,
  176.                 GL11.GL_ONE_MINUS_SRC_ALPHA,
  177.                 GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
  178.        
  179.         //3. draw our lights... a feathered white circle on a transparent background
  180.         alphaMap.startUse();
  181.         for (int i=0; i<lights.size(); i++) {
  182.             Light light = lights.get(i);
  183.             light.tint.bind();
  184.             alphaMap.drawEmbedded(light.x-(light.scale*alphaMap.getWidth()/2f),
  185.                                   light.y-(light.scale*alphaMap.getHeight()/2f),
  186.                                   light.scale*alphaMap.getWidth(),
  187.                                   light.scale*alphaMap.getHeight());
  188.         }
  189.         alphaMap.endUse();
  190.        
  191.         //4. reset the draw mode
  192.         lightsGraphics.setDrawMode(Graphics.MODE_NORMAL);
  193.        
  194.         //5. flush the light image graphics!!
  195.         lightsGraphics.flush();
  196.        
  197.         //---- Now we can start rendering to the screen
  198.         Graphics.setCurrent(g);
  199.        
  200.         //1. Draw our map and entities image
  201.         spriteSheet.startUse();
  202.         for (int x = 0; x < mapWidth; x++) {
  203.             for (int y = 0; y < mapHeight; y++) {
  204.                 tileMap[x][y].drawEmbedded(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
  205.             }
  206.         }
  207.         player.drawEmbedded(150, 150);
  208.         spriteSheet.endUse();
  209.        
  210.         //2. Set up blend mode for masking
  211.         GL11.glBlendFunc(GL11.GL_ZERO, GL11.GL_SRC_COLOR);
  212.        
  213.         //3. Draw our light map
  214.         lightsImage.draw();
  215.        
  216.         //---- Reset the mode to normal before continuing!
  217.         g.setDrawMode(Graphics.MODE_NORMAL);
  218.        
  219.         g.setColor(Color.white);
  220.         g.drawString("Mouse click to add a light (total count: "+lights.size()+")", 10, 25);
  221.         g.drawString("Press R to randomize the map tiles", 10, 40);
  222.         g.drawString("Press SPACE to reset the lights", 10, 55);
  223.     }
  224.  
  225.     public void update(GameContainer container, int delta)
  226.             throws SlickException {
  227.         if (container.getInput().isKeyPressed(Input.KEY_R))
  228.             randomizeMap(container);
  229.         if (container.getInput().isKeyPressed(Input.KEY_SPACE)) {
  230.             resetLights(container);
  231.         }
  232.         elapsed += delta;
  233.  
  234.         //update all lights to have them smoothly scale
  235.         for (int i=0; i<lights.size(); i++) {
  236.             lights.get(i).update(elapsed / 1000f);
  237.         }
  238.  
  239.         //the last-added light will be the one under the mouse
  240.         if (lights.size()>0) {
  241.             Light l = lights.get(lights.size()-1);
  242.             l.x = container.getInput().getMouseX();
  243.             l.y = container.getInput().getMouseY();
  244.         }
  245.        
  246.     }
  247.  
  248.     //adds a new light
  249.     public void mousePressed(int button, int x, int y) {
  250.         float randSize = random.nextInt(15)*.1f;
  251.         Color randColor = new Color(random.nextFloat(), random.nextFloat(), random.nextFloat());
  252.         lights.add(new Light(x, y, randSize, randColor));
  253.     }
  254.  
  255.     public static void main(String[] args) {
  256.         try {
  257.             new AppGameContainer(new LightingTestAlpha(), 800, 600, false).start();
  258.         } catch (SlickException e) {
  259.             e.printStackTrace();
  260.         }
  261.     }
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement