How To Write A Video Game - Language Suggestions

  • Thread starter Danoff
  • 25 comments
  • 2,418 views

Danoff

Premium
34,344
United States
Mile High City
I'm interested in writing a video game and I'd like to know what kinds of programming language I should be focusing on. Does anyone know how to write a graphics application for windows and easily obtain keyboard commands realtime?

Do I write C++ code and interface it with OpenGL or something? Any help is appreciated, I'm a bit lost.
 
Here is some code I wrote a while back that uses OpenGL on windows, trapping keyboard events like you wanted to do.

Code:
#include <windows.h>
#include <gl\gl.h>
#include <gl\glut.h>

void init(void);
void display(void);
void keyboard(unsigned char, int, int);

int main (int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(600, 600);
	glutInitWindowPosition(50, 50);
	glutCreateWindow("A 3D Object");
	init();
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);  /* set keyboard handler */
	glutMainLoop();
	return 0;
}

void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);

	//lighting
	glShadeModel(GL_SMOOTH);

	//glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	// Create light components
	GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
	GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
	GLfloat position[] = { -15, -15, -15, -15};

	// Assign created components to GL_LIGHT0
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
	glLightfv(GL_LIGHT0, GL_POSITION, position);

	// enable color tracking
	glEnable(GL_COLOR_MATERIAL);
	// set material properties which will be assigned by glColor
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_QUADS);
		//base
		glColor3f(0.2, 0.2, 0.2);
		glVertex3f(8.0, -5.0, 8.0);
		glVertex3f(-8.0, -5.0, 8.0);
		glVertex3f(-8.0, -5.0, -8.0);
		glVertex3f(8.0, -5.0, -8.0);

		//front
		glColor3f(0.2, 0.2, 1.0);
		glVertex3f(8.0, 4.0, -8.0);
		glVertex3f(8.0, -5.0, -8.0);
		glVertex3f(-8.0, -5.0, -8.0);
		glVertex3f(-8.0, 4.0, -8.0);

		//back
		glColor3f(0.2, 1.0, 0.2);
		glVertex3f(8.0, 8.0, 8.0);
		glVertex3f(8.0, -5.0, 8.0);
		glVertex3f(-8.0, -5.0, 8.0);
		glVertex3f(-8.0, 8.0, 8.0);

		//side
		glColor3f(0.5, 0.5, 0.5);
		glVertex3f(8.0, -5.0, -8.0);
		glVertex3f(8.0, -5.0, 8.0);
		glVertex3f(8.0, 8.0, 8.0);
		glVertex3f(8.0, 4.0, -8.0);
	
		//side
		glVertex3f(-8.0, -5.0, -8.0);
		glVertex3f(-8.0, -5.0, 8.0);
		glVertex3f(-8.0, 8.0, 8.0);
		glVertex3f(-8.0, 4.0, -8.0);

		//top
		/*
		glColor3f(1.0, 0.5, 0.5);
		glVertex3f(8.0, 4.0, -8.0);
		glVertex3f(8.0, 8.0, 8.0);
		glVertex3f(-8.0, 8.0, 8.0);
		glVertex3f(-8.0, 4.0, -8.0);
		*/

	glEnd();
	glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y)
{
	/* this is the keyboard event handler
	   the x and y parameters are the mouse 
	   coordintes when the key was struck */
	switch (key)
	{
	case 'w':
	case 'W':
		glRotatef(3.0, 1.0, 0.0, 0.0); /* rotate up */
		break;
	case 's':
	case 'S':
		glRotatef(-3.0, 1.0, 0.0, 0.0); /* rotate down */
		break;
	case 'a':
	case 'A':
		glRotatef(3.0, 0.0, 1.0, 0.0); /* rotate left */
		break;
	case 'd':
	case 'D':
		glRotatef(-3.0, 0.0, 1.0, 0.0); /* rotate right */
	}
	display(); /* repaint the window */
}

To the general internet audience: This code is presented for personal learning. I do this in my free time. Don't steal from me and make money off it!

I used Visual studio 2005 (there is a free express edition available, I got the pay version with my MSDN subscription).

You have to do some setup in the project properties, I followed this tutorial.

http://csf11.acs.uwosh.edu/cs371/visualstudio/

EDIT1: I also helped someone else on a side-scrolling 2d game written in Java, which is much easier to do. You cna interface OpenGL in Java apps as well. If you want to get started with java, go to java.sun.com and check out the NetBeans 5.5 and jdk 6.0 bundle.

