Wednesday, September 21, 2016

The 10 Most Common Mistakes That Unity Developers Make

Unity is a great and straightforward tool to use for multi-platform development. Its principles are easy to understand, and you can intuitively begin to create your products. However, if some things are not taken in mind, they’ll slow your progress when you proceed with your work to the next level, as you are moving from initial prototype phase or approaching a final release. This article will provide advice on how to overcome most common problems and how to avoid fundamental mistakes in your new or existing projects. Please note, the perspective of this article is focused more on 3D application development, but everything mentioned is applicable for 2D development as well.
UnityUnity is a great and straightforward tool to use for multi-platform development.

Common Unity Mistake #1: Underestimating Project Planning Phase

For every project, it’s crucial to determine several things before the application design and programming part of the project even begins. These days, when product marketing is an important part of the whole process, it’s also important to have a clear idea of what the business model of the implemented application will be. You have to be sure what platforms you will be releasing product for, and what platforms are in your plan. It’s also necessary to set the minimal supported devices specifications (will you support older low-end devices or just more recent models?) to have the idea of what performance and visuals you can afford. Every topic in this article is influenced by this fact.
From a more technical point of view, it should be necessary to set in advance the whole workflow of creating assets and models while providing them to the programmer, with particular attention to iteration process when the models will need some more changes and refinements. You should have a clear idea about desired frame rate and vertex budget, so the 3D artist can know in what maximal resolution the models have to be, and how many LOD variations he has to do. It should also be specified how to unify all the measurements to have a consistent scale, and import process throughout the whole application.
The way the levels will be designed is crucial for future work because the division of the level influences the performance a lot. Performance concerns have to always be in your mind when designing new levels. Don’t go with unrealistic visions. It’s always important to ask yourself the question “can it be reasonably achieved?” If not, you shouldn’t waste your precious resources on something hardly achievable (in case it’s not part of your business strategy to have it as your main competitive advantage, of course).

Common Unity Mistake #2: Working with Unoptimized Models

It’s critical to have all your models well prepared to be able to use them in your scenes without further modifications. There are several things that the good model should fulfill.
It’s important to set the scale correctly. Sometimes it’s not possible to have this correctly set from your 3D modeling software because of different units these applications are using. To make everything right, set the scale factor in models import settings (leave 0.01 for 3dsMax and Modo, set 1.0 for Maya), and note that sometimes you will need to re-import objects after changing the scale setting. These settings should assure that you can use just basic scale 1,1,1 in your scenes to get consistent behavior and no physics problems. Dynamic batching will also more likely work correctly. This rule should also be applied on every subobject in the model, not just the main one. When you need to tweak object dimensions, do it with regards to other objects in 3D modeling application rather than in Unity. However, you can experiment with scale in Unity to find out appropriate values, but for the final application and consistent workflow, it’s good to have everything well prepared before importing to Unity.
Regarding object’s functionality and their dynamic parts - have your models well divided. The fewer subobjects, the better. Separate parts of the object just in case when you need them, for example, to move or rotate dynamically, for animation purposes, or other interactions. Every object and its subobjects should have its pivot properly aligned and rotated with regards to its main function. The main object should have the Z axis pointing forward and pivot should be at the bottom of the object for better placement to the scene. Use as few materials on objects as possible (more on this below).
All assets should have proper names which will easily describe its type and functionality. Keep this consistency throughout all of your projects.

Common Unity Mistake #3: Building Interdependent Code Architecture

Prototyping and implementation of functionality in Unity is quite easy. You can easily drag and drop any references to other objects, address every single object in the scene, and access every component it has. However, this can also be potentially dangerous. On top of noticeable performance issues (finding an object in the hierarchy and access to components has its overhead), there is also great danger in making parts of your code entirely dependent on each other. Or being dependent on other systems and scripts unique to your application, or even on the current scene, or current scenario. Try to take a more modular approach and create reusable parts which can be used in other parts of your application, or even shared across your whole application portfolio. Build your framework and libraries on top of Unity API the same way you are building your knowledge base.
There’s a lot of different approaches to ensure this. A good starting point is the Unity component system itself. Complications may appear when particular components need to communicate with other systems of the application. For this, you can use interfaces to make parts of your system more abstract and reusable. Alternatively, you can use an event-driven approach for reacting to particular events from outside scope, either by creating a messaging system or by registering directly to parts of the other system as listeners. The right approach will be trying to separate gameObject properties from program logic (at least something like model-controller principle), because it’s tough to identify which objects are modifying its transform properties, like position and rotation. It should be exclusively its controller’s responsibility.
Try to make everything well documented. Treat it always like you should return to your code after a long time and you need to understand quickly what exactly this part of the code is doing. Because in reality, you will quite often get to some parts of your application after some time and it’s an unnecessary obstacle for quickly jumping into the problem. But do not overdo this. Sometimes, an appropriate class, method or property name is quite sufficient.

