How do I implement framework function touchDown in a turnbased loop? - ios

I'm using a simple turn based loop, switching between player turn and enemy turn. In the player turn the loop should "pause" until framework function touchDown has been activated, then pass the turn to the enemy. I'm not sure how to implement this as touchDown triggers automatically whenever you press the screen.
Am I to use an observer of some sort or a #selector? Tried both unsuccessfully, but that may just be for my lack of experience. If I use the selector the loop doesn't pause to wait for the screen to be clicked. As for the observer, I'm just not sure how its implemented. I also tried just adding the whole touchDown method into the player turn but that obviously didn't work.
The loop simply looks like this:
var state = "PLAYER"
func runGame() {
while(gameIsProgressing) {
if(state == "PLAYER") {
print("Player is doing stuff")
//THE touchDown METHOD SOULD BE TRIGGERD HERE
state = "ENEMY"
}else if(state == "ENEMY") {
print("\n🙈ENEMY IS DOING STUFF🙈")
state = "PLAYER"
}
}
}
Also, it is important that touchDown is triggerd only in the player turn, and not whenever the screen is pressed.
Any ideas?

Since you are programming something with a GUI here, you should not think in this imperative way. There is no (good) way to "pause" a while loop "until" something happens. You should think in a more event-driven way.
Instead of thinking about the while loop, think in terms of the events that happen. In this case, the event is touchDown. Note that I don't know of a library function called touchedDown (did you mean touchesBegan or is this an action for a UIControl?), but I'll assume it exists. When the player touches the screen, what do you want to happen? Well, probably something like this:
guard gameIsProgressing else { return }
if(state == "PLAYER") {
someFunctionThatShowsWhatThePlayerDid()
state = "ENEMY"
print("\n🙈ENEMY IS DOING STUFF🙈")
someFunctionThatMakesTheEnemyDoStuff(completion: {
self.state = "PLAYER"
})
}

Related

UIPanGestureRecognizer fails to enter .ended state after screen rotation

I'm having an issue with handling screen rotations when a UIPanGestureRecognizer is in the .changed state. My handling logic looks something like:
#objc fileprivate func handlePanGesture() {
let state = self.panGestureRecognizer.state
if state == .began {
// Log beginning state
} else if state == .changed {
// Track position, update constraints
} else if state == .ended {
// Reset and prepare for new gesture
}
}
Everything seems to be working well, but when the device is rotated to a new orientation (without lifting my finger), the gesture recognizer stops receiving updates for the active touch, but never triggers the handlePanGesture() with the .ended state set.
Right now I'm handling this by looking out for viewWillTransition(to:with:) and cleaning up the state when that happens, but this approach fails when, e.g., an iPad is rotated from portrait-right-side-up to portrait-upside-down--there is never any size transition. Is there something that can be done to cancel the gesture recognizer on rotation (and trigger a call to handlePanGesture())?
You also need to check for the .cancelled state.
btw, switch on the state rather than if, else if, else if, else if

How to stop regenerating the wall after first click?

I just coded a game that needs the wall to be generated forever randomly (just like the walls in Flappy Bird), but every time when I touched the screen, it started to generate again which ended up with generating too much walls. Is there any methods I could use when clicking the screen (to make player jump) without generating too much walls?
Ok so based on our conversation in the comments, what you would want to do is create a boolean like so
var gameStarted = Bool()// outside of didMoveToView
override func touchesBegan() {
if gameStarted == false{
gameStarted = true
movingGround.start()
// add whatever code is left
}
}
Hopefully this is what you were looking for

Swift: How can I wait for an event and then switch the view?

Hey I'm doing a mini game application atm, which switches from one minigame view to the next one. Is there some kind of event listener in swift? If a game (SpriteKit Game) is finished it should fire an event, that its done now, and the view controller should then know, that it should switch to the next game view. I tried around with segues, but it doesn't seem to work like it should.
I know a way, but it's not a very 'clean' way. You could add an if statement to your update function to check for a condition. For example a gameOver boolean that becomes true when a certain condition is met.
If it's true you can move to another scene.
var gameOver = false
override func update(currentTime: CFTimeInterval) {
if gameOver {
goToGameOverView()
}
}
func goToGameOverView() {
// Your code here
}
Maybe there's a better way, but this is the way that I know.

While-loop in UILongPressGestureRecognizer not working

I'm trying to adjust the position of my textField as I long-press my view, but for some reason the while-loop never stops running. My code looks like this:
func buttonLongPressed(gestureRecognizer:UIGestureRecognizer){
if textEdit.editing == true{
self.textEdit.endEditing(true)
}
while gestureRecognizer.state == UIGestureRecognizerState.Began{
println("BEGAN")
self.textEdit.frame = CGRectMake(0, gestureRecognizer.locationInView(self.view).y, self.view.frame.width, 44)
}
}
I don't understand why this shouldn't work, and how to do it in any other way.
Any suggestions would be appreciated.
The gesture recognizer calls your action method when its state changes--it's not valid to poll the state from a while loop, it will never change.
It probably works like this:
Events are sent from the touch screen with a signal to wake up your app.
The gesture recognizer looks at the queued events and decides to enter "Began" state.
The gesture recognizer code invokes your action method (buttonLongPressed)
Your code enters a while look and reads gestureRecognizer.state repeatedly.
You can see, if your action method never returns, the gesture recognizer will never wake up again and look at new input.
You can probably just change your function like this:
func longPressAction( g:UILongPressGestureRecognizer )
{
switch g.state
{
case: .Changed
{
// handle one drag update... but don't loop
}
}
}

How to detect touch on a game object

I'm developing a game on Unity for iOS devices. I've implemented the following code for touch:
void Update () {
ApplyForce ();
}
void ApplyForce() {
if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began) {
Debug.Log("Touch Occured");
}
}
I've dragged this script onto my game object which is a sphere. But the log message appears no matter where I touch. I want to detect touch only when the users touches the object.
stick the code bellow in your camera, or something else that will persist in the level you're designing. It can be anything, even an empty gameobject. The only important thing is that it only exists ONCE in your level, otherwise you'll have multiple touch checks running at the same time, which will cause some seriously heavy load on the system.
void Update () {
if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay( Input.GetTouch(0).position );
RaycastHit hit;
if ( Physics.Raycast(ray, out hit) && hit.transform.gameObject.Name == "myGameObjectName")
{
hit.GetComponent<TouchObjectScript>().ApplyForce();
}
}
}
In the above script, hit.transform.gameObject.Name == "myGameObjectName" can be replaced by any other method you want to check that the object hit by the raycast is the object you want to apply a force to. One easy method is by Tags for example.
Another thing to keep in mind is that raycast will originate at your camera (at the position relative to your finger's touch) and hit the first object with a collider. So if your object is hidden behind something else, you won't be able to touch it.
Also put the script bellow in your touch object (in this example, called TouchObjectScript.cs)
void Update () {
}
public void ApplyForce() {
Debug.Log("Touch Occured");
}
If something wasn't clear, or you need any further help, leave a comment and I'll get back to you.
The best way to do this, is just adding:
void OnMouseDown () {}
to the gameobject you want to be clicked.
The problem with this is that you cannot press 2 things at one time.

Resources