help/follow me evolve as a programmer[starting with Pong]!

Started by
21 comments, last by rip-off 11 years ago

Evolving as a programmer -- An active journal of my progress

LINK TO THE JOURNAL/BLOG

Hello! My name is Tim, I'am a first year computer engineer from sweden.

This year I learnt the basics of programming. That is, learning to crawl(learning programming basics using Python) and learning how to almost walk (learning some of the basics of object-oriented programming using Java).

I just finished the Java course, and found it highly entertaining. I do love programming, and can sit for hours just coding to see what I can do.

Already during the Python course, I felt that I wanted to create some type of game. But at that time, my programming experience was far too inferior to even think of anything graphical. But I still did not give in, and decided that the best way to learn was to try. So I made a very simple and meaningless(story-wise) text-based game that simply relied on inputing pre-determined words to move the game ahead.

This was fine, although looking back, it was ofcourse horribly coded. But we all start somewhere! sadly I no longer have the "game"-file.

However!


2 months after the Python course was finished, the Java course started, opening up a whole new world of impressions, resources and experiences. I loved it.

We learnt the basics of Java and widened our experience with the language every day.

My passion for wanting to make some type of game, any game. Drove me to go far beyond the basic lectures of our Java course.

And I started reading articles, forum posts, watching youtube tutorials etc. trying to learn more about where I should start and HOW I should start.

This brought me to a Java library for making 2d game, named slick2d.

For the last 2 months I have been familiarising myself with the library, learning about how to handle basic inputs, loading sprites, making simple(and without doubt, highly innefective) collission detections etc.

I've started on multiple projects, which naturally has led to me not getting anything done and probably only making my programming experience slow down much more then it has to.

