My SwiftUI book is on sale now as part of the Ray Wenderlich Learn At Home Sale for 50% off. TThere’s also an update coming this summer that updates the bug to Swift 5.2 and Xcode 11.4. It also addresses feedback, bugs, and questions asked since the last update. If you purchase the digital copy now, you’ll get the update when it comes out.
May 20, 2020
April 13, 2020
What’s New in Swift 5.2
I wrote a summary of the changes in Swift 5.2 for raywenderlich.com.
January 6, 2020
New Tutorial: Creating Charts in SwiftUI
My most recent tutorial at raywenderlich.com is up on Creating Charts using SwiftUI.
November 30, 2019
SwiftUI by Tutorials Black Friday Sale
I know it’s not Black Friday, but who just puts things on sale one day anymore.
If you missed the launch sale on SwiftUI by Tutorials when it came out in October, you’ve another change to pick it up at half price through Monday, December 2 as part of the bigger site sales on raywenderlich.com.
SwiftUI by Tutorials will help you learn the “new way” of building responsive UI with modern declarative syntax with SwiftUI. It assumes a knowledge of Swift, but requires no experience with app creation. By the end of the book, you’ll have a firm understanding of using SwiftUI and be ready to put it to use in your own apps.
If you’re looking for a bit more than one book, you can also pick it up as part of the Advanced iOS & Swift Black Friday Bundle through Monday for a total of ten books.
The sale is only through December 2.
November 14, 2019
Updated SwiftUI Book
If you’re the time that doesn’t install anything until the dot-one release, then the first major update to the SwiftUI I co-authored is available.
https://www.raywenderlich.com/6533254-swiftui-by-tutorials-new-version-available
October 3, 2019
My SwiftUI Book is Available
I spent much of the summer working as a co-author for a book on SwiftUI for raywenderlich.com. I’m excited to announce that SwiftUI by Tutorials is now available along with books on Catalyst and Combine. The book is on sale until October 11 at https://store.raywenderlich.com/products/swiftui-by-tutorials.
You can also save on a couple of bundles through October 11, 2019 as part of the iOS Fall Sale if you’d like to pick up all three for a nice discount.
Recent Tutorials and Articles
A couple of articles and tutorials of mine in the last few months:
- An update to modernize an article on Swift Interview Questions and Answers.
- Also a tutorial on using PDFKit from iOS apps – Creating a PDF in Swift with PDFKit. In it you’ll learn how to create a PDF, work with Core Text and Core Graphics and share the created document by building an app that displays the user’s input on a flyer that can be shared with other iOS apps.
January 7, 2019
Recent Work for RayWenderlich.com
I realized I’d not posted some recent articles and tutorials I’ve written since I started tutorial for raywenderlich.com at the start of 2018.
IAP: Receipt Validation – I’m really happy with this look at a fairly complex task. Come for the cryptography and stay to learn about accessing C libraries from Swift.
Text Kit Tutorial: Getting Started – An update of an existing tutorial for latest versions of iOS and Swift.
Trigonometry for Game Programming – SpriteKit and Swift Tutorial: Part 1/2 and Trigonometry for Game Programming – SpriteKit and Swift Tutorial: Part 2/2 – Another update of an existing tutorial to the (at the time) latest XCode and iOS.
April 1, 2016
Roguelike Development with C# – Part 5: Cleaning up Some Issues
First a note that I didn’t get the code for the last couple of articles posted before so that’s been done now. Today’s article will work on setting up some debugging and counter logic that we’ll use going forward. We’re also going to fix a small bug in our handling of turns left in last time.
Last time we created a pair of counters to track how long we’ve been running. The tick
variable holds how many times our game has run through the update
handler while the turn
variable tells us how many times the player has performed an action. We’re going to add three more counters and move these values into a separate class. Create a new file in the program named GameCounters.cs
and define it as follows
{
public int Tick { get; private set; }
public int Turn { get; private set; }
public DateTime StartTime { get; private set; }
private DateTime LastFrameTime { get; set; }
private double FrameDelta { get; set; }
GameCounters()
{
Tick = Turn = 0;
StartTime = DateTime.Now;
LastFrameTime = StartTime;
FrameDelta = 0.0;
}
}[/code]
This creates a class that holds our current Tick and Turn counters. It also adds three new values that hold the date and time we start our game, the date and time of each frame, and the difference in time since the last frame for each frame.
Now we’ll add a few three more calculated properties to this class. Before the constructor add the following three properties.
public double AverageFPS => Tick / SecondsSinceStart;
public double CurrentFPS => 1.0 / FrameDelta;[/code]
If this looks unfamiliar, I’m using a new syntax introduced in C# 6. This uses the lamba arrow (=>) to define the body for the expression. The effect is exactly the same as if the methods had had a block body with a single return statement. In other words
[code language=”csharp”]
public double CurrentFPS => 1.0 / FrameDelta;
[/code]is the equivalent of:
[code language=”csharp”]public double CurrentFPS
{
get
{
return 1.0 / FrameDelta;
}
}[/code]in a smaller space.
For short
get
methods I find the new syntax easier to read.
We’ll also add methods to the class to update the counters from our Update
handler.
{
DateTime now = DateTime.Now;
Tick++;
FrameDelta = (now – LastFrameTime).TotalSeconds;
LastFrameTime = now;
}
public void NewTurn()
{
Turn++;
}[/code]
Now we need to update our game to use the new class. Replace the two existing counter variables with a single variable of the new GameCounter class.
We could initialize the counter class in our OnLoad
handler, but I want to keep that to setting the initial game state. Instead we create the instance of the class immediately before starting the loop at the end of the Main method before the _rootConsole.Run();
line.
_rootConsole.Run();[/code]
We also now need to use the new methods whenever a turn or tick passes instead of directly changing the variables. Replace the turn++
call at the end of the loop handling key strokes with _counters.NewTurn();
. Replace the increase of the tick counter at the end of the Update handler with a call to the new method so tick += 1;
becomes _counters.NewFrame();
.
In additon let’s add a new print statement to show the new counters. In the Render handler after the existing print statement add a new one.
While these print statements are useful, I don’t think we’ll want them on the screen all the time as we add more functionality. Let’s add one more property to the CameCounters class.
and update the constructor to set this property to false initially.
{
Tick = Turn = 0;
StartTime = DateTime.Now;
LastFrameTime = StartTime;
FrameDelta = 0.0;
Visible = false;
}[/code]
We’ll update our Render handler to only show these statements when the Visible
property is set to true in our Render handler.
{
_rootConsole.Clear();
_rootConsole.SetChar(playerX, playerY, ‘@’);
if (_counters.Visible)
{
_rootConsole.Print(1, 1, $"Current tick: {_counters.Tick} Current turn: {_counters.Turn}", RLColor.White);
_rootConsole.Print(1, 2, $"Time since start: {_counters.SecondsSinceStart:.000} Current FPS: {_counters.CurrentFPS:.0 fps} Average FPS: {_counters.AverageFPS:.0} fps", RLColor.White);
}
_rootConsole.Draw();
}[/code]
To toggle the flag, we’ll use the d key (for Debug). After the case statement for the Q and Escape keys, add one more.
_counters.Visible = !_counters.Visible;
break;[/code]
If you run the application as it is now, you’ll see that the statements are hidden at first, but will show after you press the D
key. Pressing the D
key again hides the information.
I also mentioned a bug in our handling of turns. Restart the game and press D
. You’ll notice it shows one turn has passed. In fact if you press any key, including unrecognized ones such as F
and the turn counter increases. That’s because we’re setting the userAction
flag to true any time that we get a keypress.
We only want turns to pass when the player actually performs an action. Interface type activity (such as showing the menu here with the D
key) shouldn’t count nor should keys we don’t recognize or act upon. Let’s fix this by only seting the userAction
flag to true for keys resulting in the player peforming an action. Change the swtich statement handling keypresses within the Update
handler to the following.
if (key != null)
{
switch (key.Key)
{
case RLKey.Up:
userAction = true;
playerY -= 1;
break;
case RLKey.Left:
userAction = true;
playerX -= 1;
break;
case RLKey.Down:
userAction = true;
playerY += 1;
break;
case RLKey.Right:
userAction = true;
playerX += 1;
break;
case RLKey.Q:
case RLKey.Escape:
_rootConsole.Close();
break;
case RLKey.D:
_counters.Visible = !_counters.Visible;
break;
}
}[/code]
Now we only set the flag when the user moves. Quitting or toggling the display of debugging information does not count as an action.
Today we’ll do one more change to move the code that should only execute after a turn and the code that executes every time through the Update
handler into separate functions. This will leave the Update
handler focused on code to process player input.
Create two new methods at the bottom of the Program class.
{
_counters.NewFrame();
}
private static void ProcessTurn()
{
// Ensure player stays on the screen
if (playerX < 0)
playerX = 0;
if (playerX > screenWidth – 1)
playerX = screenWidth – 1;
if (playerY < 0)
playerY = 0;
if (playerY > screenHeight – 1)
playerY = screenHeight – 1;
_counters.NewTurn();
}[/code]
And change the end of the Update
handler to call these methods. Change this part of the Update
handler:
if (userAction)
{
// Ensure player stays on the screen
if (playerX < 0)
playerX = 0;
if (playerX > screenWidth – 1)
playerX = screenWidth – 1;
if (playerY < 0)
playerY = 0;
if (playerY > screenHeight – 1)
playerY = screenHeight – 1;
_counters.NewTurn();
}
// Real time actions
_counters.NewFrame();[/code]
into
if (userAction)
{
ProcessTurn();
}
// Update frame timers and counters
ProcessFrame();[/code]
We’ve done a number of changes in this article. download a zip file with the code to this point. Next time we’ll actually start implementing a real game by adding someone else besides our player to the game.
March 30, 2016
Article Published: Best Image Editors for OS X
Recent article of mine published on Best Image Editors for OS X at raywenderlich.com.