Participants:

Markus Barrow, mabar16@student.sdu.dk
Mikkel F******, mifor16@student.sdu.dk
Jonas Rasmussen, jonasr16@student.sdu.dk

Demo.

Introduction.

In the course it was decided to create an iOS application for a portfolio task. The idea for the application that was chosen was a treasure hunting game with a pirate theme. The application can provide a valuable bonding service if utilized as a team game for people exploring a city, furthermore it can provide users with a moderate amount of exercise. To develop this application the GPS functionality of the phone is utilized to track the location of the player dynamically and provide them with small puzzles along the way. Additionally, to create ambience a background track is played in the application.

Methods and Materials.

At the beginning of the development period a brainstorm was carried out to generate ideas for potential applications to be developed. Following this, paper prototypes for a potential GUI solution were sketched for the application. With different paper prototypes, a use case diagram was made to see what functional requirements would be needed. The use case diagram contains an actor (user) who interacts with the application and a box in the middle, which contains the identified functional requirements which should be present in the application for it to be playable.

The software will utilize some of Apple’s frameworks, namely, MapKit and AudioKit.

Puzzled Pirates will follow The Model-View-Controller architecture pattern, given that it is the industry standard for mobile applications.

To ensure that that application will remain interesting, feedback from different users will be required and taken into consideration.

Results.

In the following sections the results from the entire development process will be outlined and described.

Idea Generation and Requirements.

In the following section the text relevant to the process of generating ideas and acquiring requirements will be described.

Brainstorm:

The brainstorm resulted in some different ideas for what the project could be about. Initially two ideas were brought up on day one, an augmented reality minesweeper game and a card game that utilizes camera recognition. It was decided that the scope of these two ideas would perhaps be too small, and an idea of combining the two initial ideas was constructed, however, due to a lack of actual gameplay functionality as well as proper use cases, the idea was scrapped. After receiving user feedback from other developers in the course, a second brainstorm was held and a new idea was generated that, essentially, would be able to combine all the ideas and have actual use cases for the player. This new idea would be a treasure hunting game utilizing the iPhone’s built-in GPS function. Having the player move from point to point and solve puzzles before they were allowed to go to the next step on the treasure hunt. The way this idea would be able to utilize concepts from the other ideas, by implementing them in a smaller scope as potential puzzles in the treasure hunt.

Paper prototyping:

The results from the paper prototypes can be seen in the four pictures pictures below.

When the paper prototypes were created, the amount of knowledge regarding the capabilities of Swift 4.2 was limited, and as result the structure of the prototypes as well as as their designs were over reaching in regards to the allotted time available for the project. As a result, the actual implementation became it bit more simplistic.

Use Case Diagram:

The following use case diagram visualizes the initial functional requirements for Puzzled Pirates. It shows which functionality the user expects the application to deliver and is mostly based on the paper prototypes.

The use case diagram illustrates that the only functional requirement which was not implemented was in fact the “GetHint” functionality.

First User Feedback:

The feedback required when presenting the idea for users and not the other developers will be described in this section. The idea that was presented was a treasure hunting game which would require tasks (which could utilize the microphone, camera or simply be on-screen tasks) to be fulfilled at the different locations. The following feedback was received from the users:

    • What’s the point of the game? (Achievements)
    • It could contain: Badges, Point System, Time Trial, etc.
    • How do I play with friends?
  • What if Camera/Microphone doesn’t work?

With this feedback, some new ideas for the product were established. The application should ask for permission to use the different features of the phone that are required for the application to function correctly. The rest of the feedback would be more non-functional requirements for further development once the functional requirements are met.

Design.

This section aims to clarify design choices that have been made regarding the structure of the Puzzled Pirates application.

Architecture:

The architecture of the Puzzled Pirates application utilizes the Model-Viewer-Controller (MVC) pattern. This works well in Swift due to the tightly coupled nature of the storyboard file and its corresponding controller file.  This means that every scene in the application with meaningful functionality acts as a view and has an attached controller. These controllers require data to carry out specific functions. This data can be in the form of structs or classes with specific functionality, however, the data is encapsulated in separate files, which the controller can access.

This setup supports the fundamental principles of the MVC pattern, where the controller interacts with both its model and its view, but neither the model nor the view can call upon the controller.

When using the MVC pattern, it is normal for controllers to communicate, this is often done by having one controller act as another controller’s model. However, in Puzzled Pirates the two main controllers (for the map and puzzle) are embedded in a tab bar, so there is no direct communication between them. The architecture diagram below, illustrates how this interaction is handled.

The puzzle- and map-controllers communicate with the Shared Values file, which contains information and updates from each of the two controllers.

Class Diagram:

The following class diagram illustrates the structure of the Puzzled Pirates application, how the classes are related and how the responsibility has been separated into logical components. All logic regarding the map is collected and the same has been done for logic regarding puzzles.  

Implementation.

This following section will describe implementation specifics and design choices.

Storyboard:

