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) {

	public static void main(String[] arguments) throws SlickException {
		AppGameContainer app = new AppGameContainer(new LightingBoltTestTemporal("Name");
		app.setDisplayMode(320, 240, false);
		return app;

	public static class LightingBoltEffect {

		Collection segments;

		int totalTime;

		int currentTime;

		private float lineWidth;

		public LightingBoltEffect(int time, Collection 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;
			glColor4f(alpha, alpha, alpha, alpha);
				for (Line segment : segments) {

		public boolean isDone() {
			return currentTime <= 0;

		public void glVertex(Vector2f v) {
			glVertex3f(v.x, v.y, 0);

	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 segments = new ArrayList();
		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 newSegments = new ArrayList();
			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));
				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;

	public void update(GameContainer container, int delta) throws SlickException {
		if (!lightingBoltEffect.isDone())

		Input input = container.getInput();
		if (!input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))

		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);

	public void render(GameContainer container, Graphics g) throws SlickException {
VN:F [1.9.22_1171]
Rating: 4.0/5 (2 votes cast)
Lighting Bolts Effect, 4.0 out of 5 based on 2 ratings
  • PunkKi11a

    I love this. Have you tried it on C# XNA. I have been trying to do it on it but have no luck what so ever.

  • Ariel Coppes

    Hi PunkKi11a, I never tried it on XNA, however you could try it by using quads and mapping a texture on it since you can't render directly lines or rectangles on XNA. Take a look at the original article at to get more information about it. The main logic to create the lighting bolt should be almost the same.

  • PunkKi11a

    I know that a quad is made of for vetecies and is made of two triangles using the triangle strip primitive type. What I cant figure out is how two implement it in too a generic collection list. And take in a Quad.Add(First quad(starting position), Second quad(ending position)) When I do it as  list of my class type Quad I can only pass in one argument through the .add property.

  • Ariel Coppes

    First of all, I know too little about XNA. I was taking a look at some Quad examples in the web and my suggestion is, first build a list of segments defining the Lighting Bolt skeleton, and then build quads from each segment.

    For example, given a segment s1 with points p0 and p1, you can build four vertex for the quad in this way (pseudo code):

    vector_direction = p1 - p0
    vector_normal = vector_direction.rotate(90)

    v0 =p0.add(vector_normal)
    v1 =p0.add(-vector_normal)

    v2 =p1.add(vector_normal)

    v3 =p1.add(-vector_normal)

    You can build the Quad specifying four points instead. Can I see the code of your Quad class, where are you getting it?

  • PunkKi11a

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Content;
    using System.Collections;

    namespace Glock
        public class Line
            private Vector3 start, end, mid;
            public int cout = 0;

            public Vector3 Start
                get { return start; }
                set { start = value; }

            public Vector3 End
                get { return end; }
                set { end = value; }

            public Vector3 Mid
                get { return mid; }
                set { mid = value; }

            public Line(Vector3 start, Vector3 end)
                this.start = start;
                this.end = end;

            public virtual void Initialize()
                GenerateLines(new Vector3(50, 300, 0), new Vector3(300, 300, 0), 100);

            protected void GenerateLines(Vector3 p0, Vector3 p1, int time)
                List lines = new List();

                lines.Add(new Line(p0, p1));
                Random rnd = new Random();
                float offset = 100f;
                int links = 5;

                for (int i = 0; i < links; i++)
                    List newLine = new List();

                    foreach (Line Line in lines)
                        Vector3 middle = (p0 + p1) / 2;
                        Vector3 p = p1 - p0;
                        middle += p * (float)MathHelper.Lerp(-offset, offset, (float)rnd.NextDouble());

                        newLine.Add(new Line(p0, middle));
                        newLine.Add(new Line(middle, end));

                    lines = newLine;
                    cout = lines.Count;
                    offset /= 2;

    This is what I got so far. This is just a class in a separate .cs file. I call a constructor that takes in a vector3 for the start and end of the line. I than go through all the code to created the other points of the line by deviding it and changing the status of it.

  • Ariel Coppes

    Hi, I believe you should build the quads as I suggested now that you have the collection of lines, however, as I said before, I know too little about XNA and stuff so I suggest you to visit the original author of the article at and ask him directly, they could give you more ideas.

    Thanks for visiting the blog and good luck with the effect.

  • Anonymous

    Inside your foreach loop you are still using the positions that you passed into the generateLines method?Wouldnt that draw the same line over and over again?