Problem dotyczący zablokowania gracza, aby nie przemieszczał sie poza ramę.

0

Witam serdecznie!

Od prawie roku uczę się programowania i jestem typowym samoukiem. Teraz naszła mnie chęć do napisania własnej gry i po napisaniu pętli gry, ramy i gracza napotkałem na jeden problem (były dwa, ale właśnie drugi rozwiązałem).

Otóż nie mam pojęcia jak zrobić, żeby gracz nie poruszał się po za ekran gry. Gracz nie wylatuje poza ekran tylko na górze ramy.

Class Fish

package com;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;

public class Fish extends Canvas implements Runnable, KeyListener {


    private static final int WIDTH = 800;
    private static final int HEIGHT = 400;

    private boolean running = false;
    private Thread thread;

    private static BufferedImage background;

    public Player player;


    public Fish(){
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        addKeyListener(this);
        player = new Player(60, Fish.HEIGHT / 2);
    }

    public synchronized void start(){
        if(running) return;
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public synchronized void stop(){
        if(!running) return;
        running = false;
        try{
            thread.join();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Fish fish = new Fish();

        JFrame frame = new JFrame();
        frame.add(fish);
        frame.setTitle("Fish");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        fish.start();

    }

    @Override
    public void run() {
        //Game loop
        //Pętla gry
        requestFocus();
        int fps = 0;
        double timer = System.currentTimeMillis();
        long lastTime = System.nanoTime();
        double delta = 0;
        double ns = 1000000000.0 / 60.0;
        while (running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while (delta >= 1) {
                update();
                render();
                fps++;
                delta--;
            }
            if(System.currentTimeMillis() - timer >= 1000){
                System.out.println("FPS: " + fps + " per second");
                fps = 0;
                timer += 1000;
            }
        }
        stop();
    }
    public void render(){

        //Renderowanie obrazu.
        //Picture rendering.
        BufferStrategy bs = getBufferStrategy();
        if(bs == null){
            createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();

        //Loading picture of the background.
        //Ładowanie pliku tła.
        File file = new File("800x400.jpg");
        try{
            background = ImageIO.read(file);
        }catch (Exception e){
            e.printStackTrace();
        }
        g.drawImage(background, 0, 0, this);

        player.render(g);
        g.dispose();
        bs.show();

    }
    public void update(){
        player.update();
    }

    @Override
    public void keyTyped(KeyEvent e) {
        //Not gonna be used.
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) player.up = true;
        if (e.getKeyCode() == KeyEvent.VK_DOWN) player.down = true;
        if (e.getKeyCode() == KeyEvent.VK_LEFT) player.left = true;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) player.right = true;
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_UP) player.up = false;
        if (e.getKeyCode() == KeyEvent.VK_DOWN) player.down = false;
        if (e.getKeyCode() == KeyEvent.VK_LEFT) player.left = false;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) player.right = false;

    }
}

Class Player

package com;

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

public class Player extends Rectangle {

    public boolean right = false;
    public boolean left = false;
    public boolean up = false;
    public boolean down = false;
    private int speed = 1;

    private BufferedImage playerBody;

    public Player(int x, int y){
        //Coordinate of player, where will start the game, and player dimensions.
        //Koordynaty gracza w którym miejscu ma zaczynać, wraz z wymiarami.
        setBounds(x, y, 32, 32);
    }
    public void update(){
        //Key code with speed of player.
        //Kod klawiszy z prędkością gracza.
        if(left) x -= speed + 1;
        if(right) x += speed + 1;
        if(up) y -= speed - 0.75;
        else y += speed;
        if(down) y += speed + 2;

    }
    public void render(Graphics g){
        //Rendering a player.
        //Renderowanie gracza.

        File file = new File("obraz.jpg");
        try{
            playerBody = ImageIO.read(file);
        }catch (IOException e){
            e.printStackTrace();
        }
        g.drawImage(playerBody, x, y, null);

        //g.setColor(Color.RED);
        //g.fillOval(x, y, width, height);


    }
}

Był bym wdzięczny za jakieś rozwiązania. :)

1

Masz jakieś update w klasie Player a tam if(left) x -= speed + 1 no to zamiast zawsze odejmować od x który pewnie jest współrzędną to możesz sprawdzić czy x > 0 czyli czy nie wyszła na lewo i wtedy odjąć. Przynajmniej tak podpowiada jakakolwiek logika.

2

patrząc na deklaracje klas, to masz wszystko na kupę.

  • Fish (obiekt gry, część tzw Modelu, jak mniemam), Nie twierdzę, że prawidłowo mniemam, ale możesz to uleczyć przez nazwanie: FishGame, FishPanel, czy zupełnie inaczej - ale oddając rzeczywistą sytuację
  • Listener (część GUI - Dodam, źle się się sprawuje jeden wielki Listener, powołuje się "małe Listenerki", milion przykładów w necie)
  • a już złączenie z Runnable, to złączenie pachnie herezją, na szczęście na stosach nie palimy.
0
szweszwe napisał(a):

Masz jakieś update w klasie Player a tam if(left) x -= speed + 1 no to zamiast zawsze odejmować od x który pewnie jest współrzędną to możesz sprawdzić czy x > 0 czyli czy nie wyszła na lewo i wtedy odjąć. Przynajmniej tak podpowiada jakakolwiek logika.

if(left && x > 0) x -= speed; zrobiłem coś takiego, działa w przypadku lewej strony, teraz kombinuje z dołem i prawą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1