316
No
class Missile
package com.example.choi.ex07_graphic;
/**
* Created by choi on 2017-02-23.
*/
public class Missile {
private int mx;
private int my;
public Missile(int mx, int my) {
this.mx = mx;
this.my = my;
}
public int getMy() {
return my;
}
public void setMy(int my) {
this.my = my;
}
public int getMx() {
return mx;
}
public void setMx(int mx) {
this.mx = mx;
}
@Override
public String toString() {
return "Missile{" +
"mx=" + mx +
", my=" + my +
'}';
}
}
class GameActivity
package com.example.choi.ex07_graphic;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.List;
public class GameActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//상태 바 없애기
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
/*
//타이틀바 숨김
requestWindowFeature(Window.FEATURE_NO_TITLE);
*/
MyView myView=new MyView(this);
myView.setFocusable(true); //키이벤트를 받을 수 있도록 설정
//xml 이 아닌 내부클래스 (커스텀 뷰)로 화면 사용
setContentView(myView);
}
//내부 클래스
class MyView extends View implements Runnable{
Drawable backImg;//배경이미지
Drawable gunship;//비행기이미지
Drawable missile;//총알이미지
Drawable enemy;//적 이미지
Drawable explosure;//폭발이미지
//SoundPool 사운드(1M), MediaPlayer 사운드(1M 이상) 동영상)
MediaPlayer fire, hit;//발사음 ,폭발음
int width, height;//화면의 가로 , 세로 길이
int gunshipWidth, gunshipHeight;//비행기의 가로, 세로
int missileWidth, missileHeight; //총알의 가로, 세로
int enemyWidth, enemyHeight;//적의 가로, 세로
int hitWidth, hitHeight;//폭발이미지의 가로, 세로
int x, y; //비행기의 좌표
int mx, my; //총알 좌표
int ex, ey;//적 좌표
int hx, hy; //폭발 좌표
int point=1000;//점수
boolean isFire; //총알 발사여부
boolean isHit; //폭발 여부
List<Missile> mlist;//총알 리스트
//생성자
public MyView(Context context) {
super(context);
//이미지 생성
backImg=getResources().getDrawable(R.drawable.back0);
gunship=getResources().getDrawable(R.drawable.gunship);
missile=getResources().getDrawable(R.drawable.missile);
enemy=getResources().getDrawable(R.drawable.enemy);
explosure=getResources().getDrawable(R.drawable.hit);
//사운드 생성
fire=MediaPlayer.create(GameActivity.this, R.raw.fire);
hit=MediaPlayer.create(GameActivity.this, R.raw.hit);
//리스트 생성
mlist=new ArrayList<>();
//백그라운드 스레드 생성
Thread th =new Thread(this);
th.start();
}
//화면 사이즈가 변경될때 (최초 표시, 가로/세로 전환)
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//화면의 가로, 세로
width =getWidth();
height=getHeight();
//이미지의 가로, 세로 길이
gunshipWidth=gunship.getIntrinsicWidth();
gunshipHeight=gunship.getIntrinsicHeight();
missileWidth=missile.getIntrinsicWidth();
missileHeight=missile.getIntrinsicHeight();
enemyWidth=enemy.getIntrinsicWidth();
enemyHeight=enemy.getIntrinsicHeight();
hitWidth=explosure.getIntrinsicWidth();
hitHeight=explosure.getIntrinsicHeight();
//비행기 좌표
x =width/2 -gunshipWidth/2;
y=height -50;
//총알 좌표
mx =x +20;
my=y;
//적 좌표
ex=width - enemyWidth;
ey =50;
}
@Override
protected void onDraw(Canvas canvas) {
//배경이미지 출력
//setBounds(x1,y1, x2, y2) 영역 지정
backImg.setBounds(0, 0, width, height);
backImg.draw(canvas);//이미지를 캔버스에 출력시킴
//비행기 출력
gunship.setBounds(x, y, x+gunshipWidth, y+gunshipHeight);
gunship.draw(canvas);
//적 출력
if(isHit){ //폭발 상태
//폭발 이미지 출력
explosure.setBounds(hx-20, hy-20, hx +hitWidth+20, hy+hitHeight);
explosure.draw(canvas);
try{
Thread.sleep(200);
}catch (Exception e){
e.printStackTrace();
}
isHit=false;//폭발 하지 않은 상태로 전환
}else{
//폭발하지 않은 상태
enemy.setBounds(ex, ey, ex+enemyWidth, ey+enemyHeight);
enemy.draw(canvas);
}
//총알 출력
for( int i=0; i<mlist.size(); i++){
Missile m=mlist.get(i);//i번째 총알
//총알 이미지의 출력범위
missile.setBounds(m.getMx(), m.getMy(), m.getMx()+missileWidth,
m.getMy()+missileHeight);
missile.draw(canvas); //총알 이미지 출력
}
//점수 출력
String str ="Point : "+point;
Paint paint =new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(25);//폰트 사이즈
//텍스트 출력 drawText(문자열 , x, y, 페인트 객체)
canvas.drawText(str, 0, 30, paint);
}
//키이벤트 처리
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_LEFT:
x -=5;
x =Math.max(0, x); //큰값
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
x +=5;
x =Math.min(width-gunshipWidth, x); //작은 값
break;
}
postInvalidate();//그래픽 갱신 요청 =>다시 onDraw() 호출됨
return super.onKeyDown(keyCode, event);
}
@Override
public void run() {
//적 좌표
while (true){
ex -=3;
if(ex < 0){
ex =width - enemyWidth;
}
//총알 좌표
for(int i=0; i<mlist.size(); i++){
Missile m=mlist.get(i);//i번째 총알
m.setMy(m.getMy()-5); //y좌표 감소 처리
if(m.getMy() <0){
mlist.remove(i); //리스트에서 제거
}
//충돌여부 판정
//적의 사각영역
Rect rect1 =new Rect(ex, ey, ex+enemyWidth, ey+enemyHeight);
//총알 사각영역
Rect rect2=new Rect(m.getMx(), m.getMy(),
m.getMx()+missileWidth, m.getMy()+missileHeight);
if(rect1.intersect(rect2)){ //겹친 부분이 있으면
hit.start(); //폭발음 플레이
isHit=true; // 폭발 상태로 변경
point +=100; //점수 증가
hx=ex; //폭발한 좌표 저장
hy=ey;
mlist.remove(i); //총알 리스트에서 제거
ex=width-enemyWidth; //적 좌표 초기화
}
}
try{
Thread.sleep(30);
}catch (Exception e){
e.printStackTrace();
}
postInvalidate();//그래픽 갱신 요청 =>다시 onDraw() 호출됨
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
isFire =true; //발사 상태로 전환
fire.start(); //사운드 플레이
//총알 객체 생성
Missile ms =new Missile(x +gunshipWidth/2, y);
mlist.add(ms); //리스트에 추가
return super.onTouchEvent(event);
}
}
}
댓글 ( 4)
댓글 남기기