LoginSignup
0
2

More than 1 year has passed since last update.

Javaでブロック崩しゲームを作る

Last updated at Posted at 2022-07-25

ブロック崩し

最近、Javaを勉強しています。

image.png

こんな感じのブロック崩しを作りました。
想像以上に難しかったです。
オブジェクト指向って修正がしやすく、わかりやすく書ける気がします。

オブジェクト

  1. ボール
  2. 反射板(操作可能)
  3. 障害物

このうちボール以外は線分の組み合わせだと考えられます。
1.png
障害物がこのように長方形の場合、4つの線分で障害物を構成できます。

そこで、”線分クラス” を作り、障害物や壁・反射板は ”線分インスタンス”の集まりとしました。
こう考えることで、線分とボールの反射だけを考えるのみで、全ての "オブジェクト-ボールの反射" を考えられます。
どういうことかというと
2.png
このようにボールが障害物に向かって進んでいる状況の場合、反射後の位置の計算が必要になります。
これを、”線分インスタンス”とボールの反射が起きているのみだと考えることで

  1. 記述量が少なくなる(障害物・壁・反射板全て同じ計算になる)
  2. ボールの軌道も"線分"と考えることで、線分同士の計算となる。よって反射先計算が線分クラス内でまとまる

非常に有益であるといえます。

反射計算

  1. 衝突するか判定
  2. 反射後の地点計算

この二つになります。

2.png