Common Unity Mistake #4: Wasting Your Performance

The latest product line of mobile phones, consoles, or desktop computers will never be so advanced that there will be no need to care about performance. Performance optimizations are always needed, and they provide the foundation for making the difference in how your game or application looks like in comparison to others on the market. Because when you save some performance in one part, you can use that to polish other parts of your application.
There are a lot of areas for optimizations. The whole article would be needed just to scratch the surface about this topic. At least, I will try to divide this domain into some core areas.

Update Loops

Don’t use performance intensive things in update loops, use caching instead. A typical example is an access to components or other objects in a scene or intensive calculations in your scripts. If possible, cache everything in Awake() methods, or change your architecture to a more event-driven approach to trigger things just when they’re needed.

Instantiations

For objects that are instantiated quite often (for example, bullets in an FPS game), make a pre-initialized pool of them and just pick one already initialized when you need it and activate it. Then, instead of destroying it when it is not required anymore, deactivate it and return it to the pool.

Rendering

Use occlusion culling or LOD techniques to limit rendered parts of the scene. Try to use optimized models to be able to keep vertex count in the scene under control. Be aware, vertex count isn’t just the number of vertices on the model itself, but it’s influenced by other things like normals (hard edges), UV coordinates (UV seams) and vertex colors. Also, a number of dynamic lights in the scene will dramatically influence overall performance, so try to bake everything in advance whenever possible.

Draw Calls

Try to reduce draw calls count. In Unity, you can achieve draw calls reduction by using static batching for still objects and dynamic batching for the moving ones. However, you have to prepare your scenes and models first (batched objects have to share same materials), and batching of dynamic objects works only for low-res models. Alternatively, you could combine meshes by the script into one (Mesh.CombineMeshes) instead of using batching, but you have to be careful not to create too large objects which can’t take advantage of view frustum culling on some platforms. In general, the key is to use as little materials as possible and share them across the scene. You will sometimes need to create atlases from textures to be able to share one material between distinct objects. A good tip is also to use higher resolution of scene lightmaps textures (not generated resolution, but texture output resolution) to lower their number when you are baking light in larger environments.

Overdraw Problems

Don’t use transparent textures when not necessary, as it will cause fill-rate problems. It is okay to use it for complicated and more distant geometry, like trees or bushes. When you need to use it, prefer alpha blended shaders instead of shaders with alpha testing or instead of cutout shaders for mobile platforms. For identifying these problems in general, try to lower the resolution of your application. If it helps, it might be possible that you have these fill-rate problems, or you need to optimize your shaders more. Otherwise, it can be a more memory problem.

Shaders

Optimize your shaders for better performance. Reduce the number of passes, use variables with lower precision, replace complicated math calculations with pre-generated lookup textures.
Always use a profiler to determine the bottlenecks. It’s a great tool. For rendering, you can also use awesome Frame Debugger, which will help you learn a lot about how things work in general when decomposing rendering processes with it.

Common Unity Mistake #5: Ignoring Garbage Collection problems

It is necessary to realize that despite the fact that Garbage Collector (GC) itself helps us to be really efficient and focused on important things in programming, there are a few things we should be explicitly aware of. The usage of GC isn’t free. Generally, we should avoid unnecessary memory allocations to prevent GC from firing itself too often and thus spoiling performance by framerate spikes. Ideally, there shouldn’t be any new memory allocations happening regularly each frame at all. However, how can we achieve this goal? It’s really determined by application architecture, but there are some rules you could follow which help:
  • Avoid unnecessary allocations in update loops.
  • Use structs for simple property containers, as they’re not allocated on the heap.
  • Try to preallocate arrays or lists or other collections of objects, instead of creating them inside update loops.
  • Avoid using mono problematic things (like LINQ expressions or foreach loops, for example) because Unity is using an older, not ideally optimized version of Mono (at the time of writing it is modified version 2.6, with upgrade on the roadmap).
  • Cache strings in Awake() methods or in events.
  • If update of string property in update loop is necessary, use StringBuilder object instead of string.
  • Use profiler to identify potential problems.

Common Unity Mistake #6: Optimizing Memory and Space Usage Last