EDIT2: Also everything Java-related is usually free, that might be better if this is just a hobby...
 
Will the main character be Dagny Taggart, and you have to build as many bridges as possible before James unwittingly destroys everything? :D
 
Don't know if this is a bit of cheating but I've found GameMaker to be a great, uh, game making program.

It's very user-friendly and can really get into the deep stuff if you want to - the home page says you can make a game without using a line of code but for serious programmers you can use all the code you want. The code is best described as a pretty lax Java; it's like Java but more English-y.

Also, graphics are all part of the package, it's free, etc etc I think I'll stop now as I'm not getting any royalty fees from this :sly:

Don't know how complex/good for game-making Game Maker might be, since I'm only a high school student and my experience stems solely from AP Computer Science and their Java curriculum, but I find it a very useful tool.

Hope this helps.
 
I wanted to make a 2-D, mostly text based game. You'll have a character that you can move around on the screen, but otherwise it's mostly menus and things that don't move much. So OpenGL is the way to go? What about DirectX? I'm wary of using pre-packaged utilities since I'd want to be able to sell this at some point if it comes together. But I'm thinking that it won't require installation to run.

(Yes, Sage, it's all about Dagny Taggart. She actually has a submachine gun that she uses to blast looters as they come on to the screen. It's basically "Asteroids meets Objectivism".)
 
I've found Python to be good for simple text/2D adventures. Plus, it's one of the first languages I've learned. (Also learning HTML/PHP!)
 
I wanted to make a 2-D, mostly text based game. You'll have a character that you can move around on the screen, but otherwise it's mostly menus and things that don't move much. So OpenGL is the way to go? What about DirectX? I'm wary of using pre-packaged utilities since I'd want to be able to sell this at some point if it comes together. But I'm thinking that it won't require installation to run.
DirectX and OpenGL do the same thing.

If you just want sidescrolling/2d with animated menus, you don't need either. Check out Java2d, it will make it pretty damn easy. I've written lots of animations in Java, and if you get a better idea of what you want, I can send you some more sample code.
 
DirectX and OpenGL do the same thing.

If you just want sidescrolling/2d with animated menus, you don't need either. Check out Java2d, it will make it pretty damn easy. I've written lots of animations in Java, and if you get a better idea of what you want, I can send you some more sample code.

Sure, PM me an example. I take it I need a java complier? I've got the basic idea for the game in my head. I have a writer lined up. I'll do the music. Sound effects and artwork are still an issue but I think it should be very do-able. I know a few people that are really good artists, and I imagine I can find some public domain sound effects easily enough.
 
Compiler/IDE: http://java.sun.com/javase/downloads/netbeans.html (first download link on the page)

Documentation: https://sdlc6b.sun.com/ECom/EComActionServlet;jsessionid=FB1171A318C3AB605883EFD57258AA83 (unzip to a docs folder in the JDK directory, which is \Program Files\Java\jdk1.6.xx\ by default)

NetBeans will pick up the documentation automatically. Check out the simple demos which are installed in the jdk folder first.

Also there are excellent demos/tutorials from Sun here: http://java.sun.com/developer/codesamples/media.html
 
Code to use Java2D to draw an animation in a thread.

EngineFrame.java
Code:
import java.util.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;



public class EngineFrame extends JFrame implements ChangeListener, WindowListener {
    
    private JPanel south = null;
    private EngineSurface esf = null;
    private JSlider crankthrow = null;
    private JSlider conrodlength = null;
    private JSlider speed = null;
    private JSlider seperation = null;

    public EngineFrame() {
	super("V-Twin");
        addWindowListener(this);
	getContentPane().setLayout(new BorderLayout());
	esf = new EngineSurface();
	getContentPane().add(esf, BorderLayout.CENTER);

	south = new JPanel(new GridLayout(4,2));
	south.add(new JLabel("Crank Throw:"));
	crankthrow = new JSlider(50,200,90);
	crankthrow.addChangeListener(this);
	south.add(crankthrow);
	south.add(new JLabel("Connecting Rod Length:"));
	conrodlength = new JSlider(100,300,200);
	conrodlength.addChangeListener(this);
	south.add(conrodlength);
	south.add(new JLabel("Speed:"));
	speed = new JSlider(1,100,80);
	speed.addChangeListener(this);
	south.add(speed);
	south.add(new JLabel("Seperation:"));
	seperation = new JSlider(0,180,90);
	seperation.addChangeListener(this);
	south.add(seperation);
	getContentPane().add(south, BorderLayout.SOUTH);

	setSize(600,600);
    }

