help me fix script in Java Eclipse

link to video can someone fix my script, I want the black color to be transparent and so that when the player touches zap0 the sound "electrocuted.wav" and its other animations are played because this zap has 5 animations the player moves slightly forward, fix it so that the lever does not move towards the player and disappears when you get close and zap0 plays the sound "current.wav" in a loop and when you get close the sound starts to have a higher volume and when the player moves away the sound decreases describe what and where I should correct in which script ElectricField: package raycast3D; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; public class ElectricField { private double x, y; private BufferedImage[] frames; private int currentFrame; private long lastFrameTime; private static final int FRAME_COUNT = 6; private static final long FRAME_DURATION = 100; // 100ms per frame private boolean active; public ElectricField(double x, double y) { this.x = x; this.y = y; this.currentFrame = 0; this.lastFrameTime = System.currentTimeMillis(); this.active = true; loadFrames(); } private void loadFrames() { frames = new BufferedImage[FRAME_COUNT]; try { for (int i = 0; i < FRAME_COUNT; i++) { String path = "texture/zap" + i + ".png"; File file = new File(path); if (!file.exists()) { System.err.println("Texture file not found: " + path); throw new Exception("Missing zap texture"); } BufferedImage original = ImageIO.read(file); frames[i] = makeWhiteTransparent(original); } } catch (Exception e) { e.printStackTrace(); for (int i = 0; i < FRAME_COUNT; i++) { frames[i] = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB); Graphics2D g = frames[i].createGraphics(); g.setColor(Color.YELLOW); g.fillRect(0, 0, 64, 64); g.setColor(Color.BLACK); g.drawString("ZAP" + i, 16, 32); g.dispose(); } } } private BufferedImage makeWhiteTransparent(BufferedImage original) { BufferedImage transparent = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_ARGB); for (int x = 0; x < original.getWidth(); x++) { for (int y = 0; y < original.getHeight(); y++) { int rgb = original.getRGB(x, y); int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = rgb & 0xFF; // Detect white or near-white pixels (allowing some tolerance) if (r > 200 && g > 200 && b > 200) { transparent.setRGB(x, y, 0x00FFFFFF); // Transparent } else { transparent.setRGB(x, y, rgb); // Preserve original color (including yellow) } } } return transparent; } public void update() { if (System.currentTimeMillis() - lastFrameTime > FRAME_DURATION) { currentFrame = (currentFrame + 1) % FRAME_COUNT; lastFrameTime = System.currentTimeMillis(); } } public double getX() { return x; } public double getY() { return y; } public BufferedImage getCurrentFrame() { return frames[currentFrame]; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } } ElectricFieldManager: package raycast3D; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.sound.sampled.*; public class ElectricFieldManager { private List fields; private int[][] fieldMap; private Player player; private Map map; private Clip currentSoundClip; private float maxVolume = 0.0f; // 0 dB private float minVolume = -80.0f; // -80 dB private static final double MAX_SOUND_DISTANCE = 2.0; private static final double MIN_SOUND_DISTANCE = 10.0; private long lastZapTime; private static final long ZAP_COOLDOWN = 500; // 500ms private long soundFramePosition; private boolean enabled; // Controlled by lever public ElectricFieldManager(Player player, Map map) { this.player = player; this.map = map; this.fields = new ArrayList(); this.lastZapTime = 0; this.soundFramePosition = 0; this.enabled = true; // Start enabled initializeFieldMap(); initializeFields(); loadCurrentSound(); } private void initializeFieldMap() { fieldMap = new int[][]{ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Field at (1,1) {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

Apr 15, 2025 - 21:51
 0
help me fix script in Java Eclipse

bugs in game
link to video

can someone fix my script, I want the black color to be transparent and so that when the player touches zap0 the sound "electrocuted.wav" and its other animations are played because this zap has 5 animations the player moves slightly forward, fix it so that the lever does not move towards the player and disappears when you get close

and zap0 plays the sound "current.wav" in a loop and when you get close the sound starts to have a higher volume and when the player moves away the sound decreases

describe what and where I should correct in which script

ElectricField: package raycast3D;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

public class ElectricField {
private double x, y;
private BufferedImage[] frames;
private int currentFrame;
private long lastFrameTime;
private static final int FRAME_COUNT = 6;
private static final long FRAME_DURATION = 100; // 100ms per frame
private boolean active;

public ElectricField(double x, double y) {
    this.x = x;
    this.y = y;
    this.currentFrame = 0;
    this.lastFrameTime = System.currentTimeMillis();
    this.active = true;
    loadFrames();
}

private void loadFrames() {
    frames = new BufferedImage[FRAME_COUNT];
    try {
        for (int i = 0; i < FRAME_COUNT; i++) {
            String path = "texture/zap" + i + ".png";
            File file = new File(path);
            if (!file.exists()) {
                System.err.println("Texture file not found: " + path);
                throw new Exception("Missing zap texture");
            }
            BufferedImage original = ImageIO.read(file);
            frames[i] = makeWhiteTransparent(original);
        }
    } catch (Exception e) {
        e.printStackTrace();
        for (int i = 0; i < FRAME_COUNT; i++) {
            frames[i] = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = frames[i].createGraphics();
            g.setColor(Color.YELLOW);
            g.fillRect(0, 0, 64, 64);
            g.setColor(Color.BLACK);
            g.drawString("ZAP" + i, 16, 32);
            g.dispose();
        }
    }
}

private BufferedImage makeWhiteTransparent(BufferedImage original) {
    BufferedImage transparent = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_ARGB);
    for (int x = 0; x < original.getWidth(); x++) {
        for (int y = 0; y < original.getHeight(); y++) {
            int rgb = original.getRGB(x, y);
            int r = (rgb >> 16) & 0xFF;
            int g = (rgb >> 8) & 0xFF;
            int b = rgb & 0xFF;
            // Detect white or near-white pixels (allowing some tolerance)
            if (r > 200 && g > 200 && b > 200) {
                transparent.setRGB(x, y, 0x00FFFFFF); // Transparent
            } else {
                transparent.setRGB(x, y, rgb); // Preserve original color (including yellow)
            }
        }
    }
    return transparent;
}

public void update() {
    if (System.currentTimeMillis() - lastFrameTime > FRAME_DURATION) {
        currentFrame = (currentFrame + 1) % FRAME_COUNT;
        lastFrameTime = System.currentTimeMillis();
    }
}

public double getX() {
    return x;
}

public double getY() {
    return y;
}

public BufferedImage getCurrentFrame() {
    return frames[currentFrame];
}

public boolean isActive() {
    return active;
}

public void setActive(boolean active) {
    this.active = active;
}

}