It is necessary to keep the attention on the lowest memory and space usage of the application from the beginning of the project, as it is more complicated to do it when you leave optimization for pre-release phase. On mobile devices, this is even more important, because we are quite short on resources there. Also, by exceeding 100MB size of the installation, we can lose a significant amount of our customers. This is because of the 100MB limit for cellular network downloads, and also because of psychological reasons. It is always better when your application doesn’t waste customer’s precious phone resources, and they will be more likely to download or buy your app when its size is smaller.
For finding resource drainers, you can use editor log where you can see (after every new build) the size of resources divided into separate categories, like audio, textures, and DLLs. For better orientation, there are editor extensions on the Unity Asset Store, which will provide you a detailed summary with referenced resources and files in your filesystem. Actual memory consumption can also be seen in the profiler, but it is recommended to test it when connected to build on your target platform because there are a lot of inconsistencies when testing in an editor or on anything other than your target platform.
The biggest memory consumers are often textures. Preferably, use compressed textures as they take much less space and memory. Make all textures squared, ideally, make the length of both sides power of two (POT), but keep in mind Unity can also scale NPOT textures to POT automatically. Textures can be compressed when being in the POT form. Atlas textures together to fill the whole texture. Sometimes you can even use texture alpha channel for some extra information for your shaders to save additional space and performance. And of course, try to reuse textures for your scenes as much as possible, and use repeating textures when it is possible to retain good visual appearance. For low-end devices, you can lower the resolution of textures in Quality Settings. Use compressed audio format for longer audio clips, like the background music.
When you are dealing with different platforms, resolutions or localizations, you can use asset bundles for using different sets of textures for different devices or users. These asset bundles can be loaded dynamically from the internet after the application was installed. This way, you can exceed the 100MB limit by downloading resources during the game.

Common Unity Mistake #7: Common Physics Mistakes

Sometimes, when moving objects in the scene, we don’t realize that the object has a collider on it and that changing its position will force the engine to recalculate the whole physical world all over again. In that case, you should add Rigidbody component to it (you can set it to non-kinematic if you don’t want external forces to be involved).
To modify the position of the object with Rigidbody on it, always set Rigidbody.position when a new position doesn’t follow the previous one, or Rigidbody.MovePosition when it is a continuous movement, which also takes interpolation into account. When modifying it, apply operations always in FixedUpdate, not in Updatefunctions. It will assure consistent physics behaviors.
If possible, use primitive colliders on gameObjects, like sphere, box, or cylinder, and not mesh colliders. You can compose your final collider from more than one of these colliders. Physics can be a performance bottleneck of your application because of its CPU overhead and collisions between primitive colliders are much faster to calculate. You can also adjust Fixed Timestep setting in Time manager to reduce the frequency of physics fixed updates when the accuracy of physics interaction isn’t so necessary.

Common Unity Mistake #8: Manually Testing All Functionality

Sometimes there might be a tendency to test functionality manually by experimenting in the play mode because it is quite fun and you have everything under your direct control. But this cool factor can decrease quite quickly. The more complex the application becomes, the more tedious tasks the programmer has to repeat and think about to assure that the application behaves as it was originally intended. It can easily become the worst part of the whole development process, because of its repetitive and passive character. Also, because the manual repetition of testing scenarios isn’t that fun, so there’s a higher chance that some bugs will make it through the whole testing process.
Unity has great testing tools to automate this. With appropriate architectural and code design, you can use unit tests for testing isolated functionality, or even integration tests for testing more complex scenarios. You can dramatically reduce try-and-check approach where you’re logging actual data and comparing it with its desired state.
Manual testing is without a doubt a critical part of the development. But its amount can be reduced, and the whole process can be more robust and faster. When there’s no possible way to automate it, prepare your test scenes to be able to get into the problem you are trying to solve as quickly as possible. Ideally, a few frames after hitting the play button. Implement shortcuts or cheats to set the desired state for testing. Also, make the testing situation isolated to be sure what’s causing the problem. Every unnecessary second in the play mode when testing is accumulated, and the bigger the initial bias of testing the problem, the more likely you won’t test the problem at all, and you will hope that all works just fine. But it probably won’t.

Common Unity Mistake #9: Thinking Unity Asset Store Plugins Will Solve All Your Problems

Trust me; they won’t. When working with some clients, I sometimes faced the tendency or relicts from the past of using asset store plugins for every single little thing. I don’t mean there aren’t useful Unity extensions on the Unity Asset Store. There are many of them, and sometimes it’s even hard to decide which one to choose. But for every project, it is important to retain consistency, which can be destroyed by unwisely using different pieces that do not fit well together.
On the other hand, for functionality which would take a long time for you to implement, it is always useful to use well-tested products from Unity Asset Store, which can save you a huge amount of your development time. However, pick carefully, use the proven ones which won’t bring a lot of uncontrollable and weird bugs to your final product. Five-star reviews are a good measure for a start.
If your desired functionality isn’t hard to implement, just add it to your constantly growing personal (or company’s) libraries, which can be used in all of your projects later again. That way you are improving your knowledge and your toolset at the same time.

Common Unity Mistake #10: Having No Need to Extend Unity Basic Functionality

Sometimes it may seem that Unity Editor environment is quite sufficient for basic game testing and level design, and extending it is a waste of time. But trust me, it is not. Unity’s great extension potential comes from being able to adapt it to specific problems which need to be solved in various projects. This can either improve the user experience when working in Unity or dramatically speed up the entire development and level design workflow. It would be unfortunate not to use built-in features, like built-in or custom Property Drawers, Decorator Drawers, custom component inspector settings, or even to not build whole plugins with its own Editor Windows.

Conclusion

