Java gra snake brak reakcji na klawisze

0

Witam, jestem w trakcie pisania gry snake w javie i niby wszystko dziala prawidlowo, jednak zdarza sie, ze uruchomie program a ten nie reaguje na klawisze, zdarza sie to raz na kilka uruchomien, podejrzewam ze jest cos nie tak z timerem, ale nie mam pojecia jak to naprawic. Licze na wasza pomoc :)

package projekt;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;

public class Plansza extends JPanel{
    
    private boolean gora = false, dol = false, lewa = false, prawa = false;
    private Klawisz klawisz;
    private ArrayList<Waz> waz;
    private int x = 0, y = 0;
    private int dlugosc = 0;
    private int elementy;
    Timer czas;
    
    
    public Plansza(){
        czas = new Timer();
        Odswiezanie odswiezanie = new Odswiezanie();
        czas.scheduleAtFixedRate(odswiezanie, 1, 100);
        setPreferredSize(new Dimension(800, 600));
        klawisz  = new Klawisz();
        waz = new ArrayList();
        addKeyListener(klawisz);
        Waz p = new Waz(x,y);
        waz.add(p);
        setFocusable(true);
        elementy = 4;
        
    }
    
    private void ruch(){
        
        if(prawa){
            x += 20;
        }
        
        if(lewa){
            x-=20;
        }
        
        if(gora){
            y-=20;
        }
        
        if(dol){
            y+=20;
        }
        
        Waz p = new Waz(x,y);
        waz.add(p);
        dlugosc = 0;
        
        if(waz.size()>elementy){
            waz.remove(0);
        }
        
    
    }
    
    public void paint(Graphics g){
        
        g.clearRect(0, 0, 800, 600);
        
        for(int i = 0; i<waz.size();i++){
            g.drawOval(waz.get(i).getX(), waz.get(i).getY(), 20, 20);
        }
    }
    
    private class Odswiezanie extends TimerTask{
        
        public void run(){
            ruch();
            repaint();
        }
    }
    
    private class Klawisz implements KeyListener{
        
        public void keyPressed(KeyEvent e) {
            int klawisz = e.getKeyCode();
        
            if(klawisz == KeyEvent.VK_UP && !dol){
                gora = true;
                lewa = false;
                prawa = false;
            }
        
            if(klawisz == KeyEvent.VK_DOWN && !gora){
                dol = true;
                lewa = false;
                prawa = false;
            }
        
            if(klawisz == KeyEvent.VK_LEFT && !prawa){
                lewa = true;
                dol = false;
                gora = false;
            }
        
            if(klawisz == KeyEvent.VK_RIGHT && !lewa){
                prawa = true;
                gora = false;
                dol = false;
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public void keyReleased(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }
    
    }
}
0

DObra to inaczej, czy moge jakos zastapic timer? Czyms co bedzie zapewnialo odswiezanie co okreslony czas?

edit: Teraz to juz w ogole nie reaguje na strzalki, a do tego przy niektorych uruchomieniach wywala:

Exception in thread "Timer-0" java.lang.NullPointerException
	at projekt.Plansza.ruch(Plansza.java:93)
	at projekt.Plansza.access$200(Plansza.java:16)
	at projekt.Plansza$Odswiezanie.run(Plansza.java:148)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505) 

nowy kod klasy z jpanelem:

