Zakrywanie powierzchni

0

Cześć,
nieudolnie próbuję stworzyć moją pierwszą grę. Menu.java ją uruchamia:

 

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Menu extends JFrame {

Panel ballPanel = new Panel();
Panel commandsPanel = new Panel();

final int max = 10;
int num;
Ball[] ball = new Ball[max];


private Board displayBoard;

public Menu() {

    initUI();
    displayBoard = new Board();
    add(displayBoard);

    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });


    Font f = new Font("Courier", Font.BOLD, 18);
    Label titleLabel = new Label("GO GO LUKE", Label.CENTER);
    titleLabel.setFont(f);
    commandsPanel.add(titleLabel);


    commandsPanel.setLayout(new GridLayout(6, 10));

    addButton(commandsPanel, "Start", new ActionListener() {
        public void actionPerformed(ActionEvent evt) {

        }

    });

    addButton(commandsPanel, "Dodaj kulke", new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            Ball b = new Ball(ballPanel);
            b.start();
        }

    });

    addButton(commandsPanel, "OUT", new ActionListener() {
        public void actionPerformed(ActionEvent evt) {

        }

    });

    ballPanel.setBackground(Color.WHITE);

    add(ballPanel, BorderLayout.CENTER);
    add(commandsPanel, BorderLayout.WEST);

}

private void addButton(Panel p, String title, ActionListener a) {
    Button b = new Button(title);
    p.add(b);
    b.addActionListener(a);
}

private void initUI() {

    setTitle("GoGoLuke");
    setSize(700, 700);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}


public static void main(String[] args) {

    EventQueue.invokeLater(() - > {
        Menu ex = new Menu();
        ex.setVisible(true);
    });
}

}

Dodatkowo mam klasy:

Ball.java

 

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Panel;

public class Ball extends Thread {

Panel pl;

static final int XSIZE = 15;
static final int YSIZE = 15;

int x = 100;
int y = 100;
int dx = 2;
int dy = 2;

// konstruktor
public Ball(Panel b) {
    pl = b;
}

public void draw() {
    Graphics g = pl.getGraphics();
    g.fillOval(x, y, XSIZE, YSIZE);
    g.dispose();

}

public void move() {
    if (!pl.isVisible())
        return;
    Graphics g = pl.getGraphics();
    g.setXORMode(pl.getBackground());
    g.fillOval(x, y, XSIZE, YSIZE);
    Dimension d = pl.getSize();

    x += dx;
    y += dy;

    if (x < 0) {
        x = 0;
        dx = -dx;
    }
    if (x + XSIZE >= d.width) {
        x = d.width - XSIZE;
        dx = -dx;
    }
    if (y < 0) {
        y = 0;
        dy = -dy;
    }
    if (y + YSIZE >= d.height) {
        y = d.height - YSIZE;
        dy = -dy;
    }
    g.fillOval(x, y, XSIZE, YSIZE);
    g.dispose();
}

public void run() {
    try {
        draw();
        for (;;) {
            move();
            sleep(5);
        }
    } catch (InterruptedException e) {}
}

}

oraz Board.java

 

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel
implements ActionListener {

private final int INITIAL_X = 300;
private final int INITIAL_Y = 300;
private final int DELAY = 500;

private Image luke;
private Timer timer;
private int x, y;

public Board() {

    initBoard();

}

private void loadImage() {

    ImageIcon ii = new ImageIcon("luke.png");
    luke = ii.getImage();

}

private void initBoard() {

    setBackground(Color.WHITE);
    setDoubleBuffered(true);

    loadImage();

    x = INITIAL_X;
    y = INITIAL_Y;


}

public void gameStart() {
    timer = new Timer(DELAY, this);
    timer.start();
}

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);

    drawLuke(g);

}

private void drawLuke(Graphics g) {

    g.drawImage(luke, x, y, this);
    Toolkit.getDefaultToolkit().sync();

}

public void moveLeft() {
    x -= 50; //o ile luke przechodzi w lewo

    repaint();
}

