Java - 기본기

클래스, 메서드, 생성자, 상속 정리 : 나만의 StarCraft

TerianP 2022. 3. 1.
728x90

이번 글에서는 지난 번까지 정리해두었던 메소드와 생성자, 상속에 대해서 정리해볼까 합니다.

또한 이러한 부분을 확실하게!! 즐겁게 정리해보기위해 StarCraft 를 이용해서 유닛을 구현하고, 정리해볼까 합니다.

 

물론 복잡하게는 하지 못하고...ㅠㅠ 지금까지 배운 것들을 최대한 활용해서 간단하게만! 구현해볼 생각입니다.

 

1. StarCraft.class

- 먼저 상속을 위해 사용할 상위 클래스인 StarCraft 를 만들었습니다.

- 이 클래스에서는 하위 유닛 - 객체- 가 모두 갖고 있을 만한 속성들에 대해서 정해두었습니다.

- status 의 경우 StarCraft 객체를 매개변수로 받고 있습니다. 앞으로 아래 생성되는 Tank, Hydralisk 모두 StarCraft 클래스를 상속받고 있기 때문에 status를 문제없이 사용할 수 있습니다.

  • 이는 곧 부모 클래스의 참조 변수에 자식 클래스의 참조 값을 담는것이 가능하기 때문이다.
  • StarCraft starcraft = new Tank() 나 new Hydralisk() 가 가능!!
package Practice;

public class StarCraft {
	String name;
	String weapon;
	int x, y; // 위치
	int hp, at_point, de_point; // hp, 공격력, 방어력
	int mv_spd, at_spd; // 이동속도, 공격속도
	
	
	// 정보 출력을 위한 메소드
    // 메소드에서는 StarCfaft 객체를 매개변수로 갖는다.
	public void status(StarCraft unit) {
		System.out.println(unit+" 의 현재 정보를 출력합니다");
		System.out.println("이름 : "+unit.name);
		System.out.println("hp : "+unit.hp);
		System.out.println("공격력 : "+unit.at_point);
		System.out.println("방어력 : "+unit.de_point);
		System.out.println("이동 속도 : "+unit.mv_spd);
		System.out.println("공격 속도 : "+unit.at_spd);
	}
}

2. Tank.class

요 친구 맞습니다

- 테란의 시즈 탱크 클래스입니다!

- 시즈 탱크는 다른 유닛과는 다른 특별한 기능 - 메소드 - 를 갖습니다. 바로 모드 전환입니다.

- 시즈 탱크는 시즈 모드와 일반 모드를 전환함으로써 기존에 갖고있던 공격력이나 이동 속도 등이 변화하게 됩니다.

package Practice;

public class Tank extends StarCraft{
	
	boolean mod; // 시즈모드는 boolean 을 사용하여 true면 공성모드 false면 일반모드
	
	Tank(){ // 기본생정자를 통해서 Tank 인스턴스 생성시 변수 값 초기화
		System.out.println("시즈 탱크 등장!");
		this.name = "시즈 탱크";
		this.weapon = "아크라이트 포 && 아크라이트 중격포";
		this.x = 50;
		this.y = 50;
		this.hp = 150;
		this.at_point = 40;
		this.de_point = 1;
		this.mv_spd = 2;
		this.at_spd = 50;
		boolean mod = false;

	}
	
	void attack(StarCraft unit) {
		System.out.println(unit+" 를 공격합니다!");
		unit.hp -=at_point; // unit 의 hp에서 전차의 공격력만큼 감소
		if(mod == true) {
			System.out.println("시즈 모드로 공격!! 일부는 펑펑펑");
		}else {
			System.out.println("일반 모드로 공격!! 일부는 퉁퉁퉁");
		}
	}
	
	// 탱크의 스킬임으로 탱크 객체와 boolean 을 받겠습니다.
	void changeMod(Tank tank, boolean mod) { 
		if(mod == true) {
			System.out.println("시즈 모드로 전환합니다");
			System.out.println("전환중....");
			System.out.println("전환 완료! 능력치 변경에 주의해주세요");
			
			this.at_point += 20;
			this.mv_spd = 0;
			this.at_spd += 15;
			this.mod = mod;
		}else {
			System.out.println("일반 모드로 전환합니다");
			System.out.println("전환중....");
			System.out.println("전환 완료! 능력치 변경에 주의해주세요");
			
			this.at_point -= 20;
			this.mv_spd = 2;
			this.at_spd -= 15;
			this.mod = mod;
		}
	}
}

 


3. Hydralisk.class

요 친구 입니다!

- 히드라리스크도 마찬가지로 StartCraft 클래스를 상속받습니다.

