Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Game Development

370 Articles
article-image-earning-your-first-gold
Packt
16 Aug 2013
15 min read
Save for later

Earning Your First Gold

Packt
16 Aug 2013
15 min read
(For more resources related to this topic, see here.) You need to spend gold to make gold The adage "You need to spend money to make money" holds true in World of Warcraft as well. A lot of your income will come from manufacturing processes: taking raw materials (or mats) and turning them into finished goods for the end user. To expedite this process, we will be mostly buying the materials from the Auction House, and so you will need a sizeable supply of gold when you're starting out and building inventory. Unlike in the real world, where you can get investors or loans to start up a business, in World of Warcraft you will need to collect every bit of copper yourself. It's not until you have built up this starting capital that you can truly start making significant amounts of gold. There are a few ways to go about this and some players may be able to build capital while playing as they usually do, but most players will have to work at building this capital. All the methods in this section are designed to earn you gold, with time being the only investment; no gold needs to be invested. Once you've built your starting capital, you may find yourself moving away from these sources of revenue to focus on more lucrative markets. Reselling vendor pets There are many items that you can sell on the Auction House but vendor pets will be your best bet when trying to make gold. While your mileage may vary depending on your server's economy, there are certain vendors and items that are usually profitable. As with any other tip, you will have to confirm for yourself that this is pro fitable on your server. Even before Mists of Pandaria was announced and launched with its pet battles, pets were in great demand. There are several vendors scattered throughout Azeroth that sell pets; you can then resell the pets on the Auction House for a profit. There are two reasons why pets from these vendors can typically be sold for a profit over the vendor price: Players are too lazy to venture out into the world themselves to visit these vendors and buy the pets Players don't do their research and, when they see these pets on the Auction House, are unaware that they can get these pets from the vendors We'll take a look at some examples of where you can get pets from a vendor to sell on the Auction House. Always make sure you're selling these pets for a profit. As with most methods we will go over, this tactic's effectiveness is largely determined by your server's market. Be sure to check market prices for these pets before you go out and collect them (The Undermine Journal (https://theunderminejournal.com/) will help you with market research). Neutral vendors Players from either faction will be able to access these vendors and resell their wares on their faction-specific Auction House. One of these vendors is Dealer Rashaad at the Stormspire in Netherstorm and he can be found west of the flight master at Stormspire. The following screenshot shows the map of Netherstorm, and the player icon marks the location of Dealer Rashaad: Dealer Rashaad is marked with the <Exotic Creatures> tag and sells the following pets (as presented by the vendor, from left to right, top to bottom): Parrot Cage (Senegal): Purchase for 40 silver Cat Carrier (Siamese): Purchase for 60 silver Undercity Cockroach: Purchase for 50 silver Crimson Snake: Purchase for 50 silver Brown Rabbit Crate: Purchase for 10 gold Red Moth Egg: Purchase for 10 gold Blue Dragonhawk Hatchling: Purchase for 10 gold Mana Wyrmling: Purchase for 40 gold Dealer Rashaad has associations with the faction The Consortium, and so these pets will appear cheaper, depending on your reputation with this faction (up to 20 percent off if you have Exalted reputation). Another pet vendor you should visit is Breanni (tagged as <Pet Supplies>) at Magical Menagerie in the city of Dalaran in Crystalsong Forest, Northrend. The following screenshot shows the map of Dalaran and the player icon marks the location of Breanni: Breanni sells the following pets (listed in order of appearance): Cat Carrier (Calico Cat): Purchase price 50 gold Albino Snake: Purchase price 50 gold Obsidian Hatchling: Purchase price 50 gold Breanni also sells accessories for pets but, since these are Bind on Pickup items, you will not be able to sell them on the Auction House. There are several vendors that sell only one or two pets; while you can sell many of these on the Auction House as well, you will have to determine for yourself if the profit margins are worth your time spent in collecting them. The following is a list of these pets and their vendors. Only those pets that can be purchased for gold (or silver) are included in this list as there are several that can be purchased for other currencies: Ancona Chicken: Plucky Johnson in Thousand Needles Tree Frog Box: Flik at the Darkmoon Faire Wood Frog Box: Flik at the Darkmoon Faire Winterspring Cub: Michelle De Rum in Winterspring Parrot Cage (Cockatiel): Narkk in Booty Bay To make the most of these pet vendors, buy multiples of each pet (at least three to five of each) and store the spares in a bank while you are selling them. Doing this limits the number of repeat trips you have to make and makes it more worth your while. Be sure to empty your bags as much as possible when going out to fetch these pets. While being at Friendly reputation or better with these vendors can fetch you a discount of five to 20 percent, the amount of time it takes to reach these reputations is not really worth the discount. That being said, if you have a character that you know gets a discount with these vendors, use it to collect the pets and get the five to 20 percent discount on the purchase price. If you have trouble finding any of these pets, you can go to http://www.wowhead.com, which is a database of all the items, vendors, achievements, and more. Wowhead has every vendor listed and a map of where to find the vendors.  Pets from in-game events During most in-game holidays, there is a selection of pets you can buy with the holiday-specific currencies (typically tokens). While it's likely that it won't be worth your time to gather these currencies specifically to buy these pets, only you can decide what is worth your time; you might want to have these currencies anyway. Note that these pets are related to specific events only and are not available all year round. These pets are as follows: Captured Flame: 350 Burning Blossoms (Midsummer Fire Festival) Purchasable at vendors in every major city for every major faction during the course of the Midsummer Fire Festival Feline Familiar: 150 Tricky Treats Purchasable at vendors in Undercity and Elwynn Forest as part of the Hallow's End festivities Sinister Squashling: 150 Tricky Treats Purchasable at vendors in Undercity and Elwynn Forest as part of the Hallow's End Festivities Spring Rabbit's Foot: 00 Noblegarden Chocolate Purchasable at various vendors outside every major Alliance or Horde city as part of the Noblegarden festivities Pint-Sized Pink Pachyderm: 100 Brewfest Tokens Purchasable at vendors in Dun Morogh, Durotar, Ironforge, and Orgrimmar as part of Brewfest Activities Lunar Lantern and Festival Lantern: 50 Coins of Ancestry each Purchasable at vendors in Moonglade during the Lunar Festival event Truesilver Shafted Arrow: 40 Love Tokens Purchasable at vendors in all major Alliance and Horde cities during the Love is in the Air event These pets are available in plenty during and shortly after the events, so to get the best price out of your hard work, hold on to the pets for a month or more after the event ends. Some of these pets do drop (not significantly, though) as part of the incentive for Call to Arms but the largest supply comes from the events themselves. The currencies for these pets are obtained through quests and achievements related to the event and can thus only be obtained while the event is active. Many players choose to do these events anyway (for achievements or for the sake of completion), so you might find that selling these pets is an easy way to make extra gold. If you have any problems with the quests or achievements, the posts on Wowhead will typically have advice and the writers at WoW Insider (http://wow.joystiq.com) put up guides every year for the events. Faction-specific vendors and pets Each faction, Alliance and Horde, has a selection of pets that are specific to it. While you can sell them on your home Auction House, you can often get much better prices on the neutral Auction House, where you can sell to the opposite faction because this, and faction transfers, which cost money, are the only ways for them to get the pets. Keep in mind though that the neutral Auction House charges a higher fee—they charge a 15 percent cut on sales — so be wary when selling and adjust your profi t margins accordingly. As with the faction-neutral pets, these pets are broken into two categories: Purchasable with standard currency (gold, silver, and copper) Purchasable with other currencies Alliance The list of Alliance vendors with pets available for standard currency is as follows: Donni Anthania <Crazy Cat Lady>, Elwynn Forest: Cat Carrier (Bombay): Costs 40 silver Cat Carrier (Cornish Rex): Costs 40 silver Cat Carrier (Orange Tabby): Costs 40 silver Cat Carrier (Silver Tabby): Costs 40 silver Yarlyn Amberstill, Dun Morogh: Rabbit Crate (Snowshoe): Costs 40 silver Shylenai <Owl Trainer>, Darnassus: Great Horned Owl: Costs 50 silver Hawk Owl: Costs 50 silver Sixx <Moth Keeper>, The Exodar: Blue Moth Egg: Costs 50 silver White Moth Egg: Costs 50 silver Yellow Moth Egg: Costs 50 silver Lil Timmy <Boy with kittens>, Stormwind, rare spawn: Cat Carrier (White Kitten): Costs 60 silver The White Kitten especially commands a good price on the Auction House as it's difficult to get even for Alliance players, so always keep an eye out for Lil Timmy when you are in Stormwind. Finally, for those who are champions in the Argent Tournament with the playable races on the Alliance side, you can buy pets at the Argent Tournament for 40 Champion's Seals. All the vendors can be found in the Alliance tent on the north-east corner of the Argent Tournament grounds. The following screenshot shows the map of Icecrown; the player icon marks the location of the Alliance team: The pets available to Alliance players are as follows: Teldrassil Sproutling, Darnassus Mechanopeep, Gnomeregan Ammen Vale Lashling, Exodar Elwynn Lamb, Stormwind Dun Morogh Cub, Ironforge? Shimmering Wyrmling, Silver Covenant The Argent Tournament champions do well on the Alliance Auction House as well since no one plays the Argent Tournament any more and unlocking the pets requires a significant amount of work. Horde The list of Horde vendors with pets available for standard currency is as follows: Xan'tish <Snake Vendor>, Orgrimmar: Black Kingsnake: 50 silver Brown Snake: 50 silver Crimson Snake*: 50 silver Halpa <Prairie Dog Vendor>, Thunder Bluff: Prairie Dog Whistle: 50 silver Jeremiah Payson <Cockroach Vendor>, Undercity: Undercity Cockroach*: 50 silver Jilanne, Eversong Woods: Golden Dragonhawk Hatchling: 50 silver Red Dragonhawk Hatchling: 50 silver Silver Dragonhawk Hatchling: 50 silver Pets with an asterisk (*) next to them can also be purchased from a faction-neutral vendor and so may not get the same price on the neutral Auction House. Champions of the Horde's main races can get pets from the Argent Tournament for 40 Champion's Seals. To be able to buy any of these pets, a player must be a champion of the race that the particular pet is associated with. All the vendors for these pets can be found in the Horde tent at the Argent Tournament on the south-east corner of the grounds. The following screenshot shows the map of Icecrown; the player icon marks the location of the Horde tent: Fishing Fishing, one of the original secondary professions, is a convenient way to make gold with no real start-up costs. You don't need to level Fishing to make gold with it; you can train it and start fishing up valuable fish straightaway. Without max fishing, you can still fish from pools around Pandaria; the fish can then be sold on the Auction House to players looking to make buff foods. Make sure to only fish from pools if you don't have max fishing as a lower skill level in Fishing makes it almost impossible to pull any fish (except Golden Carp) from open waters. The following screenshot shows a character fishing from a pool in Pandaria: The Tillers, farming, and Sunsong Ranch Every player, over the course of leveling, will come across the Sunsong Ranch. The ranch is an excellent source of income for those who don't have the capital or professions to start the gold-making methods discussed later in this book. The ranch is basically 16 plots of soil (you start out with four and then unlock an additional four at every reputation level with the Tillers) where you can plant seeds for vegetables and other items such as Motes of Harmony. With the vegetables, you can either create buff food (requires 600 Cooking) or sell them on the Auction House to other players (who will more than likely be using them to create buff foods themselves). A copper saved is a copper earned A surprising amount of gold can be saved by nickel-and-diming everything in the game; when you're putting so much work into building up your pile of gold, you don't want to waste it! To keep inflation in check and the economy from getting out of hand, World of Warcraft has several gold sinks to try and keep the gold that is leaving the economy balanced with the gold entering it. One of the biggest gold sinks is armor repair, and an untold amount of gold is lost to this necessity every day. Luckily, there are ways to minimize how much gold is syphoned out of your pockets and into the repair vendors'. Vendors that are associated with factions (typically displayed in the way a player's guild would be, that is, in brackets under the name) give players discounts if they have a reputation with the faction. Discounts start at Friendly with 5 percent and continue all the way through to Exalted, which offers a 20 percent discount; and yes, this discount applies to repairs as well. What this means is that players can save up to 20 percent on their repair bills by repairing only at vendors. Obviously, you can't always get to a vendor you have Exalted reputation with but simply paying attention to where you repair can save you some serious gold. Make sure to repair before you go out into the world or get into a raid and resist the temptation of repairing between every wipe. Guilds can give many perks that provide you with ways to save gold. Guilds level 9 and higher have a perk that reduces the durability loss your gear experiences when you die or take damage. This means you need to repair your gear less often, which in turn means you have to spend less gold to keep it in good condition. Also, look into items before you buy them as sometimes, even though you can find them on a vendor, you can find them cheaper on the Auction House or vice versa. As we discussed in the previous section, there's a whole market for buying items from a vendor and selling them on the Auction House, so be an informed buyer! Similarly, there are some items, such as Disappearance Dust, which are often sold cheaper on the Auction House because it's cheaper to produce them through Inscription than it is to buy them from the vendor. Costs associated with the Auction House There are several places where you can reduce the amount of gold you lose when posting items on the Auction House. There are two ways you lose gold when posting items in the Auction House: Auction House cuts on sales: 5 percent is cut at Alliance and Horde Auction Houses 15 percent is cut at the neutral Auction House Lost deposits on expired or cancelled auctions When using the Auction House, it will benefit you greatly to be diligent in how you post. Don't use the neutral Auction House except for selling faction-specific items (the items that only players from one faction can obtain). Attempting to use the neutral Auction House for any other items will be futile; the few sales you actually make will be cut heavily and you'll waste way too much gold on deposits. On that note, it's best to limit how long you post auctions for as the longer the auction, the higher the deposit required. When an auction expires or is canceled, you don't get your deposit back, so if you know you will be canceling a lot of auctions, don't post your auctions for 48 hours; instead, post for 24 hours, if you don't have a lot of time to dedicate to the game, or for 12 hours if you can check the Auction House more frequently.
Read more
  • 0
  • 0
  • 2516

article-image-article-getting-started-on-udk-with-ios
Packt
23 Aug 2012
5 min read
Save for later

Getting Started on UDK with iOS

Packt
23 Aug 2012
5 min read
Defining UDK Unreal Development Kit (UDK) is a freely available version of Epic Games, a very popular Unreal game development engine. First developed in 1998 to power the original Unreal game, the engine (which is C++ based) has gone from strength to strength, and has not only formed the backbone of household-name Epic Games titles, such as the very popular Gears Of War series, but has also been very successfully licensed out to third-party developers. Consequent titles range from Batman: Arkham City to Mass Effect 3, many of which are as equally successful as the games developed by its parent company. Currently, the Unreal engine itself is in its fourth iteration and is considered to be a top of the range visualization tool. It is not only used in the gaming industry, but has also been used for doing any kind of work that demands real-time computer graphics. UDK uses Unreal Engine 3, but it is still a powerhouse in itself and is quite capable of delivering amazing experiences on iOS software. The offering of UDK as a concept has evolved from Epic Games content generation tools very early on with Unreal titles; tools which proved to spawn a very healthy and thriving modification (modding) community. Originally, tools like these, such as UnrealEd (the editor tool with which a user can create their own in-game level), were available to anyone who bought the game. In 2009, however, Epic turned that logic on its head by making their tools available to anybody, whether they owned an Unreal game or not. This proved to be a very successful move which expanded the Unreal developer user base thoroughly. More recently Epic Games, as part of their constant and persistent updates of UDK, have added iOS functionality (in 2010), making sure that UDK can provide games for the ever-expanding mobile customer base that the iPhone/iPad/iPod Touch devices by Apple introduced. This was first demonstrated to the public by a live tech demo called Epic Citadel; a freely available download on the iTunes store which played like an interactive walkthrough of a medieval town. This attracted a record number of downloads as at that time it was truly groundbreaking to experience high quality real-time graphics on a mobile device. Take a look at the following screenshot: In fact, although it is not within the scope of this book, very recently certain demos have surfaced highlighting a potential UDK / Adobe Flash Player pipeline, showcasing the very impressive penetration this games development application has made to a number of different platforms. Of course, we are interested in iOS here, and we'll be covering that extensively in this book, starting from the bare basics and moving on to some more advanced concepts. So what is it that we need to know about UDK and its mobile iOS limitations? Does it have any? Don't expect to make Gears of War Let's start with a fairly realistic statement; we can't make an AAA gaming title as seen on a contemporary console or PC, such as Gears of War, on iOS using UDK! It is a general limitation of doing mobile development using UDK. The main reason for this is rather obvious; we just do not have access to the same hardware. The problem is not the software! UDK can deploy the same game on a PC or an iOS device, but it is the end-hardware specification that has the final say in what can be handled in real-time or not. Mobile devices (and this of course includes iOS devices) have progressed by leaps and bounds over the last few years, and after many false starts mobile gaming today is a force to be reckoned with, both commercially and technologically. That still, however, does not change the fact that as an iOS UDK developer, you will work with more restricted hardware as opposed to, for example, someone developing for an Xbox 360 platform. Let's look at this in more detail; these are some of the current iPhone 4S technical specifications: 960 x 640 pixel display 16 GB, 32 GB, or 64 GB Flash drive Dual-core 1 GHz Cortex-A9PowerVRSGX543MP2GPU 512 MB RAM The newest iPad released in early 2012 has the following specifications: 2048 x 1056 pixel display 16 GB, 32 GB, or 64 GB Flash drive Quad-core PowerVRSGX543MP4GPU 1 GB RAM While these specs are fairly impressive compared to both mobile devices of the past, and also the fact that we are talking about what is essentially a pocket gadget, they cannot really compare with the specification of a top-of-the-range gaming PC or even a current generation console. This, of course, does not mean we can only develop poor or second rate games with UDK. Indeed, some of its contemporary examples highlight the huge potential it has in delivering AAA gaming experiences, even with its current limitations, borne, as described previously, from the hardware limitations of a mobile device. The best example by far has got to be Chair Entertainment's and Epic Games' Infinity Blade, an epic third-person sword-fighting game which came out in late 2010 and is considered the ideal showcase for UDK's technical prowess on the Apple devices. Already spawning sequels and with huge commercial success behind it from its iTunes Store business model, Infinity Blade was, and is, a big eye-opener for all aspiring games developers who want to use Unreal engine technology for a successful iOS title with a very modern feel and visuals. To see just how powerful an iOS game can be, just look at the following screenshot for a fine example:
Read more
  • 0
  • 0
  • 2488

article-image-adding-sound-music-and-video-3d-game-development-microsoft-silverlight-3-part-1
Packt
19 Nov 2009
3 min read
Save for later

Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 1

Packt
19 Nov 2009
3 min read
A game needs sound, music and video. It has to offer the player attractive background music. It must also generate sounds associated with certain game events. When a spaceship shoots a laser beam, a sound must accompany this action. Reproducing videos showing high-quality previously rendered animations is a good idea during transitions between one stage and the next. Hear the UFOs coming So far, we have worked with 3D scenes showing 3D models with textures and different kinds of lights. We took advantage of C# object-oriented capabilities and we animated 3D models and moved the cameras. We have read values from many different input devices and we added physics, artificial intelligence, amazing effects, gauges, statistics, skill levels, environments, and stages. However, the game does not use the speakers at all because there is no background music and there are no in-game sounds. Thus, we have to sort this issue out. Modern games use videos to dazzle the player before starting each new stage. They use amazing sound eff ects and music custom prepared for the game by renowned artists. How can we add videos, music, and sounds in Silverlight? We can do this by taking advantage of the powerful multimedia classes offered by Silverlight 3. However, as a game uses more multimedia resources than other simpler applications, we must be careful to avoid including unnecessary resources in the files that must be downloaded before starting the application. Time for action – installing tools to manipulate videos The 3D digital artists used Blender to create an introductory video showing a high quality rendered animation for five seconds. They took advantage of Blender's animation creation features, as shown in the following screenshot: A spaceship flies in a starry universe for a few seconds. Then, the camera navigates through the stars. Your project manager wants you to add this video as an introduction to the game. However, as the video file is in AVI (Audio Video Interleave) format and Silverlight 3 does not support this format, you have to convert the video to an appropriate format. The creation of video animations for a game is very complex and requires specialist skills. We are going to simplify this process by using an existing video. First, we must download and install an additional tool that will help us in converting an existing video to the most appropriate file formats used in Silverlight 3: The necessary tools will depend on the applications the digital artists use to create the videos. However, we will be using some tools that will work fine with our examples. Download one of the following files: parceApplication's name Download link File name Description Expression Encoder 2 http://www.microsoft.com/expression/try-it/try-it-v2.aspx Encoder_Trial_en.exe It is a commercial tool, but the trial offers a free fully functional version for 30 days. This tool will enable us to encode videos to the appropriate format to use in Silverlight 3. Expression Encoder 3 http://www.microsoft.com/expression/try-it Encoder_Trial_en.exe It is the newest trial version of the aforementioned commercial tool. Run the installers and follow the steps to complete the installation wizards. If you installed Expression Encoder 2, download and install its Service Pack 1. The download link for it is http://www.microsoft.com/expression/tryit/try-it-v2.aspx#encodersp1 file name—EncoderV2SP1_en.exe. Once you have installed one of the versions of Expression Encoder, you will be able to load and encode many video files in different file formats, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 2465

article-image-planning-characters-look
Packt
23 Dec 2013
10 min read
Save for later

Planning a character's look

Packt
23 Dec 2013
10 min read
(For more resources related to this topic, see here.) Creating a character is not an easy job, it can be done by creative insight or careful calculation. The main hero is the soul of the game and whose avatar is used by a player to explore the game world. Players identify themselves with that picture on the screen, empathizing with it, enjoying, grumbling, and taking all the situations to heart. Therefore, the objective is to generate an emotional connection between the character and the player. It is not necessary to provoke only positive feelings; ironically, sometimes the player can hate his avatar. A graphic look of the character can induce a wide spectrum of emotions, and these emotions can be calculated in advance. This is based on the fact that humans usually have nearly the same reactions; in this case, the rules of their behavior are pretty conspicuous. To illustrate the principles, I created the Scale of attractiveness, made of four main entries. At the very left, there is the Cute mark, in the middle is Brutal, followed by Human likeness, and to the right we see Scary. So, the chart begins with something very adorable and sweet but end with a scary character. Each position has its own collection of qualities. Making characters cute Cuteness is one of the most popular and demanded features that game designers want for their creations. Protagonists of majority casual games are cute to some degree; they look and act as sweet and comely creatures. It is simply impossible to ignore them and not fall in love with them. Recall the famous image of Nintendo's Mario, he is 100 percent cute. What is the secret of such popularity? First, the cuteness is not about beauty (it is hard to call an alligator's baby truly attractive, but it definitely is cute), which depends on personal taste and preferences, but about some basic patterns and proportions. Here is a citation from Natalie Angie's article The Cute Factor published in The New York Times: "Scientists who study the evolution of visual signaling have identified a wide and still expanding assortment of features and behaviors that make something look cute: bright forward-facing eyes set low on a big round face, a pair of big round ears, floppy limbs and a side-to-side, teeter-totter gait, among many others." All listed features are general descriptions of one class of creatures on Earth: little babies and cubs. They are small, their heads are noticeably bigger than their body, their limbs are short, eyes are large, and so on. When we see something like that, a special system inside us tends to react commonly. It says that probably in front of us is a defenseless young creature that needs protection, care, and tenderness; a list of positive senses is switched on. Figuratively, we are filled with light. By introducing a cute character in a game or other media, the authors simply exploits one of the natural human reactions. This is possible because it is pretty unconditional, the brain only needs some basic patterns, and the factual meaning of an object is totally irrelevant in this case. Thus, we consider something as cute despite the fact it is not a baby at all. Kittens are super cute, but adult cats can be cute too because they are small, have round and smooth bodies, and big eyes. Another popular example is owls, they have big round heads and large expressive eyes, making them one of the cutest birds on the planet. Moreover, some mechanical objects are cute as well: majority European compact cars from the 1950s are adorable, remember the BMW Isetta, Fiat 500, original Mini, and VW Beetle? All of them look so nice and sweet, that you want to hug them, cover them with a plaid, and give some milk in a plate, as though they are small mechanical babies of bigger adult cars. The industrial design in that period was inclined toward cuteness (may be it correlated with the baby boom). Even utility vehicle such as buses and trucks were cute, in addition to household devices such as radio sets and refrigerators. But the most amazing thing was cute weapons. Of course, I'm not talking about the real ones, but imaginary ray guns that appeared in sci-fi art and in the form of toys were definitely adorable. It is clear why illustrators prefer to use objects from previous decades in their pictures, the final illustrations look warmer. Therefore, to create a cute character, you need to follow some evident visual rules: Short body Rounded angles Curved contours and chubby figures Smooth surfaces without folds and wrinkles Big head with large forehead and small low jaw Small mouth and teeth Large eyes (or they stand wide) with big pupils Wide-open eyes with eyebrows lifted up Animals with big nose Short arms, legs, and fingers without visual joints Making characters scary Generally, cuteness is necessary for a protagonist to have a corner in the player's heart. An antagonist must give birth to opposite feelings: loath and fear. Good enemies are creepy characters. To choose their visual appearance, let's again exploit some ancient mechanics from the human brain. There are a lot of alarm systems that alert us when something looks or behaves suspiciously. Deep-seated fears of various forms are inside most people. A game, of course, should not provoke a real panic action, but can tickle some sensitive zones, playing with associations. Creepiness is the complete opposite of cuteness, it gives not a feeling of warmth, but that of cold. To find an effective scary factor, it is good to look at common fears. Traditionally, many people try to avoid insects or even have phobias. Attributes of such creatures are interpreted as unpleasant or frightening. The only exception is ladybugs (they are round with white dots on their head and large eyes) and butterflies, which are primarily associated with petals of bright flowers. It is important to note that in most cases, insects are not aggressive and harmful, but they remind us of creatures from our worst nightmares, giving us the creeps (few examples are mole crickets and earwigs, eek!) Besides them, there are other types of arthropods with high potential of creepiness (and some of them are really dangerous!): spiders, scorpions, and centipedes. They have adverse visual features such as jointed legs, spikes, exoskeletons, tails, multiple eyes, mandibles, and pincers. The key visual element is a gad, associated with cuts, injuries, and so on, that contradicts a cute creature's properties, which has no acute angles. Moreover, fishes, reptiles, birds, and mammals look dangerous when they show their teeth, canines, tusks, horns, clutches, or sharp beaks. A predator is frightening because it shows it threatens with its weaponry: the potential danger is pretty obvious and their current intention is questionable. Now, the eyes comes into play. If they are fixed at you and are not blinking, it is most likely that the predator is paying attention to you and that is super scary. Furthermore, the eyes can be red because the reflection of light creates such an image. Dangerous creatures are fast so they can move and attack quickly; this means their limbs are pretty long, but bodies are narrow and streamlined. The following figure shows a scary creature: Besides aggressive elements, other unpleasant properties can be used to increase the emotional impact; for example, the character can be additionally disgusting if it is covered with strange skin and even mucus. That turns on the dread of biological substances and the fear of germs and parasites. Squeamishness is one of the protection systems of a human, and sometimes it is very unconditional. Such an approach was used in Ridley Scott's science fiction classics Alien: apparently the xenomorph was inspired by various creepy creatures, including arthropods and reptiles. In addition, it had a very disgusting feature: toxic saliva was always dripping from his mouth, causing the viewers to feel terror and revulsion, a doubled negative emotion. While creating a scary character, remember some basic features it needs to express through its design: Long and skinny body Nonhumanoid structure Many angles Many legs or at least noticeable joints Acute elements, such as spikes, clutches, and horns Small head Naked eyes that stay very close and can be red Weaponry openly displayed (biological tools such as pincers, real guns, and grenades) Unpleasant skin with verruca, folds, wrinkles, and some mucus Warning color that can mean that the character is venomous Making characters brutal Brutality, at the middle of the scale of attractiveness, describes the properties of a character that should exercise some heroic duties, being a soldier or a mercenary. It is obvious that such a person cannot have cute characteristics, otherwise it would look comical. Adorable creatures are associated with something very young, but the heroic character should be an adult. He must demonstrate strength and confidence with a little aggression. So, his look should be a little scary, but only a little, as far as he is not a creepy creature from the end of the scale. Since the brutal hero performs various acts of bravery, he must be fast and agile. So, his anatomical proportions should be close to hyperbolic athletic ones like heavy action heroes from the 1980s, featuring a well-developed muscular system and military toys. The following figure shows such a heavy action hero: The apparent illustration of a brutal character is Duke Nukem, a protagonist of the game series of the same name originally developed by Apogee Software. He is brutal and fearless, and definitely not cute. A bunch of good examples is included in the game Gears of War from Epic Games. The members of Delta Squad are canonically brutal and tough guys. Such type of characters generally are used in action games such as shooters. Figuratively speaking, they are mix made of a human and an armed vehicle, since they hold heavy weapons and armor. The following are the basic visual properties of such a hero (it is important to note that the brutality is gender independent, and although many such characters are men, nobody has forbidden you from creating a strong woman protagonist): Figures with no acute angles or rounded corners, but ones that are roughed down Strong legs Heavy feet to lean on the ground reliably Big hands with tenacious fingers to hold weapons and other objects Wide chest with ram-like powerful shoulders that are bigger than the legs Normal head with mid-sized forehead and a big low jaw Naked big eyes It is pretty apparent that the extreme position on the scale is too categorical a benchmark to follow, whereas in most cases, nobody needs super cute or extremely scary characters. Something more universal is a mix of different properties, which is far more expressive. It is interesting that, as a rule, designs of a protagonist are situated between cuteness and brutality, so the character is anatomically adapted to make complex actions: move fast, climb ladders, fight, among others, and at the same time being pretty attractive. Summary The game lets you create a universe and settles it with characters, describing the rules of their behavior. This is a real gift for your imagination! And it is not about realism. The game universe can be based on your own principles and artistic taste. It can be cartoon like or gloomy and dark. It all depends on the mood of the story you are going to tell the players. Now, you know how to create a cute character and why you should be careful with real anatomical proportions. If the animation does not look scary, you can easily animate the protagonist and other characters. Resources for Article: Further resources on this subject: Development of iPhone Applications [Article] iPhone JavaScript: Installing Frameworks [Article] iPhone User Interface: Starting, Stopping, and Multitasking Applications [Article]
Read more
  • 0
  • 0
  • 2440

