3

ビデオ ゲームを作成していて、repaint() メソッドを呼び出すと、画面全体が更新されて不規則に点滅します。次のコード行で再描画されるもの (Rectangle オブジェクトである charRect) を指定することで、この問題を少し修正しました。画面全体の点滅は止まりますが、キャラクターは信じられないほどグリッチです。アニメーションを移動 (a と d) とジャンプ (w) からスムーズに実行するための助けが必要です。

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.lang.*;
import static java.lang.Math.*;
import static java.lang.System.out;
import java.util.Random.*;
import javax.swing.JApplet;
import java.awt.Graphics;

public class UltimaBlade extends JApplet implements KeyListener
{
public final int        WIDTH = 900;
public final int        HEIGHT = 650;

public  int             score = 0;
private boolean         jumping = false;
private boolean         moveRight = false;
private boolean         moveLeft = false;
private boolean         jumpRight = false;
private boolean         jumpLeft = false;
private boolean         moveRightWhileJumping = false;
private boolean         moveLeftWhileJumping = false;

public  JFrame          JTitle = new JFrame("UltimaBlade"); 
        Image           characterImg = null;
        Image           blockImg1 = null;
        Image           floorImg1 = null;
        Image           wallImg1 = null;
             JLabel          scoreLabel = new JLabel("Score: " + score);

        Rectangle       charRect = new Rectangle(25, 450, 20, 32);
        Rectangle       blockRect1 = new Rectangle(25, 482, 30, 30);
        Rectangle       floorRect1 = new Rectangle(25, 482, 200, 1);CHANGE BACK TO 30
        Rectangle       wallRect1 = new Rectangle(55, 490, 1, 30);
        //Rectangle       tempGhost = new Rectangle(charRect.x, charRect.y, 20, 32);

public  JMenuBar        mb = new JMenuBar();
public  JMenu           menuFile = new JMenu("File");
public  JMenuItem       menuItemSave = new JMenuItem("Save");
public  JMenuItem       menuItemLoad = new JMenuItem("Load");
        Container       cont;
        Runner          runner;

public void init()
{
    setSize(WIDTH, HEIGHT);

    JTitle.setJMenuBar(mb);
    menuFile.add(menuItemSave);
    menuFile.add(menuItemLoad);
    mb.add(menuFile);
    JTitle.getContentPane().setLayout(new BorderLayout());
    menuItemSave.addActionListener(new ListenMenuSave());
    setJMenuBar(mb);
    new UltimaBlade();
}

public UltimaBlade()
{
    setLayout(null);
    setSize(WIDTH, HEIGHT);
    setVisible(true);

    cont = getContentPane();
    cont.setLayout(null);
    addKeyListener(this);
    cont.setBackground(Color.WHITE);

    cont.add(scoreLabel);
    scoreLabel.setBounds(50, 50, 100, 30);
    scoreLabel.setForeground(Color.BLACK);
    cont.setLayout(null);

    repaint();
    cont.validate();

    runner = new Runner();
    runner.start();
    setContentPane(cont);
}

public class ListenMenuSave implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        new Save();
    }
}

public void paint(Graphics g)
{
    super.paint(g);

    try
    {
        URL     url1 = this.getClass().getResource("character.gif");       //Character
                characterImg = Toolkit.getDefaultToolkit().getImage(url1);
        URL     url2 = this.getClass().getResource("block.gif");           //Block
                blockImg1 = Toolkit.getDefaultToolkit().getImage(url2);
        URL     url3 = this.getClass().getResource("floor_line.gif");      //Floor Line
                floorImg1 = Toolkit.getDefaultToolkit().getImage(url3);
        URL     url4 = this.getClass().getResource("wall_line.gif");      //Wall Line
                wallImg1 = Toolkit.getDefaultToolkit().getImage(url4);
    }
    catch(Exception e)
    {

    }

    g.drawImage(characterImg, charRect.x, charRect.y, this);
    g.drawImage(floorImg1, floorRect1.x, floorRect1.y, this);
    g.drawImage(blockImg1, blockRect1.x, blockRect1.y, this);
    g.drawImage(wallImg1, wallRect1.x, wallRect1.y, this);
}

public void keyPressed(KeyEvent e)
{
    if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D')
    {
        moveRight = true;
        if(jumping)
            moveRightWhileJumping = true;
    }
    if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A')
    {
        moveLeft = true;
        if(jumping)
            moveLeftWhileJumping = true;
    }
}

public void keyReleased(KeyEvent e)
{
    if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D')
    {
        moveRight = false;
        if(!jumping)
            moveRightWhileJumping = false;
    }
    if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A')
    {
        moveLeft = false;
        if(!jumping)
            moveLeftWhileJumping = false;
    }
}

