728x90
SMALL
1.MVC 패턴 구현 프로그램 작성
1. 패키지 만들기
model - data
view - 입력,출력(사용자)
controller_로직
2.GAME Interface 작성
* 인터페이스를 구현하는 클래스에서 공통적으로 구현해야 하는 기능 정의
- 1. 메뉴 출력
- 2. 캐릭터 생성
- 3. 전투 모드
- 4. 상대 캐릭터 생성
- 5. 내 캐릭터 상태 확인
[controller 인터페이스 구현하기]
<GameInterface.java>
package com.smhrd.controller;
import com.smhrd.model.Charac; //ctrl+shift+o 하면 인폴트되면서 Charac 오류 사라짐
//게임을 만들기위한 틀
//1.게임 내에 구현해야하는 기능 정의 (로직 x)
//2.기능을 구현할 메서드의 이름 정의
public interface GameInterface {
//인터페이스는 추상메서드, 상수만 정의가능
public static final int a =10;
int b =10; //자동으로 public static final 키워드가 작성됨
//인터페이스 안에는 접근제한자를 public 만 작성 가능
//메뉴출력, 캐릭터생성, 전투모드, 상대캐리터생성, 내캐릭터상태확인
//1.메뉴 출력
public abstract void printMenu();
//2. 내 캐릭터 생성
//1,2번 중에 사용자가 선택 -> 선택한 캐릭터를 생성하여 반환
//생성될 캐릭터 -> 라이언, 춘식이
public abstract Charac myCharac(int select);
//3.상대방 캐릭터 생성
//내캐릭터가 무서인지에 따라서 상대방 캘릭터는 다른 캐릭터로 결정
//ex) 내캐릭터(춘식) -> 상대캐릭터(라이언)
public abstract Charac oppCharac(Charac myCharac);
//4. 전투모드
//내캐릭터가 공격/방어 선택 ->죽은캐릭터가 있는 지 반환 -> 또 공격/방어 결정
public abstract boolean battle(Charac myC, Charac oppC, int ad);
//인터페이스 안에서 메서드 선언(pubic abstract 키워드 작성이 기본 -> 안써도 됨)
//5. 내 캐릭터 상태확인
public abstract void checkMyC(Charac myC);
}
3. 캐릭터 추상클래스 작성
* 추상클래스를 상속받는 클래스에서 공통적으로 사용해야 하는 기능 정의
- 1. 필드(타입, 레벨, 체력, 경험치, 공격력, 방어력)
- 2. 메서드(캐릭터 정보 가져오기, 공격하기, 방어하기, 스킬사용하기, 캐릭터 아스키 아트 출력하기, 레벨업하기)
4. 캐릭터 클래스 작성(춘식/라이언)
타입: 춘식 | 타입: 라이언 |
레벨: 1 | 레벨: 1 |
체력: 20 | 체력: 20 |
경험치: 0 | 경험치:0 |
공격력: 9 | 공격력:10 |
방어력:7 | 방어력: 5 |
춘식이 아스키 출력하기 | 라이언 아스키 출력하기 |
<Charac.java>
package com.smhrd.model;
public abstract class Charac {
//추상메서드가 하나라도 있으면 -> 추상클래스
//추상메서드 없더라도 abstract 작성하면 -> 추상클래스
//추상클래스로는 객체 생성 불가능
//캐릭터들의 공통 속성
private String type; //춘식/라이언
private int level; //레벨
private int hp; //체력
private int xp; //경험치
private int atk; //공격력
private int def; //방어력
//생성자: 객체 생성
//추상클래스 -> 객체 생성 불가능
//추상클래스 내에 생성자 작성은 가능(객체 생성x, 속성 초기화용 사용)
//레벨, 체력, 경험치를 동일한 값을 가지게 초기화
//타입, 공격력, 방어력 -> 사용자가 정의한 값으로 초기화
public Charac(String type, int atk, int def) {
this.type=type;
//level,hp,xp 모든 캐릭터 동일
this.level=1;
this.hp = 50;
this.xp =0;
this.atk = atk;
this.def =def;
}
//캐릭터들의 공통 기능(메서드)
//1. 캐릭터 속성(타입, 레벨, 체력...)확인/가지고 올 수 있는 메서드
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getXp() {
return xp;
}
public void setXp(int xp) {
this.xp = xp;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
//2.공격
//누구를 공격하는지 명시, 상대방에게 데미지를 입혀야 함
public void attack(Charac oppC) {
System.out.println(this.type+"이 "+oppC.getType()+"을 공격!");
//내공격력이 상대방 방어력보다 낮으면 공격 불가능
//공격: 상대방현재체력- 내공격력+상대방 방어력
if(this.getAtk()>=oppC.getDef()) {
oppC.setHp(oppC.getHp() - this.getAtk()+ oppC.getDef());
}
}
//3.방어
//내캐릭터가 방어할때 출력
public void defence() {
System.out.println(this.type+"가 방어!");
}
//4.스킬사용
//내공격력에서 +5만큼 데미지 입힉
public void skill(Charac oppC) {
System.out.println(this.type+"이 "+oppC.getType()+"에게 스킬사용!");
//내공격력이 상대방 방어력보다 낮으면 공격 불가능
//공격: 상대방현재체력- 내공격력+상대방 방어력
if(this.getAtk()>=oppC.getDef()) {
oppC.setHp(oppC.getHp() - (this.getAtk()+5)+ oppC.getDef());
}
}
//5.라벨업
//경험치가 30보다 높아지면 레벨업
//레벨+1, 경험치-30, 체력(꽉채워줌(50)), 공격력+5, 방어력+5
public void levelUp(){
System.out.println("레벨이 올랐습니다!");
this.setLevel(this.getLevel()+1);
//this.level+=1;
this.setXp(this.getXp()-30);
this.setHp(50);
this.setAtk(this.getAtk()+5);
this.setDef(this.getDef()+5);
}
//생성한 캐릭터의 아스키 아트 출력
//캐릭터마다 출력되는 형태가 다르기 때문에
//상속받은 클래스내에서 재정의
public abstract void printASCII();
}
<Chunsik.java>
package com.smhrd.model;
public class Chunsik extends Charac{
//타입,레벨,체력,경험치,공격력,방어력 초기화
//레벨,체력,경험치 ->모든 캐릭터가 초기값이 동일 -> Charac 정의
//타입(춘식), 공격력(9), 방어력(7)
public Chunsik() {
//상위클래스가 가지고 있는 속성 초기화
// -> 상위클래스의 생성자를 호출
//상위클래스(Charac)생성자를 호출,
//지금 생성되는 춘식이의 객체의 타입, 공격력, 방어력을 초기화할 값을 보내줌!
super("춘식이", 9 ,7);
}
@Override //Add unimplemented methods를 클릭하면 @override 가 추가된다
public void printASCII() {
System.out.println("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMMWKkkOOOOkkkkkkkOOOk0NMMMMM\r\n"
+ "MMMMMMMMMMMMMM0ox0OkkkO0000OkkxkkddXMMMM\r\n"
+ "MMMMMMMMMMMMNOok0K0000000000000000ddKMMM\r\n"
+ "MMMMMMMMMMMNxdOKKKKK0KKKK0000000000xo0MM\r\n"
+ "MMMMMMMNXWWxo0KKKKkddk0K000kx0000000xdKM\r\n"
+ "MMMMMWOddxOoxK0KKKxcldkkkOOolOK00000OoOM\r\n"
+ "MMMW0xdxkxclOK0KKKklcokOkkook00000000okM\r\n"
+ "MMMOlkKxlxdckK0KK0kl:oxdxklck0000000OokM\r\n"
+ "MMMklk0klxOld0KK00000kl:ldkO00000000doKM\r\n"
+ "MMMNOkxclOKkldOK0K00K0xdk000000000Odo0MM\r\n"
+ "MMMMMMW0ocll:;:llodO000O0000000OxolxXMMM\r\n"
+ "MMMWXKko:;;:::::;;;:ccodddddddddddodXMMM\r\n"
+ "WKxlc:;::::::::::::::;:oxxxkkOO000OodNMM\r\n"
+ "Kc,:::::;,,;;:::::::::;cx00kookOOO0dl0MM\r\n"
+ "Kc,::::;',;;::::::::;;;;lOxcokOOOOOooXMM\r\n"
+ "WKdlc::,';:;::::;;:;;;:;cxl:xOOkxdod0MMM\r\n"
+ "MMMWNXK0d:;,,,,,,,,;;;::ldxdxxxxxk0NMMMM\r\n"
+ "MMMMMMMMMN0OkkkkkO000KXNWMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM");
}
}
<Ryan.java>
package com.smhrd.model;
public class Ryan extends Charac {
public Ryan() {
super("라이언", 10, 5);
}
@Override
public void printASCII() {
System.out.println("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMMWNXNWWMMMMMMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMW0kO0KXNWWMMMMMMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMWXOkdxkO0KKKXXNNWWMMMMMMMMMMMM\r\n"
+ "MMMMMMMMWKdclodxkO0KKKKKXXXXXNWMMMMMMMMM\r\n"
+ "MMMMMMMWOc;codxkkolloox0XXXXXXNWMMMMMMMM\r\n"
+ "MMMMMMM0c,;cldxkOOoloodOXXXK0KXNMMMMMMMM\r\n"
+ "MMMMMMNd,,;cloxkOkook0KKKXXOdod0WMMMMMMM\r\n"
+ "MMMMMMKl,,;:lodxkO000KXOdkKKxod0WMMMMMMM\r\n"
+ "MMMMMMXl,;;::loxxOkxx0WKoxXKkk0XWMMMMMMM\r\n"
+ "MMMMMMWk:;;;::lodxdoldO0KNXK000NMMMMMMMM\r\n"
+ "MMMMMMMNkc;;::cclooooddddkOOOOXWMMMMMMMM\r\n"
+ "MMMMMMMMWKxl;;:clllooooddxxxOXWMMMMMMMMM\r\n"
+ "MMMMMMMMMMWk;;okOkdlllllodkKNMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMXl,:x0KKOkxkO000XWMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMWk;,cx0K0000OkOkOKNMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMNo,,:dO0000K0kxdx0NMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMNkdddk0XXKKXXKKKKNWMMMMMMMMMMMM\r\n"
+ "MMMMMMMMMMMMMMWWMWWWWMMMMMMMMMMMMMMMMMMM");
}
}
<Test.java>
package com.smhrd.view;
import com.smhrd.model.Charac;
import com.smhrd.model.Chunsik;
import com.smhrd.model.Ryan;
public class Test {
public static void main(String[] args) {
//배열/arrayList안에 춘식, 라이언을 같이 넣을 수 있다
//배열/arraylist 기본적으로 같은 타입만 넣을 수 있어요
int[]arr = new int[10]; //정수형만 들어갈 수 있음
Chunsik[]css=new Chunsik[4];
//춘식(캐릭터 상속받음 ) ->캐릭터 타입을 바꿀수 있음(업캐스팅)
Chunsik cs = new Chunsik();
cs.printASCII();
//라이언(캐릭터 상속받음) -> 캐릭터 타입으로 바꿀수있음(업케스팅)
Ryan r = new Ryan();
r.printASCII();
Charac[] cr = new Charac[2]; //Object[]cr = new Object[2];
//업캐스팅은 자동형변환(따로 지정하지 않아도 됨)
cr[0]=cs;
cr[1]=r;
cr[0].printASCII();
//Chunsik c = (Chunsik)cr[0];
//c.printASCII();
//추상클래스 절대 객체 생성 불가능 -> 컴파일오류
//new Charac("a",20,20);
}
}
<GameMain>
package com.smhrd.view;
import java.util.Scanner;
import com.smhrd.controller.GameController;
import com.smhrd.model.Charac;
public class GameMain {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// msin 실행되게 되면은
// 사용자가 메뉴(캐릭터 생성, 전투, 내캐릭터 확인, 종료)를 선택할 수 있게 함
// ->controller - prinMenu()
// 1.GameController 객체 생성 후 참조값 저장하고있는 레퍼런스 변수 선언
GameController gc = new GameController();
// 메뉴가 반복적으로 출력 -> 사용자는 1~4 숫자 입력
// 1 -> 내 캐릭터 생성! 2-> 전투모드! 3->내 캐릭터 확인! 4 ->반복문 종료
// 내캐랙터(라이언/춘식)저장 공간
Charac myC = null;
while (true) {
gc.printMenu();
int menu = sc.nextInt(); // 1~4
if (menu == 1) {
System.out.println("내 캐릭터 생성!");
if (myC == null) {
System.out.println("[1]라이언 [2]춘식이");
int select = sc.nextInt();
myC = gc.myCharac(select);// 캐릭터생성
gc.checkMyC(myC);
}else {
System.out.println("이미 생성된 캐릭터가 있습니다!");
}
// 1. 캐릭터는 딱 1개만 생성할 수 있음!
// 만약, 캐릭터가 생성된 상태라면 "이미 생성된 캐릭터가 있습니다!" 출력
// 캐릭터가 생성되지 않았을 때
// [1]라이언 [2]춘식이 선택하게 함
// Controller - myCharac 캐릭터 생성
// 생성된 캐릭터의 타입만 출력
// ckeckMyC -> 전체 속성 출력
} else if (menu == 2) {
System.out.println("전투모드!");
if(myC==null) {
System.out.println("캐릭터를 생성하세요!");
}else {//캐릭터가 생성되어 있는 경우
//1. 상대방 캐릭터 생성
//내 캐릭터(춘식) -상대방(라이언), 내 캐릭터(라이언)-상대방(춘식)
Charac oppC = gc.oppCharac(myC);
while(true) {
System.out.println("[1]공격 [2]방어");
int ad = sc.nextInt();
// (내캐릭터, 상대방캐릭터, 공격/방어)
boolean cont = gc.battle(myC, oppC, ad);
//cont가 true 이면 계속 전투
//cont가 false이면 전투 중단 -> 반복문 중단
if(!cont) {
System.out.println("전투중단");
break;
}
}
}
} else if (menu == 3) {
System.out.println("내 캐릭터 확인!");
if(myC!=null) {//캐릭터가 생성되어있을 때에만
gc.checkMyC(myC);
}
} else {// 4
System.out.println("게임 종료!");
break;
}
}
}
}
<GameController>
package com.smhrd.controller;
import com.smhrd.model.Charac;
import com.smhrd.model.Chunsik;
import com.smhrd.model.Ryan;
public class GameController implements GameInterface {
// GameController 아래 빨간줄 떳을때 add unimplemented methods 누르면 아래 생성
@Override
public void printMenu() {
System.out.print("[1]내 캐릭터 생성 [2]전투모드 [3]내 캐릭터 확인 [4]종료 ");
}
// 내 캐릭터 생성
@Override
public Charac myCharac(int select) {
// 1번 선택 ->라이언 객체 생성
// 2번 선택 -> 춘식 객체 생성
// 생성된 캐릭터 반환
Charac myC = null; // 라이언/춘식 생성된 객체 담을 용도
if (select == 1) {
// 라이언 객체 생성
myC = new Ryan(); // 업캐스팅(자동형변환)
} else if (select == 2) {
// 춘식 객체 생성
myC = new Chunsik(); // 업캐스팅(자동형변환)
}
// 생성된 캐릭터의 아스키아트 출력
myC.printASCII();
// 생성된 객체 반환
return myC;
}
@Override
public Charac oppCharac(Charac myCharac) {
// 내 캐릭터 어떤 타입인지
// myCharac가 원래 라이언 타입 이었니?
// 원래 라이언 -> true
// 원래 라이언타입이 아니었다 -> false
Charac opp = null;
if (myCharac instanceof Ryan) {
// 춘식이 생성
opp = new Chunsik();
System.out.println("야생의 춘식이가 나왔습니다!");
} else if (myCharac instanceof Chunsik) {
// 라이언 생성
opp = new Ryan();
System.out.println("야생의 라이언이 나왔습니다!");
}
return opp;
}
// 한번의 공격 - 방어
// 한캐릭터라도 죽은 경우에는 -> flase
// 계속 전투를 할 수 있는 경우(아무도 죽지 않은 경우)에는 ->true
@Override
public boolean battle(Charac myC, Charac oppC, int ad) {
// 1. 사용자가1 -> 공격
// 내캐릭터는 상대방 공격, 상대방은 방어
// 2. 사용자가 2 -> 방어
// 상대방은 내캐릭터를 공격, 내 캐릭터는 방어
// 내캐릭터의 체력(hp)와 상대방캐릭터의 체력(hp)을 출력
if (ad == 1) {// 내캐릭터가 공격
myC.attack(oppC);
oppC.defence();
} else if (ad == 2) {
myC.defence();
oppC.attack(myC);
}
System.out.println("내캐릭터 HP : " + myC.getHp());
System.out.println("상대캐릭터 HP : " + oppC.getHp());
//1. 내캐릭터가 죽었는지(myC HP <=0)
//내캐릭터의 경험치 -10 감소
//전투종료
//2. 상대방캐릭터가 죽었는지(oppC HP <=0)
//내캐릭터의 경험치를 +10증가
//만약에 경험치를 10 증가시킨후 내 경험치가 30이상이 되면은
// ->레벨1증가
boolean cont = true; //전투를 계속 할 수 있는지 없는지
if(myC.getHp()<=0) {
if(myC.getXp()>=10) {
myC.setXp(myC.getXp()-10);
}else {//경험치가 10보다 작을 때는 무조건 0으로 수정
myC.setXp(0);
}
System.out.println(myC.getType()+"이 죽었습니다!");
cont = false;
}else if(oppC.getHp()<=0) {
myC.setXp(myC.getXp()+10);
if(myC.getXp()>=30) {
myC.levelUp();
}
System.out.println(oppC.getType()+"이 죽었습니다!");
cont = false;
}
//캐릭터중 하나라도 죽은 캐릭터가 있으면 false 반환
//죽은 캐릭터가 없으면 true반환
return cont;
}
// 내캐릭터 현재 상태 출력
// 타입, hp,xp,atk...
@Override
public void checkMyC(Charac myC) {
System.out.println("내 캐릭터 타입 : " + myC.getType());
System.out.println("내 캐릭터 레벨 : " + myC.getLevel());
System.out.println("내 캐릭터 HP : " + myC.getHp());
System.out.println("내 캐릭터 XP : " + myC.getXp());
System.out.println("내 캐릭터 공격력 : " + myC.getAtk());
System.out.println("내 캐릭터 방어력 : " + myC.getDef());
}
}
728x90
LIST
'JAVA' 카테고리의 다른 글
반복문(for문) 예제 (0) | 2022.09.04 |
---|---|
JDBC응용 (0) | 2022.09.01 |
[Java] 자료구조(선형구조와 비선형구조) (0) | 2022.08.28 |
[Java] 상속의 개념과 코드 예제 (0) | 2022.08.27 |
[JAVA] 객체, 클래스,인스턴스의 차이 및 예시 (0) | 2022.08.27 |