I brought this up in one of my other questions, but I'm working on a text based adventure game designed for IOS.
One of the things I'm working on is to give a button multiple different functions under specific circumstances. I read in a handful of other posts that I can achieve this by using swift statements and I have been somewhat successful in changing the action, however it is not the correct action.
As shown below most of my story, and what options the player is given, are stored in a structure, and can be switched using the PickStory method.
func mainStory()
{
Storys =
[Story(Story: "You are walking along a dirt path and come to a cross roads. You see a small shack just off the trail. What do you want to do?", Action: "Heal", North: true, South: true, East: false, West: false, storyProg: true, resultN: "You walk north and see a gate in the distance.", resultS: "Their is nothing to turn back for.", resultE: "", resultW: ""),
Story(Story: "You see a small gate at the end of the dirt path, and their is a gaurd standing infront of the gate.", Action: "Approach", North: true, South: true, East: true, West: true, storyProg: false, resultN: "", resultS: "", resultE: "", resultW: ""),
Story(Story: "You see a small well in the middle of town.", Action: "Attack", North: true, South: true, East: true, West: true, storyProg: false, resultN: "", resultS: "", resultE: "", resultW: "")]
PickStory()
}
func PickStory()
{
if Storys.count > 0
{
storyNum = 0
storyLabel.text = Storys[storyNum].Story
actionButton.setTitle(Storys[storyNum].Action, for: UIControl.State.normal)
adjustButtons(North: Storys[storyNum].North,
South: Storys[storyNum].South,
East: Storys[storyNum].East,
West: Storys[storyNum].West)
Storys.remove(at: storyNum)
}
else
{
NSLog("Done!")
}
}
Now while the text of the Action button is established in the PickStory method, the actual actions are changed in the actual button method that follows a few lines after (Please note that the print statements are only temporary place holders for the methods that will be placed later).
@IBAction func actionButton(_ sender: Any)
{
switch Storys[storyNum].Action
{
case "Attack":
print("Attacking")
break
case "Heal":
print("Healing")
break
case "Approach":
print("Approaching")
break
default:
break
}
}
To summarize the problem, the text will change to the correct action, but the actual action won't change.
My original guess was that because the actionButton comes a while later, after the PickStory method, it would read the next story after the index was removed. However, I cannot get any progress through the story without removing indexes.
You cannot send parameters through a selector action, but you could subclass the UIButton
to add a custom property, which can be anything.
import UIKit
class CustomButton: UIButton {
var storyAction: String
override init(frame: CGRect) {
self.storyAction = ""
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
self.storyAction = ""
super.init(coder: aDecoder)
}
}
You can set this property when you set the title:
let action = Storys[storyNum].action // Customary to use lower case for instance properties and upper case for classes
actionButton.setTitle(action, for: UIControl.State.normal)
actionButton.storyAction = action
You can check it in the switch statement.
@IBAction func actionButton(_ sender: CustomButton)
{
switch sender.storyAction
{
case "Attack":
print("Attacking")
break
case "Heal":
print("Healing")
break
case "Approach":
print("Approaching")
break
default:
break
}
}
Note that I called the property storyAction
so as not to conflict with the button’s pre-existing action
property.
It might be safer to use an enum
for all your storyAction
types, instead of strings. This would make it easier to ensure there were no spelling mistakes causing problems!
enum StoryAction {
case attack
case heal
case approach
}
This can be extended as much as you need. It is easy to check in a switch statement with case .attack
etc.