Forumet - Hjälp med spel i Java

Hjälp med spel i Java

301 0 17
Hejsan UM tänkte börja med att säga att detta EJ är för en skoluppgift utan jag gör det för att jag tycker det är kul och vill lära mig... Detta är även mitt första försök till spel, innan har det bara varit skolarbete.

I min main klass:

package tetris;

import javax.swing.*;

public class Tetris {
public static void main(String[] args) {
JFrame frame = new JFrame("Tetris");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TetrisPanel());


frame.pack();
frame.setVisible(true);
}

}

Som skapar en ny TetrisPanel

I TetrisPanel så målar en paintComponent(Graphics page) metod ut en massa GIF bilder

public void paintComponent(Graphics page) {

super.paintComponent(page);

currentRed.paintIcon(this, page, x, y);
currentGreen.paintIcon(this, page, xx, yy);


}

Om jag trycker på en specifik tangent så så händer det vissa saker. ex att en utav bildernas koordinater ändras och den rör sig i framen...

I min TetrisPanel klass så när jag trycker på E, så skapar den ett nytt objekt utav klassen Bullet, som tar x och y koordinater ifrån där i detta fall en stridsvagn var och åt vilket håll den är riktad och sedan uppdaterar Bullet klassen dessa x och y koordinater och använder repaint(); för att skriva ut kulan på de x och y koordinater som är just då. Bullet klassen har en egen paintComponent metod.

public void paintComponent(Graphics page) {

super.paintComponent(page);
System.out.print("Ok");
bullet.paintIcon(this, page, x, y);


}


Och nu till problemet, när repaint(); i Bullet kallas så körs inte Bullet klassens paintComponent metod, vilket resulterar i att kulan inte renderas ut alls...

Så, till frågan: Hur fixar jag detta?

Några andra saker jag behöver hjälp med:

Ljud? kan ej få ljud att fungera


All källkod:

Klassen med mainmetoden


package tetris;

import javax.swing.*;

public class Tetris {
public static void main(String[] args) {
JFrame frame = new JFrame("Tetris");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TetrisPanel());


frame.pack();
frame.setVisible(true);
}

}


Huvudklassen TetrisPanel

package tetris;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class TetrisPanel extends JPanel {
private final int WIDTH = 1000, HEIGHT = 800, JUMP = 10;
private ImageIcon red, green, winGreen, winRed, currentRed,
currentGreen, tankUp, tankDown, tankLeft, tankRight, redUp,
redDown, redLeft, redRight;
private int x, y, xx, yy, xxx, yyy, redWin, greenWin, range,
startingValuesRedXY, startingValuesGreenX, startingValuesGreenY;
private String direction;

public TetrisPanel() {
addKeyListener(new DirectionListener());

startingValuesRedXY = 20;
startingValuesGreenX = 930;
startingValuesGreenY = 730;

x = startingValuesRedXY;
y = startingValuesRedXY;

xx = startingValuesGreenX;
yy = startingValuesGreenY;

redWin = 0;
greenWin = 0;
String winReds = Integer.toString(redWin);
String winGreens = Integer.toString(greenWin);

System.out.print(redWin + winReds);

range = 60;

red = new ImageIcon("square.gif");
green = new ImageIcon("green.gif");
winGreen = new ImageIcon("wingreen.gif");
winRed = new ImageIcon("winred.gif");
tankUp = new ImageIcon("tankUp.gif");
tankDown = new ImageIcon("tankDown.gif");
tankLeft = new ImageIcon("tankLeft.gif");
tankRight = new ImageIcon("tankRight.gif");
redUp = new ImageIcon("redUp.gif");
redDown = new ImageIcon("redDown.gif");
redLeft = new ImageIcon("redLeft.gif");
redRight = new ImageIcon("redRight.gif");

currentGreen = tankUp;
currentRed = redDown;

setBackground(Color.WHITE);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);

Timer time = new Timer(7, taskPerformer);
time.start();

}

ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (currentRed != winRed) {
if (xx > x) {

x += 1;
currentRed = redRight;
}

else {
x -= 1;
currentRed = redLeft;
}

if (yy > y) {
y += 1;
currentRed = redDown;
}

else {
y -= 1;
currentRed = redUp;
}

}

repaint();
}

};

public void paintComponent(Graphics page) {

super.paintComponent(page);

currentRed.paintIcon(this, page, x, y);
currentGreen.paintIcon(this, page, xx, yy);


}

