본문 바로가기
학교 강의/모겜프

11주차

by hoshi03 2023. 11. 16.

버블 랜덤하게 생성해서 움직이고 클릭하면 터져서 작은 버블이 나옴

 

bubble

package com.example.myapplication;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;

import java.util.Random;

public class Bubble {
    private int scrW, scrH;

    public boolean isDead;

    private Context context;

    private int speed;
    private PointF dir = new PointF();
    private Random rnd = new Random();

    private Long currentTime;
    private float deltaTime;

    public float x,y;
    public int r;
    public Bitmap bubble;

    public Bubble(Context context, int width, int height){
        this.context = context;
        scrW = width;
        scrH = height;
        r = rnd.nextInt(71) + 50;

        bubble = BitmapFactory.decodeResource(context.getResources(), R.drawable.bubble);
        bubble = Bitmap.createScaledBitmap(bubble, r * 2, r * 2, true);

        initBubble();
    }

    private void initBubble(){
        speed = rnd.nextInt(51) + 150;
        double rad = Math.toRadians(rnd.nextInt(360));

        dir.x = (float) Math.cos(rad) * speed;
        dir.y = (float) -Math.sin(rad) * speed;

        x = rnd.nextInt(scrW - r* 4) + r * 2;
        y = rnd.nextInt(scrH - r* 4) + r * 2;

        currentTime = System.nanoTime();
    }

    public void update(){
        x += dir.x * Time.deltaTime; // 이동
        y += dir.y * Time.deltaTime;

        //화면의 경계에서 반사
        if (x < r || x > scrW - r) {
            dir.x = -dir.x;
            x += dir.x * Time.deltaTime;
        }
        if (y < r || y > scrH - r) {
            dir.y = -dir.y;
            y += dir.y * Time.deltaTime;
        }
    }

    public boolean hitTest(float px, float py) {
        boolean hit = false;
        isDead = (x - px) * (x - px) + (y - py) * (y - py) < r * r;
        float dist = (x - px) * (x - px) + (y - py) * (y - py);

        if (dist < r * r){
            int cnt = rnd.nextInt(6) + 25;     // 25~30 (파편의    수)
            for (int i = 1; i <= cnt; i++) {
                GameView.mSmall.add(new SmallBubble(context, scrW, scrH, x, y));
            }
            isDead = true;
        }
        return isDead;
    }

}

 

smallbubble

 

package com.example.myapplication;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;

import java.util.Random;

public class SmallBubble {
    // 화면   크기
    private int scrW, scrH;
    // 이동 방향, 속도, 수명
    private PointF dir = new PointF();
    private int speed;
    private float life;
    // 현재 위치, 반지름
    public float x, y;
    public int r;
    // 투명도, 소멸, 비트맵
    public int alpha = 255;
    public boolean isDead;
    public Bitmap bubble;

    public SmallBubble(Context context, int sw, int sh, float px, float py){
        scrW = sw;     // 화면    크기
        scrH = sh;
        x = px;        // 초기    위치
        y = py;

        Random rnd = new Random();
        //speed = 300;
        speed = rnd.nextInt(201) + 300; // 300~500
        life = (rnd.nextInt(6) + 10) / 10f; // 1~1.5초

        // 이동  방향
        double rad = Math.toRadians(rnd.nextInt(360));
        dir.x = (float) Math.cos(rad) * speed;
        dir.y = (float) -Math.sin(rad) * speed;

        // 반지름, 이미지  번호
        r = rnd.nextInt(11) + 10;     // 10~20
        int n = rnd.nextInt(6);  // 이미지 번호 (0~5)

        bubble = BitmapFactory.decodeResource(context.getResources(), R.drawable.b0 + n);
        bubble = Bitmap.createScaledBitmap(bubble, r * 2, r * 2, true);
    }

