プロ2 > 資料 > 第6章

第6回:アニメーションとゲーム

目標

5.1 アニメーションの原理

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Sample61 extends JPanel { ArrayList<Figure> figs = new ArrayList<Figure>(); Circle c1 = new Circle(Color.BLUE, 100, 100, 30); Text t1 = new Text(20, 40, "?", new Font("serif", Font.BOLD, 36)); //テキストのオブジェクト public Sample61() { setOpaque(false); figs.add(t1); figs.add(c1); final long tm0 = System.currentTimeMillis(); //開始時刻の取得 new javax.swing.Timer(50, new ActionListener() { //タイマーの設定.50ミリ秒間隔で繰り返す. public void actionPerformed(ActionEvent evt) { double tm = 0.001 * (System.currentTimeMillis() - tm0); //経過時間を計算 t1.setText(String.format("%4.2f", tm)); //経過時間の表示 c1.moveTo(20 + (int) (tm * 100) % 250, 100); //円の移動 repaint(); } }).start(); //タイマーの開始 } public void paintComponent(Graphics g) { for (Figure f : figs) { f.draw(g); } } public static void main(String[] args) { JFrame app = new JFrame(); app.add(new Sample61()); app.setSize(400, 300); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); app.setVisible(true); } interface Figure { public void draw(Graphics g); } static class Circle implements Figure { Color col; int xpos, ypos, rad; public Circle(Color c, int x, int y, int r) { col = c; xpos = x; ypos = y; rad = r; } public boolean hit(int x, int y) { return (xpos - x) * (xpos - x) + (ypos - y) * (ypos - y) <= rad * rad; } public void setColor(Color c) { col = c; } public void moveTo(int x, int y) { xpos = x; ypos = y; } public void draw(Graphics g) { g.setColor(col); g.fillOval(xpos - rad, ypos - rad, rad * 2, rad * 2); } } static class Text implements Figure { int xpos, ypos; String txt; Font fn; public Text(int x, int y, String t, Font f) { xpos = x; ypos = y; txt = t; fn = f; } public void setText(String t) { txt = t; } public void draw(Graphics g) { g.setColor(Color.BLACK); g.setFont(fn); g.drawString(txt, xpos, ypos); } } }

6.2 人間の情報処理能力とゲーム

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Ex62def extends JPanel { ArrayList<Figure> figs = new ArrayList<Figure>(); Font fn = new Font("Serif", Font.BOLD, 36); Text t1 = new Text(20, 30, "Click when red", fn); Text t2 = new Text(20, 60, "0", fn); GameCircle[] a = new GameCircle[5]; //5つの円を生成 int count; //叩けた数を数えるカウンタ public Ex62def() { setOpaque(false); figs.add(t1); figs.add(t2); for (int i = 0; i < 5; ++i) { a[i] = new GameCircle(Color.BLUE, 50 + 50 * i, 100, 20); figs.add(a[i]); //青の円を5個描画 } count = 0; final long tm0 = System.currentTimeMillis(); new javax.swing.Timer(30, new ActionListener() {//30ミリ秒毎に繰り返す double tmc = 10.0 + 3.0 * Math.random();//円が移動するまでの時間を設定 double tm = 0.0;//時計 public void actionPerformed(ActionEvent evt) { if (tm >= 40.0) {//時計が40秒経つと終了 return; } tm = 0.001 * (System.currentTimeMillis() - tm0);//時計を進める if (tm >= tmc) { //円が移動開始時刻になる tmc = tm + (40.0 - tm) * 0.1 * Math.random();//次に円が移動するまでの時間を設定 int i = (int) (a.length * Math.random());//円をランダムに選択する if (a[i].getColor() != Color.RED) {//円が青なら赤にして移動開始 a[i].setColor(Color.RED); a[i].start(); } } for (GameCircle c1 : a) {//全ての円を移動させる c1.proceed(); } t1.setText(String.format("%2.2f", 40.0 - tm));//残り時間を表示 repaint(); } }).start(); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent evt) { for (GameCircle c1 : a) { if (c1.getColor() == Color.RED && c1.hit(evt.getX(), evt.getY())) {//赤の円をクリックしたかの判定 c1.setColor(Color.BLUE);//円を青にする ++count;//叩いた回数を1増やす t2.setText(String.format("%d", count));//叩いた回数を表示する } } } }); } public void paintComponent(Graphics g) { for (Figure f : figs) { f.draw(g); } } public static void main(String[] args) { JFrame app = new JFrame(); app.add(new Ex62def()); app.setSize(400, 300); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); app.setVisible(true); } interface Figure { public void draw(Graphics g); } static class Circle implements Figure { Color col; int xpos, ypos, rad; public Circle(Color c, int x, int y, int r) { col = c; xpos = x; ypos = y; rad = r; } public boolean hit(int x, int y) { return (xpos - x) * (xpos - x) + (ypos - y) * (ypos - y) <= rad * rad; } public void setColor(Color c) { col = c; } public void moveTo(int x, int y) {//このプログラムでは利用していない xpos = x; ypos = y; } public void draw(Graphics g) { g.setColor(col); g.fillOval(xpos - rad, ypos - rad, rad * 2, rad * 2); } } static class GameCircle extends Circle { int ybase, mcount; public GameCircle(Color c, int x, int y, int r) { super(c, x, y, r); ybase = y; mcount = 0; } public Color getColor() {//円の色を返す return col; } public void start() {//円を動かし始める mcount = 20; } public void proceed() {//円を1回分動かす if (mcount <= 0) {//原点に戻っていたら何もしない return; } mcount -= 1; ypos = ybase + 100 - Math.abs(mcount - 10) * 10;//円を移動させる.10回目で跳ね返る. if (mcount == 0) { col = Color.BLUE;//原点に戻れば青にする } } } static class Text implements Figure { int xpos, ypos; String txt; Font fn; public Text(int x, int y, String t, Font f) { xpos = x; ypos = y; txt = t; fn = f; } public void setText(String t) { txt = t; } public void draw(Graphics g) { g.setColor(Color.BLACK); g.setFont(fn); g.drawString(txt, xpos, ypos); } } }


ykitamura@kwansei.ac.jp