private class DirectionListener implements KeyListener {

public void keyPressed(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.VK_UP:
if (y >= 10)
y -= JUMP;
if (currentRed != winRed)
currentRed = redUp;
if ((xx - range) < x && x < (xx + range) && (yy - range) < y
&& y < (yy + range)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;
case KeyEvent.VK_DOWN:
if (y <= 740)
y += JUMP;
if (currentRed != winRed)
currentRed = redDown;
if ((xx - range) < x && x < (xx + range) && (yy - range) < y
&& y < (yy + range)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;
case KeyEvent.VK_LEFT:
if (x >= 10)
x -= JUMP;
if (currentRed != winRed)
currentRed = redLeft;
if ((xx - range) < x && x < (xx + range) && (yy - range) < y
&& y < (yy + range)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;
case KeyEvent.VK_RIGHT:
if (x <= 940)
x += JUMP;
if (currentRed != winRed)
currentRed = redRight;
if ((xx - range) < x && x < (xx + range) && (yy - range) < y
&& y < (yy + range)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;

case KeyEvent.VK_W:
if (yy >= 10)
yy -= JUMP;
currentGreen = tankUp;
if ((xx - 65) < x && x < (xx + 65) && (yy - 65) < y
&& y < (yy + 65)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;

case KeyEvent.VK_S:
if (yy <= 740)
yy += JUMP;
currentGreen = tankDown;
if ((xx - 65) < x && x < (xx + 65) && (yy - 65) < y
&& y < (yy + 65)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;
case KeyEvent.VK_A:
if (xx >= 10)
xx -= JUMP;
currentGreen = tankLeft;
if ((xx - 65) < x && x < (xx + 65) && (yy - 65) < y
&& y < (yy + 65)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;
case KeyEvent.VK_D:
if (xx <= 940)
xx += JUMP;
currentGreen = tankRight;
if ((xx - range) < x && x < (xx + range) && (yy - range) < y
&& y < (yy + range)) {
currentRed = winRed;
redWin++;

x = 300;
y = 200;
}
break;

case KeyEvent.VK_SPACE:
currentGreen = tankUp;
currentRed = redDown;
x = startingValuesRedXY;
y = startingValuesRedXY;

xx = startingValuesGreenX;
yy = startingValuesGreenY;

break;
case KeyEvent.VK_E:
if (currentGreen == tankUp)
direction = "up";
else if (currentGreen == tankDown)
direction = "down";
else if (currentGreen == tankRight)
direction = "right";
else if (currentGreen == tankLeft)
direction = "left";
new Bullet(direction, xx, yy);


break;
}
repaint();
}

public void keyReleased(KeyEvent event) {

}

public void keyTyped(KeyEvent event) {

}

}

}

Och sist men inte minst, Bullet klassen


package tetris;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class Bullet extends JPanel {
private int x, y;
private String direction;
private ImageIcon bullet;

public Bullet(String s, int xCoord, int yCoord) {
bullet = new ImageIcon("bullet.gif");
x = xCoord;
y = yCoord;
direction = s;
new Timer(100, taskPerformer).start();
}



public void paintComponent(Graphics page) {

super.paintComponent(page);
System.out.print("Ok");
bullet.paintIcon(this, page, x, y);


}

ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {

if (direction == "right" )
x++;
else if (direction == "left" )
x--;
else if (direction == "up" )
y--;
else if (direction == "down" )
y++;
System.out.print(x + " " + y + " ");
repaint();
}

};

}

Tack på förhand, säg till ifall ni behöver mer info osv.

Spana också in:

ankzor:

går ej att editera längre, tyvär.


Släng upp din kod på pastebin eller nåt och skicka den via PM till mig så kan jag lägga in den med [ pre ]-taggar i första inlägget.

ankzor:

sen undrar jag hur man skulle veta att det fanns pre-taggar? D:


Det undrar jag med. Undrar varför vi inte lagt in det i UM++? [shake]

ankzor:

haha, kanske borde byta språk eller någe


Jag sitter och skriver Lua med Löve för att hantera grafik, ljud, input o.s.v. Annars är ju Python + Pygame en vanlig kombination för 2d-spel. Båda vore att föredra framför Java. [cry]

Men vem vet, kanske någon Java-kunnig dyker upp och kan hjälpa dig med ditt problem.
Testa att skriva @Override framför paintComponent, och ta bort super.paintComponent.. vet inte om det hjälper, kollade bara igenom snabbt. Men det är vad jag vet standardsättet att skriva det på; alltså:

@Override public void paintComponent(Graphics page)

Annars; är du säker på att där felet sitter? Knappt använt swing själv, men ska testa ladda in koden i eclipse o se om problemet kan lösas (om inte @Override löser det)



Åtta:

Annars är ju Python + Pygame en vanlig kombination för 2d-spel. Båda vore att föredra framför Java.


Varför så? Själv tycker jag Java är ett ypperligt val för just 2d spel! Tycker också TS borde testa Slick 2d biblioteket till java, väldigt bra för just 2d spelprogrammering!
shazbot:

Själv tycker jag Java är ett ypperligt val för just 2d spel!


Instämmer med Åtta; har du prövat någonting annat? Den vanligaste anledningen till att folk "gillar" C++ eller Java är att det är de enda de egentligen kan.

ankzor:

.


Så vitt jag kan se lägger du aldrig till ditt Bulletobjekt i tetrispanelen. Faktum är att du bara skapar ett Bulletobjekt utan att göra någonting alls med det; släng in en this.add(new Bullet(direction, xx, yy)); istället för new Bullet(direction, xx, yy); så kommer du att se den.

Jag skulle dock skrota hela koden och börja om från början. T ex måste du hålla koll på alla kulor så du kan göra dig av med dem när du träffar något eller de försvinner från brädet, varför är TetrisPanel.direction en String, och varför i hela fridens namn representerar du dina tanks som en drös medlemsvariabler istället för som separata objekt?! Ta dig tid till att tänka igenom din design innan du sätter dig och börjar koda, så kommer du att få betydligt bättre resultat, och får man bättre resultat blir det dessutom roligare.

Lär de inte ut grundläggande objektorienterad design vid KTH?
Gentlernen:

skrota hela koden


jo det var ungefär det jag kom fram till, det var dock mest ett litet experiment från min sida, då vi nästan ej hållit på alls med grafiskt. tack för hjälpen iaf.

Gentlernen:

Lär de inte ut grundläggande objektorienterad design vid KTH?


Missade antagligen den föreläsning ;)

Gentlernen:

this.add(new Bullet(direction, xx, yy));


Det fungerade delvis, nu kör den paintComonent i Bullet iaf, vilket den är gjorde tidigare. dock syns den fortfarande ej