Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Create an Eclipse game plug-in, Part 2: Building and firing a BB gun

How to build fun plug-ins for Eclipse using the SWT, OpenGL, and the LWJGL

Tyler Anderson (tyleranderson5@yahoo.com), Freelance Writer, Stexar Corp.
Tyler Anderson graduated with a degree in computer science from Brigham Young University in 2004 and graduated with a master's degree in computer engineering in December 2005, also from Brigham Young University. He is currently an engineer for Stexar Corp., based in Beaverton, Ore.

Summary:  Although most users think of Eclipse as an integrated development environment for building Java™ technology applications, it is really something much more basic. Eclipse is a framework for building plug-ins, allowing you to extend its functionality to solve nearly any problem -- just by leveraging a set of APIs and readily available libraries. In this four-part "Create an Eclipse game plug-in" tutorial series, you will solve a pressing problem most programmers encounter daily: how to break away to play a quick video game without switching applications and making it obvious. You'll develop a simple game that will read the bugs entered on the a view and blast them to bits. The game will run inside Eclipse as a plug-in, that will demonstrate how to write to the Eclipse API, while using the Standard Widget Toolkit, the Open Graphics Library, and the Lightweight Java Games Library.

View more content in this series

Date:  28 Mar 2006
Level:  Intermediate PDF:  A4 and Letter (448 KB | 33 pages)Get Adobe® Reader®

Activity:  16742 views
Comments:  

Setting up a custom GLScene

The example plug-in download comes with several scenes you can take a look at. However, in this tutorial, you'll build your own and build a game around it.

Importing class dependencies

Your scene class depends on several others. Thus, you'll need to import them for your use. Create a com.ibm.eclipse.shootout.scenes package and make a new class in this package, the GameScene class. Then begin defining it, as shown in Listing 2.


Listing 2. Class dependencies
                    
package com.ibm.eclipse.shootout.scenes;

import com.ibm.eclipse.shootout.views.ShootoutView;

import org.eclipse.swt.examples.openglview.CompiledShape;
import org.eclipse.swt.examples.openglview.GLScene;
import org.eclipse.swt.examples.openglview.SceneGrip; 
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

import org.eclipse.opengl.GL;
import org.eclipse.opengl.GLU;

import java.util.Timer;
import java.util.TimerTask;


public class GameScene extends GLScene {

Notice that you import the ShootoutView class, used to get the number of tasks from in the Task View. Then we import three more classes:

CompiledShape
A compiled shape is what each shape class will extend. It has some handy methods that help abstract away OpenGL details from you.
GLScene
This is the class your new GameScene class extends. It, too, helps abstract some of the low-level OpenGL details away from you, which are beyond the scope of this tutorial. Feel free, however, to experiment with them.
SceneGrip
This is a cool class that handles all the events from the OpenGL canvas. These events include mouse and keyboard events. Later in this tutorial, you'll use the keyboard to shoot BBs and blow up a perfectly happy bug.

Next, you'll define the GameScene's class variables.


Class variables

There are several shapes to create, which we declare now. You can create dummy static classes for them so the Eclipse integrated development environment (IDE) doesn't highlight all your code in evil red squiggles. Continue defining the GameScene class, as shown in Listing 3.


Listing 3. Defining class variables
                    
public class GameScene extends GLScene {    
    private static final float[][] COLOR = {
        {1.0f, 1.0f, 0.0f, 0.7f},
        {0.0f, 1.0f, 0.0f, 0.7f},
        {0.0f, 0.0f, 1.0f, 0.7f},
        {1.0f, 0.0f, 1.0f, 0.7f},
    };