I hope these topics will be useful for you as you move your Unity projects further. There are a lot of things which are project specific, so they can’t be applied, but it’s always useful to have some basic rules in mind when trying to solve more difficult and specific problems. You might have different opinions or procedures on how to solve these problems in your projects. The most important is to keep your idioms consistent throughout your project so that anyone in your team can clearly understand how the particular domain should have been solved correctly.
This article was written by Tomas Macek, a Toptal freelance developer.

Thursday, September 15, 2016

Ultimate Guide to the Processing Language Part I: The Fundamentals

You are struggling with boredom, and itching to use your creativity. You want to build something, something visually impressive, something artsy. Or maybe you want to learn programming and make something impressive as soon as possible. If so, then the Processing language is the way to go.
Among all the programming languages I have worked with so far, Processing was without a doubt one of the most entertaining ones. It is a straightforward language - easy to learn, understand and use, yet it is very powerful. It is almost like you are painting on an empty canvas with lines of code. There are no rigid rules or guidelines whatsoever to limit your creativity, the only limit is your imagination.
Ultimate Guide to the Processing language Part I: The Fundamentals
In college I was a teaching assistant of a program that gathered high school students and taught them Processing. Most of them didn’t have a strong programming background, some hadn’t even written a single line of code before. In only five days, they were expected to learn the language and build simple games of their own. The success rate was almost a hundred percent, we rarely faced failure. In this article, this is exactly what we’ll be doing. I shrank down the entire program into two parts. First part, I will be talking about the language. I will give a basic overview, a walkthrough for Processing and I will give some tips & tricks. Then in the next part, we will build a simple game step by step, each step will be explained in detail. I will also convert the code of the game into JavaScript using p5js, so that our game can run in a web browser.

What You Should Already know

To understand and easily follow these articles, you should have a basic knowledge of programming, as I will not be talking about programming fundamentals. I will mostly not be touching any advanced programming concepts though, so a superficial understanding will do. There are some parts where I talk about some low level ideas and concepts such as object-oriented programming (OOP), but they are not crucial. Those are for curious readers who are interested in the structure of the language. If you don’t want to know, you can just skip those parts. Other than that, the only thing you should have is the ambition to learn this awesome language and enthusiasm to create your own game!

How to Follow

I’m always in favor of learning programming by trying and experimenting. The sooner you dive into your own game, the faster you’ll get comfortable with Processing. So that will be my first suggestion, try each and every step in your own environment. Processing has a simple and easy to use IDE (i.e. a code editor), it is the only thing you’ll need to download & install to follow. You can download it from here.
So let’s get started!

What is the Processing Language?

This section includes a brief technical overview of the language, its structure and some notes on the compilation and execution process. The details will include some advanced knowledge on programming and the Java environment. If you don’t mind about details for now and can’t wait to learn and code your own game, you can skip to the “Fundamentals of Processing” section.
Processing is a visual programming language that allows you to sketch with codes, so to speak. However it is not exactly a programming language on its own, it is what they call a “Java-esque” programming language, which means the language is built on top of the Java platform, but is not exactly Java per se. It is based on Java and all your code gets preprocessed and converted directly into Java code when you hit the run button. Java’s PApplet class is the base class for all Processing sketches. To give an example, let’s take a couple of basic processing code blocks:
public void setup() {
  // setup codes goes here
}
public void draw() {
  // draw codes goes here
}
These code blocks will be converted into something like this:
public class ExampleFrame extends Frame {

     public ExampleFrame() {
         super("Embedded PApplet");

         setLayout(new BorderLayout());
         PApplet embed = new Embedded();
         add(embed, BorderLayout.CENTER);

         embed.init();
     }
}

public class Embedded extends PApplet {
   
    public void setup() {
      // setup codes goes here
    }
    public void draw() {
      // draw codes goes here
    }
    
}
You can see that the processing code block was wrapped with a class that extends from Java’s PApplet. Therefore, all the classes you define in your processing code, if any, will be treated as inner classes.
The fact that Processing is Java based gives us a lot of advantages, especially if you are a Java developer. Not only is the syntax familiar, but it also gives you the ability to do things like embedding Java code, libraries, JAR files in your sketches, using your Processing applets directly in your Java applications, defining classes and using standard data types such as int, float, char and so on. You can even write your Pocessing code directly from Eclipse, if you want to spend some time to set it up. One thing you can’t do is use AWT or Swing components in your Processing sketches, because they conflict with the looping nature of Processing. But don’t worry, we will not be doing any of that fancy stuff in this article.

Fundamentals of Processing

Processing code consists of two main parts, setup and draw blocks. Setup block runs once when the code gets executed, and the draw blocks runs continuously. The main idea behind Processing is, what you write within the draw block will be executed 60 times per second from top to bottom, until your program terminates. We will build everything by taking advantage of this this very idea. We will make our objects move, keep our scores, detect collisions, implement gravity, and do pretty much everything else using this feature. This refresh loop is the heartbeat of our project. I will be explaining how to use this heartbeat to bring your code to life in later sections. First, let me introduce you to the Processing IDE.

