Projekt ma być napisany w GUI w Javie: Jest to gra komputerowa przypominająca bardzo grę Mamba (http://www.instalki.pl/gry/download/zrecznosciowe/Mamba.php).
W oknie ma znajdować się biały prostokąt. Gracz (piksel) znajduje się na jednym z jego brzegów (może być również w kącie). Wciśnięcie kursora powodującego ruch gracza w obrębie prostokąta rozpoczyna grę. W prostokącie zamiast węża (tak jak jest to w Mambie) jest piłka (wystarczy kropka z pikseli 2x2, współrzędne piłki i jej początkowy kierunek ruchu losowane Random), gdy piłka zderzy się ze ścianą to odbija się od niej zgodnie z prawem odbicia. Podczas swojego ruchu (tylko poziomego lub pionowego) gracz kreśli linię. Gdy uda mu się dotrzeć do ściany (ew. brzegu zakreślonego wcześniej obszaru) tak, żeby piłka nie trafiła w jego linię, zamalowywuje się obszar zakreślony przez gracza (na polu, na którym nie ma piłki - analogicznie do gry Mamba) i jest on wyłączany z ruchu piłki. Gra kończy się kiedy piłka uderzy w linię gracza bądź w samego gracza. Na bieżąco liczone są punkty (pole zakreślonego obszaru). Pod prostokątem ma być umieszczony suwak regulujący prędkość piłki.
Podstawowe problemy:
- Jak sprawdzić czy piłka należy do obszaru zakreślonego przez użytkownika czy nie? Potrzebne to jest do zamalowywania obszaru i wyłączania zakreślonego obszaru z ruchu piłki - [b]ten problem jest najbardziej istotny[/b].
- Jak liczyć pole zakreślonego obszaru?
- Jak określić rodzaj odbicia piłki.
Proszę Was o pomoc.
To to co udało mi się już nasklecać:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class CloseTheBall extends Robot implements ActionListener, AdjustmentListener, KeyListener {
static int WIDTH = 610;
static int HEIGHT = 600;
static int POOL_WIDTH = WIDTH - 10;
static int POOL_HEIGHT = HEIGHT/2;
JPanel panel;
JScrollBar speed;
JLabel textSpeed;
boolean isStarted = false;
boolean left = false;
boolean up = false;
boolean right = false;
boolean down = false;
byte [][] area, now;
PaintMove top;
public static void main(String[] args) {
JFrame frame = new JFrame("Pilka");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.toFront();
try {
CloseTheBall program = new CloseTheBall();
JPanel panel = new JPanel(new GridLayout(2, 1, 0, -150) );
panel.add(program.top);
panel.add(program.panel);
frame.add(panel);
frame.addKeyListener(program);
frame.setSize(WIDTH,HEIGHT);
frame.setFocusable(true);
frame.setVisible(true);
} catch (AWTException e) {}
}
class PaintMove extends Canvas implements Runnable{
int x, y, direction, oldX, oldY, oldDirection, speed = 2;
int pX, pY, pDirection = 2, oldPX, oldPY, pSpeed = 1;
Thread thread;
public PaintMove() {
thread = new Thread (this);
x = randomX();
y = randomY();
direction = randomDirection();
pX = randomX();
pY = POOL_HEIGHT+2;
}
public void paint(Graphics g) {
background(g);
g.setColor(Color.red);
g.fillOval(x, y, 5, 5);
g.setColor(Color.blue);
g.fillOval(pX, pY, 1, 1);
}
public void background(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 2, CloseTheBall.POOL_WIDTH, CloseTheBall.POOL_HEIGHT);
g.setColor(Color.black);
g.drawRect(0, 2, CloseTheBall.POOL_WIDTH, CloseTheBall.POOL_HEIGHT);
}
public void update(Graphics g) {
g.setColor(Color.white);
g.fillOval(oldX, oldY, 5, 5);
g.setColor(Color.red);
g.fillOval(x, y, 5, 5);
g.setColor(Color.white);
g.fillOval(oldPX, oldPY, 1, 1);
g.setColor(Color.red);
g.fillOval(pX, pY, 1, 1);
g.setColor(Color.black);
g.drawLine(oldPX, oldPY, pX, pY);
g.setColor(Color.black);
g.drawRect(0, 2, CloseTheBall.POOL_WIDTH, CloseTheBall.POOL_HEIGHT);
}
public int randomX() {
Random r = new Random();
return r.nextInt(POOL_WIDTH);
}
public int randomY() {
Random r = new Random();
return r.nextInt(POOL_HEIGHT);
}
public int randomDirection() {
Random r = new Random();
return r.nextInt(360);
}
public void returnOY() {
x = oldX;
y = oldY;
direction = 360 - direction;
x += (int)((double)speed * Math.cos(Math.PI * direction / 180));
y += (int)((double)speed * Math.sin(Math.PI * direction / 180));
}
public void returnOX () {
x = oldX;
y = oldY;
direction = 180 - direction;
x += (int)((double)speed * Math.cos(Math.PI * direction / 180));
y += (int)((double)speed * Math.sin(Math.PI * direction / 180));
}
public void calcNewPosition() {
oldX = x;
oldY = y;
x += (int)((double)speed * Math.cos(Math.PI * direction / 180));
y += (int)((double)speed * Math.sin(Math.PI * direction / 180));
if(x >= POOL_WIDTH || x <= 0) returnOX();
else if (y >= POOL_HEIGHT || y <= 0) returnOY();
else {
boolean quit = false;
for(int i=(-Math.abs(oldX-x)); i<Math.abs(oldX-x+1); ++i){
for(int j=(-Math.abs(oldX-x)); j<Math.abs(oldX-x+1); ++j){
try {
if (now[x+i][y+j]==1) {
//te ify to akt rozpaczy, po prostu prawdopodobienstwo zadzialania jest duze, algorytm jest tragiczny
if(now[x+i-2][y+j]==1 && now[x+i-1][y+j]==1 && now[x+i+1][y+j]==1 && now[x+i+2][y+j]==1) returnOY();
else if(now[x+i][y+j-2]==1 && now[x+i][y+j-1]==1 && now[x+i][y+j+1]==1 && now[x+i][y+j+2]==1) returnOX();
else if ((Math.cos(Math.PI * direction / 180))>Math.sin(Math.PI * direction / 180)) returnOY();
else returnOX();
quit = true;
break;
}
}
catch (Exception e) {
System.out.println("blisko!");
}
}
if (quit) {quit = false; break;}
}
}
}
public void calcNewPlayerPosition() {
oldPX = pX;
oldPY = pY;
switch (pDirection) {
case 0: { break; }
case 1: { pX = pX - pSpeed; break; }
case 2: { pY = pY - pSpeed; break; }
case 3: { pX = pX + pSpeed; break; }
case 4: { pY = pY + pSpeed; break; }
}
if (pX >= POOL_WIDTH) { --pX; pDirection = 0; }
else if (pX <= 0) { ++pX; pDirection = 0; }
else if (pY >= POOL_HEIGHT+2) { --pY; pDirection = 0; }
else if (pY <= 2) { ++pY; pDirection = 0; }
now[pX][pY] = 1;
// System.out.println("area["+pX+"]["+pY+"]="+area[pX][pY]);
}
public void run() {
while(true) {
try {
calcNewPosition();
calcNewPlayerPosition();
repaint();
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public CloseTheBall() throws AWTException {
now = new byte[POOL_WIDTH][POOL_HEIGHT+2];
for(int i = 0; i < POOL_HEIGHT + 2 ; ++i){
for(int j = 0; j < POOL_WIDTH; ++j){
now[j][i]=0;
}
}
area = new byte[POOL_WIDTH][POOL_HEIGHT+2];
for(int i = 0; i < POOL_HEIGHT + 2 ; ++i){
for(int j = 0; j < POOL_WIDTH; ++j){
if((i == 0) || (j == 0)) { area[j][i] = 1; continue; }
else if ((i == POOL_HEIGHT+1) || (j == POOL_WIDTH-1)) { area[j][i] = 1; continue; }
else area[j][i]=0;
}
}
// System.out.println("zrobione "+ area[POOL_WIDTH-1][POOL_HEIGHT+1]);
top = new PaintMove();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
panel = new JPanel(gridbag);
speed = new JScrollBar(JScrollBar.HORIZONTAL, 0, 0, 0, 4);
speed.addAdjustmentListener(this);
textSpeed = new JLabel("Szybkosc pilki: 1");
textSpeed.setHorizontalAlignment(SwingConstants.CENTER);
c.gridwidth = 0;
c.gridheight = 2;
c.ipadx = 150;
gridbag.setConstraints(textSpeed, c);
c.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(speed, c);
panel.add(textSpeed);
panel.add(speed);
}
public void actionPerformed(ActionEvent e) {}
public void adjustmentValueChanged(AdjustmentEvent e) {
textSpeed.setText("Szybkosc: " + (1 + speed.getValue()));
top.speed = 2 * (1 + speed.getValue());
}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e){
if (isStarted == false) { top.thread.start(); isStarted = true; }
if (e.getKeyCode() == e.VK_LEFT) {
if (right) { right = false; top.pDirection = 0; }
else { top.pDirection = 1; left = true; up = false; right = false; down = false; }
}
if (e.getKeyCode() == e.VK_UP) {
if (down) { down = false; top.pDirection = 0; }
else { top.pDirection = 2; left = false; up = true; right = false; down = false; }
}
if (e.getKeyCode() == e.VK_RIGHT) {
if (left) { left = false; top.pDirection = 0; }
else { top.pDirection = 3; left = false; up = false; right = true; down = false; }
}
if (e.getKeyCode() == e.VK_DOWN) {
if (up) { up = false; top.pDirection = 0; }
else { top.pDirection = 4; left = false; up = false; right = false; down = true; }
}
}
public void keyTyped(KeyEvent e) {}
}
glewap[at]o2.pl