    private SceneGrip grip;
    private Gun gun;
    private Bug[] bugs;
    private int bugCount;
    private Bullet bullets[];
    private Pow pow;

A color array is also defined. In OpenGL, a color is defined as a float array of size 4. The first index defines red, the second green, and the third blue. To remember this order, just think "RGB." For an example empty class, here's what the empty Gun class would look like:

Class Gun extends CompiledShape{ }

Onto the GameScene class.


The constructor

We need to initialize the class. The SceneGrip class also gets initialized, which is responsible for the current view and rotation information. This will be clear when we get to see our first object in the OpenGL canvas. Define the GameScene class's constructor, as shown in Listing 4.


Listing 4. Defining class variables
                    
public GameScene(Composite parent) {
        super(parent);
        
        this.grip = new SceneGrip(this);
        this.grip.setOffsets(-3.25f, 3.25f, -30.5f);
        this.grip.setRotation(45.0f, -30.0f);
        
        this.getCanvas().addMouseListener(this.grip);
        this.getCanvas().addMouseMoveListener(this.grip);
        this.getCanvas().addListener(SWT.MouseWheel, this.grip);
        this.getCanvas().addKeyListener(this.grip);
    }

The constructor sets up the the SceneGrip and adds all the listeners to the OpenGL canvas with the SceneGrip as the listening class.

Next up is initializing the OpenGL context.


Initializing OpenGL parameters

OpenGL has numerous parameters we can configure. We define a few in the initGL method, as shown in Listing 5.


Listing 5. Initializing the OpenGL context
                    
protected void initGL() {
        super.initGL();

        GL.glLightfv(GL.GL_LIGHT1, 
                     GL.GL_DIFFUSE, 
                     new float[] {1.0f, 1.0f, 1.0f, 1.0f});
        GL.glLightfv(GL.GL_LIGHT1, 
                     GL.GL_AMBIENT, 
                     new float[] {0.5f, 0.5f, 0.5f, 1.0f});
        GL.glLightfv(GL.GL_LIGHT1, 
                     GL.GL_POSITION, 
                     new float[] {-50.f, 50.0f, 100.0f, 1.0f});
        GL.glEnable(GL.GL_LIGHT1);
        GL.glEnable(GL.GL_LIGHTING);
        GL.glEnable(GL.GL_COLOR_MATERIAL);
        GL.glColorMaterial(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE);
...

Let's initialize the light and light source for GL.GL_LIGHT1. First, the color of diffuse and ambient light are set, followed by the position of the diffuse light. Next, lighting and light1 need to be enabled. Then coloring is enabled, and the last line specifies that ambient and diffuse light can affect the color of colored objects. Next, you'll initialize the custom objects you'll create later in this tutorial.


Initializing your custom objects

There are a few more features to enable and a plethora of objects to initialize. Here, you create handles to quadrics, which are complex shapes like spheres, planes, and cylinders. Finish initializing the OpenGL context, as shown in Listing 6.


Listing 6. Initializing objects
                    
...
        GL.glEnable(GL.GL_COLOR_MATERIAL);
        GL.glColorMaterial(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE);

        Bullet.QUADRIC = GLU.gluNewQuadric();
        Bug.QUADRIC = GLU.gluNewQuadric();
        Gun.QUADRIC = GLU.gluNewQuadric();
        GLU.gluQuadricNormals(Bullet.QUADRIC, GLU.GLU_SMOOTH);
        GLU.gluQuadricNormals(Gun.QUADRIC, GLU.GLU_SMOOTH);
        GLU.gluQuadricNormals(Bug.QUADRIC, GLU.GLU_SMOOTH);
        
        this.gun = new Gun();
        
        bugCount = ShootoutView.viewer.getTable().getItemCount();
        this.bugs = new Bug[bugCount];
        for (int i = 0; i < this.bugs.length; i++){
            this.bugs[i] = new Bug(COLOR[i % COLOR.length]);
        }

        bullets = new Bullet[25];
        for(int i = 0; i < bullets.length; i++)
            bullets[i] = new Bullet();
        
        pow = new Pow();
    }

Here, we set up the three quadric handles to your bullet, bugs, and gun classes. Next, initialize the gun, bugs, bullets and pow classes. Our gun will have 25 BBs outstanding at a time; this should be plenty. We draw the scene next.


Drawing the scene

This method essentially calls the draw methods of each of your shape classes. However, to avoid having classes pile up on top of each other, we use translation to move the origin of what we're drawing. The origin is where all of the vertices (the points where two or more line segments come together) you create are based. Define the drawScene method, as shown in Listing 7.


Listing 7. The drawScene method
                    
    protected void drawScene() {
        super.drawScene();
        this.grip.adjust();
        
        pow.draw();
        GL.glTranslatef(.2f, -.2f, 9.5f);

        for(int i = 0; i < bullets.length; i++)
            if(bullets[i] != null)
                bullets[i].draw();
        
        GL.glTranslatef(-.2f, .2f, 2.5f);

        gun.draw();
        GL.glTranslatef(-Bug.RADIUS*bugCount, 0.0f, -20f);

        for(int i = 0; i < bugs.length; i++){
            bugs[i].draw();
            GL.glTranslatef(2*Bug.RADIUS, 0.0f, 0.0f);
        }
    }

Notice that the word Pow! is drawn based on the original origin. We then translate a little and place the origin at the end of the gun's barrel. Then move the origin again and draw the gun. Another translation places the origin where the bugs will be drawn. We draw them in a row, left to right. After each bug is drawn, move the origin over 2*Bug.RADIUS so they don't overlap each other. Next, we define the dispose method.


Disposing of objects on exit

When Eclipse or the view closes, you need to deallocate the objects. That's what the dispose method is for. Define it as shown in Listing 8.


Listing 8. Disposing the objects
                    
public void dispose() {
        GLU.gluDeleteQuadric(Gun.QUADRIC);
        GLU.gluDeleteQuadric(Bullet.QUADRIC);
        GLU.gluDeleteQuadric(Bug.QUADRIC);
        pow.dispose();
        this.gun.dispose();
        for(int i = 0; i < bugs.length; i++)
            bugs[i].dispose();
        for(int i = 0; i < bullets.length; i++)
            bullets[i].dispose();
        
        super.dispose();
    }

Deallocate the quadrics (a curve or surface whose equation, in Cartesian coordinates, is of the second degree), dispose of each of the objects, then dispose of the super class. We start creating shapes next.

3 of 11 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=106482
TutorialTitle=Create an Eclipse game plug-in, Part 2: Building and firing a BB gun
publish-date=03282006
author1-email=tyleranderson5@yahoo.com
author1-email-cc=troy@backstopmedia.com