article-image-2d-graphics
Packt
04 Mar 2013
8 min read
Save for later

2D Graphics

Packt
04 Mar 2013
8 min read
(For more resources related to this topic, see here.) Adding content Create a new project and call it Chapter2Demo. XNA Game Studio created a class called Game1. Rename it to MainGame so it has a proper name. When we take a look at our solution, we can see two projects. A game project called Chapter2Demo that contains all our code, and a content project called Chapter2DemoContent. This content project will hold all our assets, and compile them to an intermediate file format (xnb). This is often done in game development to make sure our games start faster. The resulting files are uncompressed, and thus larger, but can be read directly into memory without extra processing. Note that we can have more than one content project in a solution. We might add one per platform, but this is beyond the scope of this article. Navigate to the content project using Windows Explorer, and place our textures in there. The start files can be downloaded from the previously mentioned link. Then add the files to the content project by right-clicking on it in the Solution Explorer and choosing the Add | Existing Item.... Make sure to place the assets in a folder called Game2D. When we click on the hero texture in the content project, we can see several properties. First of all, our texture has a name, Hero. We can use that name to load our texture in code. Note that this has no extension, because the files will be compiled to an intermediate format anyway. We can also specify a Content Importer and Content Processor. Our .png file gets recognized as texture so XNA Game studio automatically selects the Texture importer and processor for us. An importer will convert our assets into the "Content Document Object Model", a format that can be read by the processor. The processor will compile the asset into a managed code object, which can then be serialized into the intermediate .xnb file. That file will then be loaded at runtime. Drawing sprites Everything is set up for us to begin. Let's start drawing some images. We'll draw a background, an enemy, and our hero. Adding fields At the top of our MainGame, we need to add a field for each of our objects.The type used here is Texture2D. Texture2D _background, _enemy, _hero; Loading textures In the LoadContent method, we need to load our textures using the content manager. // TODO: use this.Content to load your game content here _background = Content.Load<Texture2D>("Game2D/Background"); _enemy = Content.Load<Texture2D>("Game2D/Enemy"); _hero = Content.Load<Texture2D>("Game2D/Hero"); The content manager has a generic method called Load. Generic meaning we can specify a type, in this case Texture2D. It has one argument, being the asset name. Note that you do not specify an extension, the asset name corresponds with the folder structure and then the name of the asset that you specified in the properties. This is because the content is compiled to .xnb format by our content project anyway, so the files we load with the content manager all have the same extension. Also note that we do not specify the root directory of our content, because we've set it in the game's constructor. Drawing textures Before we start drawing textures, we need to make sure our game runs in full screen. This is because the emulator has a bug and our sprites wouldn't show up correctly. You can enable full screen by adding the following code to the constructor: graphics.IsFullScreen = true; Now we can go to the Draw method. Rendering textures is always done in a specific way: First we call the SpriteBatch.Begin() method. This will make sure all the correct states necessary for drawing 2D images are set properly. Next we draw all our sprites using the Draw method of the sprite batch. This method has several overloads. The first is the texture to draw. The second an object of type Vector2D that will store the position of the object. And the last argument is a color that will tint your texture. Specify Color.White if you don't want to tint your texture. Finally we call the SpriteBatch.End() method. This will sort all sprites we've rendered (according the the specified sort mode) and actually draw them. If we apply the previous steps, they result in the following code: // TODO: Add your drawing code here spriteBatch.Begin(); spriteBatch.Draw(_background, new Vector2(0, 0), Color.White); spriteBatch.Draw(_enemy, new Vector2(10, 10), Color.White); spriteBatch.Draw(_hero, new Vector2(10, 348), Color.White); spriteBatch.End(); Run the game by pressing F5. The result is shown in the following screenshot: Refactoring our code In the previous code, we've drawn three textures from our game class. We hardcoded the positions, something we shouldn't do. None of the textures were moving but if we want to add movement now, our game class would get cluttered, especially if we have many sprites. Therefore we will refactor our code and introduce some classes. We will create two classes: a GameObject2D class that is the base class for all 2D objects, and a GameSprite class, that will represent a sprite. We will also create a RenderContext class. This class will hold our graphics device, sprite batch, and game time objects. We will use all these classes even more extensively when we begin building our own framework. Render context Create a class called RenderContext. To create a new class, do the following: Right-click on your solution. Click on Add | New Item. Select the Code template on the left. Select Class and name it RenderContext. Click on OK. This class will contain three properties: SpriteBatch, GraphicsDevice, and GameTime. We will use an instance of this class to pass to the Update and Draw methods of all our objects. That way they can access the necessary information. Make sure the class has public as access specifier. The class is very simple: public class RenderContext { public SpriteBatch SpriteBatch { get; set; } public GraphicsDevice GraphicsDevice { get; set; } public GameTime GameTime { get; set; } } When you build this class, it will not recognize the terms SpriteBatch, GraphicsDevice, and GameTime. This is because they are stored in certain namespaces and we haven't told the compiler to look for them. Luckily, XNA Game Studio can find them for us automatically. If you hover over SpriteBatch, an icon like the one in the following screenshot will appear on the left-hand side. Click on it and choose the using Microsoft.Xna.Framework.Graphics; option. This will fix the using statement for you. Do it each time such a problem arises. The base class The base class is called GameObject2D. The only thing it does is store the position, scale, and rotation of the object and a Boolean that determines if the object should be drawn. It also contains four methods: Initialize, LoadContent, Draw, and Update. These methods currently have an empty body, but objects that will inherit from this base class later on will add an implementation. We will also use this base class for our scene graph, so don't worry if it still looks a bit empty. Properties We need to create four automatic properties. The Position and the Scale parameters are of type Vector2. The rotation is a float and the property that determines if the object should be drawn is a bool. public Vector2 Position { get; set; } public Vector2 Scale { get; set; } public float Rotation { get; set; } public bool CanDraw { get; set; } Constructor In the constructor, we will set the Scale parameter to one (no scaling) and set the CanDraw parameter to true. public GameObject2D() { Scale = Vector2.One; CanDraw = true; } Methods This class has four methods. Initialize: We will create all our new objects in this method. LoadContent: This method will be used for loading our content. It has one argument, being the content manager. Update: This method shall be used for updating our positions and game logic. It also has one argument, the render context. Draw: We will use this method to draw our 2D objects. It has one argument, the render context. public virtual void Initialize() { } public virtual void LoadContent(ContentManager contentManager) { } public virtual void Update(RenderContext renderContext) { } public virtual void Draw(RenderContext renderContext) { } Summary In this Article we have got used to the 2D coordinate system. Resources for Article : Further resources on this subject: 3D Animation Techniques with XNA Game Studio 4.0 [Article] Advanced Lighting in 3D Graphics with XNA Game Studio 4.0 [Article] Environmental Effects in 3D Graphics with XNA Game Studio 4.0 [Article]
Read more
  • 0
  • 0
  • 2431

