Sign in to follow this  
timgranstrom

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

Recommended Posts

timgranstrom    718

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.

Edited by timgranstrom

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

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!

Edited by warnexus

Share this post


Link to post
Share on other sites
timgranstrom    718

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.

Edited by timgranstrom

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

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.

Share this post


Link to post
Share on other sites
j-locke    945

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.

Share this post


Link to post
Share on other sites
timgranstrom    718

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?

Share this post


Link to post
Share on other sites
timgranstrom    718

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?

Edited by timgranstrom

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

The easy way to test collision detection between a ball and a paddle would be to use the Rectangle class built into the Java language. And use that class intersects method. The Rectangle class works well for oval, circle and rectangle shaped object for perfect collision.

 

Something like this:

 

ball.getRectangle().interesects(paddle.getRectangle());

 

The code that test to make sure the paddle does not go off the screen should not depend on the player velocity. It has to do with the position(represented by the x and y coordinates) of your paddle. I find it strange that your paddle sometimes stop at the wall and sometimes it does not. There should be no randomness. You can track the bug using println and see where the problem lies. 

 

The player is not moving. Your Player should only have basic information like "what score does the player?" and "name of the player".

 

Your paddle are moving. So the drawing movement code and the variables associated with it should be in Paddle class not the Player Class. 

Edited by warnexus

Share this post


Link to post
Share on other sites
timgranstrom    718

ball.getRectangle().interesects(paddle.getRectangle());

So I wouldn't need a collision class then?

 

You can track the bug using println and see where the problem lies.

 

I will do this! But using the Rectangleclass I think it will solve it self.

 

The player is not moving. Your Player should only have basic information like "what score does the player?" and "name of the player".

hmm okay, but then how will I actually controll the paddle? Basicly the Player class shouldn't be an actual entity then? but rather just a class that holdes these variables?

 

Earlier, you said:

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.

I think that I get that..

I made it so that when I make a player object, a paddle object is always made inside the playerclass aswell. But how should I controll the paddle in the actual game loop if I don't have a way of controlling it in there?

 

This is my Entity code:

package engine.entities;

import org.newdawn.slick.Graphics;

public abstract class Entity {

	//x & y = x-coord & y-coord in game, width & height = width & height of the entity.
	protected float x,y;
	protected float velocity = 0.3f;
	protected int width,height;
	private boolean removed = false;
	
	public Entity(float x, float y){
		this.x = x;
		this.y = y;
	}
	
	public void render(Graphics g){
		
	}

	//Get width of entity
	public int getWidth(){
		return this.width;
	}
	//Get height of entity
	public int getHeight(){
		return this.height;
	}

	//get x-coord
	public float getX(){
		return this.x;
	}
	//get y-coord
	public float getY(){
		return this.y;
	}

	//Get velocity of entity
	public float getVelocity(){
		return this.velocity;
	}
	
	//Set remove-flag for an entity
	public void remove(){
		this.removed = true;
	}
	
	//Check the remove-flag for an entity
	public boolean checkRemoved(){
		return this.removed;
	}
}

This is my Player Code:

package engine.entities;

import org.newdawn.slick.Graphics;

public class Player extends Entity{
	private float xd,yd;
	private boolean goLeft = true; //not used for now
	private boolean goDown = true; // not used for now
	private Paddle paddle;
	
	//Constructor: Every time a Player object is made, a Paddle object is created for it.
	public Player(float x, float y) {
		super(x, y);
		this.width = 7;
		this.height = 55;
		paddle = new Paddle(this.x, this.y, this.width, this.height);
	}
	
	//Updates the actual position of the player
	private void movement(){
		this.x += this.xd*this.velocity;
		this.y += this.yd*this.velocity;
	}
	
	//sets X direction movement of player
	public void setXDir(float xd){
		this.xd = xd;
	}
	
	//sets Y direction movement of player
	public void setYDir(float yd){
		this.yd = yd;
	}
	
	//render the actual player entity(in this case, a paddle is rendered by the player Entity).
	public void render(Graphics g){
		this.movement();
		paddle.move(this.x, this.y);
		paddle.render(g);
		
	}

}

And finally this is my Paddle code:

package engine.entities;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;

public class Paddle extends Entity {

	private Color paddleColor = Color.white;
	
	//Constructor.
	public Paddle(float x, float y, int width, int height){
		super(x,y);
		this.width = width;
		this.height = height;
	}
	
