Napisałem w Javie Arkanoida. Ogólnie rzecz biorąc działa nieźle, ale... No właśnie - nie jest idealna :P Nie działa w pełni dobrze. Napiszę jakie mam problemy:
- Kulka nie odbija się prawidłowo od deski (paletki, którą się steruje) - kąt odbicia nie jest zawsze przewidywalny.
- Kulka nie odbija się prawidłowo od boków ekranu (czasami przelatuje przez nie - tak samo i przez deskę czasem).
Problem polega na tym, że współrzędne zapisuję w zmiennych double - i czasem piłka po zmianie kąta po kontakcie z przeszkodą - nie opuszcza w pełni przeszkody - co powoduje następną zmianę konta i tak w kółko, aż albo nie wyleci za ekran, albo wróci. Proszę o pomoc jak to załatwić. Nie będę sępem i podzielę się z Wami moim kodem :)
//Ark.java
import java.awt.Color;
import java.awt.Cursor;
import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Ark extends JFrame implements KeyListener
{
private class ArkanoidPanel extends JPanel implements MouseMotionListener, MouseListener
{
private Cegielka ceg [][];
private Deska des;
private Kulka kul;
private boolean start;
public ArkanoidPanel(int xE, int yE)
{
ceg = zbudujCegielki(xE, yE);
des = new Deska(xE, yE);
kul = new Kulka(xE, yE, des);
start = false;
addMouseMotionListener(this);
addMouseListener(this);
}
public Cegielka [][] getC()
{
return ceg;
}
public Deska getD()
{
return des;
}
public Kulka getK()
{
return kul;
}
public Cegielka [][] zbudujCegielki(int xE, int yE)
{
Cegielka [][] c = new Cegielka [10][20];
double ax = 0.005 * xE;
double ay = 0.04 * yE;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 20; j++)
{
c[i][j] = new Cegielka();
c[i][j].setX((int)(ax));
c[i][j].setY((int)(ay));
c[i][j].setW((int)(0.04 * xE));
c[i][j].setH((int)(0.02 * yE));
ax += 0.05 * xE;
}
ay += 0.03 * yE;
ax = 0.005 * xE;
}
return c;
}
public void wyswietlCegielki(Graphics g)
{
for (int i = 0; i < ceg.length; i ++)
for (int j = 0; j < ceg[i].length; j++)
ceg[i][j].wyswietlCegielke(g);
}
public void wyswietlDeske(Graphics g)
{
des.wyswietlDeske(g);
}
public void wyswietlKulke(Graphics g)
{
kul.wyswietlKulke(g);
}
public boolean czyZawiera(Kulka k, int x, int y)
{
if (((x - k.getX() - k.getR() / 2) * (x - k.getX() - k.getR() / 2)) + ((y - k.getY() - k.getR() / 2) * (y - k.getY() - k.getR() / 2)) <= (k.getR() / 2) * (k.getR() / 2))
return true;
return false;
}
public int yOdcinek(Odcinek o, int x)
{
return ((o.getY2() - o.getY1()) * (x - o.getX1()) / (o.getX2() - o.getX1()) + o.getY1());
}
public boolean kolizjaKulkaOdcinek(Kulka k, Odcinek o)
{
if (o.getX1() == o.getX2() && o.getY1() == o.getY2())
return czyZawiera(k, o.getX1(), o.getY1());
else if (o.getX1() == o.getX2())
{
for (int i = o.getY1(); i <= o.getY2(); i++)
if (czyZawiera(k, o.getX1(), i))
return true;
}
else if (o.getY1() == o.getY2())
{
for (int i = o.getX1(); i <= o.getX2(); i++)
if (czyZawiera(k, i, o.getY1()))
return true;
}
else
for (int i = o.getX1(); i <= o.getX2(); i++)
if (czyZawiera(k, i, yOdcinek(o, i)))
return true;
return false;
}
public int kolizjaKulkaCegielka(Kulka k, Cegielka c)
{
if (c.getS() == false)
return -1;
else
for (int i = 0; i < 4; i++)
if (kolizjaKulkaOdcinek(k, c.zwrocOdcinek(i)))
return i;
return -1;
}
public int kolizjaKulkaBanda(Kulka k)
{
if (k.getX() + k.getR() / 2 <= 0)
return 3;
else if ((k.getX() + k.getR() / 2) > Toolkit.getDefaultToolkit().getScreenSize().width)
return 1;
else if ((k.getY() + k.getR() / 2) <= 0)
return 0;
else if ((k.getY() + k.getR() / 2) > Toolkit.getDefaultToolkit().getScreenSize().height)
return 2;
return -1;
}
public boolean kolizjaKulkaDeska(Kulka k, Deska d)
{
return kolizjaKulkaOdcinek(k, d.zwrocOdcinek());
}
public void przesunKulke()
{
kul.przesun();
for (int i = 0; i < 10; i++)
for (int j = 0; j < 20; j++)
{
int bok = -1;
if ((bok = kolizjaKulkaCegielka(kul, ceg[i][j])) != -1)
{
ceg[i][j].setS(false);
kul.zmienKatCegielka(bok);
}
}
int bok = -1;
if ((bok = kolizjaKulkaBanda(kul)) != -1)
kul.zmienKatBanda(bok);
if (kolizjaKulkaDeska(kul, des))
kul.zmienKatDeska(des);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.black);
wyswietlCegielki(g);
wyswietlDeske(g);
wyswietlKulke(g);
if (start)
przesunKulke();
}
@Override
public void mouseDragged(MouseEvent me) {
}
@Override
public void mouseMoved(MouseEvent me) {
des.setX(me.getX() - des.getW() / 2);
if (!start)
kul.setX(me.getX() - kul.getR() / 2);
}
@Override
public void mouseClicked(MouseEvent me) {
start = true;
}
@Override
public void mouseEntered(MouseEvent me) {
}
@Override
public void mouseExited(MouseEvent me) {
}
@Override
public void mousePressed(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent me) {
}
}
@Override
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_ESCAPE)
System.exit(0);
}
@Override
public void keyReleased(KeyEvent ke) {
}
@Override
public void keyTyped(KeyEvent ke) {
}
public Ark()
{
ArkanoidPanel p = new ArkanoidPanel(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
add(p);
addKeyListener(this);
requestFocus();
setUndecorated(true);
setResizable(false);
przelaczNaPelnyEkran();
ukryjKursorMyszy();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Wat(p);
}
public void przelaczNaPelnyEkran()
{
DisplayMode displayMode = new DisplayMode(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height, 24, 75);
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
device.setFullScreenWindow(this);
try
{
device.setDisplayMode(displayMode);
}
catch (IllegalArgumentException e)
{
System.out.println("Wyjątek!");
}
}
public void ukryjKursorMyszy()
{
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
Cursor invisibleCursor = Toolkit.getDefaultToolkit().createCustomCursor(Toolkit.getDefaultToolkit().getImage(""), new Point(0, 0), "invisible");
device.getFullScreenWindow().setCursor(invisibleCursor);
}
public static void main(String[] args) {
new Ark();
}
}
//Cegielka.java
import java.awt.Graphics;
public class Cegielka {
private int x, y;
private int w, h;
private boolean s;
public Cegielka()
{
s = true;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getW()
{
return w;
}
public int getH()
{
return h;
}
public boolean getS()
{
return s;
}
public void setX(int nX)
{
x = nX;
}
public void setY(int nY)
{
y = nY;
}
public void setW(int nW)
{
w = nW;
}
public void setH(int nH)
{
h = nH;
}
public void setS(boolean bS)
{
s = bS;
}
public void wyswietlCegielke(Graphics g)
{
if (s)
g.fillRect(x, y, w, h);
}
public Odcinek zwrocOdcinek(int num)
{
switch (num)
{
case 0: return new Odcinek(x, y, x + w, y);
case 1: return new Odcinek(x + w, y, x + w, y + h);
case 2: return new Odcinek(x, y + h, x + w, y + h);
case 3: return new Odcinek(x, y, x, y + h);
default: return null;
}
}
}
//Deska.java
import java.awt.Graphics;
public class Deska {
private int x, y;
private int w, h;
public Deska(int xE, int yE)
{
setWH(xE, yE);
x = (int)((xE - w) / 2);
y = (int)(0.95 * yE);
}
public void setX(int nX)
{
x = nX;
}
public void setY(int nY)
{
y = nY;
}
public void setWH(int xE, int yE)
{
w = (int)(0.1 * xE);
h = (int)(0.01 * yE);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getW()
{
return w;
}
public int getH()
{
return h;
}
public void wyswietlDeske(Graphics g)
{
g.fillRect(x, y, w, h);
}
public Odcinek zwrocOdcinek()
{
return new Odcinek(x, y, x + w, y);
}
public double punktDeski(Kulka k)
{
return (double)w / (k.getX() + k.getR() / 2 - x);
}
}
//Kulka.java
import java.awt.Graphics;
import java.util.Random;
public class Kulka {
private double x, y;
private int r;
private double angle;
public Kulka(int xE, int yE, Deska d)
{
setR(xE, yE);
x = d.getX() + d.getW() / 2 - r / 2;
y = d.getY() - r;
katZZakresu(45, 135);
}
public void setX(int nX)
{
x = nX;
}
public void setY(int nY)
{
y = nY;
}
public void setR(int xE, int yE)
{
r = (int)(xE * yE / 100000);
}
public void setA(double dA)
{
angle = dA;
}
public int getX()
{
return (int)x;
}
public int getY()
{
return (int)y;
}
public int getR()
{
return r;
}
public double getA()
{
return angle;
}
public void wyswietlKulke(Graphics g)
{
g.fillOval((int)x, (int)y, r, r);
}
public void katZZakresu(int n1, int n2)
{
setA(((new Random()).nextInt(n2 + 1 - n1) + n1) * Math.PI / 180);
}
public double zwrocKat(int n1, int n2)
{
return ((new Random()).nextInt(n2 + 1 - n1) + n1) * Math.PI / 180;
}
public void przesun()
{
x += Math.cos(angle);
y -= Math.sin(angle);
}
public void zmienKatCegielka(int num)
{
if (num == 0 || num == 2)
angle = 2 * Math.PI - angle;
else if (num == 1 || num == 3)
angle = 3 * Math.PI - angle;
}
public void zmienKatDeska(Deska d)
{
angle = d.punktDeski(this) * zwrocKat(90, 90) + zwrocKat(45, 45);
}
public void zmienKatBanda(int num)
{
if (num == 0 || num == 2)
angle = 2 * Math.PI - angle;
else if (num == 1 || num == 3)
angle = 5 * Math.PI - 2 * angle;
}
}
//Odcinek.java
public class Odcinek {
private int x1, y1, x2, y2;
public Odcinek(int nX1, int nY1, int nX2, int nY2)
{
x1 = nX1;
y1 = nY1;
x2 = nX2;
y2 = nY2;
}
public int getX1()
{
return x1;
}
public int getY1()
{
return y1;
}
public int getX2()
{
return x2;
}
public int getY2()
{
return y2;
}
}
//Wat.java
import java.awt.Component;
public class Wat implements Runnable
{
private final Component c;
public Wat(Component c)
{
this.c = c;
(new Thread(this, "F")).start();
}
@Override
public void run() {
while (true)
{
c.repaint();
try {
Thread.sleep(1);
} catch (Exception e)
{
System.out.println("Wyjątek!");
}
}
}
}
Dodatkowo załączam plik jar gotowej gry