- 기본 생성자를 이용해 기본 히드라를 만들 수 있도록하였고, String 매개변수를 갖는 생성자를 하나더 만들어 객체 생성시 해당 생성자를 사용하면 기존 능력치에서 추가된 수치를 갖는 영웅 히드라가 만들어집니다.

- 히드라는 탱크와는 다르게 버로우 스킬을 갖습니다. 버로우시 무적 상태가 되지만(실제로는 무적이 아니고, 시야에서만 안보이는 것이지만 여기서는 무적으로 만들어보았습니다) 공격을 할 수 없게 됩니다.

 

package Practice;

public class Hydralisk extends StarCraft{ // 스타크래프트 클래스를 상속	
	
	boolean burrow; 
	// 히드라는 탱크와 비슷하게 잠복하는 능력을 갖습니다.
	// 한번 잠복하는 경우 더이상 공격할 수 없으며 무적상태가 됩니다.

	Hydralisk(){
		System.out.println("히드라리스크 등장!");
		this.name = "히드라리스크";
		this.weapon = "바늘 가시뼈";
		this.x = 55;
		this.y = 60;
		this.hp = 80;
		this.at_point = 10;
		this.de_point = 0;
		this.mv_spd = 3;
		this.at_spd = 30;
		this.burrow = false;
	}
	
	Hydralisk(String name){
		// 영웅 히드라를 만드는 생성자입니다.
		// 이름을 주면 해당 이름으로 기본 능력치에서 일정한 수치만큼 뻥튀기된 영웅 히드라가 만들어집니다
		
		this(); // 기본생성자로 변수값 초기화
		
		// 이후 초기화된 값 + 1 ~ 10 까지의 랜덤한 값 추가
		this.name = name;
		this.hp += (int)(Math.random()*10)+1;
		this.at_point +=(int)(Math.random()*10)+1;
		this.de_point +=(int)(Math.random()*10)+1;
		this.at_spd +=(int)(Math.random()*10)+1;
		this.mv_spd +=(int)(Math.random()*10)+1;
		System.out.println("영웅 히드라 "+name+ "가 등장했습니다");
	}
	
	void attack(StarCraft unit){
		if(this.burrow == false) {
			System.out.println(unit + " 를 공격합니다");
			System.out.println("가시뼈 슉슉슉");
			unit.hp -= this.at_point;
		}else {
			System.out.println("버로우 상태에서는 공격할 수 없습니다");
		}
	}
	
	// 히드라의 능력임으로 매개변수는 히드라 객체와 boolean 타입을 받겠습니다.
	void change_form(Hydralisk h, boolean burrow) { 
		if(burrow == true) {
			System.out.println("히드라가 땅속으로 잠복합니다");
			System.out.println("능력치 변경에 주의해주세요");
			
			this.burrow = true;
			this.hp = 999999999; // int형 최대값
			this.at_point = 0;
			this.de_point = 0;
			this.mv_spd = 0;
			this.at_spd = 0;
			
		}else {
			System.out.println("히드라가 잠복에서 벗어납니다");
			System.out.println("능력치 변경에 주의해주세요");
			
			this.burrow = false;
			this.hp = 80;
			this.at_point = 10;
			this.de_point = 0;
			this.mv_spd = 3;
			this.at_spd = 30;
		}
	}
}

4. Game.class

- 실제로 게임을 해보는 클래스입니다.

- 각 클래스를 사용해서 공격이 되는지, 스킬을 잘 쓸 수 있는지 확인해보겠습니다.

 

1) round 1

- 히드라와 탱크의 공격 메소드 동작 확인 => 히드라와 탱크가 서로를 공격하고, 공격한 후 hp가 제대로 달았는지 확인해보겠습니다.

- 아래에서 확인할 수 있는 것은 메서드에 들어오는 매개변수가 객체라면, 메서드에서는 해당 객체의 주소값을 그대로 참조하여 메서드 안에서 동작하는 것을 알 수 있다.

System.out.println("------- round 1--------");
Tank tank = new Tank();
tank.status(tank);
		
System.out.println("-----------------------");
Hydralisk hydra = new Hydralisk();
hydra.status(hydra);
		
System.out.println("-----------------------");
tank.attack(hydra);
hydra.attack(tank);
		
System.out.println("-----------------------");
tank.status(tank);
System.out.println("-----------------------");
hydra.status(hydra);
        
        
        