	//Move the paddle
	protected void move(float x, float y){
		this.x = x;
		this.y = y;
	}
	
	//set new height of paddle
	protected void setHeight(int height){
		this.height = height;
	}
	
	//set new width of paddle
	protected void setWidth(int width){
		this.width = width;
	}
	
	//renders the paddle graphics.
	public void render(Graphics g){
		g.setColor(this.paddleColor);
		g.fillRect(this.x, this.y, this.width, this.height);
	}
	
}

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

Sure, if you get the collision to work, you can have a collision class if you want to isolate your functionality even further. 

 

To make the paddle move involves 3 things:

1) You would implement a KeyListener interface for your Paddle which is a set of methods associated with the KeyListener interface.

2) Add KeyListener to your Paddle.

3) Once you implemented the KeyListener interface, you need to override the methods from that interface so you can create very own desired effect of what should happen if a user presses a certain key which causes the paddle to move a certain direction.

3) The methods you override from the interface are called automatically for you by the parameter KeyEvent object when your added KeyListener has listened for a KeyEvent generated by the user. 

 

an example of the override method:

 

public void keyPressed(KeyEvent e)

{

 

 

 

Feedback on your code:

1) the boolean variables goLeft and goRight should be in the paddle. Why does player have width and height if your paddle has those variables already? Paddle should have the movement code not the Player.

2) I do not think an Entity class is necessary, it save you an extra class you do not need for a Pong Game. The reason being Paddle has position x,y and width and height but Player do not need these variables in the game. You should be moving and testing collision on the Paddle not the player. Player should only have to keep track of their own score and their own name. 

3) I made a mistake from what I told you yesterday. In this case, since your game has paddle being added into the game then each paddle should hold a Player object for (name and score). So, you were correct, Player object should be inside the Paddle class.

Edited by warnexus

Share this post


Link to post
Share on other sites
timgranstrom    718

To make the paddle move involves 3 things:

1) You would implement a KeyListener interface for your Paddle which is a set of methods associated with the KeyListener interface.

2) Add KeyListener to your Paddle.

3) Once you implemented the KeyListener interface, you need to override the methods from that interface so you can create very own desired effect of what should happen if a user presses a certain key which causes the paddle to move a certain direction.

3) The methods you override from the interface are called automatically for you by the parameter KeyEvent object when your added KeyListener has listened for a KeyEvent generated by the user.



an example of the override method:



public void keyPressed(KeyEvent e)

{



}

 

The problem with this is the updates, within the paddle it'd look something like this then right? (note I'am using a KeyListener interface from the slick2d library which is slightly different from the KeyListener interface from the Java library.):

 

public void keyPressed(int key, char c) {
			if (key == Input.KEY_W || key == Input.KEY_UP) {
	           this.setYDir(-1*delta); //Moves the paddle up.
	        } else if (key == Input.KEY_S || key == Input.KEY_DOWN) {
	        	this.setYDir(-1*delta); //Moves the paddle down.
	        }
	    }

The problem here is the delta, if I don't update the paddle with the delta I get from the game loop update function, it won't update correctly, and the paddle will move ultra fast..

 

also, if I have a keylistener interface implemented in the paddle object, will it be enough to just create the object in the game loop for it to actually draw and everything?

like, all I need is to put it in the render method of my game loop? I'm not sure about how to think about all of this, and then I'm having a hard time visualising the outcome..

Edited by timgranstrom

Share this post


Link to post
Share on other sites
timgranstrom    718

1) You would implement a KeyListener interface for your Paddle which is a set of methods associated with the KeyListener interface.

2) Add KeyListener to your Paddle.

3) Once you implemented the KeyListener interface, you need to override the methods from that interface so you can create very own desired effect of what should happen if a user presses a certain key which causes the paddle to move a certain direction.

3) The methods you override from the interface are called automatically for you by the parameter KeyEvent object when your added KeyListener has listened for a KeyEvent generated by the user.



an example of the override method:



public void keyPressed(KeyEvent e)

{



}

 

I need some serious help with the implementation.. I've been trying for 3 hours to no use..

I just can't get it to work..

I've implemented the KeyListener to the paddle.