ElectricFieldManager: package raycast3D;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.*;

public class ElectricFieldManager {
private List fields;
private int[][] fieldMap;
private Player player;
private Map map;
private Clip currentSoundClip;
private float maxVolume = 0.0f; // 0 dB
private float minVolume = -80.0f; // -80 dB
private static final double MAX_SOUND_DISTANCE = 2.0;
private static final double MIN_SOUND_DISTANCE = 10.0;
private long lastZapTime;
private static final long ZAP_COOLDOWN = 500; // 500ms
private long soundFramePosition;
private boolean enabled; // Controlled by lever

public ElectricFieldManager(Player player, Map map) {
    this.player = player;
    this.map = map;
    this.fields = new ArrayList<>();
    this.lastZapTime = 0;
    this.soundFramePosition = 0;
    this.enabled = true; // Start enabled
    initializeFieldMap();
    initializeFields();
    loadCurrentSound();
}

private void initializeFieldMap() {
    fieldMap = new int[][]{
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Field at (1,1)
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    };
}

private void initializeFields() {
    for (int y = 0; y < fieldMap.length; y++) {
        for (int x = 0; x < fieldMap[0].length; x++) {
            if (fieldMap[y][x] == 1 && map.get(x, y) == 0) {
                fields.add(new ElectricField(x + 0.5, y + 0.5));
            }
        }
    }
}

private void loadCurrentSound() {
    AudioInputStream audioInputStream = null;
    try {
        String soundPath = "texture/current.wav";
        File soundFile = new File(soundPath);
        if (!soundFile.exists()) {
            System.err.println("Sound file not found: " + soundFile.getAbsolutePath());
            return;
        }
        audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        currentSoundClip = AudioSystem.getClip();
        currentSoundClip.open(audioInputStream);
        setVolume(minVolume);
    } catch (Exception e) {
        System.err.println("Error loading sound: " + e.getMessage());
        e.printStackTrace();
    } finally {
        if (audioInputStream != null) {
            try {
                audioInputStream.close();
            } catch (Exception e) {
                System.err.println("Error closing audio stream: " + e.getMessage());
            }
        }
    }
}

private void setVolume(float gain) {
    if (currentSoundClip != null && currentSoundClip.isOpen()) {
        try {
            FloatControl gainControl = (FloatControl) currentSoundClip.getControl(FloatControl.Type.MASTER_GAIN);
            float clampedGain = Math.max(minVolume, Math.min(maxVolume, gain));
            gainControl.setValue(clampedGain);
        } catch (IllegalArgumentException e) {
            System.err.println("Failed to set volume: " + e.getMessage());
        }
    }
}

public void update() {
    double minDist = Double.MAX_VALUE;
    long currentTime = System.currentTimeMillis();

    for (ElectricField field : fields) {
        field.setActive(enabled); // Control visibility via lever
        if (enabled) {
            field.update(); // Update animation only if enabled
            double dist = Math.sqrt(Math.pow(player.x - field.getX(), 2) + Math.pow(player.y - field.getY(), 2));
            minDist = Math.min(minDist, dist);
            if (dist < 0.5 && (currentTime - lastZapTime) > ZAP_COOLDOWN) {
                SoundManager.playZapSound();
                lastZapTime = currentTime;
            }
        }
    }

    // Manage current.wav sound
    if (currentSoundClip != null && currentSoundClip.isOpen()) {
        if (!enabled || minDist >= MIN_SOUND_DISTANCE) {
            if (currentSoundClip.isRunning()) {
                currentSoundClip.stop();
            }
            setVolume(minVolume);
        } else {
            float volume;
            if (minDist <= MAX_SOUND_DISTANCE) {
                volume = maxVolume;
            } else {
                double t = (minDist - MAX_SOUND_DISTANCE) / (MIN_SOUND_DISTANCE - MAX_SOUND_DISTANCE);
                volume = minVolume + (maxVolume - minVolume) * (float) Math.exp(-t * 2.0);
            }
            setVolume(volume);
            if (!currentSoundClip.isRunning()) {
                currentSoundClip.setFramePosition((int) soundFramePosition);
                currentSoundClip.loop(Clip.LOOP_CONTINUOUSLY);
            }
        }
    }
}

public void pauseSound() {
    if (currentSoundClip != null && currentSoundClip.isRunning()) {
        soundFramePosition = currentSoundClip.getFramePosition();
        currentSoundClip.stop();
    }
}

public void resumeSound() {
    if (!enabled || currentSoundClip == null || !currentSoundClip.isOpen()) return;
    double minDist = Double.MAX_VALUE;
    for (ElectricField field : fields) {
        if (field.isActive()) {
            double dist = Math.sqrt(Math.pow(player.x - field.getX(), 2) + Math.pow(player.y - field.getY(), 2));
            minDist = Math.min(minDist, dist);
        }
    }
    if (minDist < MIN_SOUND_DISTANCE) {
        currentSoundClip.setFramePosition((int) soundFramePosition);
        currentSoundClip.loop(Clip.LOOP_CONTINUOUSLY);
        float volume;
        if (minDist <= MAX_SOUND_DISTANCE) {
            volume = maxVolume;
        } else {
            double t = (minDist - MAX_SOUND_DISTANCE) / (MIN_SOUND_DISTANCE - MAX_SOUND_DISTANCE);
            volume = minVolume + (maxVolume - minVolume) * (float) Math.exp(-t * 2.0);
        }
        setVolume(volume);
    }
}

public void stopSound() {
    if (currentSoundClip != null) {
        if (currentSoundClip.isRunning()) {
            currentSoundClip.stop();
        }
        currentSoundClip.close();
        currentSoundClip = null;
    }
}

public List getFields() {
    return fields;
}

public int[][] getFieldMap() {
    return fieldMap;
}

public void setEnabled(boolean enabled) {
    this.enabled = enabled;
}

public boolean isEnabled() {
    return enabled;
}

}