 package projekt;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Plansza extends JPanel{
    
    private boolean gora = false, dol = false, lewa = false, prawa = false;
    private Klawisz klawisz;
    private ArrayList<Waz> waz;
    private ArrayList<Bonus> bonus;
    private int x = 100, y = 100;
    private int bx, by;
    private int dlugosc;
    private boolean over = false;
    //private Image snake;
   // private Image jablko;
    private Image tlo;
    Timer czas;
    Random los;
    
    
    public Plansza(){
        czas = new Timer();
        Odswiezanie odswiezanie = new Odswiezanie();
        czas.scheduleAtFixedRate(odswiezanie, 1, 100);
        
        setPreferredSize(new Dimension(800, 600));
        
        klawisz  = new Klawisz();
        
        los = new Random();
        bx = (los.nextInt(39)+1)*20;
        by = (los.nextInt(29)+1)*20;
        
        waz = new ArrayList();
        bonus = new ArrayList();
        Waz w = new Waz(x,y);
        Bonus b = new Bonus(bx,by);
        
        
        setFocusable(true);
        
        dlugosc = 4;
        
        addKeyListener(klawisz);
        waz.add(w);
        bonus.add(b);
        zaladujObrazki();
        
        
    }
    
    private void zaladujObrazki(){
        //ImageIcon iiw = new ImageIcon("dot.png");
        //w = iiw.getImage();
        //ImageIcon iij = new ImageIcon("dot.png");
        //jablko = iij.getImage();
        ImageIcon iit = new ImageIcon("tlo.png");
        tlo = iit.getImage();
    }
    
    private void ruch(){
        
        if(prawa){
            x += 20;
        }
        
        else if(lewa){
            x-=20;
        }
        
        else if(gora){
            y-=20;
        }
        
        else if(dol){
            y+=20;
        }
        
        
        Waz w = new Waz(x,y);
        waz.add(w);
        
        if(waz.size()>dlugosc){
            waz.remove(0);
        }
    }
    private void kolizje(){
        
        for(Bonus b : bonus){
            if(b.getX()==x && b.getY() ==y){
                b.setX((los.nextInt(39)+1)*20);
                b.setY((los.nextInt(29)+1)*20);
                dlugosc++;
            }
        }
        
        for(int i = 0; i < waz.size()-1 ; i++){
            if(dlugosc>=5 && waz.get(i).getX() == x && waz.get(i).getY() == y){
                over  = true;
            }
        }
        
        if(x<0 || y<0 || x>780 || y>580){
            over = true;
        }
    }
        
    
    public void paint(Graphics g){
        
        g.clearRect(0, 0, 800, 600);
        //g.drawImage(tlo, 0, 0, 800, 600, this);
        g.setColor(Color.BLACK);
        
        for(int i = 0; i<waz.size();i++){
            g.fillOval(waz.get(i).getX(), waz.get(i).getY(), 20, 20);
        }
        
        for(int i = 0; i<bonus.size();i++){
            g.fillOval(bonus.get(i).getX(), bonus.get(i).getY(), 20, 20);
        }
        
        if(over){
            czas.cancel();
            g.clearRect(0, 0, 800, 600);
            g.drawImage(tlo, 0, 0, this);
            g.setColor(Color.BLACK);
            g.setFont(new Font("TimesRoman", Font.BOLD, 100)); 
            g.drawString("KONIEC", 200, 150);
        }
    }
    
    private class Odswiezanie extends TimerTask{
        
        public void run(){
            ruch();
            repaint();
            kolizje();
            System.out.println(waz.size());
        }
    }
    
    private class Klawisz implements KeyListener{
        
        public void keyPressed(KeyEvent e) {
            int klawisz = e.getKeyCode();
        
            if(klawisz == KeyEvent.VK_UP && !dol){
                gora = true;
                lewa = false;
                prawa = false;
            }
        
            if(klawisz == KeyEvent.VK_DOWN && !gora){
                dol = true;
                lewa = false;
                prawa = false;
            }
        
            if(klawisz == KeyEvent.VK_LEFT && !prawa){
                lewa = true;
                dol = false;
                gora = false;
            }
        
            if(klawisz == KeyEvent.VK_RIGHT && !lewa){
                prawa = true;
                gora = false;
                dol = false;
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public void keyReleased(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }
    
    }
}
0

Timer to nic innego jak nowy wątek. Możesz spróbować go zastąpić zwykłym Thread.
Tylko musisz zrozumieć na jakiej zasadzie to działa. http://javastart.pl/zaawansowane-programowanie/watki-wprowadzenie-i-przyklad/

0

EDIT: Rozwiazalem ten problem, po prostu zbyt szybko uruchamialem timer czas.scheduleAtFixedRate(odswiezanie, 1, 100) zamienilem na czas.scheduleAtFixedRate(odswiezanie, 100, 100) i jest okej :)

Ten problem juz rozwiazalem :) dodalem w metodzie run polecenie requestFocus()

Mam za to ciagle problem z bledem:

Exception in thread "Timer-0" java.lang.NullPointerException
	at projekt.Plansza.ruch(Plansza.java:99)
	at projekt.Plansza.access$200(Plansza.java:16)
	at projekt.Plansza$Odswiezanie.run(Plansza.java:162)
	at java.util.TimerThread.mainLoop(Timer.java:555)
	at java.util.TimerThread.run(Timer.java:505)

Jendak nie pojawia sie on zawsze, tylko przy niektorych uruchomieniach, wskazuje na linijke w ktorej jest waz.add(w) czyli kiedy dodaje element do listy. Blad nigdy nie wystepuje w trakcie dziala nia programu, jedynie przy uruchomieniu (wiec albo sie uruchamia i dziala dobrze, albo sie uruchamia i wywala blad, okno na nic nie reaguje, a ni nie pojawiaja sie elementy). Aktualny kod wyglada tak:

package projekt;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Plansza extends JPanel{
    
    private boolean gora = false, dol = false, lewa = false, prawa = true;
    private Klawisz klawisz;
    private ArrayList<Waz> waz;
    private ArrayList<Bonus> bonus;
    private int x = 0, y = 0;
    private int bx, by;
    private int dlugosc;
    private boolean over = false;
    private Image snake;
    private Image jablko;
    private Image tlo;
    private Image glowa;
    private int punkty;
    Timer czas;
    Random los;
    
    
    public Plansza(){
        punkty = 0;
        
        czas = new Timer();
        Odswiezanie odswiezanie = new Odswiezanie();
        czas.scheduleAtFixedRate(odswiezanie, 1, 100);
        
        setPreferredSize(new Dimension(800, 600));
        
        klawisz  = new Klawisz();
        
        los = new Random();
        bx = (los.nextInt(39)+1)*20;
        by = (los.nextInt(29)+1)*20;
        
        waz = new ArrayList();
        bonus = new ArrayList();
        Waz w = new Waz(x,y);
        Bonus b = new Bonus(bx,by);
        
        
        
        dlugosc = 4;
        
        addKeyListener(klawisz);
        waz.add(w);
        bonus.add(b);
        zaladujObrazki();
        setFocusable(true);
        
        
    }
    
    private void zaladujObrazki(){
        ImageIcon iis = new ImageIcon("cialo.png");
        snake = iis.getImage();
        ImageIcon iij = new ImageIcon("jablko.png");
        jablko = iij.getImage();
        ImageIcon iit = new ImageIcon("tlo.png");
        tlo = iit.getImage();
        ImageIcon iig = new ImageIcon("glowa.png");
        glowa = iig.getImage();
    }
    
    private void ruch(){
        
        if(prawa){
            x += 20;
        }
        
        if(lewa){
            x-=20;
        }
        
        if(gora){
            y-=20;
        }
        
        if(dol){
            y+=20;
        }
        
        
        Waz w = new Waz(x,y);
        waz.add(w);
        
        if(waz.size()>dlugosc){
            waz.remove(0);
        }
        
    }
    private void kolizje(){
        
        for(Bonus b : bonus){
            if(b.getX()==x && b.getY() ==y){
                b.setX((los.nextInt(39)+1)*20);
                b.setY((los.nextInt(29)+1)*20);
                dlugosc++;
                punkty += 10;
            }
        }
        
        for(int i = 0; i < waz.size()-1 ; i++){
            if(dlugosc>=5 && waz.get(i).getX() == x && waz.get(i).getY() == y){
                over  = true;
            }
        }
        
        if(x<0 || y<0 || x>780 || y>580){
            over = true;
        }
        
    }
        
    
    public void paint(Graphics g){
        
        g.clearRect(0, 0, 800, 600);
        g.drawImage(tlo, 0, 0, 800, 600, this);
        g.setColor(Color.BLACK);
        
        for(int i = 1; i<waz.size();i++){
            if(i+1 == waz.size()){
                g.drawImage(glowa, waz.get(i).getX(), waz.get(i).getY(),this);
            }
            else g.drawImage(snake, waz.get(i).getX(), waz.get(i).getY(),this);
        }
        
        for(int i = 0; i<bonus.size();i++){
            g.drawImage(jablko, bonus.get(i).getX(), bonus.get(i).getY(), this);
        }
        
        if(over){
            czas.cancel();
            g.clearRect(0, 0, 800, 600);
            g.drawImage(tlo, 0, 0, this);
            g.setColor(Color.BLACK);
            g.setFont(new Font("TimesRoman", Font.BOLD, 100)); 
            g.drawString("Punkty:", 150, 150);
            g.drawString(" "+punkty, 300, 270);
            System.out.println(punkty);
        }
    }
    
    private class Odswiezanie extends TimerTask{
        
        public void run(){
            ruch();
            repaint();
            kolizje();
            requestFocus();
            
        }
    }
    
    private class Klawisz implements KeyListener{
        
        public void keyPressed(KeyEvent e) {
            int klawisz = e.getKeyCode();
        
            if(klawisz == KeyEvent.VK_UP && !dol){
                gora = true;
                lewa = false;
                prawa = false;
                ImageIcon iig = new ImageIcon("glowapion.png");
                glowa = iig.getImage();
            }
        
            if(klawisz == KeyEvent.VK_DOWN && !gora){
                dol = true;
                lewa = false;
                prawa = false;
                ImageIcon iig = new ImageIcon("glowapion.png");
                glowa = iig.getImage();
            }
        
            if(klawisz == KeyEvent.VK_LEFT && !prawa){
                lewa = true;
                dol = false;
                gora = false;
                ImageIcon iig = new ImageIcon("glowa.png");
                glowa = iig.getImage();
            }
        
            if(klawisz == KeyEvent.VK_RIGHT && !lewa){
                prawa = true;
                gora = false;
                dol = false;
                ImageIcon iig = new ImageIcon("glowa.png");
                glowa = iig.getImage();
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public void keyReleased(KeyEvent e) {
            //To change body of generated methods, choose Tools | Templates.
        }
    
    }
}

0

odpala ci Taska zanim stworzysz ArrayListe waz.

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