public void moveRight() {
    x += 50;

    repaint();
}

public void moveUp() {
    y -= 50;

    repaint();
}

public void moveDown() {
    y += 50;

    repaint();
}

@Override
public void actionPerformed(ActionEvent e) {


    repaint();

}

}

Co muszę zmienić aby stworek i piłki pojawiły się jednocześnie? Gdy usuwam piłki pojawia się stworek więc coś go przykrywa... :/

0

Jakieś pomysły?

1

A czy nie byłoby czytelniej, gdyby stworek (Luke?) był także obiektem, jak Ball?
Dlaczego ball jest Threadem?
Generalna zasada pisania gier, to że masz pętle główną:

 while(!koniecGry){
    ruszajObekty();
    sprawdźKolizje();
    odrysuj();
}

Przykład możesz zobaczyć tutaj:
https://github.com/bartlomiej-gora/JPong2/blob/master/src/pl/bgora/game/MainFrame.java

Jakbyś miał jakieś pytania to wal śmiało :)

0

Dziękuję!
Czy mógłbyś mi podpowiedzieć jak opisać stworka żeby również był obiektem? To moje początki z java więc głównie uczę się metodą prób i błędów, coś się nie kompiluje to poczytam, przekleję, dokleję, obserwuję...Starałam się pozbyć class Board żeby 'Luke' był na tej samej płaszczyźnie co 'Ball', ale wtedy program nie chce go nawet wczytać :/ Jakies sugestie?

1

Ball i np. Monster powinny przechowywać informacje o pozycji, czyli x i y, oraz o prędkości dx i dy.
Monster może też przechowywać informacje o obrazku, który ładujesz z png.
Board, powinno być plansza na której odrysowujesz obiekty Ball i Monster.

Czyli mniej więcej tak:

Obiekty gracza i piłki tylko przechowują informację o położeniu i prędkości.
Natomiast Board powinno rozszerzać JFrame -> nadpisujesz metodę paint - odrysowując wszystkie elementy.

Czyli tak np (Przykładowy obiekt piłki):

 package pl.bgora.game;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Point;


public class Ball extends Canvas{
  
  private Point position;
  private Color color;
  private double speedx;
  private double speedy;
  
  public static final double DEFAULT_SPEED = 10;
  
  public static final int HEIGHT = 20;
  public static final int WIDTH = 20;
  
  public Ball(Color color, Point startPosition){
    this.setColor(color);
    this.setPosition(startPosition);
    setBounds(startPosition.x, startPosition.y, WIDTH, HEIGHT);
  }

  public synchronized void setPosition(Point position) {
    this.position = position;
    setBounds(position.x, position.y, WIDTH, HEIGHT);
  }

  public Point getPosition() {
    return position;
  }

  public synchronized void setColor(Color color) {
    this.color = color;
  }

  public Color getColor() {
    return color;
  }

public double getSpeedx() {
	return speedx;
}

public synchronized void setSpeedx(double speedx) {
	this.speedx = speedx;
}

public double getSpeedy() {
	return speedy;
}

public synchronized void setSpeedy(double speedy) {
	this.speedy = speedy;
}


  
  
}

Potem masz MainFrame, czyli główne okno gry:

 import org.apache.log4j.Logger;