Lever: package raycast3D;

import java.awt.image.BufferedImage;

public class Lever {
private double x, y;
private boolean isOn;
private BufferedImage textureOn;
private BufferedImage textureOff;
private String orientation;

public Lever(double x, double y, String orientation, Texture texture) {
    this.x = x;
    this.y = y;
    this.isOn = true; // Start in ON state
    this.orientation = orientation;
    this.textureOn = texture.getLever1();
    this.textureOff = texture.getLever0();
}

public void toggle(boolean playSound) {
    isOn = !isOn;
    if (playSound) {
        if (isOn) {
            SoundManager.playLeverOnSound();
        } else {
            SoundManager.playLeverOffSound();
        }
    }
}

public double getX() {
    return x;
}

public double getY() {
    return y;
}

public String getOrientation() {
    return orientation;
}

public boolean isOn() {
    return isOn;
}

public BufferedImage getCurrentTexture() {
    return isOn ? textureOn : textureOff;
}

}

LeverManager: package raycast3D;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class LeverManager {
private List levers;
private Player player;
private Map map;
private ElectricFieldManager electricFieldManager;
private Texture texture;
private boolean keyEHeld;
private long lastToggleTime;
private static final long TOGGLE_COOLDOWN = 500;

public LeverManager(Player player, Map map, ElectricFieldManager electricFieldManager) {
    this.player = player;
    this.map = map;
    this.electricFieldManager = electricFieldManager;
    this.levers = new ArrayList<>();
    this.texture = new Texture();
    this.keyEHeld = false;
    this.lastToggleTime = 0;
    initializeLevers();
}

private void initializeLevers() {
    for (int y = 0; y < map.getHeight(); y++) {
        for (int x = 0; x < map.getWidth(); x++) {
            if (map.get(x, y) == 16) {
                // Check adjacent walls to determine orientation
                if (map.get(x, y - 1) == 1) {
                    levers.add(new Lever(x + 0.5, y + 0.1, "north", texture));
                } else if (map.get(x, y + 1) == 1) {
                    levers.add(new Lever(x + 0.5, y + 0.9, "south", texture));
                } else if (map.get(x - 1, y) == 1) {
                    levers.add(new Lever(x + 0.1, y + 0.5, "west", texture));
                } else if (map.get(x + 1, y) == 1) {
                    levers.add(new Lever(x + 0.9, y + 0.5, "east", texture));
                }
            }
        }
    }
}

public void update() {
    boolean anyLeverOn = false;
    for (Lever lever : levers) {
        if (lever.isOn()) {
            anyLeverOn = true;
            break;
        }
    }
    electricFieldManager.setEnabled(anyLeverOn);
}

public void interact(Player player) {
    long currentTime = System.currentTimeMillis();
    if (keyEHeld && (currentTime - lastToggleTime) > TOGGLE_COOLDOWN) {
        for (Lever lever : levers) {
            double dist = Math.sqrt(Math.pow(player.x - lever.getX(), 2) + Math.pow(player.y - lever.getY(), 2));
            if (dist < 1.0) { // Increased interaction range
                lever.toggle(true); // Toggle with sound
                lastToggleTime = currentTime;
                break;
            }
        }
    }
}

public void setKeyEHeld(boolean held) {
    this.keyEHeld = held;
}

public void render3D(Graphics g, Player player, int width, int height) {
    List sortedLevers = new ArrayList<>(levers);
    sortedLevers.sort((l1, l2) -> {
        double dist1 = Math.pow(player.x - l1.getX(), 2) + Math.pow(player.y - l1.getY(), 2);
        double dist2 = Math.pow(player.x - l2.getX(), 2) + Math.pow(player.y - l2.getY(), 2);
        return Double.compare(dist2, dist1);
    });

    for (Lever lever : sortedLevers) {
        double leverX = lever.getX() - player.x;
        double leverY = lever.getY() - player.y;

        double invDet = 1.0 / (player.planeX * player.dirY - player.dirX * player.planeY);
        double transformX = invDet * (player.dirY * leverX - player.dirX * leverY);
        double transformY = invDet * (-player.planeY * leverX + player.planeX * leverY);

        if (transformY > 0.1) { // Prevent rendering too close
            int leverScreenX = (int) (width / 2 * (1 + transformX / transformY));
            if (leverScreenX < 0 || leverScreenX >= width) continue;

            int baseLeverHeight = height / 2;
            int leverHeight = (int) (baseLeverHeight / Math.max(transformY, 0.1)); // Prevent division by zero
            int drawStartY = height / 2 - leverHeight / 2;
            int drawEndY = height / 2 + leverHeight / 2;

            BufferedImage frame = lever.getCurrentTexture();
            int leverWidth = (int) (leverHeight * (frame.getWidth() / (double) frame.getHeight()));
            int drawStartX = leverScreenX - leverWidth / 2;
            int drawEndX = leverScreenX + leverWidth / 2;

            // Render even if close, but ensure it doesn't clip through walls
            int clippedStartX = Math.max(drawStartX, 0);
            int clippedEndX = Math.min(drawEndX, width);
            int clippedWidth = clippedEndX - clippedStartX;
            int clippedStartY = Math.max(drawStartY, 0);
            int clippedEndY = Math.min(drawEndY, height);
            int clippedHeight = clippedEndY - clippedStartY;

            if (clippedWidth > 0 && clippedHeight > 0) {
                g.drawImage(frame, clippedStartX, clippedStartY, clippedWidth, clippedHeight, null);
            }
        }
    }
}

public List getLevers() {
    return levers;
}

}