    public static void main(String args[]) {
	EngineFrame fr = new EngineFrame();
	fr.setVisible(true);
    }

    public void stateChanged(ChangeEvent e) {
	esf.radius = crankthrow.getValue();
	esf.conrodlength = conrodlength.getValue();
	esf.counterInc = (float)(speed.getValue()/1000.0);
	esf.seperation = seperation.getValue();
    }
    
    //WINDOW LISTENER METHODS
    public void windowClosing(WindowEvent w){
        System.exit(0);
    }
    public void windowOpened(WindowEvent w){}
    public void windowIconified(WindowEvent w){}
    public void windowDeiconified(WindowEvent w){}
    public void windowClosed(WindowEvent w){}
    public void windowActivated(WindowEvent w){}
    public void windowDeactivated(WindowEvent w){}

}


class EngineSurface extends Surface implements Runnable {
    public float counterInc = (float)0.08;
    public double radius = 90;
    public double conrodlength = 200;
    public double seperation = 90;
    private float counter = 0;


    public EngineSurface() {
	super();
    }

    // ...implement this routine for painting...
    public void render(int w, int h, Graphics2D g2) {
        float size = (w > h) ? h : w;
	double journalsep = seperation*Math.PI/90;

	Ellipse2D ellipse = new Ellipse2D.Double();
        ellipse.setFrame(w/2-radius,2*h/3-radius,2*radius,2*radius);
	Line2D crank1 = new Line2D.Double();
	crank1.setLine(w/2,2*h/3,w/2+radius*Math.cos(counter),2*h/3+radius*Math.sin(counter));
	Line2D axis1 = new Line2D.Double();
	axis1.setLine(0,0,w/2,2*h/3);
	Line2D conrod1 = new Line2D.Double();
	conrod1 = getLinePosSlope(0,0,w/2,2*h/3,w/2+radius*Math.cos(counter),2*h/3+radius*Math.sin(counter),conrodlength,0,w/2);

	Line2D crank2 = new Line2D.Double();
	crank2.setLine(w/2,2*h/3,w/2+radius*Math.cos(counter+journalsep),2*h/3+radius*Math.sin(counter+journalsep));
	Line2D axis2 = new Line2D.Double();
	axis2.setLine(w,0,w/2,2*h/3);
	Line2D conrod2 = new Line2D.Double();
	conrod2 = getLineNegSlope(w,0,w/2,2*h/3,w/2+radius*Math.cos(counter+journalsep),2*h/3+radius*Math.sin(counter+journalsep),conrodlength,w/2,w);

        g2.setColor(Color.black);
	g2.setStroke(new BasicStroke((float)1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0));
        g2.draw(ellipse);
	g2.setStroke(new BasicStroke((float)1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[]{0,6,0,6}, 0));
	g2.draw(axis1);
	g2.draw(axis2);

        g2.setColor(Color.red);
	g2.setStroke(new BasicStroke((float)12, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.draw(crank1);
	g2.setStroke(new BasicStroke((float)6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
	g2.draw(conrod1);
	g2.setStroke(new BasicStroke((float)48, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
	g2.draw(getParallelRect(conrod1.getX1(), conrod1.getY1(), w/2, 2*h/3, 24));

        g2.setColor(Color.blue);
	g2.setStroke(new BasicStroke((float)12, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.draw(crank2);
	g2.setStroke(new BasicStroke((float)6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
	g2.draw(conrod2);
	g2.setStroke(new BasicStroke((float)48, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
	g2.draw(getParallelRect(conrod2.getX1(), conrod2.getY1(), w/2, 2*h/3, 24));
    }
    
    //return a line of distance d, one endpoint (p,q) and one endpoint on the line defined by (x1,y1) and (x2,y2)
    //returned x values must be between xmin and xmax
    //slope must be positive!!!
    Line2D getLinePosSlope(double x1, double y1, double x2, double y2, double p, double q, double d, double xmin, double xmax) {
	double xsamp, ysamp, dist;
	while (true) {
	    xsamp = (xmax+xmin)/2;
	    ysamp = (y2-y1)*(xsamp-x1)/(x2-x1)+y1;
	    dist = Math.sqrt((xsamp-p)*(xsamp-p)+(ysamp-q)*(ysamp-q));
	    if (Math.abs(dist-d)<1) break;
	    else if (dist<d) xmax = xsamp;
	    else if (dist>d) xmin = xsamp;
	}
	
	Line2D tmp = new Line2D.Double();
	tmp.setLine(xsamp,ysamp,p,q);
	return tmp;
    }
    //slope must be negative!!!
    Line2D getLineNegSlope(double x1, double y1, double x2, double y2, double p, double q, double d, double xmin, double xmax) {
	double xsamp, ysamp, dist;
	while (true) {
	    xsamp = (xmax+xmin)/2;
	    ysamp = (y2-y1)*(xsamp-x1)/(x2-x1)+y1;
	    dist = Math.sqrt((xsamp-p)*(xsamp-p)+(ysamp-q)*(ysamp-q));
	    if (Math.abs(dist-d)<1) break;
	    else if (dist>d) xmax = xsamp;
	    else if (dist<d) xmin = xsamp;
	}
	
	Line2D tmp = new Line2D.Double();
	tmp.setLine(xsamp,ysamp,p,q);
	return tmp;
    }
    
    //get a rectangle located parallel to line defined by (x1,y1) and (x2,y2), located at one end, and side length s.
    Line2D getParallelRect(double x1, double y1, double x2, double y2, double s) {
	double theta = Math.atan2(y2-y1, x2-x1);
	theta += Math.PI/2;
	
	Line2D tmp = new Line2D.Double();
	tmp.setLine((int)(x1+s*Math.cos(theta)), (int)(y1+s*Math.sin(theta)), (int)(x1+s*Math.cos(theta+Math.PI)), (int)(y1+s*Math.sin(theta+Math.PI)));

	return tmp;
    }
    
    //threading....
    public void run() {
	long lastRepaint = 0;
	long sleepTime = 0;

	while (true) {
	    //mark when we started
	    lastRepaint = new Date().getTime();
	    //do the work
	    counter+=counterInc;
	    repaint();
	    //calculate time we must sleep
	    sleepTime = 10 - (new Date().getTime() - lastRepaint);
	    try {
		if (sleepTime > 0) Thread.currentThread().sleep(sleepTime);
		else Thread.currentThread().yield();
	    } catch (java.lang.InterruptedException e) {}
	}
    }


}

Surface.java
Code:
import java.util.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;


/**
 * Surface is the base class for the 2d rendering.  Subclasses must
 * implement the render() method.
 */
public class Surface extends JPanel implements Runnable {


    public Object AntiAlias = RenderingHints.VALUE_ANTIALIAS_ON;
    public Object Rendering = RenderingHints.VALUE_RENDER_SPEED;
    public BufferedImage bimg;        
    public boolean clearSurface = true;

    private long orig, start, frame;
    private Toolkit toolkit;
    private int biw, bih;
    private boolean clearOnce;


    public Surface() {
        setDoubleBuffered(true);
        toolkit = getToolkit();
	new Thread(this).start();
    }

    public void setAntiAlias(boolean aa) {
        AntiAlias = aa 
            ? RenderingHints.VALUE_ANTIALIAS_ON
            : RenderingHints.VALUE_ANTIALIAS_OFF;
    }

    public void setRendering(boolean rd) {
        Rendering = rd
            ? RenderingHints.VALUE_RENDER_QUALITY
            : RenderingHints.VALUE_RENDER_SPEED;
    }

    //THESE METHODS MANAGE THE Graphics2D object and pass painting tasks to render()
    //Taken, in part, form demo/jfc/Java2D/java2d.Surface
    public BufferedImage createBufferedImage(Graphics2D g2, int w, int h) {
	BufferedImage bi = (BufferedImage) g2.getDeviceConfiguration().createCompatibleImage(w, h);  
        biw = w;
        bih = h;
        return bi;
    }

    public Graphics2D createGraphics2D(int width, int height, BufferedImage bi, Graphics g) {

        Graphics2D g2 = null;

        if (bi != null) {
            g2 = bi.createGraphics();
        } else {
            g2 = (Graphics2D) g;
        }

        g2.setBackground(getBackground());
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, AntiAlias);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, Rendering);

        if (clearSurface || clearOnce) {
            g2.clearRect(0, 0, width, height);
            clearOnce = false;
        }

        return g2;
    }

    public void paint(Graphics g) {
        Dimension d = getSize();

        if (bimg == null || biw != d.width || bih != d.height) {
            bimg = createBufferedImage((Graphics2D)g, d.width, d.height);
            clearOnce = true;
        }
	
	Graphics2D g2 = createGraphics2D(d.width, d.height, bimg, g);
        render(d.width, d.height, g2);
        g2.dispose();
	
        if (bimg != null)  {
            g.drawImage(bimg, 0, 0, null);
            toolkit.sync();
        }
    }
    //End of the painting methods.

    // ...implement this routine for painting...
    public void render(int w, int h, Graphics2D g2) {
    }
    
    
    //threading....
    public void run() {
    }


}

To the general internet audience: This code is presented for personal learning. I do this in my free time. Don't steal from me and make money off it!
 
Thanks skip,

Quick question. Is there an easy way to imbed mp3s/wavs/jpgs into the executiable itself, or do I have to have a bunch of folders with all of my sounds/music/images etc. that I refer to.

I'd like to protect some of that stuff if I can. But if not, oh well.
 
Thanks skip,

Quick question. Is there an easy way to imbed mp3s/wavs/jpgs into the executiable itself, or do I have to have a bunch of folders with all of my sounds/music/images etc. that I refer to.

I'd like to protect some of that stuff if I can. But if not, oh well.
No problem, if I have time I'll do my best to help with anything that comes up.

Java programs are distributed in jar files, which are just zip files with a specific file structure and a different extension. You can put any sort of audio or image file in the jar and access it from the program as if it was directly on the hard drive, but thats not much security. You can always just use DES encryption if it's really important.

EDIT: You'll see jar files autogenerated in the .\dist directory of your project if you use NetBeans.

Not all together that relevant to what you're doing, but if you did use C++/Win32, there are options to embed images in an .exe file, and they are pretty well hidden (but can still be extracted with the right tool).
 
I managed to get your example up and running (cool stuff, it'll take me a while to figure it out) and have read through most of the tutorials on the sun website. I've come a long way toward figuring out this whole object-oriented programming nonsense and I've learned how to import and manipulate images (the basics). I'm gonna call that a successful first day.

In general I have to say I'm really impressed with the NetBeans development suite. How is this stuff free? I feel like I should have paid a couple hundred bucks for that.
 
👍 Nice, Danoff. Cool that you're keeping the thread up-to-date with your progress, as well.

Importing and manipulating images is definitely non-trivial...and certainly not something I was doing the first day I started with Java :)
 
Just spent all afternoon trying to get a subset of the background loaded for the game - eventually I figured it out. Next I need to write a game loop that reads keyboard inputs to move the background around (I decided to have the background move and the main guy stay in one place). I made the background origin part of the image object so that I can change it with keyboard inputs, I guess I'll have to figure out how it redraws based on the updated coordinates.

After I get the background to move I need to get the background to wrap. Next I'll have to set triggers based on position to switch the backgrounds back and forth. Then I'll have made some real progress.

After that, I'll try to tidy things up and store them away so I can be sure that the game is scalable. This java business isn't as easy as it looks.
 
Java events--as you may have found out--are handled in listeners, which call a method every time an event is triggered. For keyboard events...you need the Key Listener: http://java.sun.com/j2se/1.3/docs/api/java/awt/event/KeyListener.html

Now, a few points:
1) while you are in a event handling method, everything else stops...no new events are trapped, and no UI updates are made until the method exits. This means you cant have a UI update loop inside a event handler
2) since a method is entered for every event, you can't turn that into a game loop

What I suggest:
1) you need to have 3 threads in your application. 2 are created automatically by Java--the main thread and the event thread. You also need to make a UI update thread (where the game loop would be). Events are trapped in the main thread--you won't need to really do anything there. Then java transfers control to the event thread when it calls your handler.
2) in the event handler (event thread) I would add the event to a list (Vector object in java) then just quit. Then in the game loop (UI thread) you can poll this Vector to see what events have been trapped.

This way you will have the most seamless response in your game.

:)
 
I think you're right. Right now I'm handling events in the game loop, but I should probably move as many of them out as possible - perhaps into some kind of trigger class that checks for events and processes them as necessary.

I worked on the game a bit more today and I accomplished a few big milestones.

- map scrolling in the background according to arrow keys
- hero icon changes depending on which keys were hit last (left facing after left key was hit, etc.)
- background changes when certain points are reached on the screen
- movement capability on the map is blocked so that the map mostly stays on the screen at all times.

I think my biggest problem right now is that I need to organize my code a bit. It isn't particularly scalable in its current state. My second biggest problem is that when my map pans across the screen, I can kinda see it draw. I'm not quite sure how to improve the refresh rate (I've played with a pause timer at the end of the game loop to no avail). Any tips on improving the redraw?
 
My second biggest problem is that when my map pans across the screen, I can kinda see it draw. I'm not quite sure how to improve the refresh rate (I've played with a pause timer at the end of the game loop to no avail). Any tips on improving the redraw?

Luckily, there is a nice trick that will improve the "flicker"...it's called double buffering.

Sun explains it better than I can: http://java.sun.com/docs/books/tutorial/extra/fullscreen/doublebuf.html

Actually, you'll see that that article is talking about a BufferStrategy class. Since I learned and coded on earlier versions of Java, I've never actually used this class, but I implemented the double buffering manually myself (you can probably find how I implemented it in that sample code I gave you). But it seems that using the class is much easier and will work just the way you want it to.

If you want to improve the FPS, there is no magic trick: you just have to be clever with what draw operations you do each time. Basically, the fewer Graphics.whatever calls you can make, the better off you are.
 
Will the main character be Dagny Taggart, and you have to build as many bridges as possible before James unwittingly destroys everything? :D

Uh&#8230; kay?

Sounds like an interesting project Danoff. 👍
 
Read Danoff&#8217;s reply &#8211; he knows exactly what I&#8217;m talking about. ;)
 
I make games, I'm soon learning (quite soon) C++ or C# To expand on it, I use GML though, Its quite easy. Although i'd take awhile to learn. Just as any others. It runs off an object type coding. Mainly If Statements and such. If you want, I could send you some tutorials. Heres the program you'll need www.yoyogames.com You may think its going to suck, A: Its free, B: It looks childish, But if you have seen some games responsible people that take time into there games, have made, you would be astonished.
 
Luckily, there is a nice trick that will improve the "flicker"...it's called double buffering.

Sun explains it better than I can: http://java.sun.com/docs/books/tutorial/extra/fullscreen/doublebuf.html

Actually, you'll see that that article is talking about a BufferStrategy class. Since I learned and coded on earlier versions of Java, I've never actually used this class, but I implemented the double buffering manually myself (you can probably find how I implemented it in that sample code I gave you). But it seems that using the class is much easier and will work just the way you want it to.

If you want to improve the FPS, there is no magic trick: you just have to be clever with what draw operations you do each time. Basically, the fewer Graphics.whatever calls you can make, the better off you are.



I think I'm already doing double buffering (or is it page flipping).

Outside my game loop I have this:
createBufferStrategy(2);
strategy = getBufferStrategy();

Inside the game loop:
Graphics2d g = (Graphics2D) strategy.getDrawGraphics();
strategy.show();


Is the "2" Buffer strategy not double buffering? The image doesn't draw nicely as it is.
 
Sorry for the slow response, I was moving to a new place.

That should work. If it still isn't good enough, try making more of your drawn items images instead of drawing them from lines.
 
I figured it's been a while since I updated this thread so I should let you guys know about my progress.

The graphics for the game are pretty much in place. I still have a ton of logic to work out, but it's really coming along quite nicely. I've still got a few things to work out when it comes to the fundamental game mechanics, but I can see the light at the end of the tunnel, and it shouldn't be long before I'm ready to start building levels and working out play balance - which should be more fun.

I'm actually done with the graphics (aside from the fact that I still don't like the redraw issues). I'm hoping that when I switch to a lower-resolution image those will clear up. When I say I'm done with the graphics, I mean I'm done with the graphic effects - I haven't even started on artwork yet, which is going to be challenging. I'm thinking that in order to get a shell working I'll just steal artwork from the internet and use it as a placeholder until I can either find an artist or do the artwork myself.

I also haven't gotten started on sound yet, or game saving.

Still lots of work to do, but I'm starting to get excited because a lot of the fundamentals are in place. Here's what I've gotten done that's new:

- Nested Menu logic
- Menu item selection and logic
- Word-wrapped text boxes for dialogue
- Map-based event triggers
- Fight sequences

I've still got some of the menu items to flesh out, but the menu logic is in place (at least for the main menu, not entirely for the fight menu).
 
I haven't been back to this thread in some time mostly because I don't have a whole lot of exciting progress to report. I got sound working, so that's something. Mostly I've been trying to make my life easier for level-building. I've found that if you don't streamline the process of getting maps put together in the code, it's a huge pain in the neck. So I've been trying to squeeze every last bit of automation out of my code so that I can plug a new level in and move on without spending a whole lot of time making it work.

I still have a little ways to go on that end, but there's a lot more I want to do in other areas. The further I dig into this the more appreciation I have for the effort that went into videogames that were popular 20 years ago, let alone what they're doing today.
 
Back