The storyboard of Puzzled Pirates represents the interface with which the player can interact. The interface consists of a tab bar controller embedded in a navigation controller. The navigation controller’s initial view is the game’s start menu and allows the player to return to the start menu at any point during the treasure hunt.

The tab bar controller contains two tabs, the map view and the puzzle view. The map shows the player’s current location in real-time (updates every 0.5s) whilst also indicating where the next hint is located. The puzzle view contains four buttons, which the player can click in order to solve the given puzzle. These buttons are hidden when the player is too far away from the location indicated in the map view.

Map Controller:

The Map Controller’s functionality consists of the logic for the map and are the controller who handles the players location and the current point location, where the next puzzle is located. A tutorial for how to get the player location and how to setup the Map was used from the given source in the Media section which is a three part series on MapKit. It uses the class MapLogic which contains the different treasure hunts’ locations and the logic to calculate the distance between the player and the goal location. The logic for the Map Controller that checks if the player is within the threshold of the point, is called every 0.5 seconds. This logic needs to be repeatedly called given that the player is moving around and the location is updated and therefore needs to be checked if the player is within the threshold, which is set to 30 meters, because of the slightly unreliable nature of the GPS. As seen in the code below, the methods from SharedValues are used to check if the game should go to the next puzzle and the SharedValues boolean “ifAtLocation”, which is true if the player is within threshold, is set.

    @objc func atPuzzleLocation(){
        DispatchQueue.main.async(){}
        let converted = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)

        SharedValues.setIfAtLocation(boolean: gameLogic.checkIfWithinThreshold(onePoint: converted, secondPoint: playerLocationPoint))
        
        if(SharedValues.getIfNextPuzzle()){
            nextPuzzle()
        }
    }

Shared Values:

Given that two controllers need functionality with regards to the points on the map, the two controllers need a shared class containing the values of these points. This class should also contain methods to interact with the points, like add new points and return the first point. This is obtained by the Shared Values class that enables them to work with the same points. The Shared Values class consists only of static variables and functions and thereby achieve the desired functionality for different controllers having access read and write access to the same points.

Outsider:

The type of puzzle that was implemented is a game called Outsider. It is a simple word-game, where the player is presented with 4 words – 3 of which are in some way related and a final word, the outsider, must be singled out by the player. As an example the words dog, green, red and blue could be presented. The last three words are all colors, whereas dog is not and is therefore the outsider.

This functionality was factored out to the puzzle controller’s accompanying model. It consists of two data types, a class and a struct. The struct “OutsiderRound” encapsulates a single instance of Puzzled Pirates’ Outsider feature. The struct contains the two properties that are required to play a round of Outsider, namely, a list of related words and an odd one out.

struct OutsiderRound
{
    let outsider : String
    let matchingWords : [String]
    
    init(outsider: String,matchingWords: [String]){
        self.outsider = outsider;
        self.matchingWords = matchingWords;
    }
}

The OutsiderGame class is responsible for managing these OutsiderRounds. The class initializes an array of rounds and passes them to the Puzzle Controller as the player progresses throughout the game. This achieves the design principle, where the data is located in the model and not in the controller directly.

Puzzle Controller:

This part of the code is responsible for handling all interaction with the puzzle scene of the Puzzled Pirates application. Upon initialization it starts a new instance of the OutsiderGame class and asks for the first puzzle. Then, the puzzle controller subsequently proceeds to ping the Shared Values class to see if the player is at the correct location. The player must be close enough to the target location for the game to show the puzzle UI.

This occurs asynchronously on a timed schedule. The delay on this timer is set to 1 second, which is double the delay of the MapKit position update. This was chosen so that player’s actual location would always be updated before the puzzle asks whether or not the player is currently at the correct location.  

    var gameTimer: Timer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        showPuzzle();
        gameTimer = Timer.scheduledTimer(timeInterval:1, target: self, selector: #selector(checkLocation), userInfo: nil, repeats: true)
    }

The puzzle controller receives a copy of an OutsiderRound and randomly assigns the outsider and the matching words to the four buttons in the UI. When the player clicks on one of the buttons, the controller checks if the text on the pressed button matches this round’s outsider.

If the selected option is indeed the outsider, the puzzle will be popped from the list of Outsider rounds and the game will proceed to the next puzzle, which will require the player to move to the next location.

Frameworks.

In the following sections, the frameworks utilized in the development of the Puzzled Pirates iOS application will be described.

CocoaPods:

CocoaPods (ref. in Media section) is a 3rd party dependency manager developed for usage with Swift and Objective-C, it is used for installation of other 3rd party frameworks, as well as updating the frameworks defined in the CocoaPods files. CocoaPods is installed through the terminal, with administrator rights. After this, the directory is changed to the project folder and two commands are executed, the first being Pod init, which creates an empty pod file in which the dependencies can be declared, and lastly the Pod install command is run, which installs the declared dependencies into the Xcode project.

AudioKit:

