유니티3D 프로그래밍
C# 1주차 5일 연습 과제 (21.03.12) 본문
SCV 자원 캐기
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class App
{
public App()
{
//Unit타입일뿐 unit변수의 값은 SCV의 인스턴스이다
SCV unit = new SCV();
unit.SetPosition(2, 4);
float[] positions = unit.GetPosition();
float x = positions[0];
float y = positions[1];
Console.WriteLine("미네랄 위치로 이동합니다 : {0} {1}", x, y);
unit.GatherResource(SCV.eResource.Mineral);
Console.WriteLine();
unit.SetPosition(9, 12);
positions = unit.GetPosition();
x = positions[0];
y = positions[1];
Console.WriteLine("가스 위치로 이동합니다 : {0} {1}", x, y);
unit.GatherResource(SCV.eResource.Gas);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class SCV : Unit
{
public enum eResource
{
Mineral,
Gas
}
//생성자
public SCV()
{
Console.WriteLine("SCV 생성자 호출");
}
public void GatherResource(eResource resource)
{
if(resource == eResource.Mineral)
{
Console.WriteLine("미네랄을 채취합니다.");
}
if(resource == eResource.Gas)
{
Console.WriteLine("가스를 채취합니다.");
}
}
}
}
SCV를 지정한 위치로 이동해 미네랄과 가스를 캐는 방식
SCV 건물 건설
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class App
{
public App()
{
//Unit타입일뿐 unit변수의 값은 SCV의 인스턴스이다
SCV unit = new SCV();
unit.SetPosition(2, 4);
float[] positions = unit.GetPosition();
float x = positions[0];
float y = positions[1];
Console.WriteLine("위치로 이동합니다 : {0} {1}", x, y);
Console.Write("건설할 건물을 입력하세요. : ");
string input = Console.ReadLine();
Console.WriteLine(unit.Build(input));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Unit
{
private float x;
private float y;
//생성자
public Unit()
{
Console.WriteLine("Unit 생성자 호출");
}
public float[] GetPosition()
{
float[] arr = new float[2];
arr[0] = this.x;
arr[1] = this.y;
return arr;
}
public void SetPosition(float x, float y)
{
this.x = x;
this.y = y;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Terran : Unit
{
public enum eBuild
{
CommandCenter,
SupplyDepot,
VespeneGas,
Barracks,
EngineeringBay,
Turret,
Academy,
Bunker,
Factory,
Armory,
Starport,
ScienceFacility
}
// 생성자
public Terran()
{
Console.WriteLine("Terran 생성자 호출");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class SCV : Terran
{
public enum eResource
{
Mineral,
Gas
}
//생성자
public SCV()
{
Console.WriteLine("SCV 생성자 호출");
}
public void GatherResource(eResource resource)
{
if(resource == eResource.Mineral)
{
Console.WriteLine("미네랄을 채취합니다.");
}
if(resource == eResource.Gas)
{
Console.WriteLine("가스를 채취합니다.");
}
}
public string Build(string build)
{
if(!Enum.IsDefined(typeof(eBuild), build))
{
return "없는 건물입니다.";
}
else
{
eBuild newBuild = (eBuild)Enum.Parse(typeof(eBuild), build);
foreach (eBuild build1 in Enum.GetValues(typeof(eBuild)))
{
if (build1 == newBuild)
{
return newBuild.ToString() + " 을/를 건설합니다.";
}
}
}
return null;
}
}
}
App 클래스에서 SCV 클래스를 호출하고 SCV 클래스는 Terran 클래스의 자식관계이며 Terran 클래스는 Unit 클래스의 자식관계다.
Unit 클래스에서는 스타크래프트 유닛의 공통적인 부분을 입력하고 Terran 클래스는 테란종족의 공통 부분 및 정보를 담당하고 SCV은 유닛 마다의 객체 정보를 담당한다.
Unit 클래스의 Position관련 메소드를 통해 건설할 부분으로 이동하고 App클래스에서 건설할 건물을 입력 받고 SCV 클래스의 Build를 통해 Terran클래스의 eBuild 객체에서 동일한 건물이 있으면 건물을 건설하고 없으면 "건물이 없습니다"를 출력한다.
Marine의 일정
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class App
{
public App()
{
Marine marine1 = new Marine();
Marine marine2 = new Marine();
marine1.name = "marine1";
marine2.name = "marine2";
//마린의 이동
marine1.SetPosition(3, 5);
float[] positions = marine1.GetPosition();
float x = positions[0];
float y = positions[1];
Console.WriteLine();
Console.WriteLine("마린이 이동합니다 : {0} {1}", x, y);
//적이 죽을때 까지 공격
while(true)
{
Console.WriteLine("적을 공격합니다. 적의 체력 : {0}", marine2.hp);
Console.WriteLine();
marine1.Attack(marine2);
if (marine2.hp <= 0)
{
break;
}
}
}
}
}
App 클래스에서 마린의 활동을 정의한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Unit
{
private float x;
private float y;
public string name;
public int hp;
public int damage;
public int shield;
public int attackRange;
public int mineral;
public int gas;
//생성자
public Unit()
{
Console.WriteLine("Unit 생성자 호출");
}
public float[] GetPosition()
{
float[] arr = new float[2];
arr[0] = this.x;
arr[1] = this.y;
return arr;
}
public void SetPosition(float x, float y)
{
this.x = x;
this.y = y;
}
public void Attack(Unit target)
{
//타깃에게 피해를 줍니다.
Console.WriteLine("{0}이(가) {1}을 공격합니다.", this.name, target.name);
target.Hit(this);
}
public void Hit(Unit unit)
{
if(this.shield - unit.damage < 0)
{
this.hp = this.hp + (this.shield - unit.damage);
}
else
{
this.hp -= 1;
}
Console.WriteLine("{0}가 피해를({1})을 받았습니다..", this.name, damage);
if (this.hp <= 0)
{
this.Die();
}
}
public void Die()
{
Console.WriteLine("{0}가 죽었습니다.", this.name);
}
}
}
Unit 클래스는 유닛들의 공통적인 특징을 정의한다. poistion 메소드들을 통해 위치를 지정하고 Attack과 Hit를 통해 공격에 관한 정보들을 정의한다. 스타의 게임 특성상 방어력의 크기만큼 공격력을 감소시켜서 맞기 때문에 맞는 유닛의 방어력과 공격하는 유닛의 공격력을 빼서 나오는 값 만큼 맞는 유닛의 체력을 감소시킨다.
만약 방어력이 데미지보다 높다면 1씩 데미지가 감소하게끔 만들었다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Terran : Unit
{
public enum eBuild
{
CommandCenter,
SupplyDepot,
VespeneGas,
Barracks,
EngineeringBay,
Turret,
Academy,
Bunker,
Factory,
Armory,
Starport,
ScienceFacility
}
// 생성자
public Terran()
{
Console.WriteLine("Terran 생성자 호출");
}
}
}
테란이라는 종족의 특성을 정의하는 Terran 클래스다. 현재 구현한 클래스들로는 테란 고유 특성을 정의하지 못했다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Marine : Terran
{
//생성자
public Marine()
{
Console.WriteLine("Marine 생성자 호출");
this.name = "Marine";
this.damage = 6;
this.hp = 40;
this.shield = 0;
this.attackRange = 4;
}
}
}
Marine 클래스는 marine 유닛을 정의하는 클래스로 생성자를 통해 마린의 기본 정보들을 설정한다.
엔지니어링 베이
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class App
{
public App()
{
//Unit타입일뿐 unit변수의 값은 SCV의 인스턴스이다
SCV scv = new SCV();
scv.SetPosition(2, 4);
float[] positions = scv.GetPosition();
float x = positions[0];
float y = positions[1];
Console.WriteLine("위치로 이동합니다 : {0} {1}", x, y);
Console.Write("건설할 건물을 입력하세요. : ");
string input = Console.ReadLine();
var terranBuild = scv.Build(input);
Marine marine = new Marine();
//엔지니어링 베이 건설
Console.WriteLine("현재 공격력 : {0}", marine.damage);
Console.WriteLine("공격력을 업그레이드 합니다.");
Console.WriteLine();
terranBuild.AttackUp(marine);
Console.WriteLine("현재 공격력 : {0}", marine.damage);
Console.WriteLine();
Console.WriteLine("현재 방어력 : {0}", marine.shield);
Console.WriteLine("방어력을 업그레이드 합니다.");
Console.WriteLine();
terranBuild.ShieldUp(marine);
Console.WriteLine("현재 방어력 : {0}", marine.shield);
}
}
}
scv가 지정한 위치로 이동해서 건물을 건설한다. 아직 위치의 정의가 제대로 되지 않았기 때문에 같은 자리에 건물을 또 올릴 수 있다.
엔지니어링 베이를 건설해서 공격력과 방어력을 업그레이드 한다.
scv.Build를 통해 엔지니어링베이 클래스를 호출하고 마린 클래스를 호출한다.
엔지니어링 베이 클래스의 매개변수에 Unit 클래스를 넣고 AttackUp이라는 메소드를 호출해서 마린 클래스의 데미지를 증가시킨다. 마찬가지로 방어력도 증가시킨다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class EngineeringBay : Terran
{
int attackUpgradeCount = 0;
int shieldUpgradeCount = 0;
//생성자
public EngineeringBay()
{
Console.WriteLine("EngineeringBay 생성자 호출");
this.damage = 6;
this.hp = 40;
this.shield = 0;
this.attackRange = 4;
}
public void AttackUp(Unit unit)
{
switch (attackUpgradeCount)
{
case 0:
if (unit.mineral >= 100 && unit.gas >= 100)
{
Console.WriteLine("무기가 한번 업그레이드 되었습니다.");
attackUpgradeCount++;
unit.SetUpgradeDamage();
unit.mineral -= 100;
unit.gas -= 100;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
case 1:
if (unit.mineral >= 175 && unit.gas >= 175)
{
Console.WriteLine("무기가 두번 업그레이드 되었습니다.");
attackUpgradeCount++;
unit.SetUpgradeDamage();
unit.mineral -= 175;
unit.gas -= 175;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
case 2:
if (unit.mineral >= 250 && unit.gas >= 250)
{
Console.WriteLine("무기가 세번 업그레이드 되었습니다.");
attackUpgradeCount++;
unit.SetUpgradeDamage();
unit.mineral -= 250;
unit.gas -= 250;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
default:
Console.WriteLine("최대 업그레이드 입니다.");
break;
}
}
public void ShieldUp(Unit unit)
{
switch (shieldUpgradeCount)
{
case 0:
if (unit.mineral >= 100 && unit.gas >= 100)
{
Console.WriteLine("방어가 한번 업그레이드 되었습니다.");
shieldUpgradeCount++;
unit.SetUpgradeShield();
unit.mineral -= 100;
unit.gas -= 100;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
case 1:
if (unit.mineral >= 175 && unit.gas >= 175)
{
Console.WriteLine("방어가 두번 업그레이드 되었습니다.");
shieldUpgradeCount++;
unit.SetUpgradeShield();
unit.mineral -= 175;
unit.gas -= 175;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
case 2:
if (unit.mineral >= 250 && unit.gas >= 250)
{
Console.WriteLine("방어가 세번 업그레이드 되었습니다.");
shieldUpgradeCount++;
unit.SetUpgradeShield();
unit.mineral -= 250;
unit.gas -= 250;
}
else
{
Console.WriteLine("자원이 부족합니다.");
}
break;
default:
Console.WriteLine("최대 업그레이드 입니다.");
break;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class SCV : Terran
{
//생성자
public SCV()
{
Console.WriteLine("SCV 생성자 호출");
}
public EngineeringBay Build(string build)
{
EngineeringBay terranBuild = new EngineeringBay();
for(int i = 0; i < terranBuild.build.Length; i++)
{
if (terranBuild.build[i] == build)
{
Console.WriteLine(terranBuild.build[i] + " 을/를 건설합니다.");
return terranBuild;
}
}
Console.WriteLine("없는 건물입니다.");
return null;
}
//Attack Override
public void Attack(Unit target)
{
//공격할 때 대상이 미네랄이면 미네랄을 채취하고
//대상이 가스면 가스를 채취하고
//대상이 유닛이면 유닛을 공격한다.
if(target.name == "mineral")
{
Console.WriteLine("미네랄을 채취합니다.");
this.mineral += 8;
}
else if (target.name == "gas")
{
Console.WriteLine("가스를 채취합니다.");
this.gas += 8;
}
else
{
//타깃에게 피해를 줍니다.
Console.WriteLine("{0}이(가) {1}을 공격합니다.", this.name, target.name);
target.Hit(this);
}
}
}
}
scv클래스를 보완했다. 나중에 인터페이스를 통해 다중 상속으로 바꾼 후 Resouce라는 클래스를 만들어서 자원을 Unit 클래스에서 내보낼 계획이다. Unit 클래스의 Attack을 오버라이딩해서 적을 공격하는것 뿐만 아니라 scv의 특징인 미네랄과 가스를 캐는 것을 추가했다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Study00
{
public class Unit
{
private float x;
private float y;
public string name;
public int hp;
public int damage;
public int shield;
public int attackRange;
public int mineral = 200;
public int gas = 200;
//생성자
public Unit()
{
Console.WriteLine("Unit 생성자 호출");
}
public float[] GetPosition()
{
float[] arr = new float[2];
arr[0] = this.x;
arr[1] = this.y;
return arr;
}
public void SetPosition(float x, float y)
{
this.x = x;
this.y = y;
}
public void Attack(Unit target)
{
//타깃에게 피해를 줍니다.
Console.WriteLine("{0}이(가) {1}을 공격합니다.", this.name, target.name);
target.Hit(this);
}
public void Hit(Unit unit)
{
if(this.shield - unit.damage < 0)
{
this.hp = this.hp + (this.shield - unit.damage);
}
else
{
this.hp -= 1;
}
Console.WriteLine("{0}가 피해를({1})을 받았습니다..", this.name, damage);
if (this.hp <= 0)
{
this.Die();
}
}
public void Die()
{
Console.WriteLine("{0}가 죽었습니다.", this.name);
}
public void SetUpgradeDamage()
{
this.damage += 1;
}
public void SetUpgradeShield()
{
this.shield += 1;
}
}
}
'C# > 수업과제' 카테고리의 다른 글
C# 2주차 2일 수업 과제 (21.03.16) (0) | 2021.03.16 |
---|---|
C# 2주차 1일 수업 과제 (21.03.15) (0) | 2021.03.15 |
C# 1주차 4일 연습 과제 (21.03.11) (0) | 2021.03.11 |
C# 1주차 3일 연습 과제 (21.03.10) (0) | 2021.03.10 |
C# 1주차 2일 연습 과제 (21.03.09) (0) | 2021.03.09 |