Processing IDE

If you have read until this point and still didn’t download the Processing IDE, please go ahead and do it. Throughout the article, I will outline some easy tasks for you to try on your own, you can only practice if you have the IDE up and running. Here is a brief introduction of the processing IDE. It is very simple and self explanatory, so I will keep it short.
As you’d expect, run and stop buttons do what they suggest. When you click on the run button, your code will get compiled and executed. By nature, processing programs never get terminated, they run forever and ever until they get disturbed. You can terminate it programmatically, however if you don’t, you can use the stopbutton.
The button that looks like a butterfly on the right of the run & stop is the debugger. Using the debugger needs a whole other article dedicated to it. It is out of the scope of this article, so you can ignore it for now. The dropdown next to debugger button is where you add / set mods. Mods provide you some certain functionality, allow you to write code for Android, allow you to write code in Python, and so on and so forth. Mods are also out of the scope, so you can keep it in the default Java mode and ignore it as well.
The window on the code editor is where your sketches normally run. In the image it is blank, because we haven’t set any property like size or background color, or we didn’t draw anything.
There is nothing much to talk about the code editor, it is simply where you write your code. There are line numbers(!) Older versions of Processing didn’t have that and you can’t imagine how happy I was when I first saw them.
The black box below is the console. We will use it to print out stuff for quick debugging purposes. The errorstab next to the console is where your errors will appear. This is also a new useful feature that came with Processing 3.0. In the older versions, the errors were printed to the console and it was hard to keep track of them.

Setup Block

As stated before, setup blocks get executed once when the program starts. You can use it for making configurations and for things that you’d like to run only once, for instance, loading images or sounds. Here is an example setup block. Run this code in your own environment and see the results for yourself.
public void setup() {
  // Size of our sketch will be 800x600, 
  // and use the P2D rendering engine.
  size(800, 600, P2D);
  
  // We could have used this function instead of size()
  // fullScreen(P2D);
  
  // The background color of our sketch will be black
  // by default, unless specified otherwise
  background(0);
  
  // We could have used this to set a background image.
  // Note that size of our sketch should be the same as the image.
  // background(loadImage("test.jpg"));
  
  // Shapes and objects will be filled with red by default,
  // unless specified otherwise.
  fill(255,0,0);
  
  // Shaped and objects will have a white border by default,
  // unless specified otherwise.
  stroke(255);
}
The methods related with styling (background, fill, stroke) will be explained at the properties & settings sections. For now, what you need to know is how the settings and configurations we set here affects our whole sketch. Codes written here are used to set some base rulesets applicable throughout the sketch. What you should also understand in this section are the methods listed below:
size() - As the name suggests, this function is used to configure the size of our sketch. It has to be in the first line of the setup code block. It could be used in the following forms:
  • size(width,height);
  • size(width, height, renderer);
The width and height values could be given in pixels. Size function accepts a third parameter, renderer, which is used to set which rendering engine our sketch will use. By default, the renderer is set to P2D. The available renderers are P2D (Processing 2D), P3D (Processing 3D, should be used if your sketches will include 3D graphics) and PDF (2D graphics are drawn directly into an Acrobat PDF file. More inforation can be foundhere). P2D and P3D renderers make use of OpenGL compatible graphics hardware.
fullScreen() - As of Processing 3.0, fullScreen function can now be used instead of the size() function. Just like the size() function, it should be in the first line of the setup block as well. The usage is as follows:
  • fullScreen();
  • fullScreen(display);
  • fullScreen(renderer);
  • fullScreen(display, renderer);
If you use it without any parameters, your processing sketch will simply run in fullscreen, and will run on your main display. The ‘display’ parameter is used to set on which display your sketch will run. For example if you connect external monitors to your computer, you can set the display variable to 2 (or 3, 4 etc.) and your sketch will run there. The ‘renderer’ parameter is as explained at the size() part above.

Settings Block

This is another feature that is introduced with the new release of Processing. It is a code block, just like setup and draw. It is useful when you want to define size() or fullScreen() methods with variable parameters. It is also necessary to define size() and other styling properties such as smooth() in this code block if you are using any environment other than Processing’s own IDE, such as Eclipse. But you will not be needing it in most cases, definitely not in this article.

Draw Block

