2 player Java game

Started by
20 comments, last by Mossflower 17 years, 4 months ago
I just started learning java and am starting my own game. I don't know how to make it 2 players though. When I execute the code, only 1 player can be moved at a time. How do I fix this? Here's the first part of my code(please point out any others mistakes I'm making if you see it): Edit: I reposted it to make it easier to see. Didn't know you could do that. [Edited by - Mossflower on December 11, 2006 11:20:22 PM]
Advertisement
I'm not proficient in Java, so I can't answer your question, but I recommend that you edit or re-post your code using [source] tags so that it is readable. Also I'm not sure if the multiple statements on one line are intentional or are a formatting error, but I would fix those as well.

In other words, make your posted source as easy to read as possible; you'll be much more likely to get help that way.
Like this?(this doesn't include the player class I made, if that's needed, I'll gladly post it):
import java.applet.Applet;import java.applet.AudioClip;import java.awt.*;import java.awt.font.FontRenderContext;import java.awt.event.KeyListener;import java.awt.event.KeyEvent;import java.awt.geom.Rectangle2D;/**LIBnation.java *The Fighting Game *@author David Finol  *@version 0.2 12/10/06*/public class LIBnation extends Applet implements KeyListener{	private final int APPLET_WIDTH = 500;	private final int APPLET_HEIGHT = 375;	private int width, height;	private Image background, p1l1, p1l2, p1r1, p1r2, p1j, p1f, p1a;//still  to add jr,fr, al1,	private Image backbuffer, p2l1, p2l2, p2r1, p2r2, p2j, p2f, p2a;//al2, ar1, ar2	private AudioClip music;//background, later coming sound effects with move and attack	private Player p1, p2;	private String name1 = "Mossflower", name2 = "Nyteshade";//causes character select	private String level = "LIBnation Homepage", healthsign1, healthsign2;//causes level select	private int p1width = 45, p1height = 30, p1atk = 2, p1def = 2, p1speed = 5, p1range = 100, health = 50;	private int p2width = 40, p2height = 40, p2atk = 3, p2def = 2, p2speed = 2, p2range = 100;//stats of players	private boolean gravity, offscreen, dissappear, teleport, team, com;//features and options	private boolean victory, spec1, spec2;//in-game events	Graphics2D Stringmaker;	Graphics backg;	Rectangle2D bounds, bounds2;	Font font = new Font("SansSerif", Font.BOLD+Font.ITALIC, 24);//for health and name output	FontRenderContext context;/**Initializes the game by loading all necessary files */	public void init ()	{		setSize (APPLET_WIDTH, APPLET_HEIGHT);		setBackground (Color.black);		background = getImage (getDocumentBase(), level+".jpg");		music = getAudioClip (getDocumentBase(), level+".au");		backbuffer = createImage(APPLET_WIDTH, APPLET_HEIGHT);      	        backg = backbuffer.getGraphics();      	        backg.drawImage(background, 0, 0, this );      	        Stringmaker = (Graphics2D) backg; //helps with context		context = Stringmaker.getFontRenderContext(); //helps with drawP1&P2		addKeyListener(this);	}/**Starts the game by drawing the screen and looping the music */	public void start ()	{		makeP1();		makeP2();//the following lines prevent the character from mysteriously dissappearing the first time that you move them?		p1.jump();                drawP1(backg);                p1.fall();                drawP1(backg);                p1.attack(p2);                p1.attack(p2);                drawP1(backg);		p1.moveRight();                drawP1(backg);                p1.moveRight();                drawP1(backg);		p1.moveLeft();                drawP1(backg);                p1.moveLeft();                drawP1(backg);                p1.moveRight();                drawP1(backg);		p2.jump();                drawP2(backg);                p2.fall();                drawP2(backg);                p2.attack(p1);                p2.attack(p1);                drawP2(backg);		p2.moveLeft();                drawP2(backg);                p2.moveLeft();                drawP2(backg);		p2.moveRight();                drawP2(backg);                p2.moveRight();                drawP2(backg);                p2.moveLeft();                drawP2(backg);		backg.drawImage(background, 0, 0, this );		repaint();		music.loop();	}/**Unused method *@param typed the event that occurs when a character is typed */	public void keyTyped(KeyEvent typed){}/**Contols character *@param pressed the button that is pressed to move the character */	public void keyPressed(KeyEvent pressed)//try to find 2 player input	{		if(pressed.getKeyCode() == KeyEvent.VK_A)			p1.moveLeft();		if(pressed.getKeyCode() == KeyEvent.VK_W)			p1.jump();		if(pressed.getKeyCode() == KeyEvent.VK_D)			p1.moveRight();		if(pressed.getKeyCode() == KeyEvent.VK_S)			p1.fall();		if(pressed.getKeyCode() == KeyEvent.VK_CAPS_LOCK)			p1.attack(p2);		if(pressed.getKeyCode() == KeyEvent.VK_LEFT)			p2.moveLeft();		if(pressed.getKeyCode() == KeyEvent.VK_UP)			p2.jump();		if(pressed.getKeyCode() == KeyEvent.VK_RIGHT)			p2.moveRight();		if(pressed.getKeyCode() == KeyEvent.VK_DOWN)			p2.fall();		if(pressed.getKeyCode() == KeyEvent.VK_NUMPAD0)			p2.attack(p1);		backg.drawImage(background, 0, 0, this);		drawP1(backg);		drawP2(backg);		repaint();	}/**Unused method *@param released the event that occurs when a character is typed */	public void keyReleased(KeyEvent released){}/**Method used by paint to prevent flickering *@param screen the screen that the screen is drawn on */	public void update(Graphics screen) 	{      	        screen.drawImage(backbuffer, 0, 0, this );   	}/**Draws the screen *@param screen the screen that is drawn on */	public void paint (Graphics screen)	{		update (screen);	}/**Draws the first player, his/her name, and its health *@param c the screen that is drawn on */	public void drawP1 (Graphics c)	{		c.setFont(font);		c.setColor(Color.blue);		bounds = font.getStringBounds(name1, context); //to find where to put string		c.drawString (name1, 0, (int) bounds.getHeight());		healthsign1 = p1.getHealth();		bounds2 = font.getStringBounds(healthsign1, context);		c.drawString (healthsign1, 0, (int) bounds.getHeight()+ (int) bounds2.getHeight());		c.drawImage (p1.getSprite(), p1.getX(), p1.getY(), p1.getWidth(), p1.getHeight(), this);	}/**Draws the second player, his/her name, and its health *@param c the screen that is drawn on */	public void drawP2 (Graphics c)	{		c.setFont(font);		c.setColor(Color.blue);		bounds = font.getStringBounds(name2, context); //to find where to put strings		c.drawString (name2, APPLET_WIDTH- (int) bounds.getWidth(), (int) bounds.getHeight());		healthsign2 = p2.getHealth();		bounds2 = font.getStringBounds(healthsign2, context);		c.drawString (healthsign2, APPLET_WIDTH- (int) bounds2.getWidth(), (int) bounds.getHeight()+ (int) bounds2.getHeight());		c.drawImage (p2.getSprite(), p2.getX(), p2.getY(), p2.getWidth(), p2.getHeight(), this);	}/**Downloads the necesary images for the first player and instantiates it */	public void makeP1()	{		p1l1 = getImage (getDocumentBase(), name1+"l1.png");		p1l2 = getImage (getDocumentBase(), name1+"l2.png");		p1r1 = getImage (getDocumentBase(), name1+"r1.png");		p1r2 = getImage (getDocumentBase(), name1+"r2.png");		p1j = getImage (getDocumentBase(), name1+"j.png");		p1f = getImage (getDocumentBase(), name1+"f.png");		p1a = getImage (getDocumentBase(), name1+"a.png");		p1 = new Player(p1l1, p1l2, p1r1, p1r2, p1j, p1f, p1a, p1width, p1height,						 1, health, p1atk, p1def, p1speed, p1range);		healthsign1 = p1.getHealth();	}/**Downloads the necessary images for the second player and instatiates it */	public void makeP2()	{		p2l1 = getImage (getDocumentBase(), name2+"l1.png");		p2l2 = getImage (getDocumentBase(), name2+"l2.png");		p2r1 = getImage (getDocumentBase(), name2+"r1.png");		p2r2 = getImage (getDocumentBase(), name2+"r2.png");		p2j = getImage (getDocumentBase(), name2+"j.png");		p2f = getImage (getDocumentBase(), name2+"f.png");		p2a = getImage (getDocumentBase(), name2+"a.png");		p2 = new Player(p2l1, p2l2, p2r1, p2r2, p2j, p2f, p2a, p2width, p2height,						 2, health, p2atk, p2def, p2speed, p2range);		healthsign2 = p2.getHealth();	}/**Plays out the commands of the level */	public void levelEffects()	{		//filld in later	}/**Stops the music */	public void stop ()	{		music.stop();	}}
Edit: My bad; was thinking wrong. Meant to say: move the key input into the player class, so that each player instance has it's own movement handler.
I move the input, but I get a "cannot find symbol class addKeyListener(Player)" error. Here's what I tried(the beginning of the player class):
import java.awt.*;import java.awt.event.KeyListener;import java.awt.event.KeyEvent;/**A player is used to show up on a screen, and interact with other player. */public class Player implements KeyListener{	private int width, height, X, Y, player, health, atk, defense, speed, range;	private Image sprite, right1, right2, left1, left2, jump, fall, attack, die;	private Player enemy;	private boolean dead;/**Constructs a player with the images and stats specified *@param l1 the image for beginning to move the player left *@param l2 the image for ending to move the player left *@param r1 the image for beginning to move the player right *@param r2 the image for ending to move the player right *@param j the image for making the player jump *@param f the image for making the player fall *@param a the image for making the player attack *@param w the width size of the player *@param h the height size of the player *@param p the player character (player 1 or player 2) *@param hp the health of the player *@param at the atk stat of the player *@param def the defense stat of the player *@param s the movement speed stat of the player *@param r the attack range stat of the player */	public Player(Image l1, Image l2, Image r1, Image r2, Image j, Image f, Image a, 					int w, int h,int p, int hp, int at, int def, int s, int r, Player enemy)	{		left1 = l1;		left2 = l2;		right1 = r1;		right2 = r2;		jump = j;		fall = f;		attack = a;		defense = def;		width = w;		height = h;		player = p;		if(player == 1)		{			X = 0;			sprite = right1;		}		else		{			X = 500-width;			sprite = left1;		}		Y = 375-height;		health = hp;		atk = at;		speed = s;		range = r;		dead = false;                addkeyListener(this);	}/**Unused method *@param typed the event that occurs when a character is typed */	public void keyTyped(KeyEvent typed){}/**Contols character *@param pressed the button that is pressed to move the character */	public void keyPressed(KeyEvent pressed)	{		if(player == 1)		{			if(pressed.getKeyCode() == KeyEvent.VK_A)				moveLeft();			if(pressed.getKeyCode() == KeyEvent.VK_W)				jump();			if(pressed.getKeyCode() == KeyEvent.VK_D)				moveRight();			if(pressed.getKeyCode() == KeyEvent.VK_S)				fall();			if(pressed.getKeyCode() == KeyEvent.VK_CAPS_LOCK)				attack();		}		else		{			if(pressed.getKeyCode() == KeyEvent.VK_LEFT)				moveLeft();			if(pressed.getKeyCode() == KeyEvent.VK_UP)				jump();			if(pressed.getKeyCode() == KeyEvent.VK_RIGHT)				moveRight();			if(pressed.getKeyCode() == KeyEvent.VK_DOWN)				fall();			if(pressed.getKeyCode() == KeyEvent.VK_NUMPAD0)				attack();		}	}/**Unused method *@param released the event that occurs when a character is typed */	public void keyReleased(KeyEvent released){}


[Edited by - Mossflower on December 12, 2006 1:33:00 AM]
Need a capital 'K' on "addkeyListener(this);" to make it "addKeyListener(this);."
OOPS, that's a stupid mistake. When I fixed it, I still got the eame error, so I did this:

public class Player extends Component implements KeyListener

Now that the movement is there, how can I get the characters to be drawn? Originally, I called the drawPX() method whenever one of the buttons was pressed, but that doesn't work now that they are in different classes. I tried making another method that would check to see if the character had been moved and then insert it the start method, but that causes the paint method never to be called.
So what can I do?

[Edited by - Mossflower on December 12, 2006 5:04:19 PM]
By using a so-called game loop, in which you handle input, update game logic, and render the screen every cycle. That's actually the most common way to handle games.

Personally, I would keep input handling apart from the Player class. The input should message a Player object to move instead. This allows you to keep the input handling central, and it allows you to write AI code that can send the same messages to a Player, without any changes to the Player class.
Create-ivity - a game development blog Mouseover for more information.
I agree with keeping the input handling away from the player class, but how would I be able to allow the two players to move at the same time? My previous code didn't work. And could you post an example of the game loop? SO I know what you're talking about.
Err, yeah, I'm bein' an idiot; lol. I'm just so upside-down these days now that it's finals week (got two exams tomorrow; fun!). Yes, keep the input outside of the player class.

Last time I tried doing two-player input I think I ran into the same problem at one point. Not sure how I got by it. I'll look around through my old code and get back to ya. Just a hunch, but I believe I had to separate the input into two threads somehow, since each thread can handle only one key event at a time. Maybe... I'll check.

This topic is closed to new replies.

Advertisement