package Pokemon;
import PokemonEditor.*;
import PokemonEditor.media.MediaPlayer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class Canvas extends JPanel {
private BlockArrayList mapLayer1;
private BlockArrayList mapLayer2;
private BufferedImage tilesetBufferedImage;
private final BufferedImage spritesBufferedImage;
private final int ZOOM = 4;
private final int TILESIZE = 16;
private final String spritesFilename = GuiData.filenameSpriteSet;
private int feetPosition = 2;
private String direction = "right";
private boolean pressing = false;
private Timer moveTimer;
private Timer jumpUpTimer;
private Timer jumpDownTimer2;
private int positionX = 2 * TILESIZE * ZOOM;
private int positionY = 10 * TILESIZE * ZOOM;
private int finalPositionX;
private final int OFFSET = 12 * ZOOM;
private int finalPositionY;
private int walkSpeed = 4;
private final int jumpDownTimerSpeed = 30;
private long start;
private final Physics physics = new Physics();
private int feetPositionBackup;
private String directionBackup;
public Canvas() throws IOException {
keyBinding();
MediaPlayer mediaPlayer = new MediaPlayer();
LoadMap loadMap = new LoadMap();
if (loadMap.getMapString() != null) {
this.mapLayer1 = loadMap.getLoadedMap()[0];
this.mapLayer2 = loadMap.getLoadedMap()[1];
}
try {
tilesetBufferedImage = TilePanel.getExistingInstance().getBufferedImage();
} catch (Exception e) {
System.err.println("Konnte TilePanel-Image nicht holen");
e.printStackTrace();
}
spritesBufferedImage = loadMap.getBufferedImage(spritesFilename);
mediaPlayer.playWav();
moveTimer = new Timer(10, ae -> {
if (direction.equals("right") || direction.equals("left")) {
if (positionX == finalPositionX) {
changeFeetPosition();
if (jumpUpTimer.isRunning() || jumpDownTimer2.isRunning()) {
refreshFinalPositionXslowly(direction);
}
if (!jumpUpTimer.isRunning() && !jumpDownTimer2.isRunning()) {
refreshFinalPositionX(direction);
}
repaint();
}
if (!pressing) {
moveTimer.stop();
feetPosition = 2;
System.out.println("moveTimer stopped");
}
repaint();
}
if (direction.equals("right")) {
for (int i = 0; i < ZOOM * walkSpeed; i++) {
positionX++;
repaint();
}
}
if (direction.equals("left")) {
for (int i = 0; i < ZOOM * walkSpeed; i++) {
positionX--;
repaint();
}
}
});
jumpUpTimer = new Timer(1, jumpEvent -> {
if (direction.equals("left")) {
feetPosition = 1;
}
if (direction.equals("right"))
feetPosition = 2;
physics.setTimeElapsedInMs(System.currentTimeMillis() - start);
physics.setPixelPerTimerPass(
physics.getNeededPixelPerTimerPassWithGivenSpeedInMeterPerSecond(
physics.getSpeedAfterTimeInMeterPerSecond(
physics.getStartSpeedInMeterPerSecond(), physics.getGravitation(), physics.getTimeElapsedInMs())));
for (int i = 0; i < physics.getPixelPerTimerPass(); i++) {
positionY--;
repaint();
physics.setJumpedPixelCounter(physics.getJumpedPixelCounter() + 1);
if (physics.getPixelPerTimerPass() < 2) {
jumpUpTimer.stop();
finalPositionY = positionY + physics.getJumpedPixelCounter();
physics.setJumpedPixelCounter(0);
physics.setFallStartTime(System.currentTimeMillis());
jumpDownTimer2.start();
break;
}
}
});
jumpDownTimer2 = new Timer(1, jE -> {
direction = "down";
fallDownMethodTimer(jumpDownTimerSpeed);
});
}
private void fallDownMethodTimer(int jumpDownTimerSpeed) {
jumpDownTimerSpeed = (int) (jumpDownTimerSpeed / physics.getGravitation());
for (int i = 0; i < jumpDownTimerSpeed; i++) {
positionY++;
repaint();
if (positionY == finalPositionY) {
jumpDownTimer2.stop();
direction = directionBackup;
feetPosition = feetPositionBackup;
break;
}
}
}
public void keyBinding() {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "pressedSpace");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "releasedSpace");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "pressedLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "releasedLeft");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "pressedRight");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "releasedRight");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "pressedUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "releasedUp");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "pressedDown");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "releasedDown");
am.put("pressedSpace", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
feetPositionBackup = feetPosition;
directionBackup = direction;
doJump();
}
});
am.put("releasedSpace", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
pressing = false;
start = System.currentTimeMillis();
}
});
am.put("pressedLeft", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!pressing && !moveTimer.isRunning()) {
pressing = true;
direction = "left";
refreshFinalPositionX(direction);
changeFeetPosition();
moveTimer.start();
}
}
});
am.put("releasedLeft", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
pressing = false;
start = System.currentTimeMillis();
}
});
am.put("pressedRight", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!pressing && !moveTimer.isRunning()) {
pressing = true;
System.out.println(positionY);
direction = "right";
refreshFinalPositionX(direction);
changeFeetPosition();
moveTimer.start();
}
}
});
am.put("releasedRight", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
pressing = false;
start = System.currentTimeMillis();
}
});
am.put("pressedUp", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!pressing && !moveTimer.isRunning()) {
pressing = true;
direction = "up";
moveTimer.start();
}
}
});
am.put("releasedUp", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
pressing = false;
start = System.currentTimeMillis();
}
});
am.put("pressedDown", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!pressing && !moveTimer.isRunning()) {
pressing = true;
direction = "down";
moveTimer.start();
}
}
});
am.put("releasedDown", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
pressing = false;
start = System.currentTimeMillis();
}
});
setFocusable(true);
requestFocusInWindow();
}
private void paintLayer(Graphics g, BlockArrayList mapLayer) {
for (int i = 0; i < mapLayer.size(); i++) {
g.drawImage(tilesetBufferedImage, mapLayer.get(i).getDestinationX() * TILESIZE * ZOOM, mapLayer.get(i).getDestinationY() * TILESIZE * ZOOM, (mapLayer.get(i).getDestinationX() + 1) * TILESIZE * ZOOM, (mapLayer.get(i).getDestinationY() + 1) * TILESIZE * ZOOM, mapLayer.get(i).getSourceX() * TILESIZE, mapLayer.get(i).getSourceY() * TILESIZE, (mapLayer.get(i).getSourceX() + 1) * TILESIZE, (mapLayer.get(i).getSourceY() + 1) * TILESIZE, null);
}
}
private void refreshFinalPositionX(String direction) {
if (direction.equals("right")) {
finalPositionX = positionX + (TILESIZE / 2) * ZOOM;
}
if (direction.equals("left")) {
finalPositionX = positionX - (TILESIZE / 2) * ZOOM;
}
}
private void refreshFinalPositionXslowly(String direction) {
if (direction.equals("right")) {
finalPositionX = positionX + (TILESIZE / 2) * ZOOM * 3;
}
if (direction.equals("left")) {
finalPositionX = positionX - (TILESIZE / 2) * ZOOM * 3;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintLayer(g, mapLayer1);
paintLayer(g, mapLayer2);
if (direction.equals("left")) {
switch (feetPosition) {
case 1 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 1, 91, 17, 118 + 1, null);
case 2 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 19, 91, 35, 118 + 1, null);
case 3 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 37, 91, 53, 118 + 1, null);
}
}
if (direction.equals("right")) {
switch (feetPosition) {
case 1 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 1, 31, 17, 58 + 1, null);
case 2 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 19, 31, 35, 58 + 1, null);
case 3 -> g.drawImage(spritesBufferedImage, positionX, positionY - OFFSET, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM, 37, 31, 53, 58 + 1, null);
}
}
if (direction.equals("up")) {
switch (feetPosition) {
case 1 -> g.drawImage(spritesBufferedImage, positionX, positionY - 27, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2) - 27, 1, 1, 17, 29, null);
case 2 -> g.drawImage(spritesBufferedImage, positionX, positionY, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2), 19, 1, 35, 29, null);
case 3 -> g.drawImage(spritesBufferedImage, positionX, positionY, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2), 37, 1, 53, 29, null);
}
}
if (direction.equals("down")) {
switch (feetPosition) {
case 1 -> g.drawImage(spritesBufferedImage, positionX, positionY - 27, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2) - 27, 1, 61, 17, 89, null);
case 2 -> g.drawImage(spritesBufferedImage, positionX, positionY, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2), 19, 61, 35, 89, null);
case 3 -> g.drawImage(spritesBufferedImage, positionX, positionY, positionX + TILESIZE * ZOOM, positionY + TILESIZE * ZOOM + (TILESIZE * ZOOM / 2), 37, 61, 53, 89, null);
}
}
}
private void doJump() {
if (!jumpUpTimer.isRunning() && !jumpDownTimer2.isRunning()) {
finalPositionY = positionY - physics.getJumpedPixelCounter();
start = System.currentTimeMillis();
jumpUpTimer.start();
}
}
private void changeFeetPosition() {
if (feetPosition == 1) {
feetPosition = 2;
repaint();
} else if (feetPosition == 2) {
feetPosition = 1;
repaint();
}
}
}