Gra strzelanka w Javie pomoc

0

Robię grę w której steruje postacią po lewej stronie ekranu poruszam się w góra/dół i strzelam poziomo w prawo gdzie wyskakują przeciwnicy.
Po każdym kliknięciu myszą tworzy się nowa instancja klasy Bullet, a problem jest z wyświetleniem jak należy pocisku. Pocisk często znika w połowie drogi lub wcale się nie pojawia. Jest jakiś lepszy sposób wyświetlenia go?

package gra2;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Paint;
import java.awt.PaintContext;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Bullet
{

	static ImageIcon imBullet = new ImageIcon("bullet.gif");
	static JLabel lBullet = new JLabel(imBullet);
	private int x = 40;
	private int y;
	static JPanel jpanel;
	static Thread wątek;
	static ArrayList<Alien> listaAlien;
	
	
	public Bullet(final JPanel panel, int yMyszki, final ArrayList<Alien> listaaAlien)
	{

		y = yMyszki;
		jpanel = panel;
		
		jpanel.add(lBullet);
		listaAlien = listaaAlien;
		wątek = new Thread(new Runnable(){		
		public void run()
		{
			// TODO Auto-generated method stub
			
			for (;x < 600; x += 10)
			{
				try
				{
					Thread.sleep(10);
				} catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				lBullet.setBounds(x, y, 30, 6);
				wykryjKolizje();				
			}
			delete();

		}});
		wątek.start();
		
	}
	
	
	
	/**
	 * Przerywa bierzący wątek i usuwa Bullet z panelu
	 */
	public static void delete()
	{
		jpanel.remove(lBullet);
		wątek.interrupt();
	}
	
	/**
	 * Zwraca współrzędną X Bulletu
	 * @return 
	 */
	public static int getBulletX()
	{
		return lBullet.getX()+30;
	}
	
	/**
	 * Zwraca współrzędną Y Bulletu
	 * @return
	 */
	public static int getBulletY()
	{
		return lBullet.getY()+3;
	}
	
	public static void wykryjKolizje()
	{
		for (int i = 0; i < listaAlien.size(); i++)
		{
			if ((Bullet.getBulletY() < listaAlien
					.get(i).getAlienDolnyY())
					&& (Bullet.getBulletY() > listaAlien
							.get(i).getAlienGórnyY()))
				if (Bullet.getBulletX() > listaAlien
						.get(i).getAlienX())
				{
					Bullet.delete();
					listaAlien.get(i).delete();
				}
		}
	}
}
0
  1. Zrób jeden JPanel w JFrame, to powinna być plansza twojej gry.
  2. przeciąż metodę paint(Graphics g) stworzonego JPanel.
  3. Jeden wątek programu, który wyglada mniej wiecej tak:
    while(!gameOver) {
    moveObjects();
    panel.reapint();
    }
    moveObject - metoda któa porusza, postacią, pociskami itd.
    panel.repaint() - wymusi wywołanie przeciążonej metody paint.
  4. W metodzie paint rysuj wszystko, pociski, postacie itd - poczytaj jak rysować na Graphics
  5. Przeczytaj to : http://www.zetcode.com/gfx/java2d/
0

Nie polecałbym ci pisanie gier w tych pakietach bardziej optymalnym i lepszym rozwiązaniem jest pisanie gier w bibliotekach do tego przeznaczonych. W tym przepadku polecałbym Slick2d. Prosty w obsłudze i przejrzysty.

0
Czarny Mistrz napisał(a):

Nie polecałbym ci pisanie gier w tych pakietach bardziej optymalnym i lepszym rozwiązaniem jest pisanie gier w bibliotekach do tego przeznaczonych. W tym przepadku polecałbym Slick2d. Prosty w obsłudze i przejrzysty.

Kiedyś na pewno to zrobię teraz muszę tu bo nie nauczę się tego tak szybko, zostało niewiele czasu a chciałbym to mieć z głowy przed sesją.

xxx_xx_x napisał(a):
  1. Zrób jeden JPanel w JFrame, to powinna być plansza twojej gry.
  2. przeciąż metodę paint(Graphics g) stworzonego JPanel.
  3. Jeden wątek programu, który wyglada mniej wiecej tak:
    while(!gameOver) {
    moveObjects();
    panel.reapint();
    }
    moveObject - metoda któa porusza, postacią, pociskami itd.
    panel.repaint() - wymusi wywołanie przeciążonej metody paint.
  4. W metodzie paint rysuj wszystko, pociski, postacie itd - poczytaj jak rysować na Graphics
  5. Przeczytaj to : http://www.zetcode.com/gfx/java2d/

Nie wiem czy dobrze rozumiem, cała gra ma być w jednym wątku? Jakoś trudno mi to sobie wyobrazić.

Nie da się tego jakoś naprawić bez kompletnej przebudowy kodu/pisania gry od nowa. Załączam jeszcze jedną klasę.