article-image-unity-ios-essentials-flyby-background
Packt
08 Dec 2011
12 min read
Save for later

Unity iOS Essentials: Flyby Background

Packt
08 Dec 2011
12 min read
(For more resources on UnityiOS, see here.) Set up a background scene Typically, the background scene for the menu system will also be a scene from the game. But because the player will not be interacting with the menu's background scene, they will not be able to see it from all angles, jump on objects, and so on. It is possible to strip out many of the components from the scene to optimize it for use as a menu background. Another option is to create a brand new background scene that incorporates game assets from multiple game levels into a single menu background to give the player a full picture of the scope of our game. Again, we can achieve this by being selective about the game assets that we use and stripping out all but the most essential visual components of those assets. The background scene can be a teaser, it can include Easter Egg hints, it can contain character cameos from other games, and it can contain parts of other games. Finally, the background scene can be a selling opportunity. It can contain advertising or it can contain objects that the player may be interested in purchasing, using game purchase. The contents of the menu background scene are limited only by what we can imagine. In the following image, we show the original first level of a game that we have selected to be used as the background scene for our game: The scene is adequate and we could use it as the background for our game menu, but we want to give the game player a better idea, right on the main menu, of just how large the game is. So instead, we add some buildings from a second level (we could do more; we could make our menu level huge, but this should do for now), and come up with the new, much larger scene, as shown in the following screenshot to use as the background for our main menu: Set up the camera path Once we have decided on the final scene that we want to use as the background for our main menu, we need to decide on the path that the camera will follow as it moves through the scene. While it is not a requirement that the camera moves along a path, it adds interest to the menu, and so we will continue with that menu theme for our game. This is an opportunity for us to tease the player, since it may be some time before they arrive at a specific part of the menu scene during actual gameplay. We can flyby Easter Eggs or we can flyby specific objectives. Again, this is the part of the game where we get to be creative and draw the player into the game. If we want to, we can even defy the physics of the game and fly through things, so that we don't give away the secret of how to achieve a game objective or how to obtain an Easter Egg, but we do let the player know that they are there. We need to be careful to do this in such a way as to fade through scenes rather than clip through the geometry, so that we don't disturb the immersive feel of the game in order to hide things from the player's view. To set up a path, the first thing we need to do is create a gizmo. A gizmo is an image that appears in the Unity3D editor at the position of a game object's transform, but otherwise will not be visible in the game. As a game designer, we use gizmos to arrange these game objects graphically in the editor, rather than having to find each object in the game hierarchy, and enter x, y, and z values to position the transformation. Gizmos, while not necessary, are very useful because they allow us to create a visual representation of an otherwise empty game object in the Unity3D editor. To create a gizmo, you need two things: A gizmo image A gizmo script The following is an example of a gizmo image. It can be anything you want. In this case, we have simply chosen an image of the letter W – for waypoint. The image file is named Waypoint.tif, and it has been imported into Unity3D as a standard GUITexture as follows: The following is an example of a gizmo script that draws a waypoint gizmo image at the location of the game object transform to which it is attached: // Draw the waypoint gizmo at the Game Object's// transform position. // You can use any image that you want // This gizmo will be pickable which means you// can click on it in the editor to select// the attached game object function OnDrawGizmos (){//The image must be in Assets/Gizmos – the size of the image//is how large it will be drawn in the scene view Gizmos.DrawIcon (transform.position, "Waypoint.tif");} To use a waypoint in the editor, we need to do the following: Create an empty game object Attach the waypoint.js script to the game object The following image shows our example level with a number of waypoints added to define the path that we want the camera to follow for our menu flyby. Everywhere you see the letter W in this image, denotes a waypoint along the path: Adding waypoints and drawing a gizmo at a waypoint's location in the editor is helpful, but one more thing that we can do to make the order of the waypoints clear is to draw a line between the waypoints. So, for example, we would draw a line from wp1 to wp2, from wp2 to wp3, and so on. The following script fragment, which is part of the SeekSteer script, shows how to draw the lines between the waypoints: // draws a line from waypoint to waypoint public void OnDrawGizmos() { Vector3 l_prevWaypointPosition; Vector3 l_currentWaypointPosition; // Choose a color, it can be any color you like Gizmos.color = Color.red; // Draws a line between the last waypoint // and the first waypoint l_prevWaypointPosition = waypoints[waypoints.Length-1].position; l_currentWaypointPosition = waypoints[0].position; Gizmos.DrawLine(l_prevWaypointPosition, l_currentWaypointPosition); // Choose another color, it can be any color you like // except the first color Gizmos.color = Color.green; // For each remaining waypoint, in the waypoints array // draw a line between the two points for (int i=1;i < waypoints.Length;i++) { l_currentWaypointPosition = waypoints[i].position; l_prevWaypointPosition = waypoints[i-1].position; Gizmos.DrawLine(l_prevWaypointPosition, l_currentWaypointPosition); } } The following screenshot shows the new scene with lines being drawn between the waypoints. It's easy to identify the first and last waypoint, because they are the points with the red lines between them: Once the waypoints have been set up, we need something to follow them. There are literally dozens of ways that we can use to follow a path, and many kinds of paths that we can follow. In fact, there are complete Unity3D projects devoted to path finding. In this case, we have chosen to use the SteerSeaker method of following a path. The SteerSeaker creates an array (or list) of all the waypoints, and moves from one waypoint to the next in the same amount of time. In order to keep the time between waypoints constant, the SteerSeaker speeds up or slows down based on the distance between the waypoints, which makes it easy for us to predict the total time it will take to follow our path and create sections of both slow and fast movement. The rest of the SteerSeaker script (remember we looked at the previous image that draws lines between the waypoints) is shown as follows: This script is written in C# rather than JavaScript. While many people new to Unity3D prefer to work in either JavaScript or C#, it's important that we become familiar with both scripting languages, so that we can take advantage of all the open source resources available in the Unity3D community. While we don't need to be able to program in both languages, we do need to be able to read both languages. // SeekSteer.cs// Based on the original SeekSteer by Matthew Hughes// -- 19 April 2009// -- Uploaded to Unify Community Wiki on 19 April 2009// -- URL:http://www.unifycommunity.com/wiki/index.php?title=SeekSteer//// Changes by BurningThumb Software// -- March 2010//using UnityEngine;using System.Collections;public class SeekSteer : MonoBehaviour{ // This is the array of waypoints public Transform[] waypoints; // This is the radius, in meteres of a waypoint public float waypointRadius = 1.5f; // Damping is used to limit the rate at which // the object turns towards the next waypoint. // Smaller numbers slow down turns, larger // numbers speed up turns public float damping = 0.1f; // Set loop to true if the object loops // continuously around the waypoints and // to false if the object only goes around // one time public bool loop = false; // The time between waypoints is constant // so the object will speed up or slow down to // achieve this time regardless of the distance // between the points public float transittime = 2.0f; // Set faceHeading to true to make the object // turn to face the forward direction and to // false to not turn to face the forward // direction public bool faceHeading = true; // The current heading of the object private Vector3 currentHeading; // The desired heading of the object private Vector3 targetHeading; // The array index of the waypoint that the // object is heading toward private int targetwaypoint; // A reference to the transform of the object // used to speed up the script by caching the // reference which is used many times private Transform thisTransform; // If the object has a rigid body then this // is a reference to the rigid body of the object // used to speed up the script by caching the // reference which is used several times private Rigidbody thisRigidbody; // Use this for initialization protected void Start () { // If the waypoints array is empty this script // logs a message and disables itself. You need // to add waypoints to the array in the Unity3D // editor if (waypoints.Length <= 0) { Debug.Log("No waypoints on "+name); enabled = false; } // Cache a reference to the transform to speed // up the execution of the script thisTransform = transform; // Set the current heading to be forward currentHeading = thisTransform.forward; // The first target waypoint, is the first // one in the array targetwaypoint = 0; // Cache a reference to the attached Rigidbody to // speed up execution of the script. If // no Rigidbody is attached this will be null thisRigidbody = rigidbody; } // calculates a new heading. This is done in // fixed update just in case there is a // Rigidbody attached and physics are // involved protected void FixedUpdate () { // A simple Lerp with damping to adjust // the heading towards the current target // waypoint targetHeading = waypoints[targetwaypoint].position - thisTransform.position; currentHeading = Vector3.Lerp(currentHeading, targetHeading, damping * Time.deltaTime); } // moves us along current heading protected void Update() { // If a Rigidbody is attached then // physics is in use so add velocity if (thisRigidbody) { thisRigidbody.velocity = currentHeading * transittime; } // Otherwise set the position directly else { thisTransform.position = thisTransform.position + (currentHeading * Time.deltaTime * transittime); } // If the object needs to face the heading, // make it look that way if (faceHeading) { thisTransform.LookAt(thisTransform.position + currentHeading); } // Check to see if the object is inside the // waypoint radius if (Vector3.Distance(thisTransform.position, waypoints[targetwaypoint].position) <= waypointRadius) { // Add one to the target waypoint to select // the next waypoint targetwaypoint++; // if the next waypoint is past // the end of the array if(targetwaypoint>=waypoints.Length) { // set it back to the beginning targetwaypoint = 0; // If the object is only supposed // to transit the waypoints one // time then disables the script if (!loop) { enabled = false; } } } } With this final script, we create the SteerSeeker game object and attach not only the SteerSeaker script, but also a gizmo script to display the letter S. This is done so that we can see the position of the game object in the Unity3D editor. The following image shows the SteerSeaker object settings in the Unity3D editor: The variables declared as public in the script are the ones that will appear in the Unity3D editor. The following image shows its position on the waypoint path, as we run the game in the editor: Finally, we need to have the main camera follow the SteerSeaker object as it moves along the waypoint path. The advantage of using a script, instead of a simple timeline, is that we can create more dynamic camera movement, for example, a rollercoaster effect where the camera changes angles as it moves, or a script that "gobbles" up jewels along the path as it moves. It's important to understand the concept of using a script and its benefits, rather than simply looking at what this specific example does. Often, as in this case, example code is kept simple to convey the concept or idea, and is not meant to be the final solution that we would deploy in a game. This is done by attaching the FollowTransform script from the iPhone Standard Assets to the main camera, while assigning the SeekSteerObject to the Target Transform and checking the box Face Forward on that script. This is shown as follows: The output is shown in the following image:
Read more
  • 0
  • 0
  • 2368
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-adding-sound-music-and-video-3d-game-development-microsoft-silverlight-3-part-2
Packt
19 Nov 2009
5 min read
Save for later

Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

