-by Daniel Davidsen (dadav13) & Rasmus Elving (raelv13)

1. Introduction

1.1.  The Idea

The idea for this project was to produce a location based game of tag, using your smartphone. The inspiration came from the kids game “Marco Polo” which is a game that is usually played in a pool, one player is blindfolded and assigned to be “the catcher“, the rest of the players are then “hiders”. The catcher now has to catch all the hiders one by one using only his hearing, he can say “Marco” and all hiders must then respond with “Polo” giving up their position to the catcher. We wanted to make a electronic augmented reality (AR) version of this game, with similar rules, but as it seemed unpractical to blindfold a player when he is not restrained to a small area such as a pool, it would seem dangerous, so we instead wanted him to only see a glimpse (time restricted) of where other players might be. All players, both catcher and hiders, would have a interactive map on their phone showing their location and a couple of interaction options. The catcher could with some time restraint press a button that revealed to him the location of all hiders. Hiders would in turn be notified when a catcher has received their location, so that they could now move as to not get caught.

2. Method

Throughout this project a series of methods have been used, some of which will be highlighted in the following section.

2.1 Brainstorm

To ensure that the ideas we would produce where sound, and well thought through, we choose to begin the project with a brainstorm on the topic of iOS apps. Brainstorming is the process of producing a lot of tangential and random ideas around a center topic and then evaluating the ideas afterwards, to create a more worked through concept. what we came up with was the idea described earlier in 1.1

2.2 Rapid Prototyping

Rapid prototyping is when you create multiple low-fidelity prototypes to continually test a products different functionalities. This method helps highlight potential problem areas in both concept and design, before moving to a high fidelity product, potentially save a lot of time. Rapid prototyping is a method that is suitable for fast paced development with tight deadlines. In our project we made the following two low-fidelity prototypes.

2.2.1 MarvelApp

To create a visual overview and assist in the evaluation and iteration process, we developed a “responsive” design prototype with the application tool MarvelApp (Former POP “Prototype on paper”) This allowed us to draw views as we imagined they should look, take pictures of the drawings, and add “functionality” to the drawings to simulate how the final app would look and work. MarvelApp, for example, allows users to add areas to images that can be printed, and therefore act as buttons in a potential app. This resulted in 8 images representing our first idea about the design and functionality of the app.

We identified the need for four views: A Login view, so as to make sure each player has a unique identity, and a reference in the app (player name). A Lobby view, where the player could choose which room (game) they wished to enter. A Settings view to customize the player name and other preferences and lastly the Game view itself containing the map and player position.

2.2.2 FluidUI

After testing we were informed of a series of things that we could improve upon. we therefore set up a wire-frame using FluidUI to visualize the suggested changes. Most important of which was the addition a fifth view (private game creation view) and the addition of a couple of game-play features. Specifically the ability for hiders to taunt the catcher, revealing their location for a short while, and the ability to set up a decoy whose location would be  shown instead of the hiders actual location for a single Marco call.

It was also suggested that the catcher would see a picture of the hider once he got close enough, so as to confirm the catching in person. this would add a lot more game play, and fun to the experience for both the catcher and the hiders.


– Hider Taunt functionality

– Hider Decoy functionality

– Catcher Close functionality

2.3 User Testing 

Two user tests were conducted after the marvelApp prototype, with a follow up unstructured interview to gauge interest and iterate on the design of the application.

A class presentation were also made after the FluidUI prototype was constructed, that also yielded a lot of useful feedback for the final implementation of the application.

3. The Code

In this digital prototype only a part of the catchers mechanics has been implemented and annotations has been used to simulate hiders.

This application is centered around player locations and the interactions with the map. This means that location and map management is a big part of this application, and that’s why we choose to focus on this first.

The locationManager method handles the map view, to make it centered on the player’s current location. We also save the location of the player (in this case the catcher) to use it as a baseline for the simulated hiders.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations[0]
        let span:MKCoordinateSpan = MKCoordinateSpanMake(0.001, 0.001)
        let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
        let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
        map.setRegion(region, animated: true)
        self.map.showsUserLocation = true
        playerCurrentLocation.latitude = location.coordinate.latitude
        playerCurrentLocation.longitude = location.coordinate.longitude

