Jump to content

  • Log In with Google      Sign In   
  • Create Account


New to this need some help


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 17 September 2012 - 09:09 AM

Hi,

I am pretty new to game development. I used to mess with RPG Maker when I was a kid and used the RMXP and VX to write some code and have made a batle system in that so I have some experience I guess. Anyways, I am learning to program games in Java using Slick2D. I have made a Pong clone and am now on to a more adventerous project. It is a side-scrolling space shooter. I have a good start so far I have a player ship that I can move, I have enemies that I can spawn. Collision is working. But I have a few questions.

1) I have a level class that contains all the Arrays that hold my objects. One of the Arrays holds the bullets. Currently I have two different types of weapons the player can use. You start with a machine gun and can upgrade to a plasma missile (Ooooh!). Anywys I am usure of a good way of adding the weapons to the array in a clean manner. Right now each of my weapon types has a create method that will create a weapon of its type at the position of the owner and move in the direction the owner is facing. It seems bad to me to have a object have a create method that crates a copy of itslef.

Here is how it works basically (This is from the update method of my level object):


  if (player.getState() == GameEntity.State.shooting){
  
   try{
	bullets.add(player.createBullet());
   }catch(Exception e){
	System.out.println("Cant make a bullet");
   }
  
  }

and in my player object:

public BaseWeapon createBullet() throws SlickException{
  Vector2f position = this.getPosition();
  int direction = getDirection();

  if (direction == 1){
   return weapon.create(direction,(int)( position.x + bulletOffset.x), (int)(position.y + bulletOffset.y));
  }else{
   return weapon.create(direction, (int)(position.x), (int)(position.y + bulletOffset.y));
  }
}

and finally in my weapon class (this is the machine gun):

public BaseWeapon create(int direction, int x, int y)
   throws SlickException {
  // TODO Auto-generated method stub
  return new MachineGun(direction,x,y);
}

It seems like a bad way of doing it, but I am not sure how to have it determine what wepaon the player has and then create an object of that type and add it to the array other than making a method that returns the type and going through an if statement for each type. That would be a headache.

2.) Hopefully this one will be easier... In my player method I have the left mouse control shooting. All it does is set the state to shooting and the level object checks to see if a object is in the shooting state and then it creates a bullet from the code above. Sometimes if I double click or click quickly it gets stuck in the shooting state and it will fire an endless stream of bullets until I click again can you see why?

   if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON) && getState() != GameEntity.State.overheated){
  
	if(getFire() == 0){
	 System.out.println("Fire!");
	 setFire(getFireRate());
	 increaseHeat(getWeaponHeatRate());
	 setState(GameEntity.State.shooting);
	}else{
	 setState(GameEntity.State.idle);
	 System.out.println("no fire");
	 setFire(getFire() - 1);
	}
   }

If you need/want to see more code I'll glady upload the source.

Thanks for any input

Nick

Sponsor:

#2 thok   Members   -  Reputation: 685

Like
1Likes
Like

Posted 17 September 2012 - 09:40 AM

1) I have a level class that contains all the Arrays that hold my objects. One of the Arrays holds the bullets. Currently I have two different types of weapons the player can use. You start with a machine gun and can upgrade to a plasma missile (Ooooh!). Anywys I am usure of a good way of adding the weapons to the array in a clean manner. Right now each of my weapon types has a create method that will create a weapon of its type at the position of the owner and move in the direction the owner is facing. It seems bad to me to have a object have a create method that crates a copy of itslef.


This doesn't really make sense. You have an array which holds the bullets. Then you go on to talk about how you're trying to figure out "a good way of adding weapons to the array". What array? Is there an array for weapons as well?

If so, can't you just take the weapon the player has (referring to it by its BaseWeapon type) and add it to the array? There seems to be no reason to copy the weapon.

#3 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 17 September 2012 - 09:58 AM

Poor explination on my part.

I use weapons and bullets interchangably. I have an array that contains the bullets in my level object, used for updating/deleting/whatever. Weapon is simply a variable on my Player Object that holds the type of bullet to fire.

I tired to do what you said but I am still unsure of exactly how to implement it...

I created a fire function but its not working as expected. Ill show you some of the relevant code:

This is from my GameEntity class which is the parent class of the Player/Enemies. I set the direction to the players dirction and the position of it to the players position plus and offset so i looks like its coming out of the right spot.

public BaseWeapon fire(){
  Vector2f position = getPosition();
 
  weapon.setDirection(getDirection());
  weapon.setLife(0);
 
  if (getDirection() == 1){
   weapon.setPosition(position.x + bulletOffset.x, position.y + bulletOffset.y);
  }else{
   weapon.setPosition(position.x, position.y + bulletOffset.y);
  }
 
  return weapon;
}

In my level I made a simple change (changed form the create to fire);

  if (player.getState() == GameEntity.State.shooting){
  
   try{
    bullets.add(player.fire());
    System.out.println("Bullets:" + bullets.size());
   }catch(Exception e){
    System.out.println("Cant make a bullet");
   }
  
  }