Packt
19 Nov 2009
5 min read
Time for action – animating projections Your project manager wants you to animate the perspective transform applied to the video while it is being reproduced. We are going to add a StoryBoard in XAML code to animate the PlaneProjection instance: Stay in the project, 3DInvadersSilverlight. Open MainPage.xaml and replace the PlaneProjection definition with the following line (we have to add a name to refer to it): <PlaneProjection x:Name ="proIntroduction" RotationX="-40" RotationY="15" RotationZ="-6" LocalOffsetX="-70" LocalOffsetY="-105" /> Add the following lines of code before the end of the definition of the cnvVideo Canvas: <Canvas.Resources>    <Storyboard x_Name="introductionSB">        <DoubleAnimation Storyboard.TargetName="proIntroduction"                Storyboard.TargetProperty="RotationX"                From="-40" To="0" Duration="0:0:5"                AutoReverse="False" RepeatBehavior="1x" />    </Storyboard></Canvas.Resources> Now, add the following line of code before the end of the PlayIntroductoryVideo method (to start the animation): introductionSB.Begin(); Build and run the solution. Click on the butt on and the video will start its reproduction after the transition effect. While the video is being played, the projection will be animated, as shown in the following diagram: What just happened? Now, the projection that shows the video is animated while the video is being reproduced. Working with a StoryBoard in XAML to animate a projection First, we added a name to the existing PlaneProjection (proIntroduction). Then, we were able to create a new StoryBoard with a DoubleAnimation instance as a child, with the StoryBoard's TargetName set to proIntroduction and its TargetProperty set to RotationX. Thus, the DoubleAnimation controls proIntroduction's RotationX value. The RotationX value will go from -40 to 0 in five seconds—the same time as the video's duration: From="-40" To="0" Duration="0:0:5" The animation will run once (1x) and it won't reverse its behavior: AutoReverse="False" RepeatBehavior="1x" We added the StoryBoard inside . Thus, we were able to start it by calling its Begin method, in the PlayIntroductionVideo procedure: introductionSB.Begin(); We can define StoryBoard instances and different Animation (System. Windows.Media.Animation) subclasses instances as DoubleAnimation, using XAML code. This way, we can create amazing animations for many properties of many other UIElements defined in XAML code.   Time for action – solving navigation problems When the game starts, there is an undesired side effect. The projected video appears in the right background, as shown in the following screenshot: This usually happens when working with projections. Now, we are going to solve this small problem: Stay in the 3DInvadersSilverlight project. Open MainPage.xaml.cs and add the following line before the first one in the medIntroduction_MediaEnded method: cnvVideo.Visibility = Visibility.Collapsed; Build and run the solution. Click on the button and after the video reproduction and animation, the game will start without the undesired background, as shown in the following screenshot: What just happened? Now, once the video finishes its reproduction and associated animation, we have hidden the Canvas that contains it. Hence, there are no parts of the previous animation visible when the game starts. Time for action – reproducing music Great games have appealing background music. Now, we are going to search and add background music to our game: As with other digital content, sound and music have a copyright owner and a license. Hence, we must be very careful when downloading sound and music for our games. We must read licenses before deploying our games with these digital contents embedded. One of the 3D digital artists found a very cool electro music sample for reproduction as background music. You have to pay to use it. However, you can download a free demo (Distorted velocity. 1) from http://www.musicmediatracks.com/music/Style/Electro/. Save the downloaded MP3 file (distorted_velocity._1.mp3) in the previously created media folder (C:Silverlight3DInvaders3DMedia). You can use any other MP3 sound for this exercise. The aforementioned MP3 demo is not included in the accompanying source code. Stay in the 3DInvadersSilverlight project. Right-click on the Media sub-folder in the 3DInvadersSilverlight.Web project and select Add | Existing item… from the context menu that appears. Go to the folder in which you copied the downloaded MP3 file (C:Silverlight3DInvaders3DMedia). Select the MP3 file and click on Add. This way, the audio file will be part of the web project, in the Media folder, as shown in the following screenshot: Now, add the following lines of code at the beginning of the btnStartGame button's Click event. This code will enable the new background music to start playing: // Background musicMediaElement backgroundMusic = new MediaElement();LayoutRoot.Children.Add(backgroundMusic);backgroundMusic.Volume = 0.8;backgroundMusic.Source = new Uri("Media/distorted_velocity._1.mp3", UriKind.Relative);backgroundMusic.Play(); Build and run the solution. Click on the button and turn on your speakers. You will hear the background music while the transition effect starts.
Read more
  • 0
  • 0
  • 2361

article-image-editor-tool-prefabs-and-main-menu
Packt
22 Sep 2015
19 min read
Save for later

Editor Tool, Prefabs, and Main Menu

Packt
22 Sep 2015
19 min read
In this article by Edward Kyle Langley, author of the book Learning Unity iOS Game Development, we will learn that the player has the ability to send input to the device, and we will handle this by manipulating the player character GameObject. We also set up some game logic so that the player character can interact with positive and negative world objects, such as Coins and Obstacles. To further develop the sense of a complete game, we need to create the pieces of the game world that represent a floor that the player will run on. (For more resources related to this topic, see here.) To create these pieces, we will create a Unity EditorWindow class that will help us create grids that will represent the ground the player runs on and the dirt below it. Traditionally, you would have to place each sprite one at a time. With this editor tool, we will be able to crate bigger boxes in a grid based on our settings. After we have our editor tool running, we will begin to create the prefabs that will hold multiple GameObjects and their components in a single file. Finally, we will write the code needed to move the floor and ground pieces below the player character, simulating the character as running forward. To summarize, in this article, we will cover the following topics: Writing a Unity C# class that extends EditorWindow, which allows you to input settings and sprite files that will give you a box grid and simplify the level pieces creation Creating the game-related prefabs so that you have grouped files in an easy-to-use file Building the main menu user interface with Unity's UI tools, including buttons for achievements, leaderboards, and store purchases Use the prefabs we made in the C# script. This will move the level pieces of prefabs under the player character, simulating movement. We will also go through the steps to get the final aspects of the iOS integration function and set up the main menu UI so that the player can navigate between playing the game, view at leaderboards /achievements, and have the option to purchase "remove iAds" for the cost of ten thousand coins or 99 cents. Making the Sprite Tile Editor Tool The Unity engine is incredibly flexible for all the aspects of game development, including creating custom editor tools to help fast track the more tedious aspects of development. In our case, it will be beneficial to have a tool that creates a root GameObject that will then create children GameObjects in a grid. This will be spaced out by the size of the sprite component they have attached. For example, if you were to place say 24 GameObjects one at a time, it could take some time to make sure that all are snapped correctly together. With our tool, we will be able to select the X value and the Y value for the grid, the sprite that represents the ground, and the sprite that represents the dirt below the ground. Perform the following steps: To begin with, navigate to the Assets folder. Right-click on this folder and select Create and then New Folder. Name this folder Level. Right-click on the new Level folder and select Import New Asset. Right-click on the Script folder, select Create and then C# Script. Name the script SpriteTiler. The SpriteTiler C# class Double-click on the SpriteTiler C# file to open it. Change the file so that it looks similar to the following code: using UnityEngine; using UnityEditor; using System.Collections; public class SpriteTiler : EditorWindow { } The big changes from the normally generated code file is the addition to using UnityEditor, changing the inherited class to EditorWindow, and removing the Start() and Update() functions. Global variables We now want to add the global variables for this class. Add the following code in the class block:   // Grid settings to make tiled by public float GridXSlider = 1; public float GridYSlider = 1; // Sprites for both the ground and dirt public Sprite TileGroundSprite; public Sprite TileDirtSprite; // Name of the GameObject that holds our tiled Objects public string TileSpriteRootGameObjectName = "Tiled Object"; The GridXSlider and GridYSlider class will be used to generate our grid, X being left to right and Y being top down. For example, if you had X set to five and Y set to three, the grid would generate columns of five elements and rows of three elements or five sprites long and three sprites down. The TileGroundSprite and TileDirtSprite sprite files will make up the ground and dirt levels. TileSpriteRootGameObjectName is the GameObject name that will hold the GameObjects children that have the sprite components. This is editable by you so that you can choose the name of the GameObject that gets created to avoid having the default new GameObject for each one made. The MenuItem creation Next, we need to create the MenuItem function. This will represent the Editor selection drop-down list so that we can use our tool. Add the following function to the SpriteTiler class under the global variables:    // Menu option to bring up Sprite Tiler window [MenuItem("RushRunner/Sprite Tile")] public static void OpenSpriteTileWindow() { EditorWindow.GetWindow< SpriteTiler > ( true, "Sprite Tiler" ); } As this class extends EditorWindow, and the preceding function is declared as MenuItem, it will create a dropdown in the Editor named RushRunner. This will hold a selection called Sprite Tile: You can name the dropdown and selection anything you like by changing the string that is passed into MenuItem, such as MyEditorTool or Editor Tool Name. If you save the SpiteTiler.cs file and go back to Unity and allow the engine to compile, you will be able to click on the SpriteTile button under RushRunner. This will create a editor window named Sprite Tiler. The OnGUI function Next, we need to add the function that will be used to draw all the windows GUI elements or the fields that we will use to get the settings to make the grid. Under our OpenSpriteTileWindow function, add the following code: // Called to render GUI frames and elements void OnGUI() { } OnGUI is the function that will draw our GUI elements to the window. This allows you to manipulate these GUI elements so that we have values to use when we create the GameObject grid and its GameObjects children with sprite components. The GUILayout and OnGUI setup To begin with the OnGUI function, we want to add the GUI elements to the window. In the OnGUI function, add the following code:   // Setting for GameObject name that holds our tiled Objects GUILayout.Label("Tile Level Object Name", EditorStyles .boldLabel); TileSpriteRootGameObjectName = GUILayout.TextField( TileSpriteRootGameObjectName, 25 ); // Slider for X grid value (left to right) GUILayout.Label("X: " + GridXSlider, EditorStyles. boldLabel); GridXSlider = GUILayout.HorizontalScrollbar( GridXSlider, 1.0f, 0.0f, 30.0f ); GridXSlider = (int)GridXSlider; // Slider for Y grid value(up to down) GUILayout.Label("Y: " + GridYSlider, EditorStyles. boldLabel); GridYSlider = GUILayout.HorizontalScrollbar(GridYSlider, 1.0f, 0.0f, 30.0f); GridYSlider = (int)GridYSlider; // File chose to be our Ground Sprite GUILayout.Label("Sprite Ground File", EditorStyles. boldLabel); TileGroundSprite = EditorGUILayout.ObjectField (TileGroundSprite, typeof(Sprite), true) as Sprite; // File chose to be our Dirt Sprite GUILayout.Label("Sprite Dirt File", EditorStyles. boldLabel); TileDirtSprite = EditorGUILayout.ObjectField (TileDirtSprite, typeof(Sprite), true) as Sprite; GUILayout.Label is a function that creates a text label in the window we are using. Its first use is to let the user know that the next setting is for Tile Level Object Name: the name of the root GameObject that will hold children GameObjects with Sprite components. By default, this is set to Tiled Object, although we allow the user to change it. In order to allow the user to change it, we need to give them a TextField parameter to input a new string. We do this by telling that TileSpriteRootGameObjectName is equal to the GUILayout.TextField setting. As this is used in OnGUI, anything the user inputs will change the value of TileSpriteRootGameObjectName. We will use this later when the user wants to create the GameObject. We then need to create two HorizontalSlider GUI elements so that we can get values from them that represent the X and Y values of the grid. Similar to TextField, we can start each of the HorizontalSlider elements with GUILayout.Label. This describes what the slider is for. We will then assign the GridXSlider and GridYSlider values to what the HorizontalSlider element is set to, which is one by default. As the user adjusts the sliders, the GridXSlider and GridYSlider values will change so that when the user clicks on a button to create the GameObject, we will have a reference to the values that they want to use for the grid. After HorizontalSliders, we want to have ObjectFields so that the user can search for and assign sprite files that will represent the ground and dirt of the grid. EditorGUILayout.ObjectField takes a reference to the object you want to assign when the user selects one, the type of object that ObjectField wants, and if ObjectField takes SceneObjects. As we want this ObjectField to be for sprites, we will set the type of object to typeof( Sprite ) and then cast the result that is assigned to TileGroundSprite or TileDirtSprite to the sprite by using as Sprite. The OnGUI create tiled button In order to know when the user wants to create the root GameObject and its grid of children GameObjects, we will need a button. Add the following code under the last GUI Elements: // If butt "Create Tiled" is clicked if (GUILayout.Button("Create Tiled")) { // If the Grid settings are both zero, // send notification to user if (GridXSlider == 0 && GridYSlider == 0) { ShowNotification(new GUIContent("Must have either X or Y grid set to a value greater than 0")); return; } // if Dirt and Ground Sprite exist if (TileDirtSprite != null && TileGroundSprite !=null) { // If the Sprites sizes dont match, // send notifcation to user if (TileDirtSprite.bounds.size.x != TileGroundSprite. bounds.size.x || TileDirtSprite.bounds.size.y != TileGroundSprite.bounds.size.y) { ShowNotification(new GUIContent("Both Sprites must be of matching size.")); return; } // Create GameObject and tiled // Objects with user settings CreateSpriteTiledGameObject(GridXSlider, GridYSlider, TileGroundSprite, TileDirtSprite, TileSpriteRoot GameObjectName); } else { // If either Dirt or Ground Sprite dont exist, // send notifcation to user ShowNotification( new GUIContent( "Must have Dirt and Ground Sprite selected." ) ); return; } } The first condition we have set is the GUILayout.Button( "Create Tiled" ) function. The Button function will return true as soon as it is clicked on, but it will still render to the window if false. This means that although the button is not active, it'll still be seen by the user. As some settings will create a scenario that is not ideal for the concept of our SpriteTiler, we first want to make sure that the settings are in line with what we have designed the tool to perform. We will first check whether GridXSlider and GridYSlider are set to zero. If both of these values are set to zero, the grid won't create anything, and as the concept of the tool is to create a grid of children sprites, we will tell the user that they must have a selection above zero for either GridXSlider or GridYSlider. We then check whether TileDirtSprite and TileGroundSprite have a value. If either of these values are null, the settings are not complete. This results in you telling the user that Dirt and Ground sprites need a selection. If the user has set Dirt and Ground sprites to something, but their sizing is not the same, such as one being 32 x 32 and the other being 64 x 64, we will tell the user that both the sprites need to be of the same size. If we didn't check for this, the grid wouldn't align correctly, creating negative results and making the tool not function as we want it to. If the user settings are in order, we will call the CreateSpriteTiledGameObject function and pass GridXSlider, GridYSlixer, TileGroundSprite, TileDirtSprite, and TileSpriteRootGameObjectName. The CreateSpriteTiledGameObject function This function is designed to take the user settings and create the grid from them. Add the following function under the OnGUI function: // Create GameObject and tiled childen based on user settings public static void CreateSpriteTiledGameObject(float GridXSlider, float GridYSlider, Sprite SpriteGroundFile, Sprite SpriteDirtFile, string RootObjectName) { // Store size of Sprite float spriteX = SpriteGroundFile.bounds.size.x; float spriteY = SpriteGroundFile.bounds.size.y; // Create the root GameObject which will hold children that tile GameObject rootObject = new GameObject( ); // Set position in world to 0,0,0 rootObject.transform.position = new Vector3( 0.0f, 0.0f, 0.0f ); // Name it based on user settings rootObject.name = RootObjectName; // Create starting values for while loop int currentObjectCount = 0; int currentColumn = 0; int currentRow = 0; Vector3 currentLocation = new Vector3( 0.0f, 0.0f, 0.0f ); // Continue loop until all rows // and columns have been filled while (currentRow < GridYSlider) { // Create a child GameObject, set its parent to root, // name it, and offset its location based on current location GameObject gridObject = new GameObject( ); gridObject.transform.SetParent( rootObject.transform ); gridObject.name = RootObjectName + "_" + currentObjectCount; gridObject.transform.position = currentLocation; // Give child gridObject a SpriteRenderer and set sprite on CurrentRow SpriteRenderer gridRenderer = gridObject.AddComponent <SpriteRenderer>( ); gridRenderer.sprite = ( currentRow == 0 ) ? SpriteGroundFile : SpriteDirtFile; // Give the gridObject a BoxCollider gridObject.AddComponent<BoxCollider2D>(); // Offset currentLocation for next gridObject to use currentLocation.x += spriteX; // Increment current column by one currentColumn++; // If the current collumn is greater than the X slider if (currentColumn >= GridXSlider) { // Reset column, incrmement row, reset x location // and offset y location downwards currentColumn = 0; currentRow++; currentLocation.x = 0; currentLocation.y -= spriteY; } // Add to currentObjectCount for naming of // gridObject children. currentObjectCount++; } } To start with, we must first have the X and Y sizes of the sprite we want to create so that we can offset the location of the children GameObjects that were created. As we originally checked to make sure that both sprites are of the same size, it doesn't matter which sprite object we get the size from. In our case, we will use SpriteGroundFile. We will then move the rootObject position to 0X, 0Y, and 0Z so that it is in the center of our scene. This can be set to anything you like, although when rootObject and its children get created, it is easier to find it at the center of the scene world. After it has been moved, we can set its name to the setting that the user had entered or Tiled Object (the default one). Once we have rootObject set up, we can create its children GameObjects. To start this cycle, we will need a few variables to reference and change: currentObjectCount: This specifies the total number of children that will be created. This increments for each one created. currentColumn: This denotes the current column we are on in the row. currentRow: This specifies the current row we are on. currentLocation: This denotes the current location that the children GameObject will use and sets its position too. This is changed after each new child is created based on the X or Y setting of the sprite size. Now that we have our rootObject and the variables we need to create the children, we can use while loop. A while loop is a loop that will continue until its condition fails. In our case, we will check whether currentRow is less than the GridYSlider value. As soon as currentRow is equal to or greater than GridYSlider, the loop will stop because the condition failed. The reason we will look at currentRow is that for each column created, we can reset its value to zero and increment currentRow by one. This means that each row will hold as many columns as were set by the GridXSlider value, and we know that the grid is complete when currentRow is equal or greater than GridYSlider. For example, if we had a grid setting of 3X and 3Y, the first row will hold three columns. When the first row is done, the row changes to two and adds three more columns. In the last row, it completes three more columns and then the while condition fails because the row value is equal to GridYSlider. In each loop of the while loop, we start by creating gridObject. We set this grid object parent to that of rootObject, set its name to RootObjectName, and concatenate an underscore, followed by currentObjectCount and then set the gridObject position to the currentLocation value, which will change based on the size of the sprite and the column/row. We will then add a SpriteRenderer component to gridObject and assign a sprite to it. We will change the sprite based on whether currentRow is equal to zero or not. If it is, in the first row, we will set the sprite to SpriteGroundFile. If currentRow is not equal to zero, we will set the sprite to SpriteDirtFile. The ternary operator is a sort of shorthand for if → else. If the condition is true, we will set the value to what is behind the question mark. If the condition is false, we will set the value based on what's behind the colon. The question mark represents if, whereas the colon represents else. The ternary operator is as follows: Value = ( condtion == true ) ? ifTrue : elseNotTrue; Once we have the sprite assigned to the SpriteRenderer component of gridObject, we can assign a BoxCollider2D component, which will make itself the same size as the sprite. If we were to add the BoxCollider2D component to SpriteRenderer, it would be the default size of 1, 1, 1, which would be too big. We will then offset currentLocation by the spriteX size, so the next gridObject will offset the size of the spriteX size. The currentColumn value is incremented by one, and we then check whether currentColumn is greater than or equal to the GridXSlider value. If it is, we know that we need to start the next row. To do this, we reset currentColumn to zero, increment currentRow by one, set the currentLocation.x value to zero, and offset currentLocation.y by negative spriteY size. This not only results in an offset location down, but also resets the X value to zero, making it possible for the columns to be created again; just down the size of spriteY. Finally, we increment currentObjectCount by one. Building the main menu UI The main menu UI will be its own Canvas GameObject. We will then handle the main menu and the game UI via the GameInfo class. We will also use the GameInfo class to manage button presses and the iOS integration. In Hierarchy, right-click and select UI and then click on Canvas. Name this new Canvas GameObject MenuUI. Let's start by adding five buttons to achievements, playing, leaderboards, remove iAds, and restore purchase. Right-click on the new MenuUI GameObject, navigate to UI, and left-click on Button. Do this four more times, so there are a total of five buttons that are children of the MenuUI GameObject. Name the buttons and text children as follows: PlayButton, PlayText LeaderboardButton, LeaderboardText AchievementButton, AchievementText RemoveAdsButton, RemoveAdsText RestorePurchaseButton, RestorePurchaseText Adding button images Next, we need to import the art that will be used for the main menu UI. In the Assets | UI folder, right-click and select Import New Asset. Select all the new images in the Assets | UI folder and change their settings as follows: Filter Mode: Trilinear Max Size: 256 Format: Truecolor PlayButton Select PlayButton in Hierarchy and search for Inspector. Change its settings as follows: Anchor: Bottom Center Pos X: 0 Pos Y: 115 Pos Z: 0 Width: 128 Height: 128 Source Image: MenuButton Now, select PlayButtonText. In the Inspector window, change its settings as follows: Text: Play Font: Arial Font Style: Bold Font Size: 36 Alignment: Center LeaderboardButton Select LeaderboardButton in the Hierarchy tab and search for Inspector. Change its settings as follows: Anchor: Bottom Center Pos X: 135 Pos Y: 115 Pos Z: 0 Width: 128 Height: 128 Source Image: MenuButton Select LeaderboardText. In the Inspector window, change its settings to: Text: Leaderboards Font: Arial Font Style: Bold Font Size: 17 Alignment: Center AchievementButton Select AchievementButton. In Hierarchy, search for Inspector. Change its settings as follows: Anchor: Bottom Center Pos X: -135 Pos Y: 115 Pos Z: 0 Width: 128 Height: 128 Source Image: MenuButton Now, select AchievementText and then in Inspector, change its settings to: Text: Achievements Font: Arial Font Style: Bold Font Size: 17 Alignment: Center RemoveAdsButton Select RemoveAdsButton in the Hierarchy tab and navigate to Inspector. Change its settings as follows: Anchor: Bottom Center Pos X: -64 Pos Y: 55 Pos Z: 0 Width: 96 Height: 42 Source Image: RestartButton Now, select RemoveAdsText and then in the Inspector window, change its settings as shown here: Text: Remove iAds Font: Arial Font Style: Bold Font Size: 12 Alignment: Center RestorePurchaseButton Let's select RestorePurchaseButton in the Hierarchy tab and search for Inspector. Change its settings as follows: Anchor: Bottom Center Pos X: 64 Pos Y: 55 Pos Z: 0 Width: 96 Height: 42 Source Image: RestartButton Now, select RestorePurchaseText and then in the Inspector window, change its settings as follows: Text: Restore Purchase Font: Arial Font Style: Bold Font Size: 14 Alignment: Center You should now have a button layout that looks similar to the following image: Summary In this article, we discussed how to create a Unity editor tool and a grid of GameObjects. These were laid out by the size of the sprites you chose and were flexible enough to use with your own settings. We also created prefabs for all of our bigger GameObjects, which could hold all of their components in a neat package. We also covered the basics of how to create a game for iOS and utilize its GameCenter features. Feel free to explore these features and add to them. Adding more store purchases, achievements, and leaderboards is simply repeating the steps that we have already done. Resources for Article: Further resources on this subject: Components in Unity[article] Saying Hello to Unity and Android [article] Unity Networking – The Pong Game [article]
Read more
  • 0
  • 0
  • 2328