When the catcher wants to scan (Say “Marco”) for the hiders. He can use the button in the lower left corner of the screen. When the button is pressed the code uses the getLocation method to generate an array of CLLocationCoordinate2D objects which holds the coordinates of each hiders location. Then it iterates through each object in the array and instantiates an annotation for each hider. Afterwards it adds them all to the map.

The Timer is then activated and the button is disabled to make sure the catcher can not constantly use the scan option.

@IBAction func scanButton(_ sender: UIButton) {
        let hiddersLocation:[CLLocationCoordinate2D] = getLocations(catcherLocation: playerCurrentLocation)
        for hidder in hiddersLocation{
            let annotation = MKPointAnnotation()
            annotation.coordinate = hidder
            annotation.title = "Player Name"
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(buttonCooldown), userInfo: nil, repeats: true)
        scanButtonLabel.isEnabled = false
        scanButtonLabel.backgroundColor = UIColor.darkGray

At the moment, the getLocation method generates 4 random locations based on the player current location. The drand48 method is used to generate a random float between 0 and 1 and then divided by 1000 and subtracted by 0.0005 to adjust the numberframe to a number between -0.0005 and 0.0005. The results are then used to generate the location of a hider.

Each location is then appended to an array of CLLocationCoordinate2D objects which is then returned when every hiders location is created.

func getLocations(catcherLocation: CLLocationCoordinate2D) -> [CLLocationCoordinate2D] {
        var hidderLocations: [CLLocationCoordinate2D] = []
        for _ in 0 ... 3 {
            let lat = catcherLocation.latitude + (drand48()/1000) - 0.0005
            let lon = catcherLocation.longitude + (drand48()/1000) - 0.0005
            let playerLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, lon)
        return hidderLocations

After the scan button has been pressed and the timer activated, this function gets called repeatedly until the buttonCounter variable reaches 0. the buttonCounter begins at 20 and when it reaches 12 it removes the annotations that indicates the hiders location. It also updates the label of the button to show the counter, to let the player know, when he can push the button again. Once the counter hits 0 it deactivates the timer, resets the buttonCounter variable and reactivates the button for the player to use.

@objc func buttonCooldown(){
        if buttonCounter != 0 {
            if buttonCounter == 12 {
                annotations = []
            scanButtonLabel.setTitle(String(buttonCounter), for: .normal)
            buttonCounter -= 1
        } else {
            scanButtonLabel.setTitle("Scan", for: .normal)
            scanButtonLabel.isEnabled = true
            scanButtonLabel.backgroundColor = UIColor(displayP3Red: 1.0, green: 0.47, blue: 0.14, alpha: 1.0)
            buttonCounter = 20

4. Conclusion

This project has been a great learning experience. We have had to overcome many unexpected challenges, which has forced us learn and problem solve outside of our comfort zone to overcome the challenges. This has resulted in a great amount of knowledge in xCode and the corresponding Swift language.

The application in its current state does not meet the requirements of our vision for the application. Throughout the development process of the digital prototype we have had to readjust our ambitions, due to the many challenges and timeframe, in hopes of completing a working prototype in time.

The finale prototype consist of multiple views with simple button interactions and text display. The main gameview displays a map and tracks the player’s location. For this prototype, only the catchers point of view has been implemented. The catcher is able to “scan” to locate the other hiding player’s which, in this case, is randomly generated pointers.

4.1 Future work

The next logical step for us would be to implement the two missing views, with the accompanying functionality of actually creating private game rooms. Next would be to add login functionality, this could be done with a apple account validation, or creating a new a account with the app. Then working with the multiplayer part, a server would have to be established, this could be done with Googles Firebase. The hider and catcher functionality could then be implemented as well.

BitBucket Link:  Here 

Leave a Reply