Lately, I've been looking into ownCloud, an alternative to various cloud services such as Dropbox, Skydrive and Google Drive. Although it's still very much in development and not at the same level as it's competitors, I'm really impressed by the concept. Cloud storage is an amazing idea, but I always struggled with having your files stored at some random place I can't actually get to or control. Because I can host ownCloud myself, it pretty much solves those problems.
Part of the ownCloud ecosystem is the Android client. Unfortunately, this part has some catching up to do, as it lacks certain obvious features such as downloading an entire folder, picture thumbnails and a way of searching for files. So in this post, I'm covering how to set up a build server for the ownCloud Android client.
Setup environment
1. Base installation
For the build server, I'm using a virtual machine to ensure a clean installation with as few problems as possible. You can choose to do the same or simply install everything on your host machine. Anyway, should you want to use a virtual as well, here are the specs I'm using:
Oracle Virtual Box
Windows 7 Professional
1GB Ram
25GB HDD
2. Install msysgit from https://code.google.com/p/msysgit/downloads/list.
Select 'Run Git and included Unix tools from the Windows Command Prompt', so we can simply run everything from the command line.
3. Install Java Development Kit (JDK) from http://www.oracle.com/technetwork/java/javase/downloads/index.html.
4. Install Apache Ant from http://ant.apache.org/bindownload.cgi Download the zip archive and unpack to C:\apache-ant-1.9.2. Of course, the version number can deviate.
5. Add C:\apache-ant-1.9.2\bin to the PATH.
6. Install Android SDK from http://developer.android.com/sdk/index.html Unpack to C:\adt.
7. Add C:\adt\sdk\tools to PATH.
You should now be able to run 'git', 'java', 'ant' and 'android' from the command prompt.
8. Install Android API 17 or higher.
Setup resources
We now have all required software to build an .apk file. It's time to download the latest sources from github.
9. Clone the latest sources from GitHub using the command line:
Optionally, you can add the '--recursive' flag, which already downloads submodules. However, the next step will also take care of this.
This creates a directory called 'android'.
10. Run setup_env.bat from the android directory. This sets up everything android-related.
11. Create a key for signing the apk. I'm putting this in a bat file called '0 - generate-key.bat'. You only need to run this once, as long as you don't delete the resulting key file or lose the password.
The path to the jdk may vary depending on the version you downloaded.
Fill in all requested data. Use the same password for both the keystore and the signing key. Save the password somewhere.
Generating the apk
12. Update sources. '1 - get-latest.bat'. This ensures you have the latest resources from GitHub, especially useful when running a build in a couple of days or weeks.
cd android git pull git submodule foreach git pull
13. Build. '2 - build.bat'. Compiles the source files into an unsigned apk.
ant -f android\build.xml clean release -Dsdk.dir="C:\adt\sdk"
Note: Possibly, you will see a Java error here, along the lines of 'Unable to locate tools.jar. Expected to find it in C:\...'. See this for a solution.
14. Sign. '3 - sign.bat'. Signing enables verification of the application's origin. Simply put, it enables installing the app without developer mode.
Now that all scripts are in place, we can run them each time we want to roll a new release. Note that you can skip generate-key, as long as the keystore is still available.
16. Now you have a signed and aligned apk, just transfer it to your Android device via e.g. usb, bluetooth or an ftp site.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality
Anya is LIVE right now
FREE
Free to watch • No registration required • HD streaming
Some time ago, a couple of months after releasing SlenderMod, I came across a page on Wikia. I found it very interesting people are actually collecting facts and theories about slenderman in our version of the game. There are some inconsistencies in the page however, so I thought I'd provide some explanations.
It is set in a grayscale (black and white) map with ambient music beginning before the 1st note is collected. The design of the game is more in 2D than 3D.
I'm not really sure what the writer meant by being more 2D than 3D, but the game is very much 3D. It could be the post-processing effects we added like contrast and vignetting, to accomplish a classic horror movie-like feeling.
The game is still in its trial mode, but has been praised by critics and gamers to be a lot creepier than The Eight Pages.
The 'trial version' text in the bottom-right corner of the game bit us in the behind quite a few times already. Now here's the thing: it refers to the Unity engine. So SlenderMod is, as a matter of fact, the full version and the final version. Because we required some pro features, we had to use the pro trial to build a release version.
The pages are brightly lit, so they are easy to spot from a distance.
This is indeed accurate. We tried to make SlenderMod a bit easier than the original, because that one felt too hard to complete.
The map is supposed to be double the size than the map in Slender: The Eight Pages. (It is surrounded by a huge concrete wall).
We didn't actually set a fixed size, like exactly twice the size of the original. Tim tried to make a map which gave the player a stronger sense of being all alone in this giant forest.
You play as a female character in this game.
True, we liked the idea of a little, defenseless girl as the protagonist, because it adds to the helplessness.
There is a glitch where you'll sometimes see the SlenderMan, but you won't die. This will be fixed in later versions to avoid cheating.
These are actually the infamous poofers, inspired by the name sharing guys from Amnesia. There are a couple of poofers in the game, one of which at the ruins, which will show up when you turn around at the 'Behind You' note. Poofers will go off only once, if you trigger one, all of them get disabled.
The girl you play as seems to get tired easily when sprinting and will breathe heavily whenever tired rather than The Eight Pages version. This could be caused by Slender sickness or by Slender Man himself.
I'm really impressed by the creativity that got into this one. The reality is a lot simpler, I'm afraid. The breathing is to discourage sprinting, so the player will be forced to move slowly through the map. Also, it adds to the scary atmosphere of the game.
One of the pages you collect shows a drawing of Slender Man holding hands with a little girl.
The drawing with the little girl depicts one of Slendy's victims. It seems this is one of our more twisted additions.
There is a grave that marks "Here lies Felix Arvid Ulf Kjellberg (Pewdiepie), who was killed by Barrels (Pewdie's nemesis).
We love Pewdiepie. Enough said.
In the bathroom there is a broken light that flickers on and off rapidly which makes the bathroom easily noticeable from far way.
The flickering light is based on an actual light in a hallway near Tim's residence, which was broken and flickered similarly at the time of development.
The pages are easier to see (they glow in the dark).
This is correct, done on purpose.
It is not possible to escape, once all eight pages are collected you just run around until the Slender Man catches you which he will.
Also true, I believe this was the same in the original. It's a lot of fun to see people panic when they realize nothing happens when they're done. The only difference with dying before finding all notes is that you get to see some credits.
The jumpscare music when you see the Slender Man is different.
We got our very own piano slam, although you'll only hear it when Slendy is very close.
The Slender Man has a new model, he has claws, he is less tall, he has a longer tie, his tie is black instead of red (in some games Slender Man has a red tie).
Tim created his own model, but we should have made him somewhat taller. His hands are replaced with tentacles.
One of the pages reads, "BEHIND YOU". When collected, if you look behind you, Slender Man will be right there, but will instantly disappear the next second. This is just for scares and will not kill you.
As stated earlier, this is one of the poofers. A poofer cannot kill you and if you already triggered a poofer elsewhere, you won't see this one. It is not required to pick up the note to trigger the poofer.
After Tim made the environment and assets, it was my turn to bring slendy to life. The original version had some tricky stuff in it, such as the spawn logic for slendy. It took some time and a bit of trial-and-error to get it just right. Slendy had to be unpredictable, which is, from a technical point of view, pretty much impossible. The result was quite close to unpredictable though, and even Tim and I got a fair amount of scares during development.
Programming and behavior
I started work on figuring out how exactly the spawning should happen. First of all, the slenderman must not actually move, he can only teleport. Second, the player may never see the slenderman teleport, neither becoming visible in his field of view nor disappearing when looking at him. Slendy must never be spawned in a tree or a rock and he has to be facing the player. He also must be at the correct height, that is the height of the floor under him. Finally, the spawn logic must be configurably throughout the game. As the player progressed by finding notes, slendy should get more aggresive while chasing him.
Spawn area
Once I got an idea of the rules slendy must obey, I began work on the spawn algorithm. I had some help from Michel, who got the idea of splitting it up into two steps.
Step 1 included deciding the direction relative to the player in which slendy would spawn. The full radius around the player consists of 360 degrees. We especially want control over how far to the front of the player the slenderman will spawn, so we split the area up into 2 half circles of 180 degrees. This made things easier, because we could generate a random number from 0 to 180, getting closer to the player's face the larger the number gets. By inverting the value half of the time, we still covered both sides.
The spawnable area in debug view, fully configurable per note
Step 2 described the actual distance between slendy and the player. Because the distance to the player should be somewhat random as well, I fitted in a range system, in which we could define between what bounds the spawning can happen. The image above shows the radius lines (the two red ones in front of the player and the green ones overlapping on the rear), along with the range lines, the white dashed circles. Because this system is pretty fast, I can simply teleport slendy, check if he collides with something like a tree and teleport again if he does.
Timing
Now I had an area where slendy could spawn. Next step was a timed execution of the actual teleporting. So every now and then, slendy may move to a new position. What we were looking for, is that typical, classic horror feel: you would look at him, look away, then look at him again to find that he's gone. It somehow induces a sense of panic, because you just lost control over a scary and dangerous guy. I went for a pretty simple system, with a timer that counted to a set amount of time. The amount of time was configurable per collected note. Each time the timer reached the limit, there is a certain chance that slendy would teleport. The actual chance is also configurable per collected note.
For every note the player collected, the teleport interval decreased and the teleport probability increased. This made slendy more active with each collected note.
Before actually considering to teleport slendy, the game decides whether the player can see him or not. If so, we should not move him. This decision making was one of the harder parts to accomplish. For this I again went for a two-step approach. First, I check if the slenderman is in a rough line of sight of the player, whether his position is within a certain angle relative to the player. When the first check passes, I then start doing a check on obstacles that may prevent slendy from being visible to the player.
Initially, I did a raycast from the player's camera to the slenderman's center. This kind of worked, but was quite imperfect because of the large amounts of trees that block this ray but not the entire view. So the ray was interrupted and slendy could be teleported while the player was still actually able to see him. To get around this, I added multiple points around the player and multiple points around slendy.
Slendy in full view, all lines are directly connected, without interruptions
Now I sent rays from the player's camera, somewhat left of the camera and somewhat right of the camera. From these 3 positions, rays are shot to different points at slendy's position. The amount of target points and their positions relative to slendy, are configurable. So now I had around 15 rays going from the player to slendy. When at least one of these rays is not interrupted by a tree, a rock or a wall, the player could probably see slendy and we should not do a teleport.
Partial view of slendy, some lines are interrupted Same view from the player's perspective, slendy is partially visible
public bool IsInLineOfSight() { Vector3 cameraPosition = playerCamera.transform.position; Vector3 to = slenderMan.slenderTransform.position; Quaternion playerRotation = playerTransform.rotation; Quaternion slendyRotation = slenderMan.slenderTransform.rotation; Vector3 originOffset; Vector3 castOffset; RaycastHit hit; for (int j = 0; j < rayCastOriginOffsets.Length; j++) { originOffset = playerRotation * rayCastOriginOffsets[j]; for (int i = 0; i < rayCastOffsets.Length; i++) { castOffset = slendyRotation * rayCastOffsets[i]; if (Physics.Raycast(cameraPosition + originOffset, ((to + castOffset + raycastOffset) - cameraPosition).normalized, out hit)) { if (hit.transform.GetComponent()) { return true; } } } } return false; }
Chasing
At this point, the slenderman was doing some nice teleporting and scaring us now and then. We encountered a new problem however. When the player would stand still for a longer amount of time, slendy didn´t actually come closer. That would only happen when the player found a note. So I added a mechanic called 'chase mode', which made him come closer even when you´re not finding new notes. As long as the player didn´t see slendy, the spawn area would not change and slendy would keep his distance for the first set of notes. When the player got a glimpse of him however, chase mode would activate.
Chase mode activated, the red line illustrates the distance to slendy that the player must have before chasing will stop
While chase mode is active, the spawn area shrinks every set amount of time. To deactivate chase mode, the player should out-run him by clearing a set distance between himself and slendy before he teleports again. Both the shrink time and distance it took to shake him, are configurable per found note. Of course, with every found note the shrink time becomes less and the shake distance greater.
Especially after finding a few notes, this can become really eerie. The slenderman is really chasing you and the game gets more creepy.
The last bit of logic that needed to be implemented, was slendy's positioning. He needed to spawn at the correct height, which varied throughout the level. It could be the reason that the original slender game had a flat ground, because it also makes detection of visibility by the player a whole lot harder. I fixed this by placing all walkable geometry in a seperate layer and sending a ray down to the terrain. Then I could read the z-value of the point where the ray hit and use that for slendy's new location. To complete the teleport, slendy's rotation is adjusted any frame the player is not looking at him. This way, he will always look directly at the player, even after walking around him.
// Look at player Quaternion delta = Quaternion.LookRotation(slenderMan.slenderTransform.position - playerTransform.position); delta.x = 0f; delta.z = 0f;
One last thing that is worth mentioning, is the bats effect. I placed a spherical collider around a couple of trees and put a bit of code on them which detects the player walking through them. When he does, there is a certain chance that the bats - which is a particle effect - triggers. There is a certain minimum amount of time before a second batch of bats can be triggered, so you won't get them every 10 seconds.
The spherical trigger on one of the trees
I really don't want to bother you with the post-processing effects, they are way too boring to explain in detail. The only thing you might want to know, is that it's a combination of vignetting (darkened edges), noise with scratches, vortex deforming (skews the view to add a bit of disorientation), depth of field to get the distant level features blurred, motion blur to add a dramatic effect when the player suddenly turns around, extra contrast and a grayscale to get the old movie-feel.
And that's how we made SlenderMod. The rest of the time, we were tweaking and playing to see how it all feels. There are some situations where people would not see slendy for the entire game, but we knew that could happen. It basically is the risk of making the AI so unpredictable. We made the game in a week or 3, using the Unity 3D engine. You can take a look at, or download the source code at GitHub, even use it to make your own version of the game.
It is taking a whole lot longer to get that second post done on the slender game we made, so in the meantime, I thought I'd let you know that we've released the source code of SlenderMod today. For some reason, our commit history wouldn't come over. Anyway, the latest version is available at GitHub. Enjoy!
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality
Anya is LIVE right now
FREE
Free to watch • No registration required • HD streaming
After 'Slender' came out, me and a friend of mine thought is was awesome. I literally got a headache from just playing it, with every single cell in my body screaming 'Don't do this! Get the hell out!'. Soon, lots of people where convinced that it was even scarier than Amnesia, which was considered the mother of all horror games up until then. The new horror game got our attention and it didn't take long for us to start talking about creating our own version.
But why make a game that already existed? Well, the original had some flaws, although it really got people scared. All the trees where obviously the same, the ground was flat and the game was somewhat unforgiving hard. So we decided to make our very own Slender game. We set out with 2 main goals: make a game that we ourselves would actually find scary and get it to be played by PewDiePie.
Level and environment
The designer guy, who goes by the name of Tim Spaninks, started out with a level design. The basics where done quite quickly, in a matter of hours. This included 1 or 2 locations, an uneven terrain, a load of trees and grass and some test slendies. He conveniently added in some music, which actually is the soundtrack from the movie 'The Prestige', played very slowly. To top it off, a greyscale filter set the baseline for the atmosphere.
We let our willing friends play it and even without an actual chance of dying, they were impressed already. So we continued.
The train station
The first location that was added to the game, was the train station. It contained an audio trigger when walking in a certain spot, which plays a heavy train horn. The station was specifically made to contain some higher walls, so players would have to turn around a lot.
The playground
The playground was one of Tim's ideas right at the beginning of the game. He wanted to do some area where player's could hear children play. One of the very first images made by the creator of the slenderman, at the something awful forums, included a playground. The echo made the children sound like they are playing in the player's head, instead of actually being right there. It's amazing what a simple sound can do to a mental state.
The rocks and the pipes
The rocks and the pipes where kept almost the same as they where in the original game. They forced the player to look around, which increased the possibility of running into slendy.
The white tree
Some more hours went into the level and a lake was added. It had a really spooky atmosphere, because of the large, empty spot in the middle of the forest. We opted for the tree to be placed on a small island in the center of the lake, so players had to cross the water.
Funny story on the color of the leaves. In an early version, some of the trees where a bit too light. They actually lit up the environment and looked plain strange. So I searched for the texture, to tune it down a tad. I went through the textures one by one and made them completely white, so they would stand out and I would know which one it was. Anyway, I couldn't find the right texture and just waited for Tim to show up and fix his stuff. Later on, after the trees where fixed, we noticed that the tree at the lake was suddenly radiating a clear, white glow. Although this was a bug, it looked quite creepy and we decided to keep it that way.
The graveyard
It's a bit of a no-brainer to add a graveyard to a horror game, so we did that too. To induce a bit more crapped pants, we did some echo-ie violins on there. As a somewhat debatable greeting to our hero, we wrote PewDiePie's real name on the stone with the note on it. Many people noticed the writing and only realized it was a PewDiePie reference after reading the cause of death: 'Death by Barrels'. PewDie himself entered the graveyard from the rear and didn't see it though.
The bathroom
Arguably the most talked about location in the original slender, we had to be sure to include the bathroom. This was our little funhouse. Tim made it a lot easier to navigate, because the original was a real bitch to get through. Of course there has to be some dark side to that advantage, so this location also got it's own soundtrack. Then, we made one of the lights in the building blink, as inspired by a light that broke down in our neighborhood. Finally, we added our infamous poofers.
Poofers are these fake slendy's that are triggered when the player turns around in a certain spot. Each poofer has a certain probability of poofing and once one poofer has poofed, the other ones are disabled for the rest of the round. I think most players that got a poofer didn't realize that they where fake, because they turn around too fast to notice the dissolve effect. That's understandable, I saw one video where the poofers where already disabled and the player got the real slenderman at the exact same spot where a poofer normally spawns.
The ruins
Alright, so this is just a plain troll from our side. This location has some shared props with the station, which makes it a bit confusing. Also, the player is actually too tall to walk through the door. When the notes where added, we randomly placed them around the map and the one with the text 'Behind You' just happened to end up at this location. Afterwards, we added a poofer at this location because it just seemed natural. It is probably the most notorious poofer in de game, with the highest track record of scaring the hell out of people.
Bats
Another addition we made which wasn't in the original where the bats. Our friend Kevin suggested this dick move. Some strategically picked trees have a circular trigger around them. When the player enters the trigger, there's a certain chance that the bats are triggered. Although there are only a couple of trees with this trigger, players don't seem to get used to it. That's probably because the forest is big enough to prevent memorizing such details.
That's the story of the design process of Slender Mod. In the next part, I'm going to set focus on the technical bits. How does the slenderman actually work? When and where will he spawn? Does it make any difference if you walk or run? And by the way, who's the guy behind you?
It's quite common to place a checkbox's label at it's right side, because it just seems natural. But if a form has all the inputs arranged in a label-first fashion, it might look nicer when the labels of a checkbox will be on the left side as well.
Although CakePHP provides a lot of ways to customize pretty everything, I couldn't find anything in the docs on how to place the label of a checkbox on it's left side.
When inserting a new input, there is an option called 'format'. For as far as I can see, there isn't much documentation on this option, but it basically controls the order of the elements of an input.
For example, the default format for a text input looks like this:
Alternatively, we can add this to a custom FormHelper, so it will be applied to all input elements:
// app/View/Helper/CustomFormHelper.php App::import('Helper', 'Form'); class CustomFormHelper extends FormHelper { public function input($name, $options = null) { if (!$options) $options = array(); // Set the default format for all inputs, so a // checkbox will get a label in front of it $options['format'] = array( 'before', 'label', 'between', 'input', 'after', 'error'); return parent::input($name, $options); } }
Name this 'CustomFormHelper.php' and save it in 'View/Helper'.
With CakePHP 2.0, we can use helper aliasing to use this custom helper as our default form helper:
This way, we can still use the Form helper in views, with the label of each input being on the left side.
You might have been wondering what the 'before', 'between' and 'after' elements are doing in there. Well, they can be used to add extra elements to the input, such as span tags around the input:
GitHub: No supported authentication methods available
After installing Git and TortoiseGit for use with GitHub on my home pc, I was hooked. But for some reason, the same thing wouldn't work on my pc at work.
This seems to have something to do with Windows not playing well with Gits authentication system.
However, I'll try to do my best and explain here how you can resolve this issue, to get you back up and running.
Note: in this tutorial, I'm using an SSH key with a passphrase. This causes the used applications to ask for the passphrase during the tutorial and once each time you log in to Windows. If you don't want to enter a passphrase each login, you can choose to use a SSH key without a passphrase. This will be less secure, anyone who has your key can use it to access your repository.
Step 1.
The first step is to install PuTTY and its related applications, from the putty homepage. Install at least PuTTYGen and Pageant, we'll need those later on.
Step 2.
Once you've installed the PuTTY tools, start PuTTYGen and load your private key via Conversions -> Import key. Your private key will be located at one of the following locations:
Windows XP: C:\Documents and Settings\[username]\\.ssh
Windows Vista/7: C:\Users\[username]\\.ssh
Step 3.
If you have a SSH key with a passphrase, you will be prompted to enter it now.
Step 4.
Once the key is loaded, save the private key as id_rsa.ppk, in the same folder as the other keys. This is basically the same key as the one you loaded, but in PuTTY's format.
Step 5.
Copy the public key from the textbox, entitled 'Public key for pasting into OpenSSH authorized_keys file:'. Go to your GitHub page and open 'SSH Keys' under 'Account Settings' and add the key there.
Step 6.
We're done with PuTTYGen, now it's time to make the key load at login. Add a shortcut to Pageant in your Startup folder.
Step 7.
Open the properties of the shortcut and edit the target path. Append the path to the private key we just created. The full path should look something like this:
Windows XP: "C:\Program Files\PuTTY\pageant.exe" "C:\Documents and Settings\[username]\\.ssh\id_rsa.ppk"
Windows Vista/7: "C:\Program Files\PuTTY\pageant.exe" "C:\Users\[username]\\.ssh\id_rsa.ppk"
Step 8.
Close the properties window and start Pageant using the same shortcut. If all went well and if you're using a key with passphrase, you should be prompted to enter it now.
Step 9.
To verify we've done everything right, open up Pageant using the icon in the taskbar, by double clicking it or right click -> View keys. This will open a list with all loaded keys, which in our case is only one.
That's it! If the key is loaded, we can now use Git to sync with the GitHub servers. Additionally, each time Windows is booted and logs in, our SSH key will be loaded, prompting for a passphrase if using one.
You've been working on this piece of code for some time now. A couple of days, maybe even weeks. It all works, although a bit hairy. Then you wake up one day, with an epiphany. This code can be reduced to about half it's size! So you start refactoring the pages of code that now seem inefficient. Without any hesitation, you're deleting days of blood, sweat and tears.
It has been somewhat of a mystery to me as to why we don't care about the enormous amount of work we've put into this. Sure, the result will be a lot better. It will be more transparent, easier to maintain and in many cases even a bit faster. Also, in most cases, the old code is on some version control system, such as svn or git. But still, we don't care about our past code? We even enjoy tearing out so much work?
This goes a bit further as well, for those who haven't seen the myth of the genius programmer, Google talks about getting requests from developers, asking to clear their svn repositories. They have loads of space for us to use, it doesn't cost us any money whatsoever, but still we want to clear our past code? We actually want to erase the code from the face of the planet, while it doesn't even stand in our way.
I think this has to do with us, programmers, wanting to be excellent at our first try. So if that first try didn't work out perfectly, we just erase it from history, right? It's the Men in Black flasher at our finger tips!
When you think about it, this is exactly how it goes with many other professions. Painters for example, they tend to throw away entire paintings or paint over an existing one, to erase their 'failed' work from history.
In This Developer's Life, episode 'Scars', they talk about how nice it would be if your resume stated how many failed projects you've been working on. Now is refactoring code not the same as failing projects, but it's a bit of the same nature. Have you ever seen a developer stating his failed projects on his resume?
I think that gaining skill is a process done through a lot of trial-and-error. You try something out, it doesn't work out exactly the way you had in mind, so you try something else. It actually is this process of refactoring massive amounts of code that gets you to be a better programmer. Still we don't want people to see what we have been screwing up in the past.
When not reflecting the improvement in the products we create, we let out an important bit of information for our future employer: the ability to see room for improvement. It's one of the most useful and at the same time hardest skills a developer can have. Seeing a piece of code, or maybe a database diagram for that matter and noticing points of improvement upon the existing design. It's this ability of looking at a project from a more distant viewpoint, what makes a developer unique.
If you really were to write this perfect piece of code the first go, you would be lucky. No improvements would be needed and it would work out the first time. But how many times does this actually happen in practice? Most of the time, you'll create a prototype and improve it, until it gets the form your client is looking for. The better you can do this, the more of a useful asset you'll be for any client or employer.
There's a whole array of development methods created for this type of software engineering, which works exactly like this. Creating a prototype and improving upon that. It has struck me that the hardest part of developing software is not building the product right, but building the right product. It would be great if we could all leave our pride behind and start publishing our mistakes for other developers to see.
In Object Oriented Programming, inheritance is one of the most important principals. It basically means expanding an existing class with methods, fields or perhaps other members. C++ has by far the most flexible inheritance model I've ever seen in a programming language. Though it is quite hard to use, compared to Java en C#. For the most part, the syntax is quite similar and if you already understand OOP and inheritance, you'll get the hang of it in no-time.
Basic extension
public class Dog : public Animal { };
Extending a class is almost the same as in C#, using the colon : operator. Note the 'public' in front of the Animal super class. This tells the compiler that the Animal class is visible from the outside. Any methods in the super class can't be called if you omit the public keyword. It might seem weird, as you probably always want the super class to be visible. This could be useful for wrapper classes.
Overriding methods
In Java, any method is 'virtual' by default. This means you can override any method in a subclass. In C#, any method is non-virtual by default. If you want to override a method in a subclass, you should add the 'virtual' keyword to the method in the super class.
In C++ methods are also non-virtual by default. To allow overriding, add the virtual keyword in the header, similar to C#:
public class Animal { public: virtual void MakeSound(); }; public class Dog : public Animal { public: void MakeSound(); };
This is where the confusion starts. In order to override a method, the method must still be declared in the header file of the subclass. You can add the virtual keyword if you want to allow overriding in further subclasses.
Abstract classes
Abstract classes, classes which can't be used directly, but must be inherited from before an object can be created, work a little differently. You don't specify the 'abstract' keyword. To declare a class as abstract, you should make at least one method abstract:
public class Animal { public: virtual void Jump() = 0; };
Still no 'abstract' keyword. The above code declares a Jump() method, but no implementation is required in the cpp file. This is because of the '= 0', which creates a null pointer for the method. Now, only the header of the method is declared. This class cannot be instanced directly and must first be inherited from. Subclasses must implement the Jump() method:
// Dog.h public class Dog : public Animal { public: void Jump(); }; // Dog.cpp void Dog::Jump() { // Do jump here }
Now, the Dog class can be instanced and used.
Abstract classes are also a way to define interfaces, as there is no 'interface' type in C++.
One feature C++ provides over Java-like languages, is 'Multiple Inheritance'. It simply means inheriting multiple classes from a single subclass:
public class Dog : public Animal, public SomeOtherClass { };
Some think this is an incorrect way of OOP, while others think it's an advantage over Java and C#. In any way, it is a possibility and you can use it if you like.
That's inheritance in C++, although it's only the tip of the iceberg. I would like to keep it basic for now and go into deeper subjects in other posts. One of them is generics, which I'll cover in a next post.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality
Anya is LIVE right now
FREE
Free to watch • No registration required • HD streaming
XNA 4: Using the graphics device with a custom window
When using Xna’s excellent classes to create a game, sometimes you don’t want to use the Game class, but you rather want to implement this yourself. This requires a custom window, along with a custom game loop.
This is possible using the GraphicsDevice, which is handled for you in the Game class, but it can also be instantiated manually.
First, you’ll need to create a window to contain the render target.
Form mainWindow = new Form(); mainWindow.Width = 800; mainWindow.Height = 600;
You can actually use any type of container control, which can be useful if you’d like to incorporate other WinForms controls in your project, such as buttons.
Now the GraphicsDevice can be instantiated, along with a set of parameters.
Feel free to play around with these settings, they control most of the settings you’ll find at any graphics settings menu, such as Multisampling (Antialiasing).
Now the graphics device is ready to use. What we need now is a simple game loop. The WinForms Application class has an ‘Idle’ event, which we can use for this.
public static void main(String[] args) { // Above code goes here
// Note that the GraphicsDevice and the Form should be members, // so they can be accessed from the Application_Idle() method Application.Idle += new EventHandler(Application_Idle); Application.Run(mainWindow); } private static void Application_Idle(object sender, EventArgs e) { // This method gets called as much as possible, // Calls to Update() and Draw() can be made here graphicsDevice.Clear(Color.CornflowerBlue); // Drawing code here graphicsDevice.Present(); // Causes the window to redraw and call the Idle event again when it’s done mainWindow.Invalidate(); }
This is a very simple game loop, which you’ll probably want to extend with a nice Draw() and Update() method. First of all, the render target is cleared with the familiar CornflowerBlue. Then you can draw whatever you want to draw, for example using the SpriteBatch. Finally, the graphics device is instructed to present its rendertarget to the window.
From the very first day at school, computer science, we where bombarded with a phenomenon known as Object Oriented Programming, or OOP for short. During the first year, many of us saw the beauty of it, which probably was why we where supposed to use it. We never really got to alternative methods of programming, so it must've been the holy grail of software engineering.
C++ really is C with object orientated syntax additions. Only being tough Java the first year and onto C# the second, I was quite curious as to how C++ would approach the subject. So here's my second part of the journey into the universe of C++: object orientation!
The first thing any programmer notices when starting out with C++ and OOP, is the way classes are split up into two different files. Where a class in Java is defined in a single file, C++ has this extra piece of information, called a header file.
When creating a class, you actually start out with this header file, which defines the class you're about to implement. Such a file could look like this:
class Gearbox { public: Gearbox(); void changeGears(int gear); private: int currentGear; };
I'm sticking quite a lot of information at once in this header, for those who haven't seen it before. Let's start out with the awkward braces usage, which is terminated by a semicolon ;. It surprised me that this is necessary, especially the weird errors you get when you don't do it. It gives errors all over the place, except for where the actual problem lies, at the end of a header definition. So always check that bit.
Then there is the alternative method of declaring the members of the class, specifically the modifiers (public, private, protected). You only need a single 'public', after which all public methods are declared. However, there is the possibility of using multiple modifiers, if you like to group the members:
class Gearbox { public: Gearbox(); private: int currentGear; public: void changeGears(int gear); };
The Gearbox() method is the constructor of this class, but in C++, there is another special method for classes, namely the destructor. Like the name suggests, it's the method that gets called when the object is destroyed. The destructor gets called when the delete keyword is used on an object.
Gearbox* gb = new Gearbox(); delete gb; // This is where the destructor of the Gearbox object gets called
This has everything to do with memory management, where an object gets the opportunity to clean itself up before the memory manager releases the memory. This can be handy for objects referencing other objects, which won't automatically get deleted when the parent object is deleted.
When the object is on the stack, the destructor gets called at the end of the scope.
The destructor is defined by using the name as the class, like the constructor, but prefixing it with a tilde ~.
class Gearbox { Gearbox(); ~Gearbox(); };
This syntax has been adapted in some other languages as well, so you might have seen it before. The above code could go in a file called Gearbox.h.
Header files have puzzled me some time, why do they exist and why can't they be generated automatically? Well, one of it's usages is to expose classes and methods to other applications. The implementation is compiled into machine code and the header file is used to list all available methods within a class. It seems they could be automatically generated, but some keywords are specified in the header file instead of the implementation, like virtual.
On to the implementation of our class, which contains the actual code of our class.
This time, we are back to normal braces-notation, without the need of semicolons. At the top of our file, we start out by including the header file. Commands prefixed with a # are compiler commands. The compiler really pastes the code of the header in there, which could cause some issues. I'll cover those a bit later on. The first method we define is the constructor, which starts with the name of the class 'Gearbox', followed by two colons and finally the name of the constructor, which of course is the same as the class. Note that you don't need any visibility modifiers in here, those are already in the header file.
The destructor is quite similar to the constructor, with the exception of the added tilde ~. Then we define the method 'changeGears', which deviates from the other two methods in its void keyword. Regular methods also do not have a visibility modifier, but they do have a return type declared in front of them. Every method is prefixed by the name of the class, because you can actually implement multiple classes in one class file.
Now if we where to use this class in another piece of code, we would use the same include directive as in the class implementation.
#include "Gearbox.h" Gearbox* gb = new Gearbox();
Note that we only need to include the header file, the compiler will look for the appropriate implementation.
Earlier, I mentioned the include directive simply lets the compiler paste in the code of the referenced file. This could lead to issues if we would use the same include twice or more, because the same class would be defined more than once. The compiler doesn't approve of this and will give you an error. So to account for this, we can add some commands to the header file, to ensure it is only run once.
#ifndef GEARBOX_H #define GEARBOX_H class Gearbox { } #endif
This is where it really gets creepy for us Java developers. The first command in the above snippet, #ifndef GEARBOX_H, is a command for the compiler, to check if the GEARBOX_H variable has not been set ('ifndef' as in 'if not defined'). If that's the case, we're defining the variable now, using the #define GEARBOX_H directive. The contents of the variable will be the class definition, followed by the end of the if statement, #endif. The GEARBOX_H variable can have any name, it's just convenient to use descriptive names. The _H stands for 'Header'.
There is an alternative to the above code, in the form of pragma:
#pragma once class Gearbox { }
It's a lot shorter, but it has the down side of not all compilers being able to parse the command. It seems this always works on Window machines, but on other operating systems, it might not work. The first method is the classic one, the second is a bit more modern.
With one of these compiler commands added to the code, we can now safely use as many includes as we like. You won't need this for the cpp files, as those are handled by the compiler and will only be parsed once.
Those are pretty much the basics of object orientation in C++, next time I'll move on to inheritance.
Lately I've been learning C++ and coming from languages like Java and C#, it's quite a transition. I've been meaning to get started with C++ for a while now, but never really got to it. In that time, there has been lots of talk to whereas the language would be a big step, because of the complicated aspects one doesn't have in Java-like languages.
The biggest difference between C++ and Java can pretty much be described as one thing: memory management. The handling of available memory is almost completely abstracted away when using Java, you only have to worry about not overloading the device you're developing on, which is rarely a problem when developing desktop applications. In C++, however, the allocation of memory is done for you, but releasing it is not.
Consider the following piece of code:
public void changeGear(int gear) { Gearbox gb = new Gearbox(); gb.setGear(gear); }
This is a simple piece of code, which would work flawlessly in Java-like languages. A new object of the type 'Gearbox' is created, a method from that object is called and the method is done. In C++, this method would cause severe problems in some cases. First of all, the object is created on the stack instead of the heap. If you want to know more about stack an heap, take a look at this post. Actually, this code wouldn't run at all, but I'll come back to that in a bit.
public void changeGear(int gear) { Gearbox* gb = new Gearbox(); gb->setGear(gear); }
Two things have changed: the type of the object is appended with an asterisk * and the method call is done through an arrow -> instead of a period.
What this does, is create a new object of type Gearbox on the heap and store a reference to that object on the stack, named 'gb'. In Java one would say "I have an object of type 'Gearbox' called 'gb'", but in C++, this would be "I have a reference called 'gb' to an object of type 'Gearbox'. The variable named 'gb' really is a number, namely the address of the piece of memory the object resides in. The asterisk indicates it is a reference to an object of type Gearbox instead of an object of type Gearbox. This is also called a 'Pointer'.
Because the 'gb' variable no longer is the actual Gearbox object, we can't use the period notation to call methods on it, it's not an object after all. So what we can do to access the object's members, is use the arrow -> notation. The third line of code tells the compiler to "get the object referenced by the 'gb' variable and call it's method named 'setGear'". So where the period could be described as "get the following member of this object", the arrow could be described as "get the following member of the object referenced by this variable".
Earlier, I mentioned the code in the first snippet wouldn't work at all C++. This is because the 'new' keyword creates a new object on the stack and returns a reference to this object. As shown above, such a reference is represented by appending an asterisk to the type of the object (Gearbox*). The variable 'gb' in the first snippet doesn't have this asterisk (Gearbox). The syntax for creating an object on the stack looks like this:
public void changeGear(int gear) { Gearbox gb; gb.setGear(gear); }
This may seem quite unusual, as if we're declaring an object without instantiating it. Still, the object really gets instantiated, assuming it has a constructor with no parameters (also known as a default constructor). If it does have one or more parameters, the code becomes like this:
public void changeGear(int gear) { Gearbox gb(6); gb.setGear(gear); }
So much for the first issue.
Secondly, the object stays in memory, even after the method is done. While Java releases any reserved memory within the current scope, at the end of the scope, C++ does not. We need to add a command to do that:
public void changeGear(int gear) { Gearbox* gb = new Gearbox(); gb->setGear(gear); delete gb; }
Now, the memory manager will release the bit of memory used for the Gearbox object.
When a piece of memory is 'released', it becomes available for allocation at another point in your application's execution. The memory itself is not modified, so it retains its data. The problem of this method is, that when the piece of memory is allocated a second time, there's no way of telling what will be in there. Take a look at the following code:
public void enableWiper() { SoapReservoir* soapRes; }
In the above snippet, we're enabling the wipers, to clean the windshield. Before we enable the wipers, we'll check whether there's enough soap in the reservoir. Now suppose we first declare the soapRes variable, before we're going to assign it a value. In Java, the variable would have a value of null. In C++, you never know what soapRes' value will be.
This is because the piece of memory reserved to contain the value of soapRes probably has some leftover data, which could have been another type like a float, or maybe even part of an object. To ensure the default value, the variable must be assigned.
public void enableWiper() { SoapReservoir* soapRes = NULL; }
This is useful for situations where you want to check whether an object is set or not:
public void turnOnRadio() { // Check if we even have a radio if(radio != NULL) { radio.turnOn(); } }
If the radio object hasn't been assigned the NULL value on declaration, it will not be null, while the variable hasn't been assigned. This will cause the above code to think there actually is a radio object and throw an exception when the radio object doesn't appear to have a method called turnOn(), or alternatively, the application crashes.
That's about it for the basics, next time I'll talk about object orientation in C++. Going to sleep now :)
If you've been developing in Java-like languages and never had anything to do with memory management, you may not know what the stack and the heap are and what they do.
// Java public void changeGear(int gear) { Gearbox gb = new Gearbox(); gb.setGear(gear); }
The heap is the easiest to explain, it's a big pile of memory, in your computer RAM, reserved for your application. This piece of memory gets reserved at the moment you run your application and it is done by your operating system. Any memory the application uses, for example objects, comes from this 'heap'. The Gearbox object in the above example would be on this heap. You can't really do anything to control whether or not this object will be on the heap, it just will. If needed, the heap can be expanded on run time, which also is done by the operating system.
The name 'heap' comes from the fact that each piece of the memory can be accessed at any given moment, for both reading and writing. There isn't any required order for reading or writing, it is just a big pile of memory for you to use.
The other option would be the stack, which is a far smaller piece of memory, also located in your computer RAM, which controls your application's execution path. For example, the stack from an application driving a car could look like this:
The stack is used for keeping track of which method (or function) is being called and can be used to store local variables. The size of the stack is constant for an application and is small, around 2MB for Java on a desktop pc, which is enough for most applications.
The name 'stack' comes from the manner in which the memory is read from and written to. It works 'LIFO', or 'Last In, First Out', which means new data will always be written to the end of the stack and the last piece of written data will always be removed first.
A stack can be thought of as a pile of post-its. When a method or function is called, a new post-it is created and stuck to any previous post-its. Any local variables are written on this post-it and when the method or function is done, the entire post-it it is removed. While on a post-it, the previous post-it cannot be written to or read from.
Jeff Hill made a nice post about the stack and the heap on Stackoverflow.
Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
✓ Live Streaming✓ Interactive Chat✓ Private Shows✓ HD Quality
Anya is LIVE right now
FREE
Free to watch • No registration required • HD streaming
Let me start out by introducing the number one, my proverbial right hand, mister Theedrake, or Tim. We met at highschool, blabla, whatever. He's actually studying for this kind of stuff, so he might even know what he's doing! In any case, it gives a bit more of a professional feel to the project and the other way around, it provides him a nice opportunity to try out some of his skills and maybe even improve them.
He's also responsible for the soundtrack of our game, so he does pretty much the entire creative part.
I myself am currently in the last stage of my education, namely computer science. The project serves the same purpose for me, to gain more knowledge on the subject and simply because of the fun I'm getting out of it.
Yes, it's another one of those developer weblogs about what we do all day besides drinking coffee and playing with our man-toys. Well, I don't drink coffee, so hey, this might be an original!
Anyway, I'm starting this weblog (like Yahtzee said: "I refuse to use the word 'blog', because it sounds like something that lives on the riverbed and communicates through farts") to keep track of progress with a game I'm coding, with the aid of some of my friends.
The project is called 'Datamaze'. I don't want to reveal too much of the gameplay right now, since it's very pre-alpha at the moment. Still I want to take a moment now and then to discuss with myself how development is going. I can tell you that it will be inspired by the cult-classic Uplink from 2001 by one of my favorite developers, Introversion.
It should be noted that no ethically-trained software engineer would
ever consent to write a DestroyBaghdad procedure. Basic professional ethics would instead require him to write a DestroyCity procedure, to which Baghdad could be given as a parameter.