    public void update() {
        x += dir.x * Time.deltaTime;  // 이동
        y += dir.y * Time.deltaTime;

        life -= Time.deltaTime;
        if (life < 0) {
            alpha -= 5;
            if (alpha < 0) alpha = 0;
        }
        if (alpha == 0 || x < -r || x > scrW + r || y < -r || y > scrH + r) {
            isDead = true;
        }
    }

}

 

gameview

package com.example.myapplication;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.Random;

public class GameView extends View {
    private Context context;    // Context 저장용
    // 배경과    화면    크기
    private Bitmap imgBack;
    private int w, h;
    // Random. 비눗방울    저장용
    private Random rnd = new Random();
    private ArrayList<Bubble> mBubble = new ArrayList<Bubble>();

    static public ArrayList<SmallBubble> mSmall = new ArrayList<SmallBubble>();
    private Paint paint = new Paint();
    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // Context 저장
        this.context = context;
    }

    // View의 크기가 바뀔 때마다 호출. ( e.g. View 가 만들어질때, 타이틀바가 추가
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.w = w;
        this.h = h;
        // 배경    이미지
        imgBack = BitmapFactory.decodeResource(getResources(), R.drawable.sky);
        imgBack = Bitmap.createScaledBitmap(imgBack, w, h, true);
        mHandler.sendEmptyMessageDelayed(0, 10); // Handler 기동
    }
    // 화면    그리기
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(imgBack, 0, 0, null);
        // 비눗방울    그리기
        for (Bubble tmp : mBubble) {
            canvas.drawBitmap(tmp.bubble, tmp.x - tmp.r, tmp.y - tmp.r, null);
        }
        for (SmallBubble tmp : mSmall){
            paint.setAlpha(tmp.alpha);
            canvas.drawBitmap(tmp.bubble, tmp.x - tmp.r, tmp.y - tmp.r, paint);
        }

    }

    // 비눗방울    만들기. Handler가    호출
    private void makeBubble() {
        if (mBubble.size() < 20 && rnd.nextInt(1000) < 8) {
            mBubble.add( new Bubble(context, w, h) );
        }
    }
    // 비눗방울    이동. Handler가    호출
    private void moveBubble() {
        for (Bubble tmp : mBubble) {
            tmp.update();
        }
    }

    private void removeDead() {
        for (int i = mBubble.size() - 1; i >= 0; i--) {
            if (mBubble.get(i).isDead) mBubble.remove(i);
        }
    }

    private void hitTest(float x, float y) {
        for (Bubble tmp : mBubble) {
            if (tmp.hitTest(x, y)) break;
        }
    }

    // Touch Event
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            hitTest(event.getX(), event.getY());
        }
        return true;
    }
    // Handler
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Time.update();
            makeBubble();
            moveBubble();
            removeDead();
            invalidate();
            mHandler.sendEmptyMessageDelayed(0, 10);
        }
    };
}

 

time

package com.example.myapplication;


public class Time {
    static private long currentTime = System.nanoTime();
    static public float deltaTime;
    // deltaTime 계산
    static public void update() {
        deltaTime = (System.nanoTime() - currentTime) / 1000000000f;
        currentTime = System.nanoTime();
    }
}

 

mainactivity

package com.example.myapplication;

import static android.graphics.BlendMode.COLOR;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MainActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// getSupportActionBar().hide();
        setTitle("2019026380 이찬호");
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }
}

 

activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.AppCompat" />
    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginEnd="@dimen/fab_margin"
        android:layout_marginBottom="16dp"
        app:srcCompat="@android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

contentmain.xml

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <com.example.myapplication.GameView
        android:id="@+id/gameView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

실행화면

 

'학교 강의 > 모겜프' 카테고리의 다른 글

모겜프 12주차  (0) 2023.11.23
모겜프 10주차  (0) 2023.11.09
모겜프 시험대비  (1) 2023.10.23
모겜프 7주차  (1) 2023.10.19
시험대비  (0) 2023.10.12