public class Paddle extends Entity implements KeyListener {

but when I try to add a KeyListener with the

addKeyListener(this);

I only get the error that the method doesn't exist, I've tried using it in the main game loop aswell like this:

this.addKeyListener(paddle);

but to no use.. I'am completely confused why I can't add a listener to it...

Share this post


Link to post
Share on other sites
Nicholas Kong    1535
import java.awt.event.*;
 
I never use slick2d but if you use the code above, your class that imports this library will know about other the functionality of classes in the java awt event library. This event library is needed if you decide to add any features that involves the mouse or the keyboard. If you are using another library, you should still be able to use standard Java library.
 
It seems you already made the paddle move then. The KeyListener interface is one of the steps needed to be implemented to make you be able to move your paddle with keys on your keyboard.
 
On a side note: avoid magic numbers in your code. Pretty much any value in a program that is not assign a variable is a magic number. For example: -1 is a magic number.  You should replace it with a general variable name so other people looking at the thread can help you too. I would not know what -1 mean in your code even though you know what it is.
 
On another side note: do not panic. It will be okay. This is the nature of general programming and programming games. Stick with it and struggle, you will learn a lot from your mistakes. Everyday is a progress. You will later find out, it will be worth it in the end. You might want to have a pencil and a paper handy and trace through your code carefully line by line.
 
A general rule of thumb your game constructor should be the one setting up the game(ie: setup the paddles and ball in the game).
After that your gameloop starts running. Your gameloop should be the method that draws and updates the game objects (paddle,ball,score)

Share this post


Link to post
Share on other sites
timgranstrom    718

I finally found where the 'addKeyListener()' method was in slick2d, it's in the gamecontainer, which makes sense since the method needs to use a frame!

 

However I'm not sure as to how I should implement it..?

 

since the object doesn't use a gamecontainer, should I send the gamecontainer to the object when I create it?

example:

//Constructor.
	public Paddle(float x, float y, int width, int height,GameContainer gc){
		super(x,y);
		this.width = width;
		this.height = height;
		this.player = new Player();
		gc.getInput().addKeyListener(this);
		
		
	}

 

or should I add it to where I initialize the game loop?

example:

public void init(GameContainer gc, StateBasedGame sbg)
			throws SlickException {
		gc.setTargetFrameRate(60);
		input = gc.getInput();
		width = gc.getWidth();
		height = gc.getHeight();
		randomBool = new Random();
		paddle = new Paddle(5,150,7,55,gc);
		//collision = new CollisionDetection();
		ball = new Ball(ballX,ballY,15,15);
		wallUp = new Wall(0,0, width, 8);
		wallDown = new Wall(0, height - 8, width, 8);
		wallRight = new Wall(width - 8, 0, 8, height);
		gc.getInput().addKeyListener(paddle); //Should the addKeyListener look like this and be here??
	}

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

Although both code would perform the same type of action. 

 

I never used Slick2D, but you could take advantage of inheritance and try creating a Game class that extends GameContainer very much like in Standard Java where you would do code like this : Game extends Canvas.

 

Can you add a paddle onto a GameContainer? If so then you are try something similar like:

 

 

public class Game extends GameContainer
{
 
public void int()
{
 
 
Paddle paddle = new Paddle(x,y,width,height);
getInput().add(KeyListener(paddle);
add(paddle);
}
 
}

 

This should eliminate passing the GameContainer as a parameter to your object or method everytime and make your codebase look more cleaner and well structured. 

Edited by warnexus

Share this post


Link to post
Share on other sites
timgranstrom    718

I've tried using both of them, but none works.. it seems as if it doesn't really listen and to the object if a key is pressed..

 

I'am not sure what the problem is, I've tried using a simple println to check if it ever recieves anything, but it prints nothing...

 

 

-------EDIT---------

 

I found the problem, I'am now cleaning up the mess!

 

----EDIT 2---------

 

I'am done with build 2 now, it's too late for me to update the journal right now since I want to comment as much as I can about the changes, whats change, and why I've changed it the way I have etc..

 

It's already 10.55PM here and I've got school early tomorrow, but I will try to get the build uploaded and journal updated tomorrow.

 

also, a giant thanks to warnexus who has been alot of help to me when I've hit an obstacle!

Edited by timgranstrom

Share this post


Link to post
Share on other sites
timgranstrom    718

I've updated the journal with all the new source code and uploaded the eclipse file aswell as pictures of it.

 

I was hoping anyone could check the code out and comment what I did good, bad and what I need to improve etc from your perspective!
This would be a great way for me to learn from it smile.png

I will keep posting in this topic as I progress with the game, I'm sure I'll have a few questions regarding this project!

Thanks!

Edited by timgranstrom

Share this post


Link to post
Share on other sites
Nicholas Kong    1535

The code you posted up contains 2 classes:

GameSetup

PongGame

 

For a game or any type of software application, the codebase must be broken up into multiple classes so your codebase can be maintained and reusable. In programming, an application is only good if you can reuse the code for let's say another project or easy to maintain so when someone else looks at your code and want to add a new feature they can easily look at your code and say "I understand what he did". Explain why you wrote the code the way you did using comments. We can't read your mind about what you did.

 

Learn and understand how to restructure your code which is a process of moving and tweaking your code around so the code can be easy to and reusable.

 

The issue I see is with the PongGame class. PongGame class is consider to be a "godclass"(at least for the time being) which means it is a class that knows too much about the internal implementations of other objects in your game (whether it be variables or methods of other objects). You want to have all the variables and methods of Ball inside a new class you create called Ball. So create a new class called Ball and put all those variable there and then create the Ball object inside the PongGame class. 

 

What PongGame class is suppose to know is that it only needs to set up the objects in the game not have variables of the Ball. So when it is time to start the game loop, it knows it needs to load the ball, paddle, score and then in game loop: draw and update and check for collision.

 

Why would you want to do this? Let's say you want to add a new feature, instead of a ball moving in the game, I want to replace it with something else that is constructed differently than your Ball. You would have to erase all the variables and methods that is part of the Ball in your PongGame and that would be a pain to do. 

 

If you wrote a new class called Ball. Chances you only need to erase this line of code:

 

Ball ball = new Ball();

add(Game);

 

So it is important to think long term about re-usability, maintainability and adding new features.

 

And the issue is not only about the Ball. Your game can be restructure like this:

Score

Paddle

Game

Ball

Collision

 

Another important thing is to avoid using magic numbers.

An example from your code is this:

 

You may know what this is now: But what about one year from now?

 

(width/2)-150, (height/2)-40 

 

You want to assign the number 150 to a variable and write what the variable is used for.

Same thing for 40. It seems to be an offset value to me but to what exactly

the offset value is suppose to do I would not know because I cannot read your mind.

With clear variable assigned to the number, this offset value is much more clear about what it is.

 

an example that is much more clear would be:

int stringOffsetX = 150;

int stringOffsetY = 40;

 

(width/2) - stringOffsetX, (height/2)-stringOffsetY;

 

this looks way better, right?

 

I hope these ideas help you to restructure your codebase so the code can be reusable, maintained and adding new features or removing current features are a breeze.

Edited by warnexus

Share this post


Link to post
Share on other sites
timgranstrom    718

My apologies! I forgot to edit the topic update, here is a link to the new version of the game!

 

Here!!

 

I do understand your reasoning though, and just realised that I've got a few magic numbers left, such as the string code!

 

I would love it if you maybe could review the new code!

 

Thank you :)

Share this post


Link to post
Share on other sites
rip-off    10976

Please keep using your journal, but only use the forums for specific questions.

 

We have a new trend of posting "code review" requests, you may create threads for that.

Edited by rip-off

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Similar Content