There is nothing special to talk about the draw block, yet everything is special about it. Draw block is where all the magic happens. It is the heart of your program, beating 60 times a second. This code block houses all your code logic. All your shapes, objects etc. will be written in here.
Most of the code we will talk about in this article is going to be from the draw block, so it is important that you clearly understand how this code block works. To give you a demonstration, here is something you can try. First note that we can print anything to the console by using the print() or println() methods. Print methods only print to the console, println however prints and appends a newline at the end, so each println() will print in separate rows.
So, take a look at the following code block. First, try to guess what it will print in the console. Then, go ahead and try it out:
void setup(){
}
void draw(){
  int x = 0;
  x += 1;
  print(x+" ");
}
If you guessed “1 2 3 4…”, I got you! This is one of the confusions in Processing. Remember this block repeatedly gets executed? When you define a variable here, it gets defined on each loop over and over again. On each iteration, x is set to 0, gets incremented by 1 and gets printed to the console. Therefore we get the result “1 1 1 1…”. This example was somewhat obvious, but it may be confusing when things get a little complicated.
We don’t want x to get overwritten, so how can we achieve this and get the result “1 2 3 4…” ? By using global variables. This is nothing fancy, we only define the variable outside of draw block so it doesn’t get re-defined on each iteration. Also, the scope of the variable will be reachable throughout the sketch. See the code below:
int x = 0;

void setup(){
}
void draw(){
  x += 1;
  print(x+" ");
}
You might be asking yourself, how can a variable defined outside of our blocks work? And why didn’t we use the setup() block since it gets executed once at the beginning? The answer is related with object-oriented programming and scopes, if you are not familiar, you may skip this paragraph. Refer to the part where I explained how Processing code gets converted into Java. Remember how they get wrapped with a Java class? The variables we write outside of setup() and draw() block also gets wrapped, therefore they are treated as fields of the outer class that wraps our code. Using x+=1 is the same as using this.x+=1. It also functions the same in our case, no variable called x is defined in the scope of draw() and an outer scope is searched, which is the scope of this. And why didn’t we define our variable x in the setup() section? If we did, the scope of which x is defined would be the scope of the setup function and it wouldn’t be accessible from the draw() block.

Drawing Shapes & Texts

Now we know how to configure our sketch using the setup block, and we know what draw block does. So it is time to get a little visual and learn about the fun parts of processing: how to draw shapes.
Before we begin, you should understand the coordinate system. In Processing, you determine the coordinates of every object you draw on the screen. The coordinate system is in pixels. The origin (ie. starting point) is the top left corner, you should give your coordinates relative to that point. Another thing you should know is, each shape has a different reference point. For example, rect() has its top left corner as a reference point. For ellipse(), it is the center. These reference points can be changed with methods like rectMode() and ellipseMode(), which I will be explaining in the properties & settings section. An example figure is provided to help you understand better.
This article is a basic overview of Processing, so we will not be touching any complex shapes like vertexes or 3D shapes. Basic 2D shapes will actually be more than enough for us to create our own game. In the figure, you can see examples of how shapes are drawn. Each shape has its own syntax to be created, but the basic idea is to give either its coordinates or its sizes or both. Here are some shapes you should be familiar with (for all values given below, ‘x’ and ‘y’ means x and y coordinates in pixels, ‘w’ and ‘h’ means width and height values also in pixels):
point() - Simple point, only needs a single coordinate. Usage:
  • point(x, y)
  • point(x, y, z) - In case you are using 3 dimensions.
line() - For creating a line. You can create a line with only a starting and ending point. Usage:
  • line(x1, y1, x2, y2)
  • line(x1, y1, z1, x2, y2, z2) - In case you are using 3 dimensions.
triangle() - For creating a triangle. Usage: triangle(x1, y1, x2, y2, x3, y3)
quad() - For creating a quadrilateral. Usage: quad(x1, y1, x2, y2, x3, y3, x4, y4)
rect() - For creating a rectangle. The reference point is top left corner by default (refer to the figure). Here is the usage:
  • rect(x, y, w, h)
  • rect(x, y, w, h, r) - ‘r’ mean the radius in pixels to make the corners rounded.
  • rect(x, y, w, h, tl, tr, br, bl) - Radius for top left, top right, bottom right, bottom left corners respectively. This is also in pixels.
ellipse() - For creating an ellipse shape. This is also used to create a circle, same width and height values should be given. The reference point for this shape is the center by default (refer to the figure). Here is the usage:
  • ellipse(x, y, w, h)
arc() - Draw an arc. Usage:
  • arc(x, y, w, h, start, stop) - ‘start’ and ‘stop’ is used to determine the angle to start and stop drawing the arc. Values are in radians. Constants such as “PI, HALF_PI, QUARTER_PI and TWO_PI” can be used.
  • arc(x, y, w, h, start, stop, mode) - ‘mode’ variable is to determine the rendering style of the arc (string). Available options are “OPEN, CHORD, PIE”. OPEN will leave the non-drawn parts borderless. CHORD will complete the non-drawn parts with a border. PIE will make your arc look like a pie chart.
