פורסם 2012 באוגוסט 1713 שנים היי, אני מתכנת כרגע משחק SNAKE ויש לי בעיה עם מימוש double buffering כדי שהמשחק יהיה חלק יותר ולא יקפוץ כל שניה. זה הקוד: public class Snake extends JFrame implements KeyListener, Runnable { //Variabales: private JMenuBar menubar ; private JMenu game, instructions, help ; private JPanel p1, p2 ; private JTextArea t ; private ImageIcon cube = new ImageIcon ("scube.png") ; // The icons that creats the snake. private ImageIcon [] sc = new ImageIcon [500] ; // Array of images that will create the snake. private JLabel [] scj = new JLabel [500] ; //Array of labels that will store each cube. private int [] scx = new int [500] ; // The x coordinate of the cubes. private int [] scy = new int [500] ; // The y coordinate of the cubes. private final int cb = 10 ; // The size of each cube. private int c ; // counts the cubes - the length of the snake. private boolean mover, movel, moveu, moved ; // To wich direction the snake is able to move. private int xDirection, yDirection ; // Change snakes direction. private Point [] scp = new Point [500] ;// The order of the points that the snake have to reach. private int x, y ; // The diameters of the screen. private final int speed = 50 ; // The speed of the game. Snake () { // Creates a screen to run the game createGameWindow () ; // Initialize the variabales initializeValues () ; // Creates the snake createSnake () ; addKeyListener (this) ; // Threads Thread t1 = new Thread (this) ; t1.run () ; } public void initializeValues () { c = 3 ; scx [0] = 300 ; scy [0] = 200 ; movel = false ; mover = true ; moveu = true ; moved = true ; xDirection = 10 ; yDirection = 0 ; x = 700 ; y = 500 ; } public void createGameWindow () { //Window properties setVisible (true) ; setSize (700,500) ; setResizable (false) ; setTitle ("Snake") ; setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ; //Menu bar menubar = new JMenuBar () ; setJMenuBar (menubar) ; game = new JMenu ("Game") ; instructions = new JMenu ("Instructions") ; help = new JMenu ("help") ; menubar.add (game) ; menubar.add (instructions) ; menubar.add (help) ; JMenuItem newgame = new JMenuItem ("New game") ; newgame.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent e) { //Write commend here } }) ; game.add (newgame) ; //Panel p1 = new JPanel (null) ; p1.setBackground(Color.WHITE) ; add (p1) ; p2 = new JPanel () ; p2.setLayout(new GridLayout(0, 1)); p2.setBackground(Color.BLACK) ; add (p2, BorderLayout.SOUTH) ; //Scores t = new JTextArea ("Points:") ; t.setEnabled(false) ; t.setBackground(Color.BLACK) ; p2.add (t) ; } public void createSnake () { for (int i=0 ; i < 3 ; i++) { sc [i] = new ImageIcon () ; sc = cube ; scj = new JLabel (sc) ; p1.add ( scj ) ; scj.setBounds(scx , scy , cb, cb) ; scx [i+1] = scx - 10 ; scy [i+1] = scy ; } } public void move () { for (int i = 0 ;i < c ; i++) scp = scj .getLocation() ; scx [0] += xDirection ; scy [0] += yDirection ; scj[0].setBounds(scx[0], scy[0], cb, cb) ; for (int i = 1 ; i< c ; i++) scj .setLocation( scp[i-1] ) ; if (scx [0] == x ) scx [0] = 10 ; else if (scx[0] == 0) scx [0] = x -10 ; else if (scy[0] == y) scy [0] = 10 ; else if (scy[0] == 0) scy [0] = y -10 ; p1.repaint() ; } public void keyPressed (KeyEvent e) { int keyCode = e.getKeyCode() ; // Snake moves to left when the player press left arrow if (mover && keyCode == e.VK_RIGHT) { xDirection = 10 ; yDirection = 0 ; movel = false ; mover = true ; moveu = true ; moved = true ; } // Snake moves to right when the player press right arrow if (movel && keyCode == e.VK_LEFT) { xDirection = -10 ; yDirection = 0 ; movel = true ; mover = false ; moveu = true ; moved = true ; } // Snake moves up when the player press to up arrow if (moveu && keyCode == e.VK_UP) { xDirection = 0 ; yDirection = -10 ; movel = true ; mover = true ; moveu = true ; moved = false ; } // Snake moves to down when the player press down arrow if (moved && keyCode == e.VK_DOWN) { xDirection = 0 ; yDirection = 10 ; movel = true ; mover = true ; moveu = false ; moved = true ; } } public void keyReleased (KeyEvent e) { } public void keyTyped (KeyEvent e) { } public void run () { while (true) { move () ; try { Thread.sleep (speed) ; } catch (InterruptedException ie) { System.out.println ("Error") ; } } } } אשמח לעזרה, תודה רבה
פורסם 2012 באוגוסט 1913 שנים לא כלכך יצא לי לעבוד בצורה רצינית עם swing אבל נראה לי שהוא כבר תומך ב double buffering... נראה לי מה שהורג אותך פה זה הלולאה של המשחק. ספציפית השימוש ב Thread.sleep. קודם כל, התרד שלך יתעורר רק כשהמעבד פנוי להריץ אותו. דבר שני, אתה ישן 50 מלי שניות ( speed = 50 ) כל איטרציה, מה שמגביל אותך ל FPS של 20 ( 1000/50 ) וזה בלי הזמן שאתה מבזבז לחשב ולרנדר. חפש ברשת איך לבנות לולאת משחק, זה נושא שנטחן כבר מכל זווית. אה ויש לך frameworks מצויינים למשחקי 2D ב java או לפחות תשתמש ב java2D זה אחלה API והוא בא bulitin. תהנה עריכה: מצאתי הסבר מפורט ב JGO : http://www.java-gaming.org/index.php?topic=24220.0
פורסם 2012 באוגוסט 1913 שנים מחבר לא כלכך יצא לי לעבוד בצורה רצינית עם swing אבל נראה לי שהוא כבר תומך ב double buffering... נראה לי מה שהורג אותך פה זה הלולאה של המשחק. ספציפית השימוש ב Thread.sleep. קודם כל, התרד שלך יתעורר רק כשהמעבד פנוי להריץ אותו. דבר שני, אתה ישן 50 מלי שניות ( speed = 50 ) כל איטרציה, מה שמגביל אותך ל FPS של 20 ( 1000/50 ) וזה בלי הזמן שאתה מבזבז לחשב ולרנדר. חפש ברשת איך לבנות לולאת משחק, זה נושא שנטחן כבר מכל זווית. אה ויש לך frameworks מצויינים למשחקי 2D ב java או לפחות תשתמש ב java2D זה אחלה API והוא בא bulitin. תהנה עריכה: מצאתי הסבר מפורט ב JGO : http://www.java-gaming.org/index.php?topic=24220.0 תודה על העזרה אבל אני מתקשה להבין איך לאחד את השימוש הנכון בלולאה כפי שמופיע בכתובת שציינת עם הקוד שלי. אני לא כ"כ מצליח להבין את זה, אשמח להסבר
פורסם 2012 באוגוסט 2013 שנים משהו ספציפי שעושה לך צרות? בנתיים הנה משהו פשוט שאמור לעבוד: class MySnakeGame{ public static const int FPS = 30; private boolean running; public void mainLoop() { const double step = 100 / FPS; long deltaTime; long sleep; long time; while (running) { time = System.currentTimeMillis(); move(); repaint(); deltaTime = System.currentTimeMillis() - time; sleep = step - deltaTime; Thread.sleep((sleep > 0) ? sleep : 1); // clamp sleep time if update takes too long } }} כמה דברים לגבי הקוד: 1. זו דרך מאוד נאבית לבנות לולאת משחק, אבל זה יתן לך נקודת התחלה. 2. אני לא בטוח אם repaint() חוזר מיד (כלומר מרנדר ב thread נפרד) ... זו יכולה להיות בעיה, בכל מקרה תעבור ל java2D. 3. לא הרצתי את הקוד, מתנצל מראש על שגיאות תחביר 4. אה והרגע קלטתי שאני לא תופס exception ב sleep אז תקן את זה..
פורסם 2012 באוגוסט 2013 שנים מחבר תודה, שיניתי את הלופ למה שנתת,הכל עובד אבל לא השתנה שום דבר שנראה לעין, הנחש עדיין זז בפלאשים כאלה כאילו אין double buffering .
פורסם 2012 באוגוסט 2113 שנים זה כנראה בגלל שאתה מזיז אותו מספר פיקסלים כל פריים או כל מספר פריימים, בלי אינטרפלציה.שזה מילה מופלצת להגיד ערכים באמצע - נגיד ותועלת שלך זזה 30 פיקסלים בשניה, ונגיד אתה רץ ב 30 FPS.איפה היא תהיה בפריים ה 21 ? הצצתי שוב בקוד שלך, ועם ה loop החדש זה נראה שהנחש שלך היה צריך לעוף, כי אתה מזיז אותו 10 פיקסלים כל פריים...לא חושב ש double buffering זו הבעיה פה. זה מונע תופעה מעצבנת בשם tearing. אתה תראה את המסך סוג של נחצה לשניים כמו פה, זה בגלל שאתה מעדכן את ה buffer שממנו אתה מצייר. פלאשים זה לא חלק מהסיפור. אגב, תעזור לך דוגמה פשוטה עם java2D ?
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.