package gra2;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Frame extends JFrame
{
	//Bullet[] tablicaBullet = new Bullet[10];
	ArrayList<Bullet> listaBullet = new ArrayList<Bullet>();
	JPanel panel = new MyPanel();
	int liczbapocisków = 0;
	ArrayList<Alien> listaAlien = new ArrayList<Alien>();

	Frame()
	{
		setLocation(200, 100);
		setSize(600, 400);
		wyświetl();
		getContentPane().add(panel);
		panel.setBackground(Color.LIGHT_GRAY);

		Avatar avatar = new Avatar(panel);
		// usuńTrafione();
		atak(5, 10, 2000);

		addMouseListener(new MouseListener()
		{

			@Override
			public void mouseReleased(MouseEvent arg0)
			{
				// TODO Auto-generated method stub

			}

			@Override
			public void mousePressed(MouseEvent arg0)
			{
				// TODO Auto-generated method stub

				strzał(arg0);

			}

			@Override
			public void mouseExited(MouseEvent arg0)
			{
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent arg0)
			{
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseClicked(MouseEvent arg0)
			{
				// TODO Auto-generated method stub

			}
		});

	}
	
	public void wyświetl()
	{
		Thread wątek = new Thread(new Runnable()
		{
			
			@Override
			public void run()
			{
				// TODO Auto-generated method stub
				for(;;)
				{
					try
					{
						Thread.sleep(10);
					} catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					setTitle(Integer.toString(listaBullet.size()));
				}
			}
		});
		wątek.start();
	}

	/**
	 * Metoda tworzy nowe Bullety
	 * @param arg0 - domyślny parametr z metody MouseListener, potrzebny do uzyskania Y kursora
	 */
	public void strzał(MouseEvent arg0) 
	{
		
		listaBullet.add(new Bullet(panel, arg0.getY() - 34, listaAlien));
	}

	/**
	 * metoda tworzy nowe Alieny, przyjmuje dwa parametry pomiędzy którymi
	 * zostanie wylosowane opóźnienie które usypia wątek poruszający Alienem im
	 * niższy przedział tym szybciej poruszają się alieny
	 * 
	 * @param opóźnienieOd - w ms
	 * @param opóźnienieDo - w ms
	 * @param opóźnienieTegoWątku - czas w ms co który będzie tworzony nowy Alien
	 */
	public void atak(final int opóźnienieOd, final int opóźnienieDo,
			final int opóźnienieTegoWątku)
	{
		final Random losuj = new Random();
		// final int opóźnienieOd, opóźnienieDo;

		Thread wątek = new Thread(new Runnable()
		{

			@Override
			public void run()
			{
				// TODO Auto-generated method stub
				for (;;)
				{
					try
					{
						Thread.sleep(opóźnienieTegoWątku);
					} catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					int opóźnienie = losuj.nextInt(opóźnienieDo - opóźnienieOd)
							+ opóźnienieOd;
					int y = losuj.nextInt(330);

					listaAlien.add(new Alien(panel, y, opóźnienie));
				}
			}
		});
		wątek.start();

	}



	/**
	 * @author Damian
	 *
	 *Klasa nadpisuje klasę JPanel i wywołuje co jakiś czas metode repaint()  
	 */
	public static class MyPanel extends JPanel
	{
		public MyPanel()
		{
			super();

			Thread wątek = new Thread(new Runnable()
			{

				@Override
				public void run()
				{
					// TODO Auto-generated method stub
					for (;;)
					{
						try
						{
							Thread.sleep(5);
						} catch (InterruptedException e)
						{
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						repaint();
					}
				}
			});
			wątek.start();
		}

		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			
			
		}
		public static void bullet()
		{
			
		}
	}
}
0

Masz tutaj kod bazowy, dalej już powinieneś sobie poradzić.

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*;
import java.util.List;

public class GameTest {

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

    static class Frame extends JFrame {
        private JPanel mainPanel;

        private List<GameEntity> gameEntityList = new ArrayList<GameEntity>();

        private volatile boolean gameOver = false;

        private Thread th = null;

        private long time = 0;

        public Frame() {
            super("Test frame");

            gameEntityList.add(new Bullet(new Vector(50, 200), new Vector(30,10), new Vector(100, 0)));
            gameEntityList.add(new Bullet(new Vector(550, 205), new Vector(30,10), new Vector(-150, 0)));

            mainPanel = new JPanel() {
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);    //To change body of overridden methods use File | Settings | File Templates.
                    Frame.this.draw(g);
                }
            };

            mainPanel.setPreferredSize(new Dimension(640, 480));

            add(mainPanel);
            pack();

            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    super.windowClosing(e);    //To change body of overridden methods use File | Settings | File Templates.
                    gameOver = true;
                    try {
                        th.join();
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                }
            });


            th = new Thread(new Runnable() {
                @Override
                public void run() {
                    time = System.currentTimeMillis();
                    while (!gameOver) {
                        long cur_time = System.currentTimeMillis();
                        if (cur_time - time >= 10) {
                            float dt = ((float)(cur_time - time)) / 1000.0f;
                            time = cur_time;
                            Frame.this.update(dt);
                        } else {
                            try {
                                Thread.sleep(5);
                            } catch (InterruptedException e) {
                                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                            }
                        }
                    }
                }
            });
            th.start();

        }

        private void draw(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(0,0, mainPanel.getWidth(), mainPanel.getHeight());

            for(GameEntity gameEntity : gameEntityList) {
                gameEntity.draw(g);
            }
        }



        private void update(float dt) {
            for(GameEntity gameEntity : gameEntityList) {
                gameEntity.update(dt);
            }

            List<GameEntity> dead = new ArrayList<GameEntity>();
            List<GameEntity> newObj = new ArrayList<GameEntity>();

            for(int i=0; i<gameEntityList.size(); i++) {
                for (int j=i+1; j<gameEntityList.size(); j++) {
                    if (gameEntityList.get(i).testCollision(gameEntityList.get(j))) {
                        gameEntityList.get(i).setAlive(false);
                        gameEntityList.get(j).setAlive(false);

                        Vector c1 = gameEntityList.get(i).getPosition().add(gameEntityList.get(i).getSize().mul(0.5f));
                        Vector c2 = gameEntityList.get(j).getPosition().add(gameEntityList.get(j).getSize().mul(0.5f));

                        newObj.add(new Explosion(c1.add(c2).mul(0.5f), 100, 1.0f, 50));
                    }
                }
            }

            for(GameEntity gameEntity : gameEntityList) {
                if (!gameEntity.isAlive()) {
                    dead.add(gameEntity);
                }
            }

            gameEntityList.removeAll(dead);
            gameEntityList.addAll(newObj);

            repaint();
        }
    }

    public static interface GameEntity {
        public Vector getPosition();
        public Vector getSize();
        public void draw(Graphics g);
        public void update(float dt);
        public boolean testCollision(GameEntity gameEntity);
        public boolean isAlive();
        public void setAlive(boolean b);
    }
    
    public static class Bullet implements GameEntity {
        private Vector pos;
        private Vector size;
        private Vector velocity;
        private boolean alive;

        public Bullet(Vector pos, Vector size, Vector velocity) {
            this.pos = pos;
            this.size = size;
            this.velocity = velocity;
            this.alive = true;
        }

        @Override
        public Vector getPosition() {
            return pos;
        }

        @Override
        public Vector getSize() {
            return size;
        }

        @Override
        public void draw(Graphics g) {
            g.setColor(Color.BLUE);
            g.fillRect((int)pos.getX(), (int)pos.getY(), (int)size.getX(), (int)size.getY());
        }

        @Override
        public void update(float dt) {
            pos.add((new Vector(velocity)).mul(dt));
        }

        @Override
        public boolean testCollision(GameEntity gameEntity) {
            return !(getPosition().getX() > gameEntity.getPosition().getX()+gameEntity.getSize().getX()  ||
                     getPosition().getX() + getSize().getX() < gameEntity.getPosition().getX() ||
                     getPosition().getY() > gameEntity.getPosition().getY()+gameEntity.getSize().getY() ||
                     getPosition().getY() + getSize().getY()  < gameEntity.getPosition().getY());
        }

        public boolean isAlive() {
            return alive;
        }

        public void setAlive(boolean alive) {
            this.alive = alive;
        }
    }

    public static class Explosion implements GameEntity {
        private float time;
        private float maxTime;
        private float speed;
        private Vector pos;
        private Vector[] particlesPos;
        private Vector[] particlesV;

        public Explosion(Vector pos, int pNo, float maxTime, float speed) {
            this.time = 0;
            this.maxTime = maxTime;
            this.speed = speed;
            this.pos = pos;
            this.particlesPos = new Vector[pNo];
            this.particlesV = new Vector[pNo];

            for(int i=0; i<pNo; i++) {
                particlesPos[i] = new Vector(pos);
                double ang = 2 * Math.PI * Math.random();
                particlesV[i] = new Vector((float)Math.cos(ang), (float)Math.sin(ang)).mul((float)Math.random()*speed);
            }
        }

        @Override
        public Vector getPosition() {
            return pos;
        }

        @Override
        public Vector getSize() {
            return new Vector(2 * speed * time, 2 * speed * time);
        }

        @Override
        public void draw(Graphics g) {
            g.setColor(new Color(  (int)((1.0f - time/maxTime) * 255), 0,0));
            for(int i=0; i<particlesPos.length; i++) {
                g.fillRect((int) particlesPos[i].getX() - 2, (int) particlesPos[i].getY() - 2, 4, 4);
            }
        }

        @Override
        public void update(float dt) {
            time += dt;
            for(int i=0; i<particlesPos.length; i++) {
                particlesPos[i].add(new Vector(particlesV[i]).mul(dt));
            }
        }

        @Override
        public boolean testCollision(GameEntity gameEntity) {
            return false;
        }

        @Override
        public boolean isAlive() {
            return time < maxTime;
        }

        @Override
        public void setAlive(boolean b) {
        }
    }

    public static class Vector {
        private float x,y;

        public Vector(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public Vector(Vector v) {
            this.x = v.x;
            this.y = v.y;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }

        public Vector add(Vector b) {
            this.x += b.x;
            this.y += b.y;
            return this;
        }

        public Vector mul(float f) {
            this.x *= f;
            this.y *= f;
            return this;
        }
    };

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1