📜 ⬆️ ⬇️

Casual workouts for Swift

image

Hi, brothers in swift-e. I also had to learn this bird language, and there is no better way to learn than to make a software product that works on a battered iPhone. I have been bitten by an intricate math puzzle from the inside for a long time! And suddenly swift. The code in some places looks ridiculous, but understandable. I will not discuss the algorithm of the game itself, it is too complicated for local moderators who do not know how to divide 111 by 3. But here are some examples of useful functions for casual game developers - please discuss.

Randomness


First of all, in any game you need your own generator of random sequences of integers. To generate repetitive layouts and for a lot more then.
If the code of the generator function on Java, JS and C looks the same (after all, will your game be written in all languages?), Then on Swift you had to rewrite the code using the random method. Instead of 2 lines, he began to occupy 4.

var holdrand = 0 func microsoft_rnd()->Int { var k = Int.multiplyWithOverflow(holdrand, 214013) k = Int.addWithOverflow(k.0, 2531011) holdrand = k.0 return Int((holdrand >> 16) & 0x7FFF) } func microsoft_rand(number:Int)->Int { return microsoft_rnd() % number } 

')
And here is what the C-th version of the MixoPhoto sensor, which I had torn out from MSVC 15 years ago, looked like.
 - (int)microsoft_rnd { holdrand = holdrand * 214013 + 2531011; return ((holdrand >> 16) & 0x7FFF); } - (int) microsoft_rand:(int) number{ return [self microsoft_rnd] % number; } 


As you can see, Swift is very strict with overflows and adds headaches to the developer, but apparently removes stress from the runtime user. At the same time, Obj-C worked perfectly without any stresses and headaches.

So here. Defining the holdrand variable, say holdrand = 25, we will obviously repeat the alignment for the conditional level 25 in all variants of the puzzle - be it written in PHP for playing on the server, or on Swift for playing on the iPhone. This gives a sense of fraternity for the players - they are like everything is offline, but at the same time they compete in absentia in the same scenario. Looks like a bridge tournament. For a long time I did not play bridge, by the way.

Let's go to practice. Let's create a simple Swift project using Xcode. Press the button File-> New-> Project ...-> Single View Application and get the finished project blank, the main class of which AppDelegate.swift looks frighteningly simple

 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. } } 


What has changed since Obj-C? First, instead of two files, there is one. I approve of it.
In addition, strange "?" Characters appeared in the text. and "!" Do not worry, these are signs of the type of a variable, if the variable x: Float! Is it exactly float if x: float? - the author is not sure that this variable will always be Float.

Honestly, Xcode itself substitutes these characters in case of need, and after 4 hours of coding, you will begin to understand the logic of using idiotic characters.

Advertising


So, what is necessary for the game developer in the second place, but not the last? Of course, advertising. It is in this class AppDelegate it must be added. Download the latest version of Google MobileAds with Swift, add to the project and write a couple of functions

 import UIKit import GoogleMobileAds @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var bannerView: GADBannerView! var iPhone5 = true func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { startAds() return true } func startAds() { bannerView = GADBannerView(adSize: kGADAdSizeBanner) print("Google Mobile Ads SDK version: " + GADRequest.sdkVersion()) bannerView.adUnitID = yourAdMobID bannerView.rootViewController = self.window?.rootViewController let adViewHeight = bannerView.frame.size.height print("adViewHeight: \(adViewHeight)") let screenSize: CGRect = UIScreen.mainScreen().bounds let screenHeight = screenSize.height bannerView.frame.origin = CGPointMake(0, screenHeight - adViewHeight) let request = GADRequest() request.testDevices = [kGADSimulatorID ] self.window?.rootViewController!.view.addSubview(bannerView) bannerView.loadRequest(request) //    ,  2    iPhone5 = screenHeight >= heightOfScreenOfiPhone5AndMoreInLogicalPixels } func bringAdsToFront() { self.window?.rootViewController!.view.bringSubviewToFront(bannerView) } } 


The startAds () call appeared in the body of the main function.
The bringAdsToFront () function is in fact not necessary for me, but it can be useful to you if you use non-standard ViewControllers that will overlap the advertising window when it appears. In this case, the banner must be pulled out on top of all Views by calling this procedure.

The variable iPhone5 is terribly necessary, like air, as long as two Aspect Ratio on iOS are alive. I remind you that 5% of the population still uses 4 iPhones, the proportions of which differ from all modern models. In addition, if your application is iPhone only, then when you launch it on the iPad, you again get the good old mode 320 by 480 pixels.

Why so place a banner? I have an application to play in the subway with one hand on the phone, so the working mode is always defined for him - Portrait . And 320x50 ads I bring down the screen, which doubles the earnings. At the time of publication of the article, I already earned 40 US cents.

In principle, now you have learned how to program in Swift.

Sound


What else is needed in the game, even the most primitive? Sounds mu

Add two functions and one class.

 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var soundLib: SoundController? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { soundLib = SoundController.init() } func setVolume(v:Double) { soundLib?.setVolume(v*v) } func playSound(i:Int) { soundLib?.playSound(i) } } 


In addition, we add dozens of mp3 and caf files pulled out of Google to the project and create the SoundController class in a separate file
SoundController.swift
 // Created by Vadim Bashurov on 3/19/16. // import UIKit import AVFoundation class SoundController { let audioFiles: [String: String] = [ "Ashley_glad_1": "caf", "star_first": "caf", "star_third": "caf", "bouncer":"caf", "bird shot-a3":"mp3", "ball_bounce":"mp3", "bird_a4":"mp3", "HittingBasketBoard":"mp3", "piglette_a1":"mp3", ] var players : [AVAudioPlayer] = [] var volume = 0.0 init () { for (name, ext) in audioFiles { let a1 = self.setupAudioPlayerWithFile(name, type:ext) players.append(a1!) } } func setVolume(v:Double) { volume = v for audioPlayer in players { audioPlayer.volume = Float(volume) } } func playSound(i:Int) { let audioPlayer = players[i] audioPlayer.play() } func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer? { let path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String) let url = NSURL.fileURLWithPath(path!) var audioPlayer:AVAudioPlayer? do { try audioPlayer = AVAudioPlayer(contentsOfURL: url) audioPlayer!.prepareToPlay() } catch { print("Player not available") } return audioPlayer } } 



Of course, I went through all 4 options for playing sound under iOS. System sounds are not suitable for game development, as they do not programmatically control the level of reproduction. AudioService from the OAL library on Swift has not been rewritten by me, there is not enough knowledge and time. AudioQuery slows down. In the future, I will abandon the bridge from my Obj-C library, because despite the preload function, AVAudioPlayer lays at the start of the program.

And for dessert, jumpers!

Skipjack



All your lettering buttons and pictures should appear on the screen, like real objects from the fairy-tale world. Either float, or fly, go out of the shadows and poddrygivat. Starting with iOS 8, Apple offered a left-handed feature for bouncing animations.

Here is an example
  UIView.animateWithDuration(1.2, delay: 0.1, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: { box1.center = CGPointMake(box2.center.x,box2.center.y) }, completion: {finished in self.showFingers() }) 


As a result of the work of the function, box 1 will fall on box 2 (this is the plot of my puzzle) not just stupid, but with cheerful jumps, after which it will rest peacefully.
The physics of a jump can be varied with 3 parameters - the time of the whole process - in my text it is 1.2 seconds, the second parameter is the delay before the start of the fall (delay: 0.1) does not affect bouncing.
But the 3 and 4 parameters have a value from 0 to 1 and determine the quality of the jump. If you set them to 1, then there will be no rebound. If zero, the box will jump like a louse on a branch.

Experiment yourself, this exercise is extremely fun.

Now you are ready to write a simple toy on Swift and earn a few dollars for beer.
Chao!

Source: https://habr.com/ru/post/280266/


All Articles