ラベル(または通常はGUIコンポーネント)を使用して、すばやくアニメーション化され、動的に作成/移動されるオブジェクトを表すことは実用的ではありません。車を使って居間から台所まで運転するようなものです。
Swingコンポーネントには多くの優れた機能があります。たとえば、必要なスペースを決定でき、レイアウトマネージャーはそれを使用して自動的に適切に配置できます。残念ながら、ゲームの場合、すべての優れた機能は必要ありません。また、それに伴う処理オーバーヘッドを支払う必要もありません。各コンポーネントにピアコンポーネントがあることを義務付けるスイングマルチプラットフォーム機能によって、問題はさらに複雑になります(ピアはコンポーネントをアクティブな外観にレンダリングすることを処理します)。
これを解決するために、個々のゲームオブジェクトをスイングコンポーネントとして表現しません。代わりに、単一のスイングコンポーネント(通常はJPanel)をキャンバスとして使用して、ゲームオブジェクトをペイントします。そのJPanelに対して定期的に(たとえば、1秒間に30回または60回)repaint()を呼び出すだけです。もちろん、JPanelのpaintComponent()をオーバーライドして、独自のコードを使用してすべてのゲームオブジェクトをペイントします。
編集:独自のレンダリングを行う方法の概要を説明します
ゲーム関連のオブジェクトを整理する方法を決定する必要があります。非常に単純なスケルトンは次のようになります(ゲッター/セッターは省略)。
public class GameObject {
public int x;
public int y;
public Image image;
}
実際には、このクラスには追加のメンバーがあります(オブジェクトの移動方法を制御する動作や、アニメーションのいくつかの状態/カウンターなど)。また、可能な動作(船、小惑星、弾丸など)ごとに具体的なサブクラスを使用して抽象化することもできます。GameObjectのすべてのインスタンスは、ある種のコレクションで管理されています。リストを使用していると思います。
paintComponentを実装する場合、リストをループして各オブジェクトの画像をレンダリングするだけです。
public void paintComponent(Graphics g) {
List<GameObject> list = ... // however you obtain it in your game
for (GameObject gobject : list) {
g.drawImage(gobject.image, gobject.x, gobject.y, (ImageObserver) null);
}
}
より精巧なゲームは、ゲームオブジェクトが互いにどのように重なり合うかを制御するためにゲームオブジェクトを注文する場合があります。しかし、原則として、その信じられないほど単純です。