728x90
반응형
0. 이 글을 작성하는 이유
지방에 내려갔다가 서울로 올라오는 버스에서 야스오 버그 영상을 봤는데 이런 메커니즘이 빠져있어서 발생한 버그가 아닐까 하는 게 생각나서 가볍게 정리해 보기 위함(실은 직업병인 듯)
1. 버그
https://youtu.be/GCuyT0C7bBM?feature=shared
요약 :
신규 아이템을 사용하면(원래는 가지고 있으면이지만 개발 편의를 위해 사용으로 바꿔보았다. 딱 한번 사용 가능하다고 해보자.) 궁극기 쿨타임이 줄어드는데 문제는 사용하고 상점에 팔고 다시 사고 사용하고 상점에 팔고 사고.. 반복하는 만큼 쿨타임이 계속 줄어드는 것
2. 정상 동작은?
실은 팔고 나면 다시 원래대로 쿨타임이 적용되어야 하는데 그러지 못함
3. 왠지?
원래대로 돌려주는 로직이 빠져있는 느낌이다.
분명 실제 코드는 더 복잡하고 정교하고 이쁘게 작성되어 있겠지만 사건의 재구성을 위해 대충 작성해 보았다.
class Champion(
val name : String,
var hp : Int,
var mp : Int,
var skillQ : Skill,
var skillW : Skill,
var skillE : Skill,
var skillR : UltiSkill
) {
var money = 0.0
var itemList = mutableMapOf<Int, Item?>()
fun sellItem(itemIdx : Int){
val item = itemList[itemIdx]
if(item != null){
money += item.price / 2
itemList[itemIdx] = null
println("아이템 판매")
}
}
fun buyItem(item: Item){
if(itemList.size >= 6){
throw IllegalStateException()
}
for(i : Int in 0..5){
if(itemList[i] == null){
itemList[i] = item
money -= item.price
println("아이템 구매")
return
}
}
}
fun useItem(itemIdx : Int){
val item = itemList[itemIdx]
if(item != null && item.canUseItem){
item.activeItem(this)
}
}
}
class Skill(val name: String, val description: String, var cooldownTime : Double)
class UltiSkill(val name: String, val description: String, var cooldownTime : Double){
var defaultCooldownTime = cooldownTime
}
abstract class Item(
val name : String,
val description : String,
val price : Int,
val canUseItem : Boolean = false
){
abstract fun activeItem(champion : Champion)
abstract fun sellAction(champion: Champion)
}
class NewItem375 : Item(name = "버그아이템", "사용 시 궁극기 쿨타임이 줄어듭니다.", 3300, true){
var increaseAtk = 55
var increaseAtkSpeed = 0.20
var increaseHp = 500
var isUsed = false
override fun activeItem(champion: Champion){
if(!isUsed) {
champion.skillR.cooldownTime = champion.skillR.cooldownTime * 0.85
println("아이템 사용")
println("야스오 궁극기 쿨타임 : ${champion.skillR.cooldownTime}")
isUsed = true
}
}
override fun sellAction(champion: Champion) {
champion.skillR.cooldownTime = champion.skillR.defaultCooldownTime
}
}
class Game {
fun runGame() {
val yasuo = createYasuo()
yasuo.buyItem(NewItem375())
yasuo.useItem(0)
yasuo.sellItem(0)
yasuo.buyItem(NewItem375())
yasuo.useItem(0)
yasuo.sellItem(0)
yasuo.buyItem(NewItem375())
yasuo.useItem(0)
yasuo.sellItem(0)
}
fun createYasuo() : Champion = Champion(
name = "야스오",
hp = 550,
mp = 0,
skillQ = Skill("Q스킬", "대충 Q스킬", 10.0),
skillW = Skill("Q스킬", "대충 Q스킬", 10.0),
skillE = Skill(
"Q스킬", "대충 Q스킬", 10.0
),
skillR = UltiSkill("궁극기", "궁극기 가즈아", 50.0)
)
}
갑자기 작성하려니 코드가 좀 이상하다. 대충 넘어가자. data class로 뺄 수 있는 부분도 있고 그러지만 대충 넘어가는 게 우리 서로 윈윈인 것 같다.
쿨타임이 계속 줄어드는 기적을 보여준다.
이유는 간단하다. 아이템을 팔았을 때 이 쿨타임이 원상복귀가 되어야 한다.
저기 sellAction이라는 함수를 임의로 만들었는데 아이템을 팔았을 때 얻은 능력치, 효과들을 초기화시키기 위해 만들었다. 이 함수를 sellItem함수에 넣어보자.
fun sellItem(itemIdx : Int){
val item = itemList[itemIdx]
if(item != null){
money += item.price / 2
itemList[itemIdx] = null
item.sellAction(this)
println("아이템 판매")
}
}
4. 여기서 느낀 점은?
버그도 버그지만 생각보다 롤 챔피언, 아이템, 스킬, 능력치 등의 아키텍처 구성이 이쁘게 하려면 어떻게 해야 할지 머리가 좀 아프기 시작했다. 이건 좀 봐봐야 할 것 같다.
728x90
반응형
'주니어 개발자로 일하며 느낀 점' 카테고리의 다른 글
2023년을 어떻게 보냈었더라 (3) | 2024.01.14 |
---|---|
교육자료 준비 (0) | 2022.10.30 |
getter/setter 를 꼭 사용해야하는가? (0) | 2022.09.07 |
개발에 대한 생각이자 아무말 대잔치 (0) | 2022.04.30 |
2020년 뉴비 1년차 개발자를 마무리하는 회고 (0) | 2020.12.30 |