Player: package raycast3D;

import java.awt.event.KeyEvent;

public class Player {
public double x, y;
public double dirX, dirY;
public double planeX, planeY;
public double[] zBuffer;

private boolean forward, backward, left, right;
private Map map;
private ElectricFieldManager electricFieldManager;
private LeverManager leverManager;
private double moveSpeed = 0.08;
private double arrowMoveSpeed = 0.05;
private String arrowEffect;

public Player(double x, double y, double dirX, double dirY, double planeX, double planeY, Map map, ElectricFieldManager electricFieldManager, LeverManager leverManager) {
    this.x = x;
    this.y = y;
    this.dirX = dirX;
    this.dirY = dirY;
    this.planeX = planeX;
    this.planeY = planeY;
    this.map = map;
    this.electricFieldManager = electricFieldManager;
    this.leverManager = leverManager;
    this.zBuffer = new double[GamePanel.WIDTH];
    this.arrowEffect = null;
}

public void update() {
    double moveX = 0, moveY = 0;

    if (arrowEffect != null) {
        switch (arrowEffect) {
            case "up":
                moveY -= arrowMoveSpeed;
                break;
            case "left":
                moveX -= arrowMoveSpeed;
                break;
            case "right":
                moveX += arrowMoveSpeed;
                break;
            case "down":
                moveY += arrowMoveSpeed;
                break;
        }
    } else {
        if (forward) {
            moveX += dirX * moveSpeed;
            moveY += dirY * moveSpeed;
        }
        if (backward) {
            moveX -= dirX * moveSpeed;
            moveY -= dirY * moveSpeed;
        }
        if (left) {
            moveX -= dirY * moveSpeed;
            moveY += dirX * moveSpeed;
        }
        if (right) {
            moveX += dirY * moveSpeed;
            moveY -= dirX * moveSpeed;
        }
    }

    int nextTileX = map.get((int) (x + moveX + 0.2 * Math.signum(moveX)), (int) y);
    int fieldTileX = electricFieldManager.isEnabled() ? electricFieldManager.getFieldMap()[(int) y][(int) (x + moveX + 0.2 * Math.signum(moveX))] : 0;
    if (nextTileX != 1 && nextTileX != 4 && nextTileX != 5 && nextTileX != 6 &&
        nextTileX != 7 && nextTileX != 8 && nextTileX != 9 && nextTileX != 15 && fieldTileX != 1) {
        x += moveX;
    }

    int nextTileY = map.get((int) x, (int) (y + moveY + 0.2 * Math.signum(moveY)));
    int fieldTileY = electricFieldManager.isEnabled() ? electricFieldManager.getFieldMap()[(int) (y + moveY + 0.2 * Math.signum(moveY))][(int) x] : 0;
    if (nextTileY != 1 && nextTileY != 4 && nextTileY != 5 && nextTileY != 6 &&
        nextTileY != 7 && nextTileY != 8 && nextTileY != 9 && nextTileY != 15 &&
        (nextTileY != 3 || moveY >= 0) && fieldTileY != 1) {
        y += moveY;
    }
}

public void rotate(double angle) {
    double cos = Math.cos(angle);
    double sin = Math.sin(angle);

    double oldDirX = dirX;
    dirX = dirX * cos - dirY * sin;
    dirY = oldDirX * sin + dirY * cos;

    double oldPlaneX = planeX;
    planeX = planeX * cos - planeY * sin;
    planeY = oldPlaneX * sin + planeY * cos;
}

public void keyPressed(KeyEvent e) {
    if (arrowEffect == null) {
        if (e.getKeyCode() == KeyEvent.VK_W) forward = true;
        if (e.getKeyCode() == KeyEvent.VK_S) backward = true;
        if (e.getKeyCode() == KeyEvent.VK_A) left = true;
        if (e.getKeyCode() == KeyEvent.VK_D) right = true;
        if (e.getKeyCode() == KeyEvent.VK_E) {
            leverManager.setKeyEHeld(true);
            leverManager.interact(this);
        }
    }
}

public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_W) forward = false;
    if (e.getKeyCode() == KeyEvent.VK_S) backward = false;
    if (e.getKeyCode() == KeyEvent.VK_A) left = false;
    if (e.getKeyCode() == KeyEvent.VK_D) right = false;
    if (e.getKeyCode() == KeyEvent.VK_E) {
        leverManager.setKeyEHeld(false);
    }
}