article-image-3d-vector-drawing-and-text-papervision3d-part-2
Packt
20 Oct 2009
3 min read
Save for later

3D Vector Drawing and Text with Papervision3D: Part 2

Packt
20 Oct 2009
3 min read
Drawing lines with Lines3D Before VectorVision was integrated, Papervision3D already had a Lines3D class for drawing 3D lines. Two differences between drawing lines with VectorShape3D and Lines3D are: Whereas VectorShape3D enables you to easily draw rectangles, circles, and ellipses, Lines3D does not have built-in methods to do such things. Lines3D creates lines with a Vertex3D as the start and end point, resulting in 3D projection of the vertices that make the line. On the other hand, VectorShape3D lets you draw a 2D shape, which you then can rotate in order to achieve a 3D perspective. Let's take a look at how to create straight as well as curved lines with Lines3D, and how to add interactivity. The following class will serve as a template for the Lines3D examples to come: package{ import flash.events.Event; import org.papervision3d.core.geom.Lines3D; import org.papervision3d.core.geom.renderables.Line3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.materials.special.LineMaterial; import org.papervision3d.view.BasicView; public class Lines3DTemplate extends BasicView { private var lines:Lines3D; private var easeOut:Number = 0.6; private var reachX:Number = 0.5 private var reachY:Number = 0.5 private var reachZ:Number = 0.5; public function Lines3DTemplate () { super(stage.stageWidth,stage.stageHeight); stage.frameRate = 40; init(); startRendering(); } private function init():void { //code to be added } override protected function onRenderTick(e:Event=null):void { var xDist:Number = mouseX - stage.stageWidth * 0.5; var yDist:Number = mouseY - stage.stageHeight * 0.5; camera.x += (xDist - camera.x * reachX) * easeOut; camera.y += (yDist - camera.y * reachY) * easeOut; camera.z += (-mouseY * 2 - camera.z ) * reachZ; super.onRenderTick(); } }} Let's first examine what happens when we draw a line using the Lines3D class. How drawing with Lines3D works Each line is defined by a start and an end point, both being 3D vertices. The vertices are converted into 2D space coordinates. The lineTo() method of the Flash drawing API is then used to render the line. To create a line with the Lines3D class, we need to take these steps in the following order: Create line material with the LineMaterial class. The material defines the look of the line. Create a Lines3D instance, which is a do3D that will be used to store and render the lines. Use the Line3D class to instantiate a line. Add the line to the Lines3D instance with the addLine() method. Equivalent to how Particle instances need to be added in Particles using theaddParticle() method, we add Line3D instances to a Lines3D instance in order to render them. Lines3D has the following three methods to add Line3D instances: addLine() ad dNewLine() ad dNewSegmentedLine() Let's have a look at what they do and create some lines. Straight lines All t he following code should be added inside the init() method. First we create line material. var blueMaterial:LineMaterial = new LineMaterial(0x0000FF); You can pass two optional parameters as shown in the next table:   Parameter Data type Default value Description 1 color Number 0xFF0000 Defines the color of the line material using a 24 bit hexadecimal color value. 2 alpha Number 1 Sets the transparency of the material.
Read more
  • 0
  • 0
  • 2311

article-image-romeo-and-juliet
Packt
21 Aug 2013
10 min read
Save for later

Romeo and Juliet