この状況の場合、

  1. ボールの線分(軌道)と障害物の線分全てとの交点を計算
  2. 交点が線分内か検証(線分が交わっているか調べる
  3. ボールの線分の支点から、交点への距離を計算
  4. 一番近い交点で反射が起こる
  5. 反射先を計算
  6. 1に戻る

という計算の流れになります。
一番近いというのは、次のような状況への対処が必要なためです。
3.png
この場合、交点は4つありますが、反射するのは一番近い交点となります。
よって線分クラスに必要な機能が二つあります。

  1. 線分同士の交点計算
  2. 交点が線分内に存在するか(線分が交わっているか)
  3. 交点から線分の始点(ボールの軌道線分はベクトルとして考える)への距離の計算

交点計算

4.png
このように、二つの線分があるとき、交点を計算すると

p_x = -\frac{(x_1'-x_2')(x_1 y_2-x_2 y_1)  -  (x_1-x_2)(x_1' y_2'-x_2' y_1') }
{(x_1'-x_2')(y_1 - y_2) - (x_1-x_2)(y_1' - y_2')}\\

p_y = \frac{  (y_1-y_2)(x_1' y_2'-x_2' y_1') - (y_1'-y_2')(x_1 y_2-x_2 y_1)  }
{(x_1'-x_2')(y_1 - y_2) - (x_1-x_2)(y_1' - y_2')}\\

となります。
ここで、分母が0となるのは、二つの線分が平行であるときです(外積と同じ計算してるので0=平行)。

反射先計算

5.png
このように、線分とベクトルがぶつかった状況を考えます。
ぶつかった場合、反射します。

6.png

こんな感じです。

7.png

次のように名前を付けます。$\vec{e},\vec{e}_v$は線分の単位ベクトルと単位法線ベクトルです。
$\vec{v_2}$を求めることが目標となります。
交点が計算できているため$\vec{v_0},\vec{v_1}$は自明です。$\vec{e},\vec{e}_v$も正規化+90度回転で計算できます。

\vec{d} = - \vec{e}_v (\vec{v_1}*\vec{e}_v)\\
\vec{f} =\vec{e} (\vec{v_1}*\vec{e})\\
\begin{eqnarray}
\therefore \vec{v_2} &=&  \vec{f}  +\vec{d} \\
&=&\vec{e} (\vec{v_1}*\vec{e})  - \vec{e}_v (\vec{v_1}*\vec{e}_v)
\end{eqnarray}

で計算できます。$*$は内積計算

これで軌道計算が完了です。

プログラミング

Swingを使います。

以前に書いた記事です。ご参考までに

フレームの作成

JFrameを継承したクラスのインスタンスを生成した段階でフレームが生まれます。

BlockBreak frame = new BlockBreak();

タイマー処理

動的に動かすには、一定時間ごとにボールオブジェクトを動かし反射を調べて描画を更新していく、必要があります。

初期設定として、

  1. まずタイマーオブジェクトを生成します。
  2. タイマーの時間を設定します。
Timer time = new Timer();
time.scheduleAtFixedRate(new SampleTask(), delay, period);

実行内容

public class Timer_task extends TimerTask {
    public void run() {
       
    }
}

run()内の処理が一定時間ごとに実行されます。
swingではrepaint()を実行することで描画を更新できます。
repaint()の処理内にはpaint()処理が入っています。
一般にpaint()処理をorverrideして好きな内容に書き換えるみたいです。

以上で説明が必要な部分は終わりです。
後はコードを乗せます。
ほんとはGitとか使った方がいいかもですが、それはまた今度勉強しようと思います。

コード

オブジェクト

BlockBreak extend JFrame

  • mainを持つ
  • フレーム本体

Ball

  • ボール

Manipulate_obj

  • 操作板

Obstacle_polygon

  • 障害物

Line

  • 線分

以上の構成になっています。

本体

BlockBreakクラス

BlockBreak.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Timer;

public class BlockBreak extends JFrame implements KeyListener {

    private final int height = 600;
    private final int width = 600;
    private long startTime;

    Wall_Line wall;
    Ball ball;
    Obstacle_polygon obstacle1;
    Manipulate_obj board;

    ArrayList<Obstacle_polygon> obstacle_list = new ArrayList<>();


    public static void main(String[] args){
        System.out.println("Start");
        BlockBreak frame = new BlockBreak();
        java.util.Timer timer = new Timer();
        Timer_task timer_task = new Timer_task();
        timer_task.setFlame(frame);
        timer_task.setTimer(timer);
        timer_task.clearEndTimer();
        timer.scheduleAtFixedRate(timer_task, 0,30);
    }


    public BlockBreak() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(this.width, this.height);
        setVisible(true);
        this.startTime = System.currentTimeMillis();
        this.ball = new Ball(200,200,0.5,0.4,Color.red);
        ball.set_radius(4);
        ball.set_radius_Afterimage(2);
        this.wall = new Wall_Line(this.height,this.width,Color.blue);
        this.wall.set_wallSize(new int[]{10, 500}, new int[]{10, 500});
        this.obstacle1 = new Obstacle_polygon(
                new int[]{25, 145, 25, 145},new int[]{25, 25, 145, 145},Color.green);

        this.board = new Manipulate_obj(new int[]{200, 350, 350, 200},
                                        new int[]{400, 400, 420, 420},
                                        Color.green);
        this.board.set_speed(1.0);

        for(int i=0;i<10;i++){
            for(int j=0;j<4;j++){
                //i 横、j 縦
                int x1 = 70+i*40;
                int x2 = 70+i*40 + 20;
                int y1 = 50 + j*40;
                int y2 = 50 + j*40 + 20;
                this.obstacle_list.add(new Obstacle_polygon(
                        new int[]{x1, x2, x2, x1},
                        new int[]{y1, y1, y2, y2},
                        Color.green));

            }
        }
        addKeyListener(this);
    }

    @Override
    public void paint(Graphics g){
        Image imgBuf = createImage(this.width,this.height);
        Graphics gBuf = imgBuf.getGraphics();               //gBufがバッファの画像
        gBuf.setColor(Color.white);
        gBuf.fillRect(0,0,this.width,this.height);
        long now_time = System.currentTimeMillis();

        //ボールを動かす
        this.ball.move(this.width,this.height);

        //Keyboardでの入力でボードを移動する。
        //移動距離は時間を測る。
        this.board.move_speed(now_time,this.width);

        //反射処理
        this.reflection();

        if(this.wall.ball_outside_judge(this.ball)){
            System.out.println("ball outside");
            System.out.println(ball.ball_position_toString());
            while(true){
                continue;
            }
        }

        //位置を更新する
        this.ball.update();

        //描画処理開始
        this.ball.draw(gBuf);
        this.wall.draw(gBuf);
        //this.obstacle1.draw(gBuf);
        this.board.draw(gBuf);
        for(Obstacle_polygon poly:this.obstacle_list){
            poly.draw(gBuf);
        }
        //this.ball.draw_velocity(gBuf,height,width);

        //バッファを画面に表示
        Graphics graphics = getContentPane().getGraphics();
        graphics.drawImage(imgBuf,0,0,this);
    }

    public boolean ball_outside_judge(Ball ball){
        //ball が領域外にあるか判定する true->外
        double[] position = ball.get_position();
        double x = position[0];
        double y = position[1];
        if(x<0 || width < x ||
            y<0 || height < y){
            return true;
        }else{
            return false;
        }

    }
    public void reflection(){
        //反射処理:
        boolean flag = true;
        Line before_reflect_line = null;
        Obstacle_polygon min_obj = null;
        do {
            double min_distance = 1000;
            Line min_line = null;
            for (Line line : this.wall.line) {
                double distance = line.inter_section_distance(ball.ball_line);
                if (distance < min_distance && distance != 0
                        &&!line.same_line(before_reflect_line)) {
                    min_line = line;
                    min_distance = distance;
                    min_obj = null;
                }
            }
            /*
            for (Line line : this.obstacle1.line) {
                double distance = line.inter_section_distance(ball.ball_line);
                if (distance < min_distance && distance != 0
                        &&!line.same_line(before_reflect_line)) {
                    min_line = line;
                    min_distance = distance;
                }
            }
             */
            for (Line line : this.board.line) {
                double distance = line.inter_section_distance(ball.ball_line);
                if (distance < min_distance && distance != 0
                        &&!line.same_line(before_reflect_line)) {
                    min_line = line;
                    min_distance = distance;
                }
            }
            for(int i=0;i<this.obstacle_list.size();i++){
                Obstacle_polygon poly = this.obstacle_list.get(i);
                for (Line line : poly.line) {
                    double distance = line.inter_section_distance(ball.ball_line);
                    if (distance < min_distance && distance != 0
                            &&!line.same_line(before_reflect_line)) {
                        min_line = line;
                        min_distance = distance;
                        min_obj = poly;
                    }
                }
            }



            //min_line と 反射させて ballを更新する
            if (min_line != null) {
                min_line.reflect(ball);
                before_reflect_line = min_line;
                if(min_obj != null) {
                    this.obstacle_list.remove(this.obstacle_list.indexOf(min_obj));
                }
            }else{
                flag = false;
            }
            //System.out.println(ball.ball_velocity_toString());
            //flag = false;

        }while(flag);
    }
    @Override
    public void keyTyped(KeyEvent e) {
        //使用しないので空にしておきます。
    }
    @Override
    public void keyPressed(KeyEvent e) {
        switch ( e.getKeyCode() ) {
            case KeyEvent.VK_RIGHT:
                if(!this.board.get_state()){
                    this.board.set_start_time(System.currentTimeMillis());
                }
                this.board.set_right();
                this.board.set_move();
                System.out.println("right");
                break;
            case KeyEvent.VK_LEFT:
                if(!this.board.get_state()){
                    this.board.set_start_time(System.currentTimeMillis());
                }
                this.board.set_left();
                this.board.set_move();
                System.out.println("left");
                break;
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        switch ( e.getKeyCode() ) {
            case KeyEvent.VK_RIGHT:
            case KeyEvent.VK_LEFT:
                this.board.clear_move();
                System.out.println("stop");
                break;
        }

    }
}

TimerTaskクラス

Timer_task.java
import java.util.Timer;
import java.util.TimerTask;

public class Timer_task extends TimerTask {
    BlockBreak frame_timer;
    private int num = 0;
    private boolean endFlag = true;
    Timer timer;

    public void run() {
        frame_timer.repaint();
        num++;

        if(num>1000 && endFlag == true){
            System.out.println("End");
            cancel();
            frame_timer.dispose();
            timer.cancel();
        }
    }
    public void setFlame(BlockBreak frame){
        frame_timer = frame;
    }
    public void setTimer(Timer time3){
        this.timer = time3;
    }
    public void setEndTimer(){
        this.endFlag = true;
    }
    public void clearEndTimer(){
        this.endFlag = false;
    }
}
Ball.java
import java.awt.*;
import java.util.ArrayDeque;
import java.util.Queue;

public class Ball {
    private double x = 0;
    private double y = 0;
    private double next_x;
    private double next_y;
    private double velocity_x = 0;
    private double velocity_y = 0;
    private Color color;
    private Color color_Afterimage;
    private long before_time;
    private long now_time;
    private double radius = 10;
    private double radius_Afterimage = 3;
    Queue<Double> que_pos_x;
    Queue<Double> que_pos_y;
    public Line ball_line;
    public Ball(int x,int y,double velocity_x,double velocity_y,Color color){
        before_time =  System.currentTimeMillis();
        now_time =  System.currentTimeMillis();
        this.color = color;
        this.color_Afterimage = Color.CYAN;
        this.x = x;
        this.y = y;
        this.velocity_x = velocity_x;
        this.velocity_y = velocity_y;
        que_pos_x = new ArrayDeque<Double>();
        que_pos_y = new ArrayDeque<Double>();
        this.ball_line = new Line(x,y,x,y);
    }
    public void draw(Graphics g){
        if(que_pos_x.size()>= 1) {
            for (int i = 0; i < que_pos_x.size() ; i++) {
                double x = que_pos_x.remove();
                double y = que_pos_y.remove();

                g.setColor(color_Afterimage);
                g.fillOval((int)(x - radius_Afterimage), (int)(y - radius_Afterimage),
                        (int)(radius_Afterimage * 2), (int)(radius_Afterimage * 2));

                que_pos_x.add(x);
                que_pos_y.add(y);
            }
        }

        g.setColor(color);
        g.fillOval((int)(x - radius), (int)(y - radius), (int)(radius * 2), (int)(radius * 2));
        
    }
    public void draw_velocity(Graphics g,double height,double width){
        g.setColor(color);
        g.drawLine((int)width/2,(int)height/2,
                (int)(width/2+this.velocity_x*10),(int)(height/2+this.velocity_y*10));
        double x = width/2;
        double y = height/2;
        double radius = 3;
        g.fillOval((int)(x - radius), (int)(y - radius),
                (int)(radius * 2), (int)(radius * 2));

    }
    public void set_radius(int radius){
        this.radius = radius;
    }
    public void set_radius_Afterimage(int radius){
        this.radius_Afterimage = radius;
    }
    public void move(int width,int height){
        //次の場所を計算する
        this.now_time =  System.currentTimeMillis();
        long elapsed_time = this.now_time - this.before_time;
        this.next_x = this.x + this.velocity_x*elapsed_time;
        this.next_y = this.y + this.velocity_y*elapsed_time;
        if(this.next_x > width){
            this.next_x = width;
        }else if(this.next_x <0){
            this.next_x = 0;
        }
        if(this.next_y > height){
            this.next_y = height;
        }else if(this.next_y <0){
            this.next_y = 0;
        }
        this.before_time = this.now_time;
        this.ball_line.set(this.x,this.y,this.next_x,this.next_y);
    }
    public double[] get_position(){
        //x,y,next_x,next_yの順に返す
        return new double[]{x,y,next_x,next_y};
    }
    public double[] get_velocity(){
        return new double[]{this.velocity_x,this.velocity_y};
    }
    public String ball_position_toString(){
        String text;
        text = "(ball now "
                +String.valueOf(this.x)
                +" , "
                +String.valueOf(this.y)
                +")";
        return text;
    }
    public String ball_velocity_toString(){
        String text;
        text = "("
                +String.valueOf(this.velocity_x)
                +" , "
                +String.valueOf(this.velocity_y)
                +")";
        return text;
    }
    public String ball_nposition_toString(){
        String text;
        text = "(next ball "
                +String.valueOf(this.next_x)
                +" , "
                +String.valueOf(this.next_y)
                +")";
        return text;
    }
    public void reflect_UPDOWN(){
        this.velocity_y = -1 * this.velocity_y;
    }
    public void reflect_RIGHTLEFT(){
        this.velocity_x = -1 * this.velocity_x;
    }
    public void set_position(double next_x,double next_y){
        //nextの位置を変更する
        this.next_x = next_x;
        this.next_y = next_y;
    }
    public void set_velocity(double velocity_x,double velocity_y){
        this.velocity_x = velocity_x;
        this.velocity_y = velocity_y;
    }
    public void update(){
        que_pos_x.add(this.x);
        que_pos_y.add(this.y);
        //次の位置に更新する
        x = next_x;
        y = next_y;

        if(que_pos_x.size()>10){
            que_pos_x.remove();
            que_pos_y.remove();
        }
    }
}

Lineクラス

Line.java
public class Line {
    private double[][] points = new double[2][2];
    public double x_inter;
    public double y_inter;
    public Line e_vec;
    public Line e_vertical_vec;
    public Line(double x1,double y1,double x2,double y2){
        this.points[0][0] = x1;
        this.points[1][0] = x2;
        this.points[0][1] = y1;
        this.points[1][1] = y2;
    }
    public void reflect(Ball ball){
        //事前に計算された交点ー>反射先終点 にball_lineを更新
        //速度方向を変換
        this.e_vec();   //単位ベクトル計算
        Line v1;
        v1 = new Line(0,0,
                ball.ball_line.points[1][0] - x_inter,
                ball.ball_line.points[1][1] - y_inter);
        Line d;
        //d = -e2(e2'v1);
        this.e_vec();
        d = this.e_vertical_vec.product(-1*this.e_vertical_vec.dot(v1));
        Line v2;
        //v2 = d + e(e'v1)
        v2 = d.add_vec(this.e_vec.product(this.e_vec.dot(v1)));


        //ball オブジェクトの更新
        //ball_line,next,x,y,velocity を 変える
        ball.set_position(this.x_inter + v2.points[1][0]
                ,this.y_inter + v2.points[1][1]);
        ball.ball_line.set(this.x_inter,this.y_inter,
                this.x_inter + v2.points[1][0],this.y_inter + v2.points[1][1]);

        double[] velocity = ball.get_velocity();
        double norm_vel = Math.sqrt((velocity[0]*velocity[0] + velocity[1]*velocity[1]));
        v2.e_vec();
        ball.set_velocity(v2.e_vec.points[1][0]*norm_vel,
                v2.e_vec.points[1][1]*norm_vel);
        //System.out.println(norm_vel);
        //System.out.println("---");
        //System.out.println(ball.ball_velocity_toString());
        ///System.out.println(ball.ball_line.toString());

    }
    public void set(double x1,double y1,double x2,double y2){
        this.points[0][0] = x1;
        this.points[1][0] = x2;
        this.points[0][1] = y1;
        this.points[1][1] = y2;
    }
    public boolean exist_point(double x1,double y1){
        /*
        System.out.print("exist point ");
        System.out.print(this.points[0][0]);
        System.out.print(" ");
        System.out.print(this.points[1][0]);
        System.out.print(" ");
        System.out.println(x1);
        */
        //計算誤差で含まれない結果になることを防止するため
        //範囲を少し広げるための変数
        double error = 1e-10;

        if(this.points[0][0] < this.points[1][0] ){
            if(this.points[0][0]-error <= x1 &&
                    x1 <= this.points[1][0] +error){
                if(this.points[0][1] < this.points[1][1] ){
                    if(this.points[0][1] -error <= y1 &&
                            y1 <= this.points[1][1] +error){
                        return true;
                    }
                }else{
                    if(this.points[1][1]-error <= y1 &&
                            y1 <= this.points[0][1] +error ){
                        return true;
                    }
                }
            }
        }else{
            if(this.points[1][0]-error <= x1 &&
                    x1 <= this.points[0][0] +error){
                if(this.points[0][1] < this.points[1][1] ){
                    if(this.points[0][1] -error <= y1 &&
                            y1 <= this.points[1][1] +error){
                        return true;
                    }
                }else{
                    if(this.points[1][1] -error <= y1 &&
                            y1 <= this.points[0][1] +error){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    public void e_vec(){
        double x1 = this.points[0][0];
        double y1 = this.points[0][1];
        double x2 = this.points[1][0];
        double y2 = this.points[1][1];
        double norm = Math.sqrt((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2));
        this.e_vec = new Line(0,0,(x2-x1)/norm, (y2-y1)/norm);
        this.e_vertical_vec = new Line(0,0,-1*(y2-y1)/norm,(x2-x1)/norm);
    }
    public Line add_vec(Line line){
        Line line2;
        line2 = new Line(this.points[0][0],this.points[0][1],
                this.points[1][0] + line.points[1][0],
                this.points[1][1] + line.points[1][1]);
        return line2;
    }
    public Line product(double norm){
        Line line2;
        line2 = new Line(this.points[0][0]*norm,
                this.points[0][1]*norm,
                this.points[1][0]*norm,
                this.points[1][1]*norm);
        return line2;
    }
    public double dot(Line line){
        double x1 = this.points[1][0] - this.points[0][0];
        double y1 = this.points[1][1] - this.points[0][1];
        double x2 = line.points[1][0] - line.points[0][0];
        double y2 = line.points[1][1] - line.points[0][1];
        double dot;
        dot = (x1*x2 + y1*y2);
        return dot;
    }
    public double inter_section_distance(Line ball_line){
        //交点を計算ー>交点が両方のラインに含まれるか確認ー>ボールの始点からの距離を返す
        double x1 = this.points[0][0];
        double y1 = this.points[0][1];
        double x2 = this.points[1][0];
        double y2 = this.points[1][1];
        double x1q = ball_line.points[0][0];
        double y1q = ball_line.points[0][1];
        double x2q = ball_line.points[1][0];
        double y2q = ball_line.points[1][1];

        double deno;
        deno = (x1q - x2q)*(y1-y2) - (y1q - y2q)*(x1-x2);
        //System.out.println(deno);

        if(deno < 0.0000001 && deno > -0.0000001){  //平行
            return 10000;
        }else{
            this.x_inter = -1 * ((x1q - x2q) * (x1 * y2 - x2 * y1) - (x1 - x2) * (x1q * y2q - x2q * y1q));
            this.x_inter = this.x_inter / deno;
            this.y_inter = (y1 - y2) * (x1q * y2q - x2q * y1q) - (y1q - y2q) * (x1 * y2 - x2 * y1);
            this.y_inter = this.y_inter / deno;
        }
        /*
        System.out.print("inter point ");
        System.out.print(this.x_inter);
        System.out.print(" ");
        System.out.println(this.y_inter);
         */

        boolean cross_flag = (this.exist_point(this.x_inter,this.y_inter)) &&
                (ball_line.exist_point(this.x_inter,this.y_inter));

        if(cross_flag){
            double distance;
            distance = Math.sqrt((x1q-this.x_inter)*(x1q-this.x_inter)
                    + (y1q-this.y_inter)*(y1q-this.y_inter) );
            return distance;
        }else{
            return 10001;
        }
    }
    public boolean same_line(Line line){
        if(line == null){
            return false;
        }else {
            if (this.points[0][0] == line.points[0][0]) {
                if (this.points[1][0] == line.points[1][0]) {
                    if (this.points[0][1] == line.points[0][1]) {
                        if (this.points[1][1] == line.points[1][1]) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    public String toString(){
        String text;
        text =  "("
                +String.valueOf(this.points[0][0])
                +" , "
                +String.valueOf(this.points[0][1])
                +") ( "
                +String.valueOf(this.points[1][0])
                +" , "
                +String.valueOf(this.points[1][1])
                +")";
        return text;
    }
}

Obstacle_polygonクラス

Obstacle_polygon.java
import java.awt.*;

public class Obstacle_polygon {
    protected Line[] line;
    private Color color;
    protected int[] x_pos;  //多角形点座標 x
    protected int[] y_pos;  //多角形点座標 y

    public Obstacle_polygon(int[] x_pos, int[] y_pos, Color color){
        this.line = new Line[x_pos.length];
        this.x_pos = x_pos;
        this.y_pos = y_pos;
        for(int i=0;i<this.x_pos.length-1;i++){
            this.line[i] = new Line(x_pos[i],y_pos[i],x_pos[i+1],y_pos[i+1]);
        }
        this.line[x_pos.length-1] = new Line(x_pos[x_pos.length-1],y_pos[x_pos.length-1],
                                                    x_pos[0],y_pos[0]);
        this.color = color;
    }
    public void draw(Graphics g){
        g.setColor(color);
        Polygon polygon = new Polygon(this.x_pos,this.y_pos,this.x_pos.length);
        g.fillPolygon(this.x_pos,this.y_pos,this.x_pos.length);

    }
    public String ToString(){
        String text;
        text =  "("
                +String.valueOf(this.x_pos[0])
                +" , "
                +String.valueOf(this.y_pos[0])
                +") ( "
                +String.valueOf(this.x_pos[1])
                +" , "
                +String.valueOf(this.y_pos[1])
                +") ( "
                +String.valueOf(this.x_pos[2])
                +" , "
                +String.valueOf(this.y_pos[2])
                +") ( "
                +String.valueOf(this.x_pos[3])
                +" , "
                +String.valueOf(this.y_pos[3])
                +")";
        return text;
    }

}

Manipulate_objクラス

Manipulate_obj.java
import java.awt.*;

public class Manipulate_obj extends  Obstacle_polygon{
    private double speed = 0.1;
    public boolean move_enable = false;
    private long start_time = 0;
    public Manipulate_obj(int[] x_pos, int[] y_pos, Color color){
        super(x_pos,y_pos,color);
        this.start_time = System.currentTimeMillis();
    }
    public void move(int x,int width){
        for(int i=0;i<this.x_pos.length;i++){
            if(this.x_pos[i]+x < 0){
                x = this.x_pos[i]*-1;
            } else if (this.x_pos[i] + x > width) {
                x = width - this.x_pos[i];
            }
        }
        for(int i=0;i<this.x_pos.length;i++){
            this.x_pos[i] = this.x_pos[i] + x;
        }
        for(int i=0;i<this.x_pos.length-1;i++){
            this.line[i] = new Line(x_pos[i],y_pos[i],x_pos[i+1],y_pos[i+1]);
        }
        this.line[x_pos.length-1] = new Line(x_pos[x_pos.length-1],y_pos[x_pos.length-1],
                x_pos[0],y_pos[0]);
    }
    public void set_speed(double speed){
        this.speed = speed;
    }
    public void set_start_time(long time){
        this.start_time = time;
    }
    public void set_move(){
        this.move_enable = true;
    }
    public void clear_move(){
        this.move_enable = false;
    }
    public boolean get_state(){
        if(this.move_enable == true){
            return true;
        }else{
            return false;
        }
    }
    public void set_right(){
        this.speed = Math.abs(this.speed);
    }
    public void set_left(){
        this.speed = Math.abs(this.speed)*-1;
    }
    public void move_speed(long now_time,int width){
        if(this.move_enable == true){
            double x = speed * (now_time - this.start_time);
            this.move((int)x,width);
            set_start_time(now_time);
        }
    }
}

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2