(Note that I'am familiar with 2d game development from younger days, using RPG maker XP. But never did any scripting in it.)

I've been reading quite a hand full of articles here at gamedev.net the past 2-3 weeks, and found them very interesting and educational.

But I still feel that I'am too "wet behind my ears" to truly understand and implement the ideas and concepts from the articles that I've read.

This brings me to the topic.

I read a very interesting article here a few days ago. (Klick here to read it!).

It basicly said that in order to truly learn and evolve during your first steps as a game developer, you need to get one game done a time.
Not bothering making the biggest most innovative and advanced game ever built.

And as you complete game, you step up the difficulty each time.

So I decided, hey! This is exactly what I need to do. (with my own little twist of the whole idea ofcourse).

So 2 days ago, I started making a simple pong game using the slick2d and lwgl library for Java.

It currently containts the following:

  • Movable Brick
  • Moving Ball (randomly generated at start where it will move first)
  • Poor collission detection
  • score keeping
  • accelerating velocity of ball and brick based on number of times ball hits something (brick or walls)

What it's missing as far as I can imagine right now (Listed in order I believe it should be added):

  1. Object orientation (Everything is basicly just in one class atm)
  2. keep variables(data) and methods(behavior) of an object isolated within its own class. (added thanks to warnexus)
  3. Better input control/implementation
  4. better and more general collission detection
  5. enemy ai
  6. Probably something more that I've forgotten.

As you can see, the list is quite tall and large(in amount of work that has to be done).

My largest concern for the moment is how I should make it better object oriented.

For example, I know that in general I should make something like an entity class and then make a ball class and playerclass (and ai when the time comes) that inherits the entity class. This in it's turn, leads me to reason that the entity class should be abstract.

However, this is a problem for me because I'am not sure how I should make the entity class. Should it contain just a little thing, like an id method and something more, or should it be alot of code in it that handels alot of stuff. And then, if I have a playerclass for example, how would it handle inputs? So many questions...

Thats why I thought that maybe if I made this topic here, I would get help along the way (starting with this Pong game). And as I learn, get help and improve the game. I'll post my progress and how I did it.

This way, I will document my experiences and maybe(hopefully) they will help someone else in a common situation.

That is why, naturally:

All source code will be shared.

I will however, only have the latest "code build" available in this topic, but you can follow my active journal where I will document everything, including sourcecode for each build. ( thanks to ultramailman and j-locke for recomending making an actual journal instead of uploading everything in this topic.)

I hope the people of this community read this topic and help me in my progress of becoming a better programmer and game developer.

Any comments or questions are highly appreciated and I hope we all can help each other!

Now lets get busy!

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

PONG - VERSION 1 (THE BEGINNING)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Pictures:

[sharedmedia=gallery:images:3561]
[sharedmedia=gallery:images:3562]

Code:

GameSetup (basicly the window that the game is in)


package engine;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

public class GameSetup extends StateBasedGame {
	private static int width = 720;
	private static int height = (width / 12 * 9);
	public GameSetup(String name) {
		 super("Main Game");
		
	}
	
	public static void main(String args[]) {
        AppGameContainer app;
        try {
            app = new AppGameContainer(new GameSetup("Pong"));
            app.setDisplayMode(width, height, false);
            app.start();
        } catch (SlickException ex) {
            ex.printStackTrace();
        }
    }

	@Override
	public void initStatesList(GameContainer gc) throws SlickException {
		this.addState(new PongGame());
		
	}

}

PongGame (The actual game)


package engine;

import java.util.Random;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.KeyListener;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class PongGame extends BasicGameState implements KeyListener {
	
	private boolean gameStarted = false;
	private Random randomBool;
	private String start = "A self-educational game by Tim Granström\n\n         Press SPACE to start game.";
	private int width;
	private int height;
	private float pongY = 150.0f;
	private int pongLength = 55;
	private float velocityBall = 0.3f;
	private float velocityPlayer = 0.3f;
	private float ballX = -600.0f;
	private float ballY = -150.0f;
	private Input input;
	private boolean goLeft = true;
	private boolean goDown = true;
	private int score = 0;
	private int bestScore = 0;
	private String scoreBoard = "Current Score: ";
	private String scoreBestBoard = "Best Score: ";

	public void init(GameContainer gc, StateBasedGame sbg)
			throws SlickException {
		gc.setTargetFrameRate(60);
		input = gc.getInput();
		width = gc.getWidth();
		height = gc.getHeight();
		randomBool = new Random();

	}

	public void render(GameContainer gc, StateBasedGame sbg, Graphics g)
			throws SlickException {

		// draw and color the brick, walls and ball.
		g.setColor(Color.white);
		g.drawString(scoreBoard+score, 85, 10);
		g.drawString(scoreBestBoard+bestScore, 280, 10);
		g.drawString(start, (width/2)-150, (height/2)-40);
		g.fillRect(5, pongY, 7, pongLength);
		g.fillRect(0, 0, width, 8);
		g.fillRect(0, height - 8, width, 8);
		g.fillRect(width - 8, 0, 8, height);
		g.setColor(Color.blue);
		g.fillOval(ballX, ballY, 15, 15);

	}

	public void update(GameContainer gc, StateBasedGame sbg, int delta)
			throws SlickException {
		
		if(!gameStarted){
		if (input.isKeyDown(Input.KEY_SPACE)) {
			goLeft = randomBool.nextBoolean();
			goDown = randomBool.nextBoolean();
			ballX = 600.0f;
			ballY = 150.0f;
			gameStarted = true;
		}
		}
		if(gameStarted){
		start = "";
		
		// move brick up
		if (input.isKeyDown(Input.KEY_UP) || input.isKeyDown(Input.KEY_W)) {
			if (pongY > 8) {

				pongY -= velocityPlayer * delta;
			}
		}
		// move brick down
		if (input.isKeyDown(Input.KEY_DOWN) || input.isKeyDown(Input.KEY_S)) {
			if (pongY < height - (8 + pongLength)) {
				pongY += velocityPlayer * delta;
			}
		}

		// check if ball collide with brick on left.
		if (collideXLeft()) {
			goLeft = false;
		}

		// check if ball collide on right
		if (collideXRight(width - (15 + 10))) {
			score++;
			goLeft = true;
		}
		
		if(collideYDown()){
			goDown = false;
		}
		if(collideYUp()){
			goDown = true;
		}

		// if ball is moving to the left
		if (goLeft == true) {
			ballX -= velocityBall * delta ;
		}
		// if ball is moving to the right
		if (goLeft == false) {

			ballX += velocityBall * delta;
		}
		
		// if ball is moving up
		if (goDown == false){
			ballY -= velocityBall * delta;
		}
		
		// if ball is moving down
		if (goDown == true){
			ballY += velocityBall * delta;
		}
		
		if(ballX<0){
			if(score > bestScore){
				bestScore = score;
			}
			score = 0;
			velocityBall = 0.3f;
			ballX = 600.0f;
			ballY = 150.0f;
			gameStarted = false;
		}
		}

	}

	private boolean collideXLeft() {

		if (pongY - 15 < ballY & ballY < pongY + pongLength+15) {

			if (ballX < 13 & ballX > 6) {
				velocityBall += 0.0015f;
				velocityPlayer += 0.0013f;
				return true;
			} 
			else {
				return false;
			}
		}
		else {
			return false;
		}

	}

	private boolean collideXRight(int widthEdge) {
		if (ballX > widthEdge) {
			velocityBall += 0.001f;
			velocityPlayer += 0.0008f;
			return true;
		} else {
			return false;
		}

	}
	
	private boolean collideYDown() {
		if (ballY > height-8-20) {
			velocityBall += 0.001f;
			velocityPlayer += 0.0008f;
			return true;
		} else {
			return false;
		}

	}

	private boolean collideYUp() {
		if (ballY < 8) {
			velocityBall += 0.001f;
			velocityPlayer += 0.0008f;
			return true;
		} else {
			return false;
		}

	}
	
	@Override
	public int getID() {
		return 0;
	}

}

Eclipse Project file:

Here

Thank you for your time!

Cheers.
Tim.

Advertisement

It's nice you got the game to set up correctly. You're correct, you do need a ball class and Player class. You also need a brick(more appropriately called a paddle in Pong or in Breakout) class. So something like this:

4 classes

Ball

Game

Player

Paddle

ScoreMenu

It's far more important than going any further in your game development: to keep your variables(data) and methods(behavior) of an object isolated within its own class. This should be the next best step. This will create a manageable code base and allow you to traverse through the code base much easier no matter how many classes made up the game.

Nice work and good luck!

Thank you very much for you reply!

you do need a ball class and Player class. You also need a brick(more appropriately called a paddle in Pong or in Breakout) class.

I see what you mean!

Did I understand you correctly that this Paddle is the actual "brick" in my case, and that it should be controlled by implementing the Player class?

In my head, I imagined the Player class to include/be the actual Paddle.
But if this is ineffective or bad for other reasons, I'd love an explanation on why!

Also, would making an Entity class be 'overkill' or not so nessecary in my case?

keep your variables(data) and methods(behavior) of an object isolated within its own class. This should be the next best step.

I completely get what you mean! The list has been edited accordingly.

Hmm why not make a journal using the "Developer Journal" feature of this site?

http://www.gamedev.net/blogs

Thank you very much for you reply!

you do need a ball class and Player class. You also need a brick(more appropriately called a paddle in Pong or in Breakout) class.

I see what you mean!

Did I understand you correctly that this Paddle is the actual "brick" in my case, and that it should be controlled by implementing the Player class?

In my head, I imagined the Player class to include/be the actual Paddle.
But if this is ineffective or bad for other reasons, I'd love an explanation on why!

Also, would making an Entity class be 'overkill' or not so nessecary in my case?

>

keep your variables(data) and methods(behavior) of an object isolated within its own class. This should be the next best step.

I completely get what you mean! The list has been edited accordingly.

Yes it is called a paddle. It would be weird to whack a ball with a brick. happy.png Might be heavy and difficult to play the game.

It is actually the other way around. If you think about it in the object oriented sense: each player should have their own paddle and their own score. You can make the paddle object be inside the Player class based on what I said previously. I would not make the paddle be the actual player because the player is controlling the paddle and the player is not necessarily a paddle.

Hmm why not make a journal using the "Developer Journal" feature of this site?

http://www.gamedev.net/blogs

I agree with this. Sharing your experiences is a very cool idea. But a forum will be a pretty poor way to do that about the time you're posting your 3rd update. A blog or journal sounds like exactly what you need.

GameDev has dev journals available. Google has Blogger available. WordPress has WordPress.com blogs available. And all for free. Pick one and go to town. And don't forget to share a link to it, where ever you end up posting at.

Hmm why not make a journal using the "Developer Journal" feature of this site?

http://www.gamedev.net/blogs

I agree with this. Sharing your experiences is a very cool idea. But a forum will be a pretty poor way to do that about the time you're posting your 3rd update. A blog or journal sounds like exactly what you need.



GameDev has dev journals available. Google has Blogger available. WordPress has WordPress.com blogs available. And all for free. Pick one and go to town. And don't forget to share a link to it, where ever you end up posting at.

Good idea, thanks! I have made a journal that I will update, and I will only "update" this topic with the latest builds, instead of adding them all into the topic. This was very reasonable smile.png

link can be found here and in the starting-post.

Thank you very much for you reply!

you do need a ball class and Player class. You also need a brick(more appropriately called a paddle in Pong or in Breakout) class.

I see what you mean!

Did I understand you correctly that this Paddle is the actual "brick" in my case, and that it should be controlled by implementing the Player class?

In my head, I imagined the Player class to include/be the actual Paddle.
But if this is ineffective or bad for other reasons, I'd love an explanation on why!

Also, would making an Entity class be 'overkill' or not so nessecary in my case?

"1365622876">&gt

;

keep your variables(data) and methods(behavior) of an object isolated within its own class. This should be the next best step.

lockquote>

I completely get what you mean! The list has been edited accor

dingly.

Yes it is called a paddle. It would be weird to whack a ball with a brick. happy.png Might be heavy and difficult to play the game.

It is actually the other way around. If you think about it in the object oriented sense: each player should have their own paddle and their own score. You can make the paddle object be inside the Player class based on what I said previously. I would not make the paddle be the actual player because the player is controlling the paddle and the player is not necessarily a paddle.

Haha yes that seems to make sense. ;)

Ah I see. Then, the Player class needs to handle the input then?

Let the game class handle the input

yes, I figured that out just a few minutes ago, I'm just about to start making an abstract Entity class and a Player class!

I've gotten my entities to work, but I'am having problem with the collision detection..

The problem is that, when I check if the player and the wall collide, it seems like it can't keep up with the collision detection..

For example: sometimes the paddle stops at the wall, sometime it doesn't, and it seems to be directly related to how "fast" the player moves.


package engine;

import engine.entities.Ball;
import engine.entities.Player;
import engine.walls.Wall;

public class CollisionDetection {
	private float x1,x2,y1,y2;
	
	
	//Check if ball and player entity intersect.
	public boolean collidesWith(Ball b, Player p){
		this.x1 = b.getX();
		this.y1 = b.getY();
		this.x2 = p.getX();
		this.y2 = p.getY();

		return collideCheck(b.getWidth(),p.getWidth(),b.getHeight(),p.getHeight());
		
	}
	
	//not finished.
	public boolean collidesWith(Ball b, Wall w){
		this.x1 = b.getX();
		this.y1 = b.getY();
		this.x2 = w.getX();
		this.y2 = w.getY();
		
		return true;
	}
	
	
	//Check if player entity and wall obstacle intersect
	public boolean collidesWith(Player p, Wall w){
		this.x1 = p.getX();
		this.y1 = p.getY();
		this.x2 = w.getX();
		this.y2 = w.getY();
		
		return collideCheck(p.getWidth(),w.getWidth(),p.getHeight(),w.getHeight());
		
		
	}
	
	
	//Check if objects intersect
	private boolean collideCheck(float width1,float width2, float height1,float height2){
		
		float deltaX;
		float deltaY;

		deltaX = delta(this.x1,this.x2);
		deltaY = delta(this.y1,this.y2);

		float halfWidth_x1 = width1/2;
		float halfHeight_y1 = height1/2;
		
		float halfWidth_x2 = width2/2;
		float halfHeight_y2 = height2/2;
		
		float gapBetweenX = deltaX - halfWidth_x1 - halfWidth_x2;
		float gapBetweenY = deltaY - halfHeight_y1 - halfHeight_y2;
		
		if(gapBetweenX>0 || gapBetweenY>0){
			return false;
		}
		
		if(gapBetweenX == 0 && gapBetweenY == 0){
			return false;
		}
		
		else{
			return true;
		}
		
	}
	
	//get delta of 2 values.
	private float delta(float x1, float x2){
		
		if(x1>x2){
			return x1-x2;
		}
		else{
			return x2-x1;
		}
		
	}
}


Is there a way to make this more effective?

Note that

each object (player, wall,ball) holds their current x,y-cords, width and height.

The collision detection is loosely based on the first part of this article (Projection along an arbitrary axis).

Any help, suggestions or explanations as to why this is happening or how to resolve this I would greatly appreciate. smile.png

Also note that the collission check between ball and player is working fine..

Is there a better (but still simple) way to do this kind of collision detection?

This topic is closed to new replies.

Advertisement