Displaying texts on the screen is similar to displaying shapes, the basic idea is that you determine a coordinate at which you want your text to be displayed. There is however more to handling texts. You will have more control over your texts after the properties & settings section, where you’ll learn how to apply settings and properties to objects. For now, I will show the basics of displaying texts. There are many ways to do it, I’ll only show the essentials.
text() - Display texts. Usage:
  • text(c, x, y) - ‘c’ means character, any alphanumeric character will be displayed.
  • text(c, x, y, z) - In case you are working with 3 dimensions.
  • text(str, x, y) - ‘str’ is the string to be displayed.
  • text(str, x, y, z) - In case you are working with 3 dimensions.
  • text(num, x, y) - ‘num’ is the numeric value to be displayed.
  • text(num, x, y, z) - In case you are working with 3 dimensions.

Properties & Settings

First thing that should be explained in this section would be the logic behind setting properties of objects. Fill color, background color, border, border width, border color, alignment of the shapes, border styles etc. could be some examples of these properties.
When you set a property, you have to remember that the code will be executing from top to bottom. Say, you set the “fill” property to red, all the objects drawn below that line will be filled with red until it gets overwritten by another fill property. Same thing applies for other properties as well, however note that not all properties will overwrite each other. For example “stroke” property doesn’t overwrite “fill” property, instead they work together. Here is a visual representation for you to comprehend the logic:
As you can see in the image, first line sets the fill color to red and the second line sets the stroke color to blue. We now have two active settings: fill red and blue strokes. As you’d expected, whatever our object may be on the next line, it will be filled with red and have blue strokes (if applicable). You can keep examining the image this way, and you will grasp the logic.
Here are some essential properties & settings that are commonly used:

Styling settings

fill() - Sets the fill color to objects. This setting is also used to color texts. For now, we only need to know the following usage:
  • fill(r, g, b) - Red, green and blue values as integer
  • fill(r, g, b, a) - Additional alpha value, max is 255
noFill() - Sets the fill color to transparent.
stroke() - Sets the stroke color to objects. Stroke property is applicable for lines and borders around objects. For now, we only need to know the following usage:
  • stroke(r, g, b) - Red, green and blue values as integer.
  • stroke(r, g, b, a) - Additional alpha value, max is 255
noStroke() - Removes the stroke.
strokeWeight() - Sets the width of the stroke. Usage:
  • strokeWeight(x) - x is an integer and represents the width of stroke in pixels.
background() - Sets the background color. For now, we only need to know the following usage:
  • background(r, g, b) - Red, green and blue values as integer.
  • background(r, g, b, a) - Additional alpha value, max is 255

Alignment Settings

ellipseMode() - Sets where to take as reference point aligning ellipses. Usage:
  • ellipseMode(mode) - ‘mode’ is the parameter, here are the available parameters:
    • CENTER (default): Take the center as the reference point.
    • RADIUS: This also takes the center as a the reference point, but in this mode, the w and h values you specify are treated as half (ie. radius instead of diameter)
    • CORNER: Takes top left corner as a reference point.
    • CORNERS: Sets the first two parameters (x and y) as the location of the top-left corner, and last two parameters (w and h) as the location of the bottom left corner of the ellipse. So this mode, “width” and “height” is irrelevant. Thinking it as ellipse(x_tl,y_tl,x_br,y_br) makes more sense in this case.
rectMode() - Sets where to take as reference point aligning rectangles. Usage:
  • rectMode(mode) - ‘mode’ is the parameter, here are the available parameters:
    • CENTER: Take the center as the reference point.
    • RADIUS: This also takes the center as a the reference point, but in this mode, the w and h values you specify are treated as half
    • CORNER (default): Takes top left corner as a reference point.
    • CORNERS: Sets the first two parameters (x and y) as the location of the top-left corner, and last two parameters (w and h) as the location of the bottom left corner of the ellipse. So this mode, “width” and “height” is irrelevant. Thinking of it as rect(x_tl,y_tl,x_br,y_br) makes more sense in this case.
textSize() - Sets the font size of text. Usage:
  • textSize(size) - Integer value of the desired size.
textLeading() - Sets the line height of your texts. Usage:
  • textLeading(lineheight) - Pixel value of the space between lines.
textAlign() - Sets where to take as reference point aligning texts. Usage.
  • textAlign(alignX) - ‘alignX’ is for horizontal alignment. Available: LEFT, CENTER, RIGHT
  • textAlign(alignX, alignY) - ‘alignY’ is for vertical alignment. Available: TOP, BOTTOM, CENTER, BASELINE.

Animations

So far, we learned how to draw objects and texts. But the problem with them is that they are static. Now how do we make them move? Simple, instead of giving coordinates as integers, we use variables so that we can increment / decrement them. Make sense? Take a look at the following code:
// initialize x and y as 0
int x=0;
int y=0;

void setup(){
  size(800,600);
  background(255); // set background color to white
}

