Lighting Bolts Effect
Some time ago I made a lighting bolt effect in Java, using Slick2D library, following the tutorial of Drilian’s House of Game Development. My results:
If you are looking to make a nice lighting bolt effect for your game, I recommend you to follow the original tutorial.
Here is my code if you want to use it and/or modify it:
package com.gemserk.commons.tests; import static org.lwjgl.opengl.GL11.*; import java.util.ArrayList; import java.util.Collection; import java.util.Random; import java.util.concurrent.Callable; import org.newdawn.slick.AppGameContainer; import org.newdawn.slick.BasicGame; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.Input; import org.newdawn.slick.SlickException; import org.newdawn.slick.geom.Line; import org.newdawn.slick.geom.Vector2f; import org.newdawn.slick.opengl.SlickCallable; public class LightingBoltTestTemporal extends BasicGame { public LightingBoltTestTemporal(String title) { super(title); } public static void main(String[] arguments) throws SlickException { AppGameContainer app = new AppGameContainer(new LightingBoltTestTemporal("Name"); app.setDisplayMode(320, 240, false); app.setAlwaysRender(true); app.setMinimumLogicUpdateInterval(1); app.setShowFPS(true); app.start(); return app; } public static class LightingBoltEffect { Collection<Line> segments; int totalTime; int currentTime; private float lineWidth; public LightingBoltEffect(int time, Collection<Line> segments, float lineWidth) { this.totalTime = time; this.segments = segments; this.currentTime = time; this.lineWidth = lineWidth; } public void update(int delta) { currentTime -= delta; if (currentTime <= 0) currentTime = 0; } public void render() { float alpha = (float) currentTime / (float) totalTime; glPushMatrix(); glColor4f(alpha, alpha, alpha, alpha); glLineWidth(lineWidth); glBegin(GL_LINES); { for (Line segment : segments) { glVertex(segment.getStart()); glVertex(segment.getEnd()); } } glEnd(); glPopMatrix(); } public boolean isDone() { return currentTime <= 0; } public void glVertex(Vector2f v) { glVertex3f(v.x, v.y, 0); } } @Override public void init(GameContainer container) throws SlickException { generateLightingBolt(new Vector2f(50, 240), new Vector2f(290, 240), 100); } protected void generateLightingBolt(Vector2f p0, Vector2f p1, int duration) { Collection<Line> segments = new ArrayList<Line>(); segments.add(new Line(p0, p1)); float offset = 200f; double probability = 0.3; // probability to generate new partitions float height = 50.0f; Random random = new Random(); int partitions = 4; for (int i = 0; i < partitions; i++) { Collection<Line> newSegments = new ArrayList<Line>(); for (Line segment : segments) { Vector2f midPoint = segment.getStart().copy().add(segment.getEnd()).scale(0.5f); Vector2f perpendicular = midPoint.copy().add(90); perpendicular.normalise().scale(random.nextFloat() * offset - (offset / 2)); midPoint.add(perpendicular); if (random.nextFloat() < probability) { // generate new branch Vector2f direction = midPoint.copy().sub(segment.getStart()); direction.add(random.nextFloat() * height); newSegments.add(new Line(midPoint.copy(), midPoint.copy().add(direction))); } newSegments.add(new Line(segment.getStart().copy(), midPoint.copy())); newSegments.add(new Line(midPoint.copy(), segment.getEnd().copy())); } segments = newSegments; offset /= 2; } lightingBoltEffect = new LightingBoltEffect(duration, segments, 2.0f); } private LightingBoltEffect lightingBoltEffect; @Override public void update(GameContainer container, int delta) throws SlickException { lightingBoltEffect.update(delta); if (!lightingBoltEffect.isDone()) return; Input input = container.getInput(); if (!input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) return; int mouseX = input.getMouseX(); int mouseY = input.getMouseY(); Random random = new Random(); int duration = random.nextInt() % 600 + 100; generateLightingBolt(new Vector2f(mouseX, mouseY), new Vector2f((mouseX + 300), mouseY), duration); } @Override public void render(GameContainer container, Graphics g) throws SlickException { SlickCallable.enterSafeBlock(); lightingBoltEffect.render(); SlickCallable.leaveSafeBlock(); } }