##### 결과 #####
------- round 1--------
시즈 탱크 등장!
Practice.Tank@32d2fa64 의 현재 정보를 출력합니다
이름 : 시즈 탱크
hp : 150
공격력 : 40
방어력 : 1
이동 속도 : 2
공격 속도 : 50
-----------------------
히드라리스크 등장!
Practice.Hydralisk@3e57cd70 의 현재 정보를 출력합니다
이름 : 히드라리스크
hp : 80
공격력 : 10
방어력 : 0
이동 속도 : 3
공격 속도 : 30
-----------------------
Practice.Hydralisk@3e57cd70 를 공격합니다!
일반 모드로 공격!! 일부는 퉁퉁퉁
Practice.Tank@32d2fa64 를 공격합니다
가시뼈 슉슉슉
-----------------------
Practice.Tank@32d2fa64 의 현재 정보를 출력합니다
이름 : 시즈 탱크
hp : 140
공격력 : 40
방어력 : 1
이동 속도 : 2
공격 속도 : 50
-----------------------
Practice.Hydralisk@3e57cd70 의 현재 정보를 출력합니다
이름 : 히드라리스크
hp : 40
공격력 : 10
방어력 : 0
이동 속도 : 3
공격 속도 : 30

 

2) round 2

- 이번에는 히드라와 탱크의 스킬을 사용하여 각각 시즈 모드로 변환, 버로우 모드를 사용해보겠습니다.

- 이번에는 객체의 메소드가 정상적으로 동작하는것을 확인 할 수 있었습니다.

System.out.println("------- round 2--------");
		
Tank tank2 = new Tank();
tank2.changeMod(tank2, true);
		
System.out.println("-----------------------");
Hydralisk hydra2 = new Hydralisk();
hydra2.change_form(hydra2, true);
		
System.out.println("-----------------------");

tank2.attack(hydra2);
System.out.println("-----------------------");
hydra2.attack(tank2);
		
System.out.println("-----------------------");
tank2.status(tank2);
System.out.println("-----------------------");
hydra2.status(hydra2);
        
##### 결과 #####
------- round 2--------
시즈 탱크 등장!
시즈 모드로 전환합니다
전환중....
전환 완료! 능력치 변경에 주의해주세요
-----------------------
히드라리스크 등장!
히드라가 땅속으로 잠복합니다
능력치 변경에 주의해주세요
-----------------------
Practice.Hydralisk@9a7504c 를 공격합니다!
시즈 모드로 공격!! 일부는 펑펑펑
-----------------------
버로우 상태에서는 공격할 수 없습니다!
-----------------------
Practice.Tank@2c039ac6 의 현재 정보를 출력합니다
이름 : 시즈 탱크
hp : 150
공격력 : 60
방어력 : 1
이동 속도 : 0
공격 속도 : 65
-----------------------
Practice.Hydralisk@9a7504c 의 현재 정보를 출력합니다
이름 : 히드라리스크
hp : 999999939
공격력 : 0
방어력 : 0
이동 속도 : 0
공격 속도 : 0

 

3) round 3

- 마지막으로 영웅 히드라를 만들어서 탱크를 공격해보도록 하겠습니다.

- 무려 공격력 20짜리 영웅 히드라가 만들어졌습니다! 

System.out.println("------- round 3--------");
		
Hydralisk hydra_Hero = new Hydralisk("추적 도살자");
hydra_Hero.status(hydra_Hero);
		
System.out.println("-----------------------");

Tank tank3 = new Tank();
tank3.status(tank3);
		
System.out.println("-----------------------");

hydra_Hero.attack(tank3);
System.out.println("-----------------------");

tank3.status(tank3);


------- round 3--------
히드라리스크 등장!
영웅 히드라 추적 도살자가 등장했습니다
Practice.Hydralisk@9a7504c 의 현재 정보를 출력합니다
이름 : 추적 도살자
hp : 83
공격력 : 20
방어력 : 6
이동 속도 : 10
공격 속도 : 32
-----------------------
시즈 탱크 등장!
Practice.Tank@587d1d39 의 현재 정보를 출력합니다
이름 : 시즈 탱크
hp : 150
공격력 : 40
방어력 : 1
이동 속도 : 2
공격 속도 : 50
-----------------------
Practice.Tank@587d1d39 를 공격합니다
가시뼈 슉슉슉
-----------------------
Practice.Tank@587d1d39 의 현재 정보를 출력합니다
이름 : 시즈 탱크
hp : 130
공격력 : 40
방어력 : 1
이동 속도 : 2
공격 속도 : 50

5. 마치며 & 아쉬운 점

이렇게 클래스와 메소드, 기본 생성자와 매개변수가 있는 생성자, 메소드와 참조변수 등 공부한것들을 총동원하여 간단하게 정리해보았습니다.

사실은 부족한 부분이 많습니다. 공격 할 때 위치를 확인하고 사거리에 맞춰서 공격해야하고, 또 피해를 받는 쪽의 방어력도 계산하지 않았습니다. 이러한 부분은 조금 더 공부하고, 로직을 짜보면서 나중에라도 만들어볼까합니다!

댓글