Packt
21 Aug 2013
10 min read
(For more resources related to this topic, see here.) Mission Briefing To create the Processing sketches for this project, we will need to install the Processing library ttslib. This library is a wrapper around the FreeTTS Java library that helps us to write a sketch that reads out text. We will learn how to change the voice parameters of the kevin16 voice of the FreeTTS package to make our robot's voices distinguishable. We will also create a parser that is able to read the Shakespeare script and which generates text-line objects that allow our script to know which line is read by which robot. A Drama thread will be used to control the text-to-speech objects, and the draw() method of our sketch will print the script on the screen while our robots perform it, just in case one of them forgets a line. Finally, we will use some cardboard boxes and a pair of cheap speakers to create the robots and their stage. The following figure shows how the robots work: Why Is It Awesome? Since the 18th century, inventors have tried to build talking machines (with varying success). Talking toys swamped the market in the 1980s and 90s. In every decent Sci-Fi novel, computers and robots are capable of speaking. So how could building talking robots not be awesome? And what could be more appropriate to put these speaking capabilities to test than performing a Shakespeare play? So as you see, building actor robots is officially awesome, just in case your non-geek family members should ask. Your Hotshot Objectives We will split this project into four tasks that will guide you through the general on of the robots from beginning to end. Here is a short overview of what we are going to do: Making Processing talk Reading Shakespeare Adding more actors Building robots Making Processing talk Since Processing has no speaking capabilities out of the box, our first task is adding an external library using the new Processing Library Manager. We will use the ttslib package, which is a wrapper library around the FreeTTS library. We will also create a short, speaking Processing sketch to check the installation. Engage Thrusters Processing can be extended by contributed libraries. Most of these additional libraries can be installed by navigating to Sketch | Import Library… | Add Library..., as shown in the following screenshot: In the Library Manager dialog, enter ttslib in the search field to filter the list of libraries. Click on the ttslib entry and then on the Install button, as shown in the following screenshot, to download and install the library: To use the new library, we need to import it to our sketch. We do this by clicking on the Sketch menu and choosing Import Library... and then ttslib. We will now add the setup() and draw() methods to our sketch. We will leave the draw() method empty for now and instantiate a TTS object in the setup() method. Your sketch should look like the following code snippet: import guru.ttslib.*;TTS tts;void setup() { tts = new TTS();}void draw() {} Now we will add a mousePressed() method to our sketch, which will get called if someone clicks on our sketch window. In this method, we are calling the speak() method of the TTS object we created in the setup() method. void mousePressed() { tts.speak("Hello, I am a Computer");} Click on the Run button to start the Processing sketch. A little gray window should appear. Turn on your speakers or put on your headphones, and click on the gray window. If nothing went wrong, a friendly male computer voice named kevin16 should greet you now. Objective Complete - Mini Debriefing In steps 1 to 3, we installed an additional library to Processing. The ttslib is a wrapper library around the FreeTTS text-to-speech engine. Then we created a simple Processing sketch that imports the installed library and creates an instance of the TTS class. The TTS objects match the speakers we need in our sketches. In this case, we created only one speaker and added a mousePressed() method that calls the speak() method of our tts object. Reading Shakespeare In this part of the project, we are going to create a Drama thread and teach Processing how to read a Shakespeare script. This thread runs in the background and is controlling the performance. We focus on reading and executing the play in this task, and add the speakers in the next one. Prepare for Lift Off Our sketch needs to know which line of the script is read by which robot. So we need to convert the Shakespeare script into a more machine-readable format. For every line of text, we need to know which speaker should read the line. So we take the script and add the letter J and a separation character that is used nowhere else in the script, in front of every line our Juliet-Robot should speak, and we add R and the separation letter for every line our Romeo-Robot should speak. After all these steps, our text file looks something like the following: R# Lady, by yonder blessed moon I vow,R# That tips with silver all these fruit-tree tops --J# O, swear not by the moon, the inconstant moon,J# That monthly changes in her circled orb,J# Lest that thy love prove likewise variable.R# What shall I swear by?J# Do not swear at all.J# Or if thou wilt, swear by thy gracious self,J# Which is the god of my idolatry,J# And I'll believe thee. Engage Thrusters Let's write our parser: Let's start a new sketch by navigating to File | New. Add a setup() and a draw() method. Now add the prepared script to the Processing sketch by navigating to Sketch | Add File and selecting the file you just downloaded. Add the following line to your setup() method: void setup() { String[] rawLines = loadStrings ( "romeo_and_juliet.txt" );} If you renamed your text file, change the filename accordingly. Create a new tab by clicking on the little arrow icon on the right and choosing New Tab. Name the class Line. This class will hold our text lines and the speaker. Add the following code to the tab we just created: public class Line { String speaker; String text; public Line( String speaker, String text ) { this.speaker = speaker; this.text = text; }} Switch back to our main tab and add the following highlighted lines of code to the setup() method: void setup() { String[] rawLines = loadStrings ( "romeo_and_juliet.txt" ); ArrayList lines = new ArrayList(); for ( int i=0; i<rawLines.length; i++) { if (!"".equals(rawLines[i])) { String[] tmp = rawLines[i].split("#"); lines.add( new Line( tmp[0], tmp[1].trim() )); } }} We have read our text lines and parsed them into the lines array list, but we still need a class that does something with our text lines. So create another tab by clicking on the arrow icon and choosing New Tab from the menu; name it Drama. Our Drama class will be a thread that runs in the background and tells each of the speaker objects to read one line of text. Add the following lines of code to your Drama class: public class Drama extends Thread { int current; ArrayList lines; boolean running; public Drama( ArrayList lines ) { this.lines = lines; current = 0; running = false; } public int getCurrent() { return current; } public Line getLine( int num ) { if ( num >=0 && num < lines.size()) { return (Line)lines.get( num ); } else { return null; } } public boolean isRunning() { return running; }} Now we add a run() method that gets executed in the background if we start our thread. Since we have no speaker objects yet, we will print the lines on the console and include a little pause after each line. public void run() { running = true; for ( int i =0; i < lines.size(); i++) { current = i; Line l = (Line)lines.get(i); System.out.println( l.text ); delay( 1 ); } running = false; } Switch back to the main sketch tab and add the highlighted code to the setup() method to create a drama thread object, and then feed it the parsed text-lines. Drama drama;void setup() { String[] rawLines = loadStrings ( "romeo_and_juliet.txt" ); ArrayList lines = new ArrayList(); for ( int i=0; i<rawLines.length; i++) { if (!"".equals(rawLines[i])) { String[] tmp = rawLines[i].split("#"); lines.add( new Line( tmp[0], tmp[1].trim() )); } } drama = new Drama( lines );} So far our sketch parses the text lines and creates a Drama thread object. What we need next is a method to start it. So add a mousePressed() method to start the drama thread. void mousePressed() { if ( !drama.isRunning()) { drama.start(); }} Now add a little bit of text to the draw() method to tell the user what to do. Add the following code to the draw() method: void draw() { background(255); textAlign(CENTER); fill(0); text( "Click here for Drama", width/2, height/2 );} Currently, our sketch window is way too small to contain the text, and we also want to use a bigger font. To change the window size, we simply add the following line to the setup() method: void setup() { size( 800, 400 ); String[] rawLines = loadStrings ( "romeo_and_juliet.txt" ); ArrayList lines = new ArrayList(); for ( int i=0; i<rawLines.length; i++) { if (!"".equals(rawLines[i])) { String[] tmp = rawLines[i].split("#"); lines.add( new Line( tmp[0], tmp[1].trim() )); } } drama = new Drama( lines );} To change the used font, we need to tell Processing which font to use. The easiest way to find out the names of the fonts that are currently installed on the computer is to create a new sketch, type the following line, and run the sketch: println(PFont.list()); Copy one of the font names you like and add the following line to the Romeo and Juliet sketch: void setup() { size( 800, 400 ); textFont( createFont( "Georgia", 24 ));... Replace the font name in the code lines with one of the fonts on your computer. Objective Complete - Mini Debriefing In this section, we wrote the code that parses a text file and generates a list of Line objects. These objects are then used by a Drama thread that runs in the background as soon as anyone clicks on the sketch window. Currently, the Drama thread prints out the text line on the console. In steps 6 to 8, we created the Line class. This class is a very simple, so-called Plain Old Java Object (POJO) that holds our text lines, but it doesn't add any functionality. The code that is controlling the performance of our play was created in steps 10 to 12. We created a thread that is able to run in the background, since in the next step we want to be able to use the draw() method and some TTS objects simultaneously. The code block in step 12 defines a Boolean variable named running, which we used in the mousePressed() method to check if the sketch is already running or should be started. Classified Intel In step 17, we used the list() method of the PFont class to get a list of installed fonts. This is a very common pattern in Processing. You would use the same approach to get a list of installed midi-interfaces, web-cams, serial-ports, and so on.
Read more
  • 0
  • 0
  • 2255
article-image-polygon-modeling-handgun-using-blender-3d-249-part-2
Packt
30 Nov 2009
4 min read
Save for later

Polygon Modeling of a Handgun using Blender 3D 2.49: Part 2

Packt
30 Nov 2009
4 min read
Modeling the hand wrap Set the view to front again, and select the vertices pointed in the following image. This time we will need two extrusions. Select the vertices in the top-left corner of the model, and move them down to align them to the image. Then, select the other three vertices shown in the following image and extrude them once: As the extruded geometry doesn't fit the guides of our reference image, we will have to select and move the lower vertices and place them as shown in the following image. They don't have to be exactly in the same position, but they should be placed in such a way that the shape of the model looks like our reference image. Remember that you can also select the vertices with the brush select tool. Press the B key twice, and then you will be able to paint the selection. Right after you place the vertices in their new positions, make another extrusion. By the end of the extrusion, try to place the lower vertices aligned with the right side of the guidelines. Just by looking at the image, you'll notice that one side of the model won't be aligned. So, select the vertices on the left or right (any one that isn't aligned with the image) and move it until it gets aligned. By now, the work will be a repetition of extrusions until we have our model created. Select the vertices pointed in the next images, and extrude them until you get the final shape. At this point in the project, you should be familiar with the technique. It's important to remember that for those operations, most of the alignment of the objects with the reference image is done by eye. At the end of each extrusion, use the S key to set the size of the new geometry until it fits with the reference image. If you prefer, the transform ation can be executed in face select mode to speed up the selection of the faces used in the extrusion. Here, we'll use the Skin Faces/Edge-Loops option again to connect the two selected faces. Sometimes, the faces created with this option will be generated with a Set Smooth option selected. This may cause the faces to look odd and have a different set of shading from the other faces. To make it look exactly the same as other faces of the model, select the created faces and click on the Set Solid button. If you don't know where this button is located, you will find it in the Editing panel. After the Skin Faces/Edge-Loops option is applied, the shade of the object will look a bit strange. This is because the smooth option of Blender is being used. Use the Set Solid option to make the faces appear in flat shade mode. A big part of the modeling is complete, but there are a few parts of the weapon missing. Our next task is to create additional parts of the gun, such as a detail for the hand wrap and the energy tank. For this project, we will create different objects for those parts to make our modeling easier. As you can see in the following image, we have created a big part of the gun with a well-organized topology and a fairly clean mesh, which is represented by a minimum number of faces and vertices, made only by quad faces. This type of mesh can be easily edited later by using subdivisions and new extrudes, which is a good reason to keep it as clean as possible.
Read more
  • 0
  • 0
  • 2191

article-image-thumping-moles-fun
Packt
07 Mar 2013
22 min read
Save for later

Thumping Moles for Fun

Packt
07 Mar 2013
22 min read
(For more resources related to this topic, see here.) The project is… In this article, we will be building a mole thumping game. Inspired by mechanical games of the past, we will build molehills on the screen and randomly cause animated moles to pop their heads out. The player taps them to score. Simple in concept, but there are a few challenging design considerations in this deceptively easy game. To make this game a little unusual, we will be using a penguin instead of a mole for the graphics, but we will continue to use the mole terminology throughout, since a molehill is easier to consider than a penguin-hill. Design approach Before diving into the code, let's start with a discussion of the design of the game. First, we will need to have molehills on the screen. To be aesthetically pleasing, the molehills will be in a 3 x 4 grid. Another approach would be to use random molehill positions, but that doesn't really work well on the limited screen space of the iPhone.Moles will randomly spawn from the molehills. Each mole will rise up, pause, and drop down. We will need touch handling to detect when a mole has been touched, and that mole will need to increase the player's score and then go away. How do we make the mole come up from underground? If we assume the ground is a big sprite with the molehills drawn on it, we would need to determine where to make the "slot" from which the mole emerges, and somehow make the mole disappear when it is below that slot. One approach is to adjust the size of the mole's displayed frame by clipping the bottom of the image so that the part below the ground is not visible. This needs to be done as a part of every update cycle for every mole for the entire game. From a programming standpoint this will work, but you may experience performance issues. Another consideration is that this usually means the hole in the molehill will always appear to be a straight-edged hole, if we trim the sprite with a straight line. This lacks the organic feel we want for this game. The approach we will take is to use Z-ordering to trick the eye into seeing a flat playfield when everything is really on staggered Z-orders. We will create a "stair step" board, with multiple "sandwiches" of graphics for every row of molehills on the board. For each "step" of the "stair step", we have a sandwich of Z-ordered elements in this order, from back to front: molehill top, mole, ground, and molehill bottom. We need to have everything aligned so that the molehill top graphic overlaps the ground of the next "step" further towards the top of the screen. This will visually contain the mole, so it appears to be emerging from inside the molehill. We intentionally skipped the Z value of 1, to provide an extra expansion space if we later decide that we need another element in the "sandwich". It is easier to leave little holes like this than to worry about changing everything later, if we enhance our design. So throughout our layout, we will consider it as a sandwich of five Z values, even though we only use four elements in the sandwich. As we said, we need this to be a "stair step" board. So for each row of molehills, from the top of the screen to the bottom, we will need to increase the Z-ordering between layers to complete the illusion. This is needed so that each mole will actually pass in front of the ground layer that is closer to the top of the screen, yet will hide completely behind the ground layer in its own sandwich of layers. Designing the spawn That covers the physical design of the game, but there is one additional design aspect we need to discuss: spawning moles. We need to spawn the moles whenever we need one to be put into the play. Just as we reviewed two approaches to the hiding mole problem earlier, we will touch on two approaches to mole spawning. The first approach (and most common) is to create a new mole from scratch each time you need one. When you are done with it, you destroy it. This works fine for games with a small number of objects or games of more limited complexity, but there is a performance penalty to create and destroy a lot of objects in a short amount of time. Strictly speaking, our mole thumping game would likely work fine with this approach. Even though we will be creating and destroying quite a few moles all the time, we only have a dozen possible moles, not hundreds. The other approach is to create a spawning pool. This is basically a set number of the objects that are created when you start up. When you need a mole, in our case, you ask the pool for an unused "blank mole", set any parameters that are needed, and use it. When you are done with it, you reset it back to the "blank mole" state, and it goes back into the pool. For our game the spawning pool might be a little more heavily coded than needed, as it is doubtful that we would run into any performance issues with this relatively simple game. Still, if you are willing to build the additional code as we are doing here, it does provide a strong foundation to add more performance-heavy effects later on. To clarify our design approach, we will actually implement a variation of the traditional spawning pool. Instead of a general pool of moles, we will build our "blank mole" objects attached to their molehills. A more traditional spawning pool might have six "blnk moles" in the pool, and they are assigned to a molehill when they are needed. Both approaches are perfectly valid. Portrait mode The default orientation supported by cocos2d is landscape mode, which is more commonly used in games. However, we want our game to be in portrait mode. The changes are very simple to make this work. If you click once on the project name (and blue icon) in the Project Navigator pane (where all your files are listed), and then click on the name of your game under TARGETS , you will see the Summary pane. Under the Supported Interface Orientations, select Portrait, and deselect Landscape Left and Landscape Right . That will change your project to portrait. The one adjustment to the cocos2d template code we need is in the IntroLayer.m. After it sets the background to Default.png, there is a command to rotate the background. Remove, or comment out this line, and everything will work correctly. Custom TTF fonts In this project we will be using a custom TTF font. In cocos2d 1.x, you could simply add the font to your project and use it. Under cocos2d 2.0, which we are using, we have to approach this a little differently. We add the font to our project (we are using anudrg.ttf). Then we edit the Info.plist for our project, and add a new key to the list, like this: This tells the project that we need to know about this font. To actually use the font, we need to call it by the proper name for the font, not the filename. To find out this name, in Finder, select the file and choose File Info . In the info box, there is an entry for Full Name . In our case, the file name is AnuDaw. Any time we create a label with CCLabelTTF, we simply need to use this as the font name, and everything works perfectly. Defining a molehill We have created a new subclass of CCNode to represent the MXMoleHill object. Yes, we will be using a subclass of CCNode, not a subclass of CCSprite . Even though we initially would consider the molehill to be a sprite, referring back to our design, it is actually made up of two sprites, one for the top of the hill and one for the bottom. We will use CCNode as a container that will then contain two CCSprite objects as variables inside the MXMoleHill class. Filename: MXMoleHill.h @interface MXMoleHill : CCNode { NSInteger moleHillID; CCSprite *moleHillTop; CCSprite *moleHillBottom; NSInteger moleHillBaseZ; MXMole *hillMole; BOOL isOccupied; } @property (nonatomic, assign) NSInteger moleHillID; @property (nonatomic, retain) CCSprite *moleHillTop; @property (nonatomic, retain) CCSprite *moleHillBottom; @property (nonatomic, assign) NSInteger moleHillBaseZ; @property (nonatomic, retain) MXMole *hillMole; @property (nonatomic, assign) BOOL isOccupied; @end If this seems rather sparse to you, it is. As we will be using this as a container for everything that defines the hill, we don't need to override any methods from the standard CCNode class. Likewise, the @implementation file contains nothing but the @synthesize statements for these variables. It is worth pointing out that we could have used a CCSprite object for the hillTop sprite, with the hillBottom object as a child of that sprite, and achieved the same effect. However, we prefer consistency in our object structure, so we have opted to use the structure noted previously. This allows us to refer to the two sprites in exactly the same fashion, as they are both children of the same parent. Building the mole When we start building the playfield, we will be creating "blank mole" objects for each hill, so we need to look at the MXMole class before we build the playfield. Following the same design decision as we did with the MXMoleHill class, the MXMole class is also a subclass of CCNode. Filename: MXMole.h #import #import "cocos2d.h" #import "MXDefinitions.h" #import "SimpleAudioEngine.h" // Forward declaration, since we don't want to import it here @class MXMoleHill; @interface MXMole : CCNode { CCSprite *moleSprite; // The sprite for the mole MXMoleHill *parentHill; // The hill for this mole float moleGroundY; // Where "ground" is MoleState _moleState; // Current state of the mole BOOL isSpecial; // Is this a "special" mole? } @property (nonatomic, retain) MXMoleHill *parentHill; @property (nonatomic, retain) CCSprite *moleSprite; @property (nonatomic, assign) float moleGroundY; @property (nonatomic, assign) MoleState moleState; @property (nonatomic, assign) BOOL isSpecial; -(void) destroyTouchDelegate; @end We see a forward declaration here (the @class statement). Use of forward declaration avoids creating a circular loop, because the MXMoleHill.h file needs to import MXMole.h . In our case, MXMole needs to know there is a valid class called MXMoleHill, so we can store a reference to an MXMoleHill object in the parentHill instance variable, but we don't actually need to import the class. The @class declaration is an instruction to the compiler that there is a valid class called MXMoleHill, but doesn't actually import the header while compiling the MXMole class. If we needed to call the methods of MXMoleHill from the MXMole class, we could then put the actual #import "MXMoleHill.h" line in the MXMole.m file. For our current project, we only need to know the class exists, so we don't need that additional line in the MXMole.m file. We have built a simple state machine for MoleState. Now that we have reviewed the MXMole.h file, we have a basic idea of what makes up a mole. It tracks the state of the mole (dead, alive, and so on), it keeps a reference to its parent hill, and it has CCSprite as a child where the actual mole sprite variable will be held. There are a couple of other variables (moleGroundY and isSpecial), but we will deal with these later. Filename: MXDefinitions.h typedef enum { kMoleDead = 0, kMoleHidden, kMoleMoving, kMoleHit, kMoleAlive } MoleState; #define SND_MOLE_NORMAL @"penguin_call.caf" #define SND_MOLE_SPECIAL @"penguin_call_echo.caf" #define SND_BUTTON @"button.caf" Unlike in the previous article, we do not have typedef enum that defines the MoleState type inside this header file. We have moved our definit ions to the MXDefinitions.h file, which helps to maintain slightly cleaner code. You can storethese "universal" definitions in a single header file, and include the header in any .h or .m files where they are needed, without needing to import classes just to gain access to these definitions. The MXDefinitions.h file only includes the definitions; there are no @interface or @implementation sections, nor a related .m file. Making a molehill We have our molehill class and we've seen the mole class, so now we can look at how we actually build the molehills in the MXPlayfieldLayer class: Filename: MXPlayfieldLayer.m -(void) drawHills { NSInteger hillCounter = 0; NSInteger newHillZ = 6; // We want to draw a grid of 12 hills for (NSInteger row = 1; row <= 4; row++) { // Each row reduces the Z order newHillZ--; for (NSInteger col = 1; col <= 3; col++) { hillCounter++; // Build a new MXMoleHill MXMoleHill *newHill = [[MXMoleHill alloc] init]; [newHill setPosition:[self hillPositionForRow:row andColumn:col]]; [newHill setMoleHillBaseZ:newHillZ]; [newHill setMoleHillTop:[CCSprite spriteWithSpriteFrameName:@"pileTop.png"]]; [newHill setMoleHillBottom:[CCSprite spriteWithSpriteFrameName:@"pileBottom.png"]]; [newHill setMoleHillID:hillCounter]; // We position the two moleHill sprites so // the "seam" is at the edge. We use the // size of the top to position both, // because the bottom image // has some overlap to add texture [[newHill moleHillTop] setPosition: ccp(newHill.position.x, newHill.position.y + [newHill moleHillTop].contentSize.height / 2)]; [[newHill moleHillBottom] setPosition: ccp(newHill.position.x, newHill.position.y - [newHill moleHillTop].contentSize.height / 2)]; //Add the sprites to the batch node [molesheet addChild:[newHill moleHillTop] z:(2 + (newHillZ * 5))]; [molesheet addChild:[newHill moleHillBottom] z:(5 + (newHillZ * 5))]; //Set up a mole in the hill MXMole *newMole = [[MXMole alloc] init]; [newHill setHillMole:newMole]; [[newHill hillMole] setParentHill:newHill]; [newMole release]; // This flatlines the values for the new mole [self resetMole:newHill]; [moleHillsInPlay addObject:newHill]; [newHill release]; } } } This is a pretty dense method, so we'll walk through it one section at a time. We start by creating two nested for loops so we can iterate over every possible row and column position. For clarity, we named our loop variables as row and column, so we know what each represents. If you recall from the design, we decided to use a 3 x 4 grid, so we will have three columns and four rows of molehills. We create a new hill using an alloc/init, and then we begin filling in the variables. We set an ID number (1 through 12), and we build CCSprite objects to fill in the moleHillTop and moleHillBottom variables. Filename: MXPlayfieldLayer.m -(CGPoint) hillPositionForRow:(NSInteger)row andColumn:(NSInteger)col { float rowPos = row * 82; float colPos = 54 + ((col - 1) * 104); return ccp(colPos,rowPos); } We also set the position using the helper method, hillPositionForRow:andColumn:, that returns a CGPoint for each molehill. (It is important to remember that ccp is a cocos2d shorthand term for a CGPoint. They are interchangeable in your code.) These calculations are based on experimentation with the layout, to create a grid that is both easy to draw as well as being visually appealing. The one variable that needs a little extra explaining is moleHillBaseZ . This represents which "step" of the Z-order stair-step design this hill belongs to. We use this to aid in the calculations to determine the proper Z-ordering across the entire playfield. If you recall, we used Z-orders from 2 to 5 in the illustration of the stack of elements. When we add the moleHillTop and moleHillBottom as children of the moleSheet (our CCSpriteBatchNode), we add the Z-order of the piece of the sandwich to the "base Z" times 5. We will use a "base Z" of 5 for the stack at the bottom of the screen, and a "base Z" of 2 at the top of the screen. This will be easier to understand the reason if we look at the following chart, which shows the calculations we use for each row of molehills: As we start building our molehills at the bottom of the screen, we start with a higher Z-order first. In the preceding chart, you will see that the mole in hole 4 (second row of molehills from the bottom) will have a Z-order of 23. This will put it behind its own ground layer, which is at a Z-order of 24, but in front of the ground higher on the screen, which would be at a Z-order of 19. It is worth calling out that since we have a grid of molehills in our design, all Z-ordering will be identical for all molehills in the same row. This is why the decrement of the baseHillZ variable occurs only when we are iterating through a new row. If we refer back to the drawHills method itself, we also see a big calculation for the actual position of the moleHillTop and moleHillBottom sprites. We want the "seam" between these two sprites to be at the top edge of the ground image of their stack, so we set the y position based on the position of the MXMoleHill object. At first it may look like an error, because both setPosition statements use contentSize of the moleHillTop sprite as a part of the calculation. This is intentional, because we have a little jagged overlap between those two sprites to give it a more organic feel. To wrap up the drawHills method, we allocate a new MXMole, assign it to the molehill that was just created, and set the cross-referencing hillMole and parentHill variables in the objects themselves. We add the molehill to our moleHillsInPlay array, and we clean everything up by releasing both the newHill and the newMole objects. Because the array retains a reference to the molehill, and the molehill retains a reference to the mole, we can safely release both the newHill and newMole objects in this method. Drawing the ground Now that we have gone over the Z-ordering "trickery", we should look at the drawGround method to see how we accomplish the Z-ordering in a similar fashion: Filename: MXPlayfieldLayer.m -(void) drawGround { // Randomly select a ground image NSString *groundName; NSInteger groundPick = CCRANDOM_0_1() * 2; switch (groundPick) { case 1: groundName = @"ground1.png"; break; default: // Case 2 also falls through here groundName = @"ground2.png"; break; } // Build the strips of ground from the selected image for (int i = 0; i < 5; i++) { CCSprite *groundStrip1 = [CCSprite spriteWithSpriteFrameName:groundName]; [groundStrip1 setAnchorPoint:ccp(0.5,0)]; [groundStrip1 setPosition:ccp(size.width/2,i*82)]; [molesheet addChild:groundStrip1 z:4+((5-i) * 5)]; } // Build a skybox skybox = [CCSprite spriteWithSpriteFrameName:@"skybox1.png"]; [skybox setPosition:ccp(size.width/2,5*82)]; [skybox setAnchorPoint:ccp(0.5,0)]; [molesheet addChild:skybox z:1]; } This format should look familiar to you. We create five CCSprite objects for the five stripes of ground, tile them from the bottom of the screen to the top, and assign the Z-order as z:4+((5-i) * 5). We do include a randomizer with two different background images, and we also include a skybox image at the top of the screen, because we want some sense of a horizon line above the mole-thumping area. anchorPoint is the point that is basically "center" for the sprite. The acceptable values are floats between 0 and 1. For the x axis, an anchorPoint of 0 is the left edge, and 1 is the right edge (0.5 is centered). For the y axis, an anchorPoint of 0 is the bottom edge, and 1 is the top edge. This anchorPoint is important here because that anchorPoint is the point on the object to which the setPosition method will refer. So in our code, the first groundStrip1 created will be anchored at the bottom center. When we call setPosition, the coordinate passed to setPosition needs to relate to that anchorPoint; the position set will be the bottom center of the sprite. If this is still fuzzy for you, it is a great exercise to change anchorPoint of your own CCSprite objects and see what happens on the screen. Mole spawning The only piece of the "sandwich" of elements we haven't seen in detail is the mole itself, so let's visit the mole spawning method to see how the mole fits in with our design: Filename: MXPlayfieldLayer.m -(void) spawnMole:(id)sender { // Spawn a new mole from a random, unoccupied hill NSInteger newMoleHill; BOOL isApprovedHole = FALSE; NSInteger rand; if (molesInPlay == [moleHillsInPlay count] || molesInPlay == maxMoles) { // Holes full, cannot spawn a new mole } else { // Loop until we pick a hill that isn't occupied do { rand = CCRANDOM_0_1() * maxHills; if (rand > maxHills) { rand = maxHills; } MXMoleHill *testHill = [moleHillsInPlay objectAtIndex:rand]; // Look for an unoccupied hill if ([testHill isOccupied] == NO) { newMoleHill = rand; isApprovedHole = YES; [testHill setIsOccupied:YES]; } } while (isApprovedHole == NO); // Mark that we have a new mole in play molesInPlay++; // Grab a handle on the mole Hill MXMoleHill *thisHill = [moleHillsInPlay objectAtIndex:newMoleHill]; NSInteger hillZ = [thisHill moleHillBaseZ]; // Set up the mole for this hill CCSprite *newMoleSprite = [CCSprite spriteWithSpriteFrameName:@"penguin_forward.png"]; [[thisHill hillMole] setMoleSprite:newMoleSprite]; [[thisHill hillMole] setMoleState:kMoleAlive]; // We keep track of where the ground level is [[thisHill hillMole] setMoleGroundY: thisHill.position.y]; // Set the position of the mole based on the hill float newMolePosX = thisHill.position.x; float newMolePosY = thisHill.position.y - (newMoleSprite.contentSize.height/2); [newMoleSprite setPosition:ccp(newMolePosX, newMolePosY)]; // See if we need this to be a "special" mole NSInteger moleRandomizer = CCRANDOM_0_1() * 100; // If we randomized under 5, make this special if (moleRandomizer < 5) { [[thisHill hillMole] setIsSpecial:YES]; } //Trigger the new mole to raise [molesheet addChild:newMoleSprite z:(3 + (hillZ * 5))]; [self raiseMole:thisHill]; } } The first thing we check is to make sure we don't have active moles in every molehill, and that we haven't reached the maximum number of simultaneous moles we want on screen at the same time (the maxMoles variable). If we have enough moles, we skip the rest of the loop. If we need a new mole, we enter a do…while loop that will randomly pick a molehill and check if it has the isOccupied variable set to NO (that is, no active mole in this molehill). If the randomizer picks a molehill that is already occupied, the do…while loop will pick another molehill and try again. When we find an unoccupied molehill, the code breaks out of the loop and starts to set up the mole. As we saw earlier, there is already a "blank mole" attached to every molehill. At this point we build a new sprite to attach to the moleSprite variable of MXMole, change the moleState to kMoleAlive, and set up the coordinates for the mole to start. We want the mole to start from underground (hidden by the ground image), so we set the mole's y position as the position of the molehill minus the height of the mole. Once we have set up the mole, we assign our calculated Z-order for this mole (based on the moleHillBaseZ variable we stored earlier for each molehill), and call the raiseMole method, which controls the animation and movement of the mole. Special moles We have seen two references to the isSpecial variable from the MXMole class, so now is a good time to explain how it is used. In order to break the repetitive nature of the game, we have added a "special mole" feature. When a new mole is requested to spawn in the spawnMole method, we generate a random number between 1 and 100. If the resulting number is less than five, then we set the isSpecial flag for that mole. This means that roughly 5 percent of the time the player will get a special mole. Our special moles use the same graphics as the standard mole, but we will make them flash a rainbow of colors when they are in the play. It is a small difference, but enough to set up the scoring to give extra points for the "special mole". To implement this special mole, we only need to adjust coding in three logic areas: When raiseMole is setting the mole's actions (to make it flashy) When we hit the mole (to play a different sound effect) When we score the mole (to score more points) This is a very small task, but it is the small variations in the gameplay that will draw the players in further. Let's see the game with a special mole in the play: Moving moles When we call the raiseMole method, we build all of the mole's behavior. The absolute minimum we need is to raise the mole from the hill and lower it again. For our game, we want to add a little randomness to the behavior, so that we don't see exactly the same motions for every mole. We use a combination of pre-built animations with actions to achieve our result. As we haven't used any CCAnimate calls before, we should talk about them first. The animation cache Cocos2d has many useful caches to store frequently used data. When we use a CCSpriteBatchNode, we are using the CCSpriteFrameCache to store all of the sprites we need by name. There is an equally useful CCAnimationCache as well. It is simple to use. You build your animation as a CCAnimation, and then load it to the CCAnimationCache by whatever name you would like. When you want to use your named animation, you can create a CCAnimate action that loads directly from CCAnimationCache. The only caution is that if you load two animations with the same name to the cache, they will collide in the cache, and the second one will replace the first. For our project, we preload the animation during the init method by calling the buildAnimations method. We only use one animation here, but you could preload as many as you need to the cache ahead of time. Filename: MXPlayfieldLayer.m -(void) buildAnimations { // Load the Animation to the CCSpriteFrameCache NSMutableArray *frameArray = [NSMutableArray array]; // Load the frames [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_forward.png"]]; [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_left.png"]]; [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_forward.png"]]; [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_right.png"]]; [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_forward.png"]]; [frameArray addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"penguin_forward.png"]]; // Build the animation CCAnimation *newAnim = [CCAnimation animationWithSpriteFrames:frameArray delay:0.4]; // Store it in the cache [[CCAnimationCache sharedAnimationCache] addAnimation:newAnim name:@"penguinAnim"]; } We only have three unique frames of animation, but we load them multiple times into the frameArray to fit our desired animation. We create a CCAnimation object from the frameArray, and then commit it to CCAnimationCache under the name penguinAnim. Now that we have loaded it to the cache, we can reference it anywhere we want it, just by requesting it from CCAnimationCache, like this: [[CCAnimationCache sharedAnimationCache] animationByName:@"penguinAnim"]]
Read more
  • 0
  • 0
  • 2188

article-image-illuminating-scene
Packt
24 Oct 2013
3 min read
Save for later

Illuminating a Scene

Packt
24 Oct 2013
3 min read
(For more resources related to this topic, see here.) Working with lights Before starting to explain about lights, we need to learn how to create and manipulate them. Once you know how to handle them, you will be ready to start learning the who-is-who in the lightning stage. Let's start with the basics. Adding a light Lights are handled in modo just like regular items. You can move, rotate, and scale them, and of course, tweak their properties. By default, a newly created scene has got a default light already. You can use it, change its type, or add as many as you need. In order to add a new light you should go to the Item List tab, and then click on the Add Item button. In the drop-down menu go to Lights, then choose the type of light you want. The other way to do this is by using the top menu. Navigate to Item | Create Light and choose the type you want. Setting the type of a light You can always change the type of the light just created (or change an existent light). In the Item List tab, right-click the light you want to change, and from the menu click on Change Type, then choose the type you want for your light. Placing lights As said previously, lights are like all other regular items. So you can move, rotate, and scale them as you need. You will have the following two ways of placing a light: Direct manipulation: Working in item mode, click on the light on any of the viewports—or directly in the Item List tab— and use the corresponding tools (W for moving, R for scaling, or Y for rotating). Subjective manipulation: A more interesting and practical way to move a light is by changing the viewport to light view mode. Once you change it, your view will be literally inside the light, so the direction you are facing will be the direction of the light. In this view, use your standard viewport controls to orientate the light. Enabling/disabling lights Usually, there are occasions when you need to turn off a light, or a number of them. The first thought would be turning its intensity value to zero, but there is a more practical way to temporarily disable a light. If you take a look at the items list, you will see a column on the left of the panel showing a little eye icon. That column shows the visibility state of each item. The eye means that it's visible, and you can click on that icon to totally disable the light (or any item, in fact), and click on it again to enable it back. Of course you can do rest of the basic operations with the lights, as with other kinds of items including enabling/disabling them, grouping them in a single folder, and so on.
Read more
  • 0
  • 0
  • 2154
article-image-building-your-first-application-papervision3d-part-2
Packt
26 Oct 2009
10 min read
Save for later

Building your First Application with Papervision3D: Part 2

Packt
26 Oct 2009
10 min read
This article covers: Basics of a 3D composition in Papervision3D Building your first application Basics of a 3D scene in Papervision3D Before we're ready to program some code for Papervision3D, we need to know a little bit more about 3D in Papervision3D. The following section is meant to give you a better understanding of the code that you will write. Each of these concepts relates directly to classes that are used by Papervision3D. All the object types that will be described are active elements in a 3D scene. Let's have a visualized look at all these objects: Scene The scene is the entire composition of 3D objects in a 3D space. Think of it as your stage in Flash with three axes—x, y, and z. Each object that you want to be visible should be added to the scene. If you don't add objects to the scene, they will not appear on your screen. Camera You can think of this as a real camera, which is somewhere in 3D space recording activity inside the scene. The camera defines the point of view from which you are viewing the scene. Because a camera in 3D is not a visible object, it is not part of our scene and you don't need to add it. Like a real camera you can, for example, zoom and focus. Cameras in 3D space can usually do more than real cameras. For example, in 3D you can, exclude objects to be rendered, when they are too close or too far away from the camera. The camera is able to ignore objects that are not in a certain, defined range. This is done for performance reasons. Objects that are too far away, or even behind the camera, don't need to be recorded, saving a lot of calculation for objects that are in a position where the camera simply can't see them. Viewport A viewport is a container sprite on your stage, and shows the output of what the camera sees. In the illustrative object overview, this has been compared with the lens of the camera. The lens is our window onto the 3D scene. We can make this window small and see just a small part of the scene, or make it big and see a lot. This works exactly as a real window in a wall—making it bigger will not affect how the world outside looks, but will have an effect on how much we can see from this world. The following illustration contains the visualization of a relatively big viewport on the left, along with a relatively small and wide viewport on the right. The thick dark outlines represent the viewports. In the right image, you can clearly see how the window to the 3D world works and how changing its size will not stretch the view of the 3D object in the scene. It only affects how much we see of it. 3D Objects A shape in 3D space is called a 3D object, or DisplayObject3D in Papervision3D. You can think of 3D objects as more advanced display objects just like sprites and movie clips. The difference is that a DisplayObject3D has a third axis, so we can place it anywhere in 3D space and rotate over each of the three axes. Material A material is the texture that is printed on an object. When an object doesn't have a material applied, it will be invisible. There are a variety of materials available for you to use. For example, a very simple material is a color; a more advanced example of a material could be a live streaming video. Render engine A render engine is like a rolling camera. As long as you trigger the render engine, it will output information of the scene recorded by the camera to the viewport. When you stop triggering the render engine, your viewport will not show any new image from the scene and shows the last rendered image. Rendering is actually the most intensive task for your computer, as it needs to recalculate each object that is placed inside your scene and output this to the viewport. Left-handed Cartesian coordinate system Flash, as well as Papervision3D, make use of the Cartesian coordinate system. In Flash, a regular visual object can be positioned on the stage by entering an x and y value. The object will be positioned according to these values and relative to the upper left corner of the stage. A higher x value moves the object to the right, whereas a higher y value moves it downward. The coordinate system in Papervision3D works essentially the same, except for the following two differences: Flash uses Cartesian coordinates on two axes, whereas Papervision3D makes use of them on three axes The y-axis in Flash is inversed compared to the y-axis in Papervision3D In Papervision3D, we want to position objects not only on the x and y axes, but also on an extra axis, in order to position objects in depth. This third axis is called the z-axis. In Flash, objects are positioned relative to the upper left corner, which is the 0, 0 coordinate. This is called the center point, or the origin. Predictably, the position of the origin in 3D space is located at 0, 0, 0. The three axes and the origin point are illustrated by the following image: The plus and minus signs illustrate whether the coordinate values are increasing or decreasing in the direction away from the origin. Notice that the y-axis is inverted compared to 2D coordinates in Flash. When you want to position an object lower on your screen in Flash, you need to give it a higher y position. This is how 2D coordinates on a computer screen work. The above figure shows the y-axis as according to the coordinate system as it is used by Papervision3D. Creating a basic class for Papervision3D In the previous sections you've learned what a basic scene is made of, and how you can create your own classes. Now that we have gone through all this theory, it's now time that we get our hands dirty by writing some code. Start your favorite authoring tool. The first application we'll build is a 3D scene containing a sphere that is rotating over its y-axis. A sphere is basically a "3D ball" and is built into Papervision3D as one of the default primitives. The basic document class First, have a look at the document class that defines the basic structure for the rotating sphere application. package { import flash.display.Sprite; import org.papervision3d.cameras.Camera3D; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class FirstApplication extends Sprite { private var scene:Scene3D; private var viewport:Viewport3D; private var camera:Camera3D; private var renderEngine:BasicRenderEngine; private var sphere:Sphere; public function FirstApplication() { scene = new Scene3D(); camera = new Camera3D(); sphere = new Sphere(); scene.addChild(sphere); viewport = new Viewport3D(); addChild(viewport); renderEngine = new BasicRenderEngine(); renderEngine.renderScene(scene,camera,viewport); } }} Let's have a look at this in detail. While we do that, you can create a new project in Flash, Flex Builder, or Flash Builder with a document class called FirstApplication. If you're using Flex Builder or Flash Builder, don't forget to configure the path to the Papervision3D source. We know that we need to have a scene, a camera, a viewport, a 3D object with a material, and a render engine, in order to create a rendered output on the screen. Remember that the document class needs to extend Sprite. To make all these available inside the class, we need to import them first. import flash.display.Sprite;import org.papervision3d.cameras.Camera3D;import org.papervision3d.objects.primitives.Sphere;import org.papervision3d.render.BasicRenderEngine;import org.papervision3d.scenes.Scene3D;import org.papervision3d.view.Viewport3D; Now that the imports are set, we define the properties of the class. private var scene:Scene3D;private var viewport:Viewport3D;private var camera:Camera3D;private var renderEngine:BasicRenderEngine;private var sphere:Sphere; We only define the properties and their class types here, without assigning any value. We'll do that inside the constructor. Let's first create the constructor. public function FirstApplication(){} We start by creating a scene inside the constructor. A scene is needed as the holder for our 3D objects. It's very easy to create one. scene = new Scene3D(); All you have to do is create an instance of the Scene3D class, which doesn't take any parameters. Next, we add a Camera3D, which is just as easy as the creation of a new Scene. camera = new Camera3D(); A camera can take parameters when you create a new instance; however, the default values will do for now. The scene and camera are useless as long as there are no 3D objects in the scene to film. For this example a sphere will be used, which is one of the built-in 3D objects. sphere = new Sphere(); A camera, as well as a sphere, takes parameters when you instantiate it. However, when you do not pass any parameters, a default sphere will be created. Now that we have created our sphere, we need to add it to the scene, otherwise it will not be seen by the camera. This works in exactly the same way as adding regular display objects to the display list in Flash, by using the addChild() method. scene.addChild(sphere); That looks familiar, right? Now that we have a scene, a camera, and a sphere, we need to set up the window to the 3D scene, so we can see what is going on in there. We need to define our viewport and add it to the stage to make it visible. viewport = new Viewport3D();addChild(viewport); While creating a new viewport, you can pass optional parameters to it, but the default parameters are again fine for now. We are now just one step away from publishing our application. First we need to get our camera rolling. This is done by defining the render engine, which will render the current view of the camera to the viewport. renderEngine = new BasicRenderEngine();renderEngine.renderScene(scene,camera,viewport); Now that the render engine is defined and an instruction to render the scene is added, we are ready to publish this project. This should result in the following image of triangles that together form something like a circle: Case sensitivityPay attention to upper cases and lower cases in the examples. Not following these conventions might result in an error. A good example of this is the definition and instantiation of a sphere as we did in our FirstApplication.var sphere:Sphere = new Sphere();Here we see that we have defined a class property called sphere (lowercase) of a Sphere (uppercase) type, containing an instance of Sphere (uppercase). Giving a variable/property the same name as the defined object type will often cause problems. The result of these few lines of code may not look very impressive yet, but in fact this is the beginning of something that will soon become exciting and could never be accomplished this easy by regular Flash use. When you have managed to compile this application that shows the triangles, you've made it through the hardest part of this example. Let's continue building your first application and see how we can add the illusion of 3D to our object, which still looks very 2D.
Read more
  • 0
  • 0
  • 2094

article-image-setting-our-development-environment-and-creating-game-activity
Packt
06 Feb 2015
17 min read
Save for later

Setting up our development environment and creating a game activity

Packt
06 Feb 2015
17 min read
In this article by John Horton, author of the book Learning Java by Building Android Games, we will learn how to set up our development environment by installing JDK and Android Studio. We will also learn how to create a new game activity and layout the same on a game screen UI. (For more resources related to this topic, see here.) Setting up our development environment The first thing we need to do is prepare our PC to develop for Android using Java. Fortunately, this is made quite simple for us. The next two tutorials have Windows-specific instructions and screenshots. However, it shouldn't be too difficult to vary the steps slightly to suit Mac or Linux. All we need to do is: Install a software package called the Java Development Kit (JDK), which allows us to develop in Java. Install Android Studio, a program designed to make Android development fast and easy. Android Studio uses the JDK and some other Android-specific tools that automatically get installed when we install Android Studio. Installing the JDK The first thing we need to do is get the latest version of the JDK. To complete this guide, perform the following steps: You need to be on the Java website, so visit http://www.oracle.com/technetwork/java/javase/downloads/index.html. Find the three buttons shown in the following screenshot and click on the one that says JDK (highlighted). They are on the right-hand side of the web page. Click on the DOWNLOAD button under the JDK option: You will be taken to a page that has multiple options to download the JDK. In the Product/File description column, you need to click on the option that matches your operating system. Windows, Mac, Linux and some other less common options are all listed. A common question here is, "do I have 32- or 64-bit windows?". To find out, right-click on your My Computer (This PC on Windows 8) icon, click on the Properties option, and look under the System heading in the System type entry, as shown in the following screenshot: Click on the somewhat hidden Accept License Agreement checkbox: Now click on the download option for your OS and system type as previously determined. Wait for the download to finish. In your Downloads folder, double-click on the file you just downloaded. The latest version at time of writing this for a 64-bit Windows PC was jdk-8u5-windows-x64. If you are using Mac/Linux or have a 32-bit OS, your filename will vary accordingly. In the first of several install dialogs, click on the Next button and you will see the next dialog box: Accept the defaults shown in the previous screenshot by clicking on Next. In the next dialog box, you can accept the default install location by clicking on Next. Next is the last dialog of the Java installer. Click on Close. The JDK is now installed. Next we will make sure that Android Studio is able to use the JDK. Right-click on your My Computer (This PC on Windows 8) icon and navigate to Properties | Advanced system settings | Environment variables | New (under System variables, not under User variables). Now you can see the New System Variable dialog, as shown in the following screenshot: Type JAVA_HOME for Variable name and enter C:Program FilesJavajdk1.8.0_05 for the Variable value field. If you installed the JDK somewhere else, then the file path you enter in the Variable value: field will need to point to wherever you put it. Your exact file path will likely have a different ending to match the latest version of Java at the time you downloaded it. Click on OK to save your new settings. Now click on OK again to clear the Advanced system settings dialog. Now we have the JDK installed on our PC. We are about half way towards starting to learn Java programming, but we need a friendly way to interact with the JDK and to help us make Android games in Java. Android Studio We learned that Android Studio is a tool that simplifies Android development and uses the JDK to allow us to write and build Java programs. There are other tools you can use instead of Android Studio. There are pros and cons in them all. For example, another extremely popular option is Eclipse. And as with so many things in programming, a strong argument can be made as to why you should use Eclipse instead of Android Studio. I use both, but what I hope you will love about Android Studio are the following elements: It is a very neat and, despite still being under development, a very refined and clean interface. It is much easier to get started compared to Eclipse because several Android tools that would otherwise need to be installed separately are already included in the package. Android Studio is being developed by Google, based on another product called IntelliJ IDEA. There is a chance it will be the standard way to develop Android in the not-too-distant future. If you want to use Eclipse, that's fine. However, some the keyboard shortcuts and user interface buttons will obviously be different. If you do not have Eclipse installed already and have no prior experience with Eclipse, then I even more strongly recommend you to go ahead with Android Studio. Installing Android Studio So without any delay, let's get Android Studio installed and then we can begin our first game project. To do this, let's visit https://developer.android.com/sdk/installing/studio.html. Click on the button labeled Download Android Studio to start the Android studio download. This will take you to another web page with a very similar-looking button to the one you just clicked on. Accept the license by checking in the checkbox, commence the download by clicking on the button labeled Download Android Studio for Windows, and wait for the download to complete. The exact text on the button will probably vary depending on the current latest version. In the folder in which you just downloaded Android Studio, right-click on the android-studio-bundle-135.12465-windows.exe file and click on Run as administrator. The end of your filename will vary depending upon the version of Android Studio and your operating system. When asked if you want to Allow the following program from an unknown publisher to make changes to your computer, click on Yes. On the next screen, click on Next. On the screen shown in the following screenshot, you can choose which users of your PC can use Android Studio. Choose whatever is right for you as all options will work, and then click on Next: In the next dialog, leave the default settings and then click on Next. Then on the Choose start menu folder dialog box, leave the defaults and click on Install. On the Installation complete dialog, click on Finish to run Android Studio for the first time. The next dialog is for users who have already used Android Studio, so assuming you are a first time user, select the I do not have a previous version of Android Studio or I do not want to import my settings checkbox, and then click on OK: That was the last piece of software we needed. Math game – asking a question Now that we have all that knowledge under our belts, we can use it to improve our math game. First, we will create a new Android activity to be the actual game screen as opposed to the start menu screen. We will then use the UI designer to lay out a simple game screen so that we can use our Java skills with variables, types, declaration, initialization, operators, and expressions to make our math game generate a question for the player. We can then link the start menu and game screens together with a push button. Creating the new game activity We will first need to create a new Java file for the game activity code and a related layout file to hold the game activity UI. Run Android Studio and select your Math Game Chapter 2 project. It might have been opened by default. Now we will create the new Android activity that will contain the actual game screen, which will run when the player taps the Play button on our main menu screen. To create a new activity, we now need another layout file and another Java file. Fortunately Android Studio will help us do this. To get started with creating all the files we need for a new activity, right-click on the src folder in the Project Explorer and then go to New | Activity. Now click on Blank Activity and then on Next. We now need to tell Android Studio a little bit about our new activity by entering information in the above dialog box. Change the Activity Name field to GameActivity. Notice how the Layout Name field is automatically changed for us to activity_game and the Title field is automatically changed to GameActivity. Click on Finish. Android Studio has created two files for us and has also registered our new activity in a manifest file, so we don't need to concern ourselves with it. If you look at the tabs at the top of the editor window, you will see that GameActivity.java has been opened up ready for us to edit, as shown in the following screenshot: Ensure that GameActivity.java is active in the editor window by clicking on the GameActivity.java tab shown previously. Here, we can see the code that is unnecessary. If we remove it, then it will make our working environment simpler and cleaner. We will simply use the code from MainActivity.java as a template for GameActivity.java. We can then make some minor changes. Click on the MainActivity.java tab in the editor window. Highlight all of the code in the editor window using Ctrl + A on the keyboard. Now copy all of the code in the editor window using the Ctrl + C on the keyboard. Now click on the GameActivity.java tab. Highlight all of the code in the editor window using Ctrl + A on the keyboard. Now paste the copied code and overwrite the currently highlighted code using Ctrl + V on the keyboard. Notice that there is an error in our code denoted by the red underlining as shown in the following screenshot. This is because we pasted the code referring to MainActivity in our file that is called GameActivity. Simply change the text MainActivity to GameActivity and the error will disappear. Take a moment to see if you can work out what other minor change is necessary, before I tell you. Remember that setContentView loads our UI design. Well what we need to do is change setContentView to load the new design (that we will build next) instead of the home screen design. Change setContentView(R.layout.activity_main); to setContentView(R.layout.activity_game);. Save your work and we are ready to move on. Note the Project Explorer where Android Studio puts the two new files it created for us. I have highlighted two folders in the next screenshot. In future, I will simply refer to them as our java code folder or layout files folder. You might wonder why we didn't simply copy and paste the MainActivity.java file to begin with and saved going through the process of creating a new activity? The reason is that Android Studio does things behind the scenes. Firstly, it makes the layout template for us. It also registers the new activity for use through a file we will see later, called AndroidManifest.xml. This is necessary for the new activity to be able to work in the first place. All things considered, the way we did it is probably the quickest. The code at this stage is exactly the same as the code for the home menu screen. We state the package name and import some useful classes provided by Android: package com.packtpub.mathgamechapter3a.mathgamechapter3a;   import android.app.Activity; import android.os.Bundle; We create a new activity, this time called GameActivity: public class GameActivity extends Activity { Then we override the onCreate method and use the setContentView method to set our UI design as the contents of the player's screen. Currently, however, this UI is empty: super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); We can now think about the layout of our actual game screen. Laying out the game screen UI As we know, our math game will ask questions and offer the player some multiple choices to choose answers from. There are lots of extra features we could add, such as difficulty levels, high scores, and much more. But for now, let's just stick to asking a simple, predefined question and offering a choice of three predefined possible answers. Keeping the UI design to the bare minimum suggests a layout. Our target UI will look somewhat like this: The layout is hopefully self-explanatory, but let's ensure that we are really clear; when we come to building this layout in Android Studio, the section in the mock-up that displays 2 x 2 is the question and will be made up of three text views (both numbers, and the = sign is also a separate view). Finally, the three options for the answer are made up of Button layout elements. This time, as we are going to be controlling them using our Java code, there are a few extra things we need to do to them. So let's go through it step by step: Open the file that will hold our game UI in the editor window. Do this by double-clicking on activity_game.xml. This is located in our UI layout folder, which can be found in the project explorer. Delete the Hello World TextView, as it is not required. Find the Large Text element on the palette. It can be found under the Widgets section. Drag three elements onto the UI design area and arrange them near the top of the design as shown in the next screenshot. It does not have to be exact; just ensure that they are in a row and not overlapping, as shown in the following screenshot: Notice in the Component Tree window that each of the three TextViews has been assigned a name automatically by Android Studio. They are textView , textView2, and textView3: Android Studio refers to these element names as an id. This is an important concept that we will be making use of. So to confirm this, select any one of the textViews by clicking on its name (id), either in the component tree as shown in the preceding screenshot or directly on it in the UI designer shown previously. Now look at the Properties window and find the id property. You might need to scroll a little to do this: Notice that the value for the id property is textView. It is this id that we will use to interact with our UI from our Java code. So we want to change all the IDs of our TextViews to something useful and easy to remember. If you look back at our design, you will see that the UI element with the textView id is going to hold the number for the first part of our math question. So change the id to textPartA. Notice the lowercase t in text, the uppercase P in Part, and the uppercase A. You can use any combination of cases and you can actually name the IDs anything you like. But just as with naming conventions with Java variables, sticking to conventions here will make things less error-prone as our program gets more complicated. Now select textView2 and change id to textOperator. Select the element currently with id textView3 and change it to textPartB. This TextView will hold the later part of our question. Now add another Large Text from the palette. Place it after the row of the three TextViews that we have just been editing. This Large Text will simply hold our equals to sign and there is no plan to ever change it. So we don't need to interact with it in our Java code. We don't even need to concern ourselves with changing the ID or knowing what it is. If this situation changed, we could always come back at a later time and edit its ID. However, this new TextView currently displays Large Text and we want it to display an equals to sign. So in the Properties window, find the text property and enter the value =. We have changed the text property, and you might also like to change the text property for textPartA, textPartB, and textOperator. This is not absolutely essential because we will soon see how we can change it via our Java code; however, if we change the text property to something more appropriate, then our UI designer will look more like it will when the game runs on a real device. So change the text property of textPartA to 2, textPartB to 2, and textOperator to x. Your UI design and Component tree should now look like this: For the buttons to contain our multiple choice answers, drag three buttons in a row, below the = sign. Line them up neatly like our target design. Now, just as we did for the TextViews, find the id properties of each button, and from left to right, change the id properties to buttonChoice1, buttonChoice2, and buttonChoice3. Why not enter some arbitrary numbers for the text property of each button so that the designer more accurately reflects what our game will look like, just as we did for our other TextViews? Again, this is not absolutely essential as our Java code will control the button appearance. We are now actually ready to move on. But you probably agree that the UI elements look a little lost. It would look better if the buttons and text were bigger. All we need to do is adjust the textSize property for each TextView and for each Button. Then, we just need to find the textSize property for each element and enter a number with the sp syntax. If you want your design to look just like our target design from earlier, enter 70sp for each of the TextView textSize properties and 40sp for each of the Buttons textSize properties. When you run the game on your real device, you might want to come back and adjust the sizes up or down a bit. But we have a bit more to do before we can actually try out our game. Save the project and then we can move on. As before, we have built our UI. This time, however, we have given all the important parts of our UI a unique, useful, and easy to identify ID. As we will see we are now able to communicate with our UI through our Java code. Summary In this article, we learned how to set up our development environment by installing JDK and Android Studio. In addition to this, we also learned how to create a new game activity and layout the same on a game screen UI. Resources for Article: Further resources on this subject: Sound Recorder for Android [article] Reversing Android Applications [article] 3D Modeling [article]
Read more
  • 0
  • 0
  • 2078
Modal Close icon
Modal Close icon