void draw(){
  fill(255,0,0); // fill color red
  stroke(0,0,255); // stroke color blue
  ellipseMode(CENTER); // ref. point to ellipse is its center
  
  ellipse(x, y, 20, 20); // draw the ellipse
  
  // increment x and y
  x+=5;
  y+=5;
}
Do you see how we managed the animation? We set x and y as global variables and their initial value to 0. In our draw loop, we created our ellipse, set the fill color to red, stroke color to blue and coordinates to x and y. When we increment x and y, the ball simply changes its location. But there is a problem with this code, can you notice it? As an easy challenge for yourself, try to figure what the problem is, and test it out. Here is the outcome:
My intention for letting this happen was to make you realise how the looping nature of Processing works. Refer to example at the “Draw Block” section, do you remember why we got “1 1 1…” instead of “1 2 3…” ? The same reason why the ball is leaving marks behind. Each time the draw block iterates, x and y gets incremented by 5 and therefore the ball gets redrawn to 5 pixels down and right. However the ball is drawn from the previous iterations remain in the view. How do we make them go away? Any guesses?
To get rid of the marks the ball leaves behind, we simply remove the background(255) from setup block, and paste it to be the very first line of the draw block. When our background code was in the setup block, it ran one time at the beginning, making our background white. But that isn’t enough, we need it to set our background to white on each loop to cover the balls drawn from the previous loops. Background being the first line means it runs first, it becomes the base layer. On each loop, our canvas is painted white, and new elements gets drawn on top of the white background. So we have no marks.
That is the idea behind animating things in Processing, manipulating the objects’ coordinates programmatically to change their location. But how will we do fancy stuff, such as keeping the ball in the screen? Or maybe implementing gravity? I will teach how to do this stuff in next part of this article. We will learn by trying and building. We will learn how to do it and apply them to our game immediately. At the end, we will have a complete, playable, and hopefully fun game.

Keyboard & Mouse Interactions

Keyboard & mouse interactions in Processing are very easy and straightforward. There are methods you can call for each event, and what you write inside will be executed once when the event occurs. Also there are global variables such as mousePressed and keyPressed you can use in your draw block to take advantage of the loop. Here are some of the methods with explanations:
void setup() {
  size(500, 500);
}

void draw() {

  if (mousePressed) {
    // Codes here will be executed as long as the mouse
    // button is pressed
    
    if (mouseButton == LEFT){
      // This lines will be executed as long as
      // the clicked mouse button is the left mouse
      // button.
    }
  }

  if (keyPressed) {
    // Codes here will be executed as long as a key
    // on the keyboard is pressed
    
    if (key == CODED) {
      // This if statement checks if the pressed key
      // is recognised by Processing.
       
      if (keyCode == ENTER) {
        // This lines will be executed if the pressed key
        // is the enter key.
      }
    }
    else{
      // This lines will be executed if the pressed key
      // is not recognised by processing.
    }
  }
  
}

void mousePressed() {
  // These codes will be executed once, when mouse
  // is clicked. Note that mouseButton variable is
  // also be used here.
}

void keyPressed() {
  // These codes will be executed once, when a key
  // is pressed. Note that key and keyCode variables
  // are also usable here.
}
As you can see, it is pretty easy to check whether the mouse is clicked or which key is being pressed. There are however more options available for mousePressed and keyCode variables. Available options formousePressed are LEFT, RIGHT and CENTER. There are many more available for keyCode; UP, DOWN, LEFT, RIGHT, ALT, CONTROL, SHIFT, BACKSPACE, TAB, ENTER, RETURN, ESC and DELETE.
One thing to know about the mouse variables, and we will use this a lot, is how to get the coordinates of the mouse. To get the exact coordinates of the cursor, we can use mouseX and mouseY variables directly in the draw() block. Last but not least, there are a lot of other useful methods that you should take a look at. They are all documented in the Processing Reference.

Conclusion

You should be getting familiar with Processing by now. However if you stop here, all this knowledge will flyaway. I strongly recommend you continue practicing, playing around with what you have learned. To help you practice, I will provide you with two exercises. You should try your best to do it on your own. If you get stuck,Google and Processing Reference should be your best friends. I will provide the code for the first one, but looking at them should be the last thing that you do.
You should make 4 balls with different colors, starting from 4 corners of the screen traveling through the center with different speeds. When you click and hold the mouse button, the balls should freeze. And when you let go of the mouse, the balls could go back to their initial position and keep moving. So, I am looking for something like this.
After you try the exercise yourself, you may check out the code here.
Remember the famous DVD screensaver which the DVD logo bounces around the screen and we all waited desperately for it to hit the corner? I want you to replicate that screensaver, but only using a rectangle instead of the DVD logo. When you start the app, the screen should be black and the rectangle should start at a random location. Each time the rectangle hits the corner, it should change its color (and obviously direction). When you move the mouse around, the rectangle should disappear and the background color should turn white (it is a screensaver, isn’t it?). I will not give the code for this exercise in this article. You should try your best to implement it, and the code will be provided in the second part of this article.
The second part of the ultimate guide to Processing, a step-by-step tutorial to building a simple game, has been published on a prior article on Treadgaming.
This article was written by Oguz Gelal, a Toptal freelance developer.