public class MainFrame extends JFrame {
//// tutaj kod

//Inicjalizacja:
  public void startGame() {
    initSounds();
    initObjects();
    initListeners();
    startThread();
  }

// Głowna pętla:
private void startThread() {
    Runnable runner = new Runnable() {
      
      @Override
      public void run() {
        Random rand = new Random();
        int leftRight = rand.nextInt(2);
        if (leftRight == 0) {
          ball.setSpeedx(Ball.DEFAULT_SPEED);
        } else {
          ball.setSpeedx(-Ball.DEFAULT_SPEED);
        }
        while (left.getScore() < 5 && right.getScore() < 5) {
            // move objects
          move();
          // Check collisions
          // collisions for players vs. court
          checkCollision(rand);
          //3. Paint!
          myPaint(getGraphics());
          try {
            Thread.sleep(0,10);
          } catch (InterruptedException e) {
            LOGGER.error("InterruptedException", e);
          }
        }
        
      }

Jak widzisz odrysowanie robi Główne okno, obiekt Ball tylko przechowuje informacje o położeniu i kierunku i prędkości.

Tak powinny mniej więcej wyglądać twoje obiekty w grze.

Twój obiekt gracza może też zawierać obrazek, np.:

 package pl.bgora.pong.objects;

import java.awt.Image;
import java.awt.Rectangle;

import javax.swing.ImageIcon;

public class Pong {

	public static final int RED = 0;
	public static final int BLUE = 2;
	
	private int type;
	private Image image;
	
	private int x;
	private int y;
	private int dx;
	private int dy;
	
	private int upKey;
	private int downKey;
	
	public Pong(int type){
		this.type = type;
		ImageIcon ii = null;
		if(type==RED){
			ii = new ImageIcon(this.getClass().getResource("pong_red.png"));
			image = ii.getImage();
		}else if(type==BLUE){
			ii = new ImageIcon(this.getClass().getResource("pong_blue.png"));
			image = ii.getImage();
		}
	}
	
	public void move(){
		x += dx;
		y += dy;
	}

	/**
	 * Zwraca wartość pola type
	 * @return Wartość pola type
	 */
	public int getType() {
		return type;
	}

	/**
	 * Ustawia wartość pola type
	 * @param type Nowa wartość pola type 
	 */
	public void setType(int type) {
		this.type = type;
	}

	/**
	 * Zwraca wartość pola image
	 * @return Wartość pola image
	 */
	public Image getImage() {
		return image;
	}

	/**
	 * Ustawia wartość pola image
	 * @param image Nowa wartość pola image 
	 */
	public void setImage(Image image) {
		this.image = image;
	}

	/**
	 * Zwraca wartość pola x
	 * @return Wartość pola x
	 */
	public int getX() {
		return x;
	}

	/**
	 * Ustawia wartość pola x
	 * @param x Nowa wartość pola x 
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * Zwraca wartość pola y
	 * @return Wartość pola y
	 */
	public int getY() {
		return y;
	}

	/**
	 * Ustawia wartość pola y
	 * @param y Nowa wartość pola y 
	 */
	public void setY(int y) {
		this.y = y;
	}

	/**
	 * Zwraca wartość pola dx
	 * @return Wartość pola dx
	 */
	public int getDx() {
		return dx;
	}

	/**
	 * Ustawia wartość pola dx
	 * @param dx Nowa wartość pola dx 
	 */
	public void setDx(int dx) {
		this.dx = dx;
	}

	/**
	 * Zwraca wartość pola dy
	 * @return Wartość pola dy
	 */
	public int getDy() {
		return dy;
	}

	/**
	 * Ustawia wartość pola dy
	 * @param dy Nowa wartość pola dy 
	 */
	public void setDy(int dy) {
		this.dy = dy;
	}

	/**
	 * Zwraca wartość pola upKey
	 * @return Wartość pola upKey
	 */
	public int getUpKey() {
		return upKey;
	}

	/**
	 * Ustawia wartość pola upKey
	 * @param upKey Nowa wartość pola upKey 
	 */
	public void setUpKey(int upKey) {
		this.upKey = upKey;
	}

	/**
	 * Zwraca wartość pola downKey
	 * @return Wartość pola downKey
	 */
	public int getDownKey() {
		return downKey;
	}

	/**
	 * Ustawia wartość pola downKey
	 * @param downKey Nowa wartość pola downKey 
	 */
	public void setDownKey(int downKey) {
		this.downKey = downKey;
	}
	
	public Rectangle getBounds(){
		return new Rectangle(x, y, getImage().getWidth(null), getImage().getHeight(null));
	}
	
}

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