    • By Jacob Laurits Besenbacher Kjeldsen
       
      Intro - "The challenges of dynamic system design"
      Custom Quest evolved during development, from a minor quest system used for our own needs in our own game production Quest Accepted, to something entirely more dynamic and customizable, now finally released, these are our thoughts on quest design and developing standalone subsystems. 
      Splitting what is a major production for a small indie team, into smaller installments such as a quest system was a good idea we thought, this way we can get some releases out there and fuel the development of our game. But building a system that works for yourself is one thing, building a unity plugin that will let other developers create quests, missions, and objectives, you would never have thought of is something else entirely.
      The first thing we had to realize was that when building a quest system, the task is not to design great quests, the task is to enable the users to create great quests.
      That still meant we had to find out what good quest design is and what a quest really is.
      Our task was to create a system where the user is free to create creative engaging and rewarding mission experiences for their players.
      What is a quest? - "Cut to the core"
      First off, we need to know what a quest really is.
      A quest is the pursuit, search, expedition, task or assignment a person(s) does in order to find, gain or obtain something.
      In games, quests and missions function in many different ways depending on the genre.
      A single game can contain a multitude of different types of quests put together in just as many ways. In an MMO, for instance, quests are vehicles for the story and the player's progression. In many cases they are formulaic and simple, some can even be repeated, there are hundreds of them and everyone can do them. In other games quests are for single player campaigns only, here they shape each level giving the player a sense of purpose.
      Quests can span the whole game or just be a minor optional task on the way, there are so many design philosophies and creative quest designs that we had to narrow it down and really cut to the core of what is needed for good quest design.
      What all quests have in common is the task, the criteria for successful completion of the quest, and the reward, the goal of the quest, what the player gets out of doing what we ask of him.
      Quests cover an incredible variety of tasks so it was important for us to base our decisions on thorough research. In our research, we found that there are three layers to quest design.
      The type, the pattern and the superstructure.
      Quest types exist within quest patterns and quest patterns exist within the quest superstructure.
      We found that there are 8 basic types of quests these are the various tasks/criteria the player must do in order to complete the specific quest.
      There are 12 quest patterns. These are ways designers can use their quests, connect multiple quests set them up in engaging ways or teach players how to interact with and get the most out of the game world creating variety and engaging the player.
      Enveloping the patterns is the quest superstructure, the overall structure of quests in the game, we found that there are two main ways of structuring your quests.
      Historically quest have a quest giver, an NPC or object that informs the player about the quest, what they need to do, the story behind it and perhaps even what their reward will be should they complete the quest.
      Quest types - "Do this, do that"
      The core task each quest consists of, the criteria for completing part of or all of a single quest. These are the actions we want Custom Quest to be able to handle.
      Kill
      Probably the most basic quest type, the task is to kill something in the game, for example; kill 10 goblins. Gather
      Again very simple, the task is to gather x things in the game world, collecting berries or the like. Escort
      The player must escort or follow a person or object from point A to B while keeping it safe. FedX
      The player is the delivery boy, they must deliver an item to a person or point. Defend
      The player has to defend a location from oncoming enemies, often for a set number of waves or time. Profit
      The player must have a certain amount of resources to complete the quest, contrary to gather quests these resources are resources the player would otherwise be able to use himself. Activate
      The player's task is to activate/interact with one or more objects in the game world or talk to a number of NPC’s. In some cases, this must be done in a certain order for a puzzle effect. Search
      Search an area, discover an area of the game world. This is useful for introducing areas of the map to the player and giving them a sense of accomplishment right off the bat, showing them a new quest hub or the like. Quest Patterns - "An engaging experience"
      Tasks are one thing, and in many games, that might be plenty but we wanted custom quest to let the users create chains of quests, specialize them and set them up in ways that draw the player into the experience, there are many ways to go about this.
       
      Arrowhead
      The most basic quest pattern, the quest chain starts out broad and easy, the player has to kill some low-level cronies. The next quest is narrower, the player must kill fewer but tougher enemies, lets say the boss' bodyguards. The last quest is the boss fight, the player has killed the gang and can now kill the boss. This quest pattern is very straightforward and works well, giving rewards either at every stage or only when the boss is dead.  
      Side stub 
      A side stub is an optional part of the overlapping quest. Lets say quest A leads to quest C but there is an option to complete a side objective B, which makes completing C easier or it changes the reward, for example. The player must escape prison, the side stub is “free the other prisoners” in this example escaping with all the prisoners is voluntary but it might make it easier to overpower the guards or the prisoners might reward the player when he gets them out. The side stub differs from a generic side quest in that it is tied to the main quest directly.  
      Continuous side-quests
      These are side-quests that evolve throughout the game, one unlocks the next, but they are also affected by external requirements such as story progress. This pattern is often found with party members in RPG games, where the player must befriend the party member to unlock their story quests.  
       
      Deadline
      As the name implies these quests are time sensitive. The task can be of any type, the important thing is that the quest fails if time runs out. This could also be used for a quest with a side quest where the side quest is timed for extra rewards but the main objective is not.  
       
      Deja-vu quests
      This kind of quest pattern gives the player a quest they have done or seen before. In some cases, this “new” quest will have a twist or something that sets it apart. It can also be the same sort of quest that exists in different areas of the game world, perhaps there is more than one goblin camp? or perhaps the player has to pick berries daily.  
       
      Delayed impact
      Delayed consequences of a previous decision. Often used in games where the story is important and the players’ choices matter. These quests are tied together without the player knowing. Let's say the player is set the optional task of giving a beggar some gold to feed himself. The player gives the beggar a few gold and is on his way. The next time he meets the beggar the beggar has become rich and rewards the player for his kindness with ten times what he gave.  
      One of many
      The player is presented with a number of quests, they have to choose which one to complete, they can only choose one. The others will not be available.  
       
      Hidden quests
      Hidden tasks that aren’t obviously quests at first glance or are hidden away for only the most intrepid players to find. This could be an item the player picks up with an inscription in it if the player then finds the person the inscription is about he can get a reward for delivering it. A good quest pattern for puzzles, these kinds of quests can really make the game world come alive and feel a lot more engaging, allowing the player to uncover secrets, Easter eggs and discover all of the world created for them   
      Moral dilemma
      Punish the bread thief who stole to feed his family? often used in games that have a good/ evil alignment level for the players, these kinds of quests make the player make a choice about what kind of character they want to play, they get to choose if their character is good or evil.  
       
      Side quests
      Optional quests, these quests are often found in level based games where the overall quest must be completed to get to the next level, the player can optionally do some extra tasks to get more points. The important part is that these are optional but they give the player a reward for, getting everything they can out of the game.  
       
      Tournament
      Tournament style quests, a series of quests that get harder as the player progresses. An example could be a gladiatorial arena if the player defeats five enemies one after the other he gets rewarded as the champion of the arena, but if for example, he fails at the third, the whole tournament is failed and he has to start all over from quest 1.  
       
      Vehicle missions
      Despite the name these quests are not confined to being about cars, these are simply quests where the players control scheme changes to complete the quest(s). An example could be; changing from running around in the game world to driving a tank to destroy a fort.  
      Quest superstructure - "The whole package"
      With quest superstructures, we are venturing into general game design. The superstructure is how the player is allowed to complete quests in the game world. It's basically a question of whether the game is “open world” or a linear experience.
       
      The diamond structure 
      The open world model, think games like The Elder Scrolls V: Skyrim, the player is introduced to the game through a quest, but after that, they can go wherever and do whatever quests they want. There are tons of quests of the above types and patterns, the player is free to pick and choose which to do, giving the player the illusion of freedom within the game world (the diamond). However, the game still ends by completing a quest that is locked and always a requirement to complete the game. This can, of course, be varied by different choices the player has made throughout the game or even have multiple endings. Quests can be concentrated into quest hubs, i.e. towns with lots to do or the like, but they don't have to be completed in a linear fashion  
       
       
      Linear hub structure
      This structure consists of a number of required “bridge” quests that need to be completed in order to unlock the next area or “hub”, each hub can have any number of quests, this could be a town full of people in trouble, each with their own quests and quest chains to complete, when they are all done, the player moves on to the next hub through another bridge quest. Limiting the quest size of the hubs will make the quest structure feel more linear and thereby the game linear, and creating larger more open hubs can make the player feel freer.  
       
      Outcome - "So many options!"
      The development of custom quest has been the quest to allow game developers to create quests and missions that use these types. However, no matter how well we have researched, some one will come up with a new and creative way of doing quests.
       
      The solution for us was to make the system more customizable. Letting users convert their quest prefabs to quest scripts that automatically inherits the core functionality, so the user can freely add their own additional functionality on top of the existing core
      Asset development as fuel - "A learning experience"
      Developing this way, splitting the production into sub systems that can function on their own and even be used by others is not something that should be taken lightly, but if you can build something lasting, something others can find value in using, then the final product will be all the better for it. Custom Quest started as a project we thought could be completed in a couple of months, it ended up taking 7.
      In part this is because we realised that if we were going to release the system, we might as well do it right, that meant creating a system that was customizable and robust, a system that can be added to the users game and not the other way around, a system we could be proud of.
      The experience of developing for other developers is quite different to developing a game. One that has made us much stronger as programmers and as a company, it forced us to think in new ways, in order to create a dynamic and customizable solution. Custom quest has evolved from an asset we could use in Quest Accepted, into a tool others can use to create a unique game experience. All in all, the experience has been a good one and Random Dragon is stronger for it, I would, however, recommend thinking about your plugin and extra time before you start developing.
       
       
      Sources:
      www.pcgamesn.com -"We know you aren't stupid" - a quest design master class from CD Projekt RED
      http://www.pcgamesn.com/the-witcher-3-wild-hunt/the-witcher-quest-design-cd-projekt-masterclass
      http://www.gamasutra.com/ - Game Design Essentials: 20 RPGs - http://www.gamasutra.com/view/feature/4066/game_design_essentials_20_rpgs.php?print=1
      Extra credits - Quest Design I - Why Many MMOs Rely on Repetitive Grind Quests https://www.youtube.com/watch?v=otAkP5VjIv8&t=219s
      Extra credits - Quest Design II - How to Create Interesting MMO and RPG Quests https://www.youtube.com/watch?v=ur6GQp5mCYs
      Center for Games and Playable Media - Situating Quests: Design Patterns for Quest and Level Design in Role-Playing Games - http://sokath.com/main/files/1/smith-icids11.pdf
      Center for Games and Playable Media - RPG Design patterns https://rpgpatterns.soe.ucsc.edu/doku.php?id=patterns:questindex
       
      Special thanks to Allan Schnoor, Kenneth Lodahl and Kristian Wulff for feedback, constructive criticism and background materials.
    • By ilovegames
      When we last saw the sunshine? ... It seems that ten years ago ...
      We both wanted to live under the warm sun, so we want to go ... 
      Having spent ten years in bins, people start an uprising. Rebellion for a place under the sun, which is now occupied by scary creatures .. When people are cornered, patience may be over. And it was over. Without hope of salvation without faith in victory, people are going to fight for own world 
      You - one of them, clean your city from hundreds of monsters and give of humanity hope of salvation on this night, full of hardcore and aggression!
      Download http://falcoware.com/NightAgression.php
       




    • By Ahrakeen
      Hello we are looking for a second coder to assit with our strategic roleplaying game. it's a unity based engine with the ORK framework.
      we hope to have someone help complete our prologue so we can turn this into a complete game.
       
      we are aiming for something close to children of zodiac or fire emblem. but heavily focused on magic and urban legends. 
      main issue we are facing is getting the combat aspects in place and tie it together with a visual novel package we aim to fit with this
    • By dobbey
      Who are you?
      We call ourselves Dobbey. Our team currently consists of two people.
      We are both early 20's and come from Germany. At the moment this is our hobby.
      What's the name of the game and what is it about?
      The game is called Insane and it is a 2D adventure puzzle game with horror elements.
      Insane is about a scientist who has been doing human experiments for years.
      His most successful experiment is number 73, which seems to be mentally labile.
      This experiment manages to flee one day but can't distinguish between reality and imagination.
      In this game you will find a creepy atmosphere with difficult and varied puzzles.
      What inspired you?
      The style of the game is inspired by Limbo. But we were also inspired by Jump 'n' Run games and movies.
      Of course, we have also our own elements like an inventory system, butterfly effect, the "INSANE" effect, using a QR-Code..
      Which program do you use to develop the game?
      We are programming it with Unity. In our opinion, it is the best program for indie games.
      And of course we are working with Photoshop to create the graphics.
      What platform will Insane be available on?
      For PC.
      How can I support you?
      Twitter:        http://bit.ly/20POkfM    
      YouTube:     http://bit.ly/2rLXoM0
      Instagram:   http://bit.ly/2qwU2bl
      Facebook:    http://bit.ly/2p3nwRQ
      Website:       http://bit.ly/2s8buqU
       

      Here you can see some of our screenshots.

       

      (You can find the animation on Twitter/Instagram.)
       

       

       

      (You can find the animation on YouTube.)

      What do you think about it?
       
      Yo can see more screenshots or videos on Twitter, Instagram or YouTube.
    • By Liquid1Phantom
      Hello, my name is Thomas and I am currently starting up a project. 
      The project is going to be a very hardcore, and tactical FPS that is similar to Escape from Tarkov. It will be made within Unity, and will be programmed in C#. Currently, I have a Unity project started, an organized Discord setup, and as well as a very organized Google Drive. The Google Drive has art references, and plenty of folders for organization. Lastly, the payment for this project will be solely rev-share as I have no money.
      I am looking for anyone who can contribute: 2D artists, 3D artists, composers, programmers, etc.
      If you would like to help out and be of use, please email me at: thomasmunson2277@gmail.com
      Alternatively, add my Discord: Thomas#3788
  • Popular Now