public void setArrowEffect(String effect) {
    this.arrowEffect = effect;
}

}

SoundManager: package raycast3D;

import javax.sound.sampled.*;
import java.io.File;

public class SoundManager {
public static void playPickupCoinSound() {
playSound("texture/pickupCoin.wav");
}

public static void playLaserSound() {
    playSound("texture/laserShoot.wav");
}

public static void playZapSound() {
    playSound("texture/electrocuted.wav");
}

public static void playLeverOnSound() {
    playSound("texture/lever.wav");
}

public static void playLeverOffSound() {
    playSound("texture/lever2.wav");
}

private static void playSound(String filePath) {
    AudioInputStream audioInputStream = null;
    Clip clip = null;
    try {
        File soundFile = new File(filePath);
        if (!soundFile.exists()) {
            System.err.println("Sound file not found: " + soundFile.getAbsolutePath());
            return;
        }
        audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        clip = AudioSystem.getClip();
        clip.open(audioInputStream);
        clip.start();
        // Zamknij clip po zakończeniu odtwarzania
        Clip finalClip = clip;
        clip.addLineListener(event -> {
            if (event.getType() == LineEvent.Type.STOP) {
                finalClip.close();
            }
        });
    } catch (UnsupportedAudioFileException e) {
        System.err.println("Unsupported audio file format: " + filePath);
    } catch (LineUnavailableException e) {
        System.err.println("Audio line unavailable for: " + filePath);
    } catch (Exception e) {
        System.err.println("Error playing sound: " + filePath);
        e.printStackTrace();
    } finally {
        if (audioInputStream != null) {
            try {
                audioInputStream.close();
            } catch (Exception e) {
                System.err.println("Error closing audio stream: " + filePath);
            }
        }
    }
}

}