It works for a hot minute but then it stops adding bullets. I'm guessing it beacuse its pass by reference in Java, but I havnt figured out a work around.

Thanks
Nick

#4 be-the-hero.net   Members   -  Reputation: 152

Like
3Likes
Like

Posted 17 September 2012 - 10:12 AM

1) Intuitively, I think I would divide it into following classes:

class Player
{
  Weapon weapon;
// ...
}
interface Weapon
{
  Bullet shoot(...);
  // ...
}

abstract class Bullet
{
  Vector2f position;
  int direction;
  // ...
}

class MachineGun implements Weapon { /*...*/ }
class MachineGunBullet extends Bullet { /*...*/ }

class RocketLauncher implements Weapon { /*...*/ }
class RocketLauncherBullet extends Bullet { /*...*/ }

2) Ideally, your:
setState(GameEntity.State.idle);
Should be triggered by a "mouse up" event to avoid any confusion / synchronisation problems.
The following seems also to make more sense to me:
if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON) && getState() != GameEntity.State.overheated){

		if(getFire() == 0){
		 System.out.println("Fire!");
		 setFire(getFireRate());
		 increaseHeat(getWeaponHeatRate());
		 setState(GameEntity.State.shooting);
		}
}else{
		 setState(GameEntity.State.idle);
		 System.out.println("no fire");
		 setFire(getFire() - 1);
}


Edited by be-the-hero.net, 17 September 2012 - 10:14 AM.


#5 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 17 September 2012 - 10:49 AM

Hero-

thanks that makes some sense to me I just never am really sure when to use interfaces or just use interitance, I read about it but if I think about it too much it starts to give me a headache. I know it is a "Can-do this" v.s. "Is-a" situation. A question remains however...

class Player
{
  Weapon weapon;
// ...
}

Is weapon referring to the interface here or an actual weapon object such as "MachineGun" or "RocketLauncher"?

Also the "mouse-up" event is huge thank you for that!

#6 Verik   Members   -  Reputation: 260

Like
0Likes
Like

Posted 17 September 2012 - 10:59 AM

I think be-the-hero.net's proposal makes sense. For bonus points, you could consider having the Weapon itself keep track of its heat and the fire (delay) counter.

Edited by Verik, 17 September 2012 - 11:00 AM.


#7 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 17 September 2012 - 11:17 AM

Verik-

Yes I am liking the thoughts expressed in the post, not 100% sure how to implement it yet but that's the fun part right? ;P (I think I have an idea)

The only thing about the heat is that it effects everything about the ship. In my game I want it to be the left mouse button shoots and the right mouse activates a shield to defend against damage. You cant shoot and use the shield at the same time but they both add the the heat value of the ship. If it hits the ceiling the ship overheads and you cant fire/use shields and you move and 1/4 your speed. Ideally when I get things up and running killing enemies will get you "credits" which you can use to upgrade you ship for better weapons/shields/heat/speed but that is WAAAAYYYY down the road

But thanks again to everyone for the comments/help!

#8 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 17 September 2012 - 12:41 PM

Ok very cool, I have it working like be-the-hero.net suggested. I learned some cool things about interfaces and how to use them. I didnt make it so the weapon keeps track of its fireRate yet but that is on the to do list.

Another question I have is where should I handle player movement... in the object itself? in the Level class? I have a camera class that handles scrolling but I am only using it for moving objects on-screen and determining if I should draw them or not. The way I have things set up right now the player doesnt really move left or right the camera translates everything and keeps the player in the middle of the screen, however the player will need to move vertically... suggestions? does it matter?

#9 Verik   Members   -  Reputation: 260

Like
2Likes
Like

Posted 17 September 2012 - 03:12 PM

Good to hear you are learning things, that's what it is all about!

Ideally I'd create a separate (new) class that handles input, possibly the same class that also controls the frame rate and signals the camera to paint the scene (if I got it right), so a sort of main game controller or game loop class.

Now if you detect that a mouse button is pressed, you can call the appropriate method in the player object to tell it that the (user) wants to fire a bullet or activate the shield. The player object itself can then decide if it is overheated or not. (So the game state actually becomes a player state, which seems more in line with what it is.)

The same goes for movement. Have the game loop call the player object to tell it that the user wants to move it up or down. Let the player object decide how fast this move will take place (if at all). Does this make sense to you?

#10 be-the-hero.net   Members   -  Reputation: 152

Like
1Likes
Like

Posted 18 September 2012 - 11:25 AM

Tip 1: always prefer interfaces to inheritance
An interface defines what functionalities an object should provide
Inheritance is a "is a" relationship, and a way of reusing code among similar objects.

As for the rest, in what classes you should put what method, the best is to follow your intuition where it fits the best.
There is no golden rule for that, it is too case specific. In the process of doing it, you'll certainly acquire a better feeling of what to place where.
Tip 2: Refactoring and improving the code as you go is always a good idea. The time it costs now will be saved several times in the future.