AudioKit (ref. in Media section) is an open source 3rd party framework developed by independent developers, and further developed by several thousand contributors. It is used in Puzzled Pirates to handle all things related to audio. CocoaPods is used to install and update this framework and handles any dependencies to the project. To then use AudioKit within the Swift project it must be imported.

    override func viewDidLoad() {
        super.viewDidLoad()
        
        music.looping = true
        AudioKit.output = mixer
        
        do {
            try AudioKit.start()
        } catch {
            print("AudioKit failed to start")
        }
        
        if(!music.isPlaying) {
            music.start()
        }
    }

The most relevant code to introduce is once the game is initially started and lands on the menu page, where there are buttons that allow the volume to be adjusted as well starting and stopping the music. The music loops, and this is a built-in function in the framework, so is setting a boolean value is all the needs to be done. Secondly, the location of the media to be played must be saved in a variable in the code. Thirdly, a try-catch must be constructed for starting up the AudioKit, which has to be done before it can play music. Lastly, an if-statement is run that simply says that if the music isn’t playing, it should start.

MapKit:

The MapKit contains all the logic for the usage of the GPS. It is a framework provided by Apple that contains most of the functionality that allows Puzzled Pirates to function. It allows for the usage of the player’s location and generation of points on the map, which are used to indicate the location of the point the player has to go to.

Discussion.

The aim of the project was to make an application, which allows the player to play though a treasure hunt where the player has to be physically active to complete it. This goal was reached, but some complications regarding how the puzzles and map points should be connected arose, which was solved through the implementation of the SharedValues file.

Feature Evaluation:

Some good features for the produced application, include the player’s location being used in the treasure hunt and therefore requires the player to be physically active to complete them. This gives the potential of the application being used for a combination of education and being active, in a form of edutainment that could be fun for all ages while either containing brain puzzles, simple questions related to math or the implemented Outsider game. A negative aspect of the current application, would be features that are missing, which would naturally be implemented if time was not an issue. These features can be seen in the following subsection.

Future Implementations:

Things that still need to be implemented:

    • Download the treasure hunt from the cloud
    • Create own hunts
    • Highscore/Achievements
  • Other Puzzles

Without these features, the current application is locked to one treasure hunt and does not seems interesting for players to play more than once. By implementing the highscore/achievements, players will have a reason to play the same treasure hunt again and compete with others to achieve the best score or clear a certain puzzle within a time limit and receive an achievement for doing so.

Rivals:

Some of the potential rivals for the produced application would be Woop and QPS Quiz. These application have some of the same functionality as Puzzled Pirates. Woop contains two game modes: One game mode being “Bombe” which purpose of the game is like Tag, where the players try to pass the bomb on to the other players. When the virtuel bomb explode the person carrying it loses and a rank list of people is calculated, where the best player is the one who have had the bomb as little as possible. The other game mode of Woop is “Jagt” which is like treasure hunt where the player have a set of points they have to go to, and if wanted the points can contain quizzes the player have to answer.
The other rival game is GPS Quiz which is the same as the second game mode of Woop, where there is a set of points the player have to go to and a possibility of having quiz questions at the points.

Conclusion:

Puzzled Pirates became an application where the player is able to start the treasure hunt and is then presented with a point on the map where they have to go. The player has to physically move to this point, since the GPS is used to track the player. When they arrive at this point they can start a task, which in the current product is in form of an Outsider question where the player has to answer which of the four options is the odd one out, and thereby find the outsider. The product is aimed to be pirate themed, which is fulfilled by having pirate pictures and given that the app is built around a treasure hunt, the aimed pirate theme is a success.

The current application has four hard-coded treasure hunts, where treasure hunts are a series of points with a puzzle at each point. Two of these treasure hunts are for simulation purposes and are located in San Francisco, which is the standard location for running simulations. One of the testing treasure hunts keeps all the locations within reach, where the other stays on top of the player location to quickly go through and see if the player can win. The two others are made for SDU’s area, so players can play at SDU. However, the different treasure hunts need to be changed in the code, so the application needs to be built with the desired treasure hunt beforehand.

Given this, the final product can be seen as a success that requires some more implementations to actually be interesting to play, but it contains the core functionality of the treasure hunt game.

The next steps would be to implement features from “Future implementations” which would make the application a more interesting and playable one. The next part would be to implement some way for the players to be able to create their own treasure hunts and make the players able to download other puzzles. Hereby also included that they should be able to choose between different treasure hunts, so that they are not stuck with only being able to play the hardcoded ones. When this is done, more feedback from players would help to see what needs to be a part of the product for it to be more entertaining.

Media.

Source of sprites:
https://pngtree.com/

Source of MapKit guide:
https://www.youtube.com/watch?v=WPpaAy73nJc

Source of Rivals (Danish):
https://www.emu.dk/modul/apps-i-idr%C3%A6tsundervisningen-gps?fbclid=IwAR3EJkrA-rrgRz3GLNyIdfhhzTE1HcyeoS8kCuR-fpoC6H9ua4_moRO7dI0

CocoaPods:
https://cocoapods.org/

AudioKit:
https://audiokit.io/

MapKit:
https://developer.apple.com/documentation/mapkit

Leave a Reply