public void keyTyped(KeyEvent e)
{
    if(e.getKeyChar() == 'w' || e.getKeyChar() == 'W')
    {
        jumping = true;
    }
}

public class Runner extends Thread// implements Runnable
{
    public void run()
    {
        while(true)
        {
            try
            {
                int     j = 5;     //Beginning velocity
                double  t = 0;
                double  sum = j/5;
                while(jumping)
                {
                    repaint(charRect.x, charRect.y, 20, 32);
                    cont.validate();
                    int jump = (int)((-4.9 * ((t * t)/10)) + (j * t));
                    if(moveRightWhileJumping)
                    {
                        charRect.x = charRect.x + j; // Move Right while jumping.
                        if(charRect.intersects(wallRect1))
                        {
                            charRect.x = wallRect1.x - 21;
                            moveRightWhileJumping = false;
                        }
                    }
                    if(moveLeftWhileJumping)
                    {
                        charRect.x = charRect.x - j;  //Move Left while jumping.
                        if(charRect.intersects(wallRect1))
                        {
                            charRect.x = wallRect1.x + 1;
                            moveLeftWhileJumping = false;
                        }
                    }
                    if(jump > 0)
                    {
                        charRect.y = charRect.y - Math.abs(jump);
                        if(charRect.intersects(floorRect1))
                        {
                            charRect.y = floorRect1.y - 32;
                            jumping = false;
                            moveRightWhileJumping = false;
                            moveLeftWhileJumping = false;
                            break;
                        }
                    }
                    else if(jump < 0)
                    {
                        charRect.y = charRect.y + Math.abs(jump);
                        if(charRect.intersects(floorRect1))
                        {
                            charRect.y = floorRect1.y - 32;
                            jumping = false;
                            moveRightWhileJumping = false;
                            moveLeftWhileJumping = false;
                            break;
                        }
                    }
                    else
                    {
                        if(charRect.intersects(floorRect1))
                        {
                            charRect.y = floorRect1.y - 32;
                            jumping = false;
                            moveRightWhileJumping = false;
                            moveLeftWhileJumping = false;
                            break;
                        }
                    }

                    t++;
                    Thread.sleep(30);
                }


                while(moveLeft)
                {
                    repaint(charRect.x, charRect.y, 20, 32);
                    cont.validate();
                    charRect.x = charRect.x - j;  //Move Left speed.
                    if(charRect.intersects(wallRect1))
                    {
                        charRect.x = wallRect1.x + 1;
                    }
                    if(charRect.intersects(floorRect1))
                    {
                        charRect.y = floorRect1.y - 32;
                        jumping = false;
                        moveRightWhileJumping = false;
                        moveLeftWhileJumping = false;
                        break;
                    }
                    t++;
                    Thread.sleep(30);
                }


                while(moveRight)
                {
                    repaint(charRect.x, charRect.y, 20, 32);
                    cont.validate();
                    charRect.x = charRect.x + j;  //Move Left speed.
                    if(charRect.intersects(wallRect1))
                    {
                        charRect.x = wallRect1.x + 1;
                    }
                    if(charRect.intersects(floorRect1))
                    {
                        charRect.y = floorRect1.y - 32;
                        jumping = false;
                        moveRightWhileJumping = false;
                        moveLeftWhileJumping = false;
                        break;
                    }
                    t++;
                    Thread.sleep(30);
                }
            }
            catch(Exception e)
            {
                break;
            }
        }
    }
}

}

4

1 に答える 1

3

主な問題の1つは、アプレットが保持するJPanelまたはJCompnentpaint(...)のメソッドではなく、JApplet自体のメソッドで直接ペイントしていることです。paintComponent(...)後者を実行すると、Swingのデフォルトのダブルバッファリングのメリットが得られ、それがすべての違いを生む可能性があります。また、オーバーロードの1つを使用して、GUIの小さい長方形を再描画することもできますがrepaint(...)、これは2番目に重要です。まず、ダブルバッファリングの不足の問題を解決する必要があります。

基本を学ぶためにこのチュートリアルから始めてください:レッスン:カスタムペイントの実行

次に、この記事に進んで、Swingでの描画に関するより高度な情報を入手してください:AWTとSwingでのペイント

編集また、またはメソッド
内からファイルを読み込まないでください。これにより、ペイントが遅くなり、GUIの応答性が数倍低下します。アプレットの起動時に一度だけファイルを読み込んでから、その内容を変数に格納してみませんか?paint(...)paintComponent(...)

于 2012-07-10T00:42:39.447 に答える