Edited by be-the-hero.net, 18 September 2012 - 11:25 AM.


#11 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 18 September 2012 - 11:52 AM

Verik-

Yes conceptually it makes sense... something like this in my level class?
(it contains all the data for player, background, enemies, bullets, etc.)

class Level{
Player player;
GameInput input;

update{

	 if( input.getInput() = foo){
	 	 player.doBar();
	 }
}

Am I thinking about it the right way? It seems like it could get complicated if I have multiple buttons pressed....

be-the-ero.net -

Yes from your example I totally see the benefit of interfaces. A question though... I have render/ update methods in my baseObject that everything else is derived from. Is it better to put that into an interface or should I just keep it as it is? I am guessing if I dont need to override the functionality just keep it in the base class but if I want each object to hande the function differently make an interface? It is definitely a learn as you go process.

Also, yeah I am slowly trying to refactor my code as I learn more about this stuff, it can get frustrating at times because I end up breaking my game every time i end up coding and end up recoding stuff but I am enjoying it and learning alot about it.

Thanks Again!

Edited by BambooCatfish, 18 September 2012 - 11:54 AM.


#12 Verik   Members   -  Reputation: 260

Like
2Likes
Like

Posted 18 September 2012 - 02:28 PM

Yes, exactly!

Now I have a little old school OO advice to add to the wise words of be-the-hero. And that is that one of the best way to make classes and decide what to put in which classes is to think about the responsibility of those classes. Responsibility formal CS lingo for that a class should mind its own business. But what business is that? Actually it is that business that is implied by its name.

You have a class named "Player". The name implies that this class and this class alone represents the player as a whole (in the context of your game). And it should be this class that manages everything that happens inside the player. Having a player consist of a location and a weapon is great. The weapon knows how to fire bullets (create bullet objects) and the weapon can decide when it can fire again. So the weapon class also fits the 'mind your own business' rule. I envision that you will be having a Shield class in the player as well that keeps track of whether the shield is active, and how long the shield is active.

In this sense: a small optimization is that you could consider to rename Player to SpaceShip or PlayerShip or something similar. As it is not really 'the player' that is flying through your level, it is a spaceship. The player is someone who is playing the game, controlling the spaceship. It may seem nit-picky, but the better you get at finding the most accurate and concise words for your classes and methods, the better a programmer you will be. And how cool is it to have a line that says: spaceship.fire()? Posted Image

Now I really like your interest in how to 'do it right'. But bear in mind that there are several different styles of how to do OO programming, and my advice is somewhat strict OO. I don't actually program this way at my work, it is not necessarily always the best way for all problems. However, I think think that it is an excellent way to learn the ropes and get a feel for the responsibilities of classes. Also your nice and compact game structure seems to lend itself very well for this. But don't think you are doing it wrong if you have a few lines that don't seem perfect. It is usually unavoidable. And at this stage it is probably better just to get a few running programs and experiment with using classes than to make the code of this one game perfect.

Wow, a lot longer post than I intended. I guess I really like conveying my ideas about how to do OO Posted Image

Cheers!

#13 BambooCatfish   Members   -  Reputation: 130

Like
0Likes
Like

Posted 19 September 2012 - 09:36 AM

Verik-

Yeah I totally get what you are saying, "Make it work right, then make it more efficient", I am actually going for a CIS degree at my college, I am almost done but I havn't done any C++ in awhile so I am rusty... but anywhoo, another question ( I am full of them lol). I have a getBounds() method that returns a rectange that is the size of the graphic of the object at the objects location. My shield is going to be a circle shape and I would like if I could return a circle instead of a square but I can't override the method like that. I would really like my shield to inherit from my baseObject class as it has alot of useful methods that I do not feel like rewritng is there any workaround?

Oh, and my playerobject is called playerShip or something like that I was just writing some quick pseudo-code. I haven't had much time to work on it, real life gets in the way but I'm sure I'll have some more questions as I progress.

Thanks,
Nick

Edited by BambooCatfish, 19 September 2012 - 09:37 AM.


#14 ppgamedev   Members   -  Reputation: 311

Like
0Likes
Like

Posted 20 September 2012 - 07:52 AM

Something like this ???

interface Shape {
   boolean contains(Point p);
   boolean coversTo(Shape s);
   boolean overlapsWith(Shape s);
...
}

class Rectangle implements Shape {...}
class Circle implements Shape {...}

class BaseObject {
   Shape getBounds() {
	  ...
   }
}

Edited by ppgamedev, 20 September 2012 - 07:55 AM.


#15 Verik   Members   -  Reputation: 260

Like
0Likes
Like

Posted 20 September 2012 - 11:47 AM

I was thinking along the same lines as ppgamedev. You are probably returning a Rectangle to do collision detection. If you define a class (Shape) that can detect collision of a point [x, y] with itself then you are free to implement whatever shape you want and have a custom collision detection for each shape. Now this gets complex fast if you want to detect collisions between to arbitrary shapes, but it might work for your setup.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS