Ich programmiere gerade an einem Tetris-Clone! Das Spielfeld ist eine Matrix, die Felder, die mit einer 1 gekennzeichnet sind werden "bemalt" und die Anderen bleiben leer. Kollisionen allgemein sind leicht zu erkennen, nur lasse ich meinen Thread eine gewisse anzahl an Millisekunden schlafen, damit die Figur nicht sofort unten ankommt. Wenn jetzt aber während der Thread schläft die aktuell fallende Figur gegen einen horizontal angrenzenten Stein stößt, geht er logischerweiße hindurch, was aber nicht Sinn und Zweck ist. Wer nicht nachvollziehen kann, was ich gerade meine, der kann sich meinen Code mal kopieren, sich einen Turm bauen und anschließend durch gedrückt halten der Cursortasten ganz schnell von der einen Seite auf die Andere wechseln. Die Figur geht durch den Turm hindurch!
Das ist der gesamte Code, wichtig ist allerdings (zumindest denke ich dass es daran liegt) nur die Methode
hat jemand ne Idee?
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Tetris extends JFrame implements KeyListener, ActionListener {
ZeichnenTet mal = new ZeichnenTet();
boolean stop = true;
boolean tiefer = true;
int fighoehe = 0;
int breite = 14;
int newBreite = 0;
int hoehe = 44;
int figur = 0;
int fast = 200;
int maxBreite = 29;
int minBreite = 0;
int breitePlus = 0;
int last[] = new int[8];
JMenuBar menu = new JMenuBar();
JMenu datei = new JMenu("Datei");
JMenu schwierigkeit = new JMenu("Schwierigkeit");
JMenu geschwindigkeit = new JMenu("Geschwindigkeit");
JMenu deadline = new JMenu("Deadline");
JMenuItem neu = new JMenuItem("Neues Spiel");
JMenuItem end = new JMenuItem("Aktuelles Spiel beenden");
JMenuItem langsam = new JMenuItem("Langsam");
JMenuItem normal = new JMenuItem("Normal");
JMenuItem schnell = new JMenuItem("Schnell");
JMenuItem hoch = new JMenuItem("Hoch");
JMenuItem mittel = new JMenuItem("Mittendrin");
JMenuItem tief = new JMenuItem("Tief");
public Tetris() {
setSize(310, 510);
addKeyListener(this);
neu.addActionListener(this);
end.addActionListener(this);
langsam.addActionListener(this);
normal.addActionListener(this);
schnell.addActionListener(this);
hoch.addActionListener(this);
mittel.addActionListener(this);
tief.addActionListener(this);
menu.add(datei);
menu.add(schwierigkeit);
datei.add(neu);
datei.add(end);
schwierigkeit.add(geschwindigkeit);
schwierigkeit.add(deadline);
geschwindigkeit.add(langsam);
geschwindigkeit.add(normal);
geschwindigkeit.add(schnell);
deadline.add(hoch);
deadline.add(mittel);
deadline.add(tief);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(menu, BorderLayout.NORTH);
getContentPane().add(mal);
}
void newGame() {
stopGame();
stop = false;
goDown();
}
void stopGame() {
stop = true;
for (int a = 0; a < 45; a++) {
for (int b = 0; b < 30; b++) {
mal.status[b][a] = 0;
}
}
repaint();
}
void goDown() {
new Thread(new Runnable() {
public void run() {
newFigur();
while (stop == false) {
aktuell();
hoehe--;
if (hoehe <= fighoehe) {
newFigur();
}
}
}
}).start();
}
void newFigur() {
reihe();
figur = (int)(Math.random() * 5);
if (figur == 4) {
figur = 5;
}
hoehe = 44;
breite = 14;
newBreite = 14;
maxBreite = 29;
minBreite = 0;
}
void reihe() {
boolean right = true;
boolean leer = true;
int high = 0;
for (int a = 0; a < 45; a++) {
for (int b = 0; b < 30; b++) {
if (mal.status[b][a] != 1) {
right = false;
}
else {
high = a;
}
}
if (right == true) {
for (int b = a; b < 44; b++) {
for (int c = 0; c < 30; c++) {
mal.status[c][b] = mal.status[c][b + 1];
}
}
a--;
for (int c = 0; c < 30; c++) {
if (mal.status[c][0] == 1) {
leer = false;
}
}
if (leer == true) {
System.out.println("Gewonnen");
}
leer = true;
}
right = true;
repaint();
}
if (44 - high < mal.dead) {
stopGame();
System.out.println("Verloren");
}
}
void canMove(int ... akt) {
if (mal.status[akt[0]][akt[1]] == 0 && mal.status[akt[2]][akt[3]] == 0 && mal.status[akt[4]][akt[5]] == 0 && mal.status[akt[6]][akt[7]] == 0) {
for (int i = 0; i < akt.length; i = i + 2) {
mal.status[akt[i]][akt[i + 1]] = 1;
}
repaint();
try {
Thread.sleep(fast);
}
catch (Exception e) {
}
if (hoehe > fighoehe + 1) {
for (int i = 0; i < akt.length; i = i + 2) {
mal.status[akt[i]][akt[i + 1]] = 0;
}
}
last = akt;
}
else {
for (int i = 0; i < akt.length; i = i + 2) {
if (mal.status[last[i]][last[i + 1] - 1] == 1) {
tiefer = false;
}
}
if (tiefer == false) {
for (int i = 0; i < last.length; i = i + 2) {
mal.status[last[i]][last[i + 1]] = 1;
repaint();
}
newFigur();
tiefer = true;
last = akt;
}
else {
for (int i = 0; i < last.length; i = i + 2) {
mal.status[last[i]][last[i + 1] - 1] = 1;
}
repaint();
try {
Thread.sleep(fast);
}
catch (Exception e) {
}
if (hoehe > fighoehe + 1) {
for (int i = 0; i < last.length; i = i + 2) {
last[i + 1]--;
mal.status[last[i]][last[i + 1]] = 0;
}
}
akt = last;
}
}
}
void aktuell() {
if (figur == 0) {
fighoehe = 2;
newBreite = breite;
canMove(newBreite, hoehe, newBreite, hoehe - 1, newBreite, hoehe - 2, newBreite, hoehe - 3);
}
else if (figur == 1) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite + 1, hoehe, newBreite, hoehe - 1, newBreite + 1, hoehe - 1);
}
else if (figur == 2) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite - 1, hoehe - 1, newBreite, hoehe - 1, newBreite + 1, hoehe - 1);
}
else if (figur == 3) {
fighoehe = 1;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite, hoehe - 1, newBreite, hoehe - 2, newBreite + 1, hoehe - 2);
}
else if (figur == 4) {
fighoehe = -1;
if (breite + 2 > maxBreite) {
breite = maxBreite - 2;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite - 1, hoehe, newBreite, hoehe, newBreite + 1, hoehe, newBreite + 2, hoehe);
}
else if (figur == 5) {
fighoehe = 1;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite + 1, hoehe, newBreite, hoehe - 1, newBreite, hoehe - 2);
}
else if (figur == 6) {
fighoehe = 1;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite, hoehe - 1, newBreite + 1, hoehe - 1, newBreite, hoehe - 2);
}
else if (figur == 7) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite - 1, hoehe, newBreite, hoehe, newBreite, hoehe - 1, newBreite + 1, hoehe);
}
else if (figur == 8) {
fighoehe = 1;
if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite, hoehe - 1, newBreite - 1, hoehe - 1, newBreite, hoehe - 2);
}
else if (figur == 9) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite - 1, hoehe, newBreite - 1, hoehe - 1, newBreite, hoehe, newBreite + 1, hoehe);
}
else if (figur == 10) {
fighoehe = 1;
if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite - 1, hoehe, newBreite, hoehe - 1, newBreite, hoehe - 2);
}
else if (figur == 11) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite + 1, hoehe, newBreite - 1, hoehe - 1, newBreite, hoehe - 1, newBreite + 1, hoehe - 1);
}
else if (figur == 12) {
fighoehe = 0;
if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
else if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite - 1, hoehe, newBreite, hoehe, newBreite + 1, hoehe, newBreite + 1, hoehe - 1);
}
else if (figur == 13) {
fighoehe = 1;
if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
newBreite = breite;
canMove(newBreite, hoehe, newBreite, hoehe - 1, newBreite, hoehe - 2, newBreite - 1, hoehe - 2);
}
else if (figur == 14) {
fighoehe = 0;
if (breite - 1 < minBreite) {
breite = 1 + minBreite;
}
else if (breite + 1 > maxBreite) {
breite = maxBreite - 1;
}
newBreite = breite;
canMove(newBreite - 1, hoehe, newBreite - 1, hoehe - 1, newBreite, hoehe - 1, newBreite + 1, hoehe - 1);
}
}
public static void main(String[] args) {
Tetris tet = new Tetris();
tet.setVisible(true);
}
public void keyTyped(KeyEvent key) {
}
public void keyReleased(KeyEvent key) {
}
public void keyPressed(KeyEvent key) {
if (key.getKeyCode() == 37 && breite > minBreite) {
breite--;
}
else if (key.getKeyCode() == 39 && breite < maxBreite) {
breite++;
}
else if (key.getKeyCode() == 38) {
if (figur == 0) {
figur = 4;
}
else if (figur == 2 && hoehe > 2) {
figur = 6;
}
else if (figur == 3) {
figur = 9;
}
else if (figur == 4 && hoehe > 3) {
figur = 0;
}
else if (figur == 5) {
figur = 12;
}
else if (figur == 6) {
figur = 7;
}
else if (figur == 7 && hoehe > 2) {
figur = 8;
}
else if (figur == 8) {
figur = 2;
}
else if (figur == 9 && hoehe > 2) {
figur = 10;
}
else if (figur == 10) {
figur = 11;
}
else if (figur == 11 && hoehe > 2) {
figur = 3;
}
else if (figur == 12 && hoehe > 2) {
figur = 13;
}
else if (figur == 13) {
figur = 14;
}
else if (figur == 14 && hoehe > 2) {
figur = 5;
}
}
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source == neu) {
newGame();
}
else if (source == end) {
stopGame();
}
else if (source == langsam) {
fast = 200;
}
else if (source == normal) {
fast = 150;
}
else if (source == schnell) {
fast = 100;
}
else if (source == hoch) {
mal.dead = 6;
}
else if (source == mittel) {
mal.dead = 14;
}
else if (source == tief) {
mal.dead = 24;
}
}
}
class ZeichnenTet extends JPanel {
int dead = 6;
int status[][] = new int[30][45];
public void paintComponent(Graphics comp) {
Graphics2D comp2D = (Graphics2D)comp;
comp2D.setColor(Color.black);
comp2D.fillRect(0, 0, 300, 450);
comp2D.setColor(Color.white);
comp2D.drawRect(0, 0, 300, 450);
comp2D.setColor(Color.yellow);
comp2D.drawLine(0, dead * 10, 300, dead * 10);
for (int a = 300; a >= 10; a = a - 10) {
for (int b = 450; b >= 10; b = b - 10) {
if (status[a / 10 - 1][44 - (b / 10 - 1)] == 1) {
comp2D.setColor(Color.red);
comp2D.fillRoundRect(a - 10, b - 10, 10, 10, 2, 2);
comp2D.setColor(Color.white);
comp2D.drawRoundRect(a - 10, b - 10, 10, 10, 2, 2);
}
}
}
}
}
Das ist der gesamte Code, wichtig ist allerdings (zumindest denke ich dass es daran liegt) nur die Methode
Code:
void canMove(int ... akt)
hat jemand ne Idee?