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
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-top-5-must-have-android-applications
Packt
28 Jun 2011
6 min read
Save for later

Top 5 Must-have Android Applications

Packt
28 Jun 2011
6 min read
  Android Application Testing Guide Build intensively tested and bug free Android applications     1. ES File Explorer Description: ES File Explorer has everything you would expect from a file explorer – you can copy, paste, rename and delete files. You can select multiple files at a time just as you would on your PC or MAC. You can also compress files to zip or gz. One of the best features of ES file explorer is the ability to connect to network shares – this means you can connect to a shared folder on your LAN and transfer files to and from your Android device. Its user interface is very simple, quick and easy to use. Screenshots:   Features: Multiselect and Operate files (Copy, Paste, Cut/Move, Create, Delete and Rename, Share/Send) in the phone and computers Application manager -- Manage apps(Install, Uninstall, Backup, Shortcuts, Category) View Different file formats, photos, docs, videos anywhere, support third party applications such as Document To Go to open document files Text viewers and editors Bluetooth file transfer tool Access your Home PC, via WIFI with SMB Compress and Decompress ZIP files, Unpack RAR files, Create encrypted (AES 256 bit) ZIP files Manage the files on the FTP server as the ones on the sd card Link: This application is available for download at: https://market.android.com/details?id=com.estrongs.android.pop 2. Go Sms Pro Description: GO SMS Pro is the ultimate messaging application for Android devices. There is a nice setting that launches a pop-up for incoming messages. Users can then respond or delete directly within the window. The app supports batch actions for deleting, marking all, or backing up. It is highly customizable; everything from the text color, to the color of the background, SMS ringtones for specific contacts, and themes for the SMS application can be customized. Another interesting feature that you can take advantage of is the multiple plug-ins that are available as free download in the market. The Facebook chat plug-in makes it possible to receive and send Facebook chat messages and since these messages are sent through the Facebook network it does not affect your SMS messages at all. Screenshots: Features: GO-MMS service (FREE), you may send picture/music to your friend(ever they are no GO SMS) through one SMS with 2G/3G/4G or WIFI Many cool themes; also support DIY theme, and Wallpaper Maker plug-in; Fully customizable look; Supports chat style and list style; Font changeable SMS backup and restore by all or by conversations, supports XML format, send backup file by email Support schedule SMS; Group texting Settings backup and restore Notification with privacy mode and reminder notification Security lock, support lock by thread; Blacklist Link: This application is available for download at: https://market.android.com/details?id=com.jb.gosms 3. Dolphin HD browser Description: Dolphin Browser HD is a professional mobile browser presented by Mobotap Inc. Dolphin Browser HD is the most advanced and customizable web browser. You can browse the Web with the greatest speed and efficiency by using Dolphin browser HD. The main browsing screen is clean and uncluttered. Other than the Home and Refresh buttons that flank the address bar, Dolphin HD doesn't clutter the main interface with other quick-access buttons. In addition to tabbed browsing, bookmarking (that syncs to Google bookmarks), and multitouch zooming, it can also flag sites to read later as well as a tie-in to Delicious. You can search content within a page, subscribe to RSS feeds through Google Reader, and share links with social networks. Another great feature of this app is the capability to download YouTube videos. Screenshots: Features: Manage Bookmarks Multi Touch pinch zoom Unlimited Tabs Colorful theme pack Gestures as shortcuts for common commands You can save web pages to read them offline with all images preserved Link: This application is available for download at: https://market.android.com/details?id=mobi.mgeek.TunnyBrowser 4. Winamp Description: The one big advantage that Winamp has over other playback apps is that it can sync tracks wirelessly to the device over your home network, so you don’t have to fuss with a USB cable, making it easier to manage your music. You can set Winamp to sync automatically, every time you connect your Android phone to Winamp, which makes it incredibly easy to send new playlists, purchases and downloads to your portable player, sans USB. The interface is probably the most notable upgrade over the stock player. The playback controls remain on-screen pretty much wherever you are in the app – a small touch, but one that vastly improves the functionality of Winamp. Being able to control playback from any point is more useful than you might expect. Screenshots: Features: iTunes library & playlist import Wireless & wired sync with the desktop Winamp Media Player Over 45k+ SHOUTcast Internet radio stations Integrated Android Search & “Listen to” voice actions Play queue management Playlists and playlist shortcuts Extras Menu – Now Playing data interacts with other installed apps Link: This application is available for download at: https://market.android.com/details?id=com.nullsoft.winamp 5. Advanced Task Killer Description: One click to kill applications running in the background. Advanced Task Killer is pretty simple and easy to use. It allows you to see what applications are currently running and offers the ability to terminate them quickly and easily, thus freeing up valuable memory for other processes. It also remembers your selections, so the next time you launch it, the previously spared apps remain unchecked and the previously selected ones are checked and are ready to be shut down. You can choose to have Advanced Task Killer start at launch and there’s even the option to have it appear in your notifications bar for swift access. Screenshots: Features: Kill multiple apps with one tap Adjust the security levels It comes with a notification bar icon You can kill apps automatically by selecting one of auto-kill level: Safe, Aggressive or Crazy Link: This application is available for download at: https://market.android.com/details?id=com.rechild.advancedtaskkiller Summary In this article we discussed the Top 5 must-have applications for your android phone. Further resources on this subject: Android Application Testing: Getting Started [Article] Flash Development for Android: Audio Input via Microphone [Article] Android Application Testing: TDD and the Temperature Converter [Article] Android User Interface Development: Animating Widgets and Layouts [Article]
Read more
  • 0
  • 1
  • 21403

article-image-excel-2010-financials-using-graphs-analysis
Packt
28 Jun 2011
6 min read
Save for later

Excel 2010 Financials: Using Graphs for Analysis

Packt
28 Jun 2011
6 min read
  Introduction Graphing is one of the most effective ways to display datasets, financial scenarios, and statistical functions in a way that can be understood easily by the users. When you give an individual a list of 40 different numbers and ask him or her to draw a conclusion, it is not only difficult, it may be impossible without the use of extra functions. However, if you provide the same individual a graph of the numbers, they will most likely be able to notice trending, dataset size, frequency, and so on. Despite the effectiveness of graphing and visual modeling, financial and statistical graphing is often overlooked in Excel 2010 due to difficulty, or lack of native functions. In this article, you will learn to not only add reusable methods to automate graph production, but also how to create graphs and graphing sets that are not native to Excel. You will learn to use box and whisker plots, histograms to demonstrate frequency, stem and leaf plots, and other methods to graph financial ratios and scenarios. Charting financial frequency trending with a histogram Frequency calculations are used throughout financial analysis, statistics, and other mathematical representations to determine how often an event has occurred. Determining the frequency of financial events in a transaction list can assist in determining the popularity of an item or product, the future likelihood of an event to reoccur, or frequency of profitability of an organization. Excel, however, does not create histograms by default. In this recipe, you will learn how to use several functions including bar charts and FREQUENCY functions to create a histogram frequency chart within Excel to determine profitability of an entity. Getting ready When plotting histogram frequency, we are using frequency and charting to determine the continued likelihood of an event from past data visually. Past data can be flexible in terms of what we are trying to determine; in this instance, we will use the daily net profit (Sale income Versus Gross expenses) for a retail store. The daily net profit numbers for one month are as follows: $150, $237, -$94.75, $1,231, $876, $455, $349, -$173, -$34, -$234, $110, $83, -$97, -$129, $34, $456, $1010, $878, $211, -$34, -$142, -$87, $312 How to do it... Utilizing the profit numbers from above, we will begin by adding the data to the Excel worksheet: Within Excel, enter the daily net profit numbers into column A starting on row 2 until all the data has been entered: We must now create the boundaries to be used within the histogram. The boundary numbers will be the highest and the lowest number thresholds that will be included within the graph. The boundaries to be used in this instance will be of $1500, and -$1500. These boundaries will encompass our entire dataset, and it will allow padding on the higher and lower ends of the data to allow for variation when plotting larger datasets encompassing multiple months or years worth of profit. We must now create bins that we will chart against the frequency. The bins will be the individual data-points that we want to determine the frequency against. For instance, one bin will be $1500, and we will want to know how often the net profit of the retail location falls within the range of $1500. The smaller the bins chosen, the larger the chart area. You will want to choose a bin size that will accurately reflect the frequency of your dataset without creating a large blank space. Bin size will change depending on the range of data to be graphed. Enter the chosen bin number into the worksheet in Column C. The bins will be a $150 difference from the previous bin.The bin sizes needed to include an appropriate range in order to illustrate the expanse of the dataset completely. In order to encompass all appropriate bin sizes, it is necessary to begin with the largest negative number, and increment to the largest positive number: The last component for creating the frequency histogram actually determines the frequency of net profit to the designated bins. For this, we will use the Excel function FREQUENCY. Select rows D2 through D22, and enter the following formula: =FREQUENCY(A:A,C2:C22) After entering the formula, press Shift + Ctrl + Enter to finalize the formula as an array formula.Excel has now displayed the frequency of the net profit for each of the designated bins: The information for the histogram is now ready. We will now be able to create the actual histogram graph. Select rows C2 through D22. With the rows selected, using the Excel ribbon, choose Insert | Column: From the Column drop-down, choose the Clustered Column chart option: Excel will now attempt to determine the plot area, and will present you with a bar chart. The chart that Excel creates does not accurately display the plot areas, due to Excel being unable to determine the correct data range: Select the chart. From the Ribbon, choose Select Data: From the select Data Source window that has appeared, you will change the Horizontal Axis to include the Bins column (column C), and the Legend Series to include the Frequency (column D). Excel will also create two series entries within the Legend Series panel; remove Series2 and select OK: Excel now presents the histogram graph of net profit frequency: Using the Format graph options on the Excel Ribbon, reduce the bar spacing and adjust the horizontal label to reduce the chart area to your specifications: Using the histogram for financial analysis, we can now determine that the major trend of the retail location quickly and easily, which maintains a net profit within $0 - $150, while maintaining a positive net profit throughout the month. How it works... While a histogram graph/chart is not native to Excel, we were able to use a bar/column chart to plot the frequency of net profit within specific bin ranges. The FREQUENCY function of Excel follows the following format: =FREQUENCY(Data Range to plot, Bins to plot within) It is important to note that within the data range, we chose the range A:A. This range includes all of the data within the A column. If arbitrary or unnecessary data unrelated to the histogram were added into column A, this range would include them. Do not allow unnecessary data to be added to column A, or use a limited range such as A1:A5 if your data was only included in the first five cells of column A. We entered the formula by pressing Shift + Ctrl + Enter in order to submit the formula as an array formula. This allows Excel to calculate individual information within a large array of data. The graph modifications allowed the bins to show frequency in the vertical axis, or indicate how many times a specific number range was achieved. The horizontal axis displayed the actual bins. There's more... The amount of data for this histogram was limited; however, its usefulness was already evident. When this same charting recipe is used to chart a large dataset (for example, multiple year data), the histogram becomes even more useful in displaying trends.
Read more
  • 0
  • 0
  • 12439

article-image-pentaho-data-integration-4-working-complex-data-flows
Packt
27 Jun 2011
7 min read
Save for later

Pentaho Data Integration 4: working with complex data flows

Packt
27 Jun 2011
7 min read
Joining two or more streams based on given conditions There are occasions where you will need to join two datasets. If you are working with databases, you could use SQL statements to perform this task, but for other kinds of input (XML, text, Excel), you will need another solution. Kettle provides the Merge Join step to join data coming from any kind of source. Let's assume that you are building a house and want to track and manage the costs of building it. Before starting, you prepared an Excel file with the estimated costs for the different parts of your house. Now, you are given a weekly file with the progress and the real costs. So, you want to compare both to see the progress. Getting ready To run this recipe, you will need two Excel files, one for the budget and another with the real costs. The budget.xls has the estimated starting date, estimated end date, and cost for the planned tasks. The costs.xls has the real starting date, end date, and cost for tasks that have already started. You can download the sample files from here. How to do it... Carry out the following steps: Create a new transformation. Drop two Excel input steps into the canvas. Use one step for reading the budget information (budget.xls file) and the other for reading the costs information (costs.xls file). Under the Fields tab of these steps, click on the Get fields from header row... button in order to populate the grid automatically. Apply the format dd/MM/yyyy to the fields of type Date and $0.00 to the fields with costs. Add a Merge Join step from the Join category, and create a hop from each Excel input step toward this step. The following diagram depicts what you have so far: Configure the Merge Join step, as shown in the following screenshot: If you do a preview on this step, you will obtain the result of the two Excel files merged. In order to have the columns more organized, add a Select values step from the Transform category. In this new step, select the fields in this order: task, starting date (est.), starting date, end date (est.), end date, cost (est.), cost. Doing a preview on the last step, you will obtain the merged data with the columns of both Excel files interspersed, as shown in the following screenshot: How it works... In the example, you saw how to use the Merge Join step to join data coming from two Excel files. You can use this step to join any other kind of input. In the Merge Join step, you set the name of the incoming steps, and the fields to use as the keys for joining them. In the recipe, you joined the streams by just a single field: the task field. The rows are expected to be sorted in an ascending manner on the specified key fields. There's more... In the example, you set the Join Type to LEFT OUTER JOIN. Let's see explanations of the possible join options: Interspersing new rows between existent rows In most Kettle datasets, all rows share a common meaning; they represent the same kind of entity, for example: In a dataset with sold items, each row has data about one item In a dataset with the mean temperature for a range of days in five different regions, each row has the mean temperature for a different day in one of those regions In a dataset with a list of people ordered by age range (0-10, 11-20, 20-40, and so on), each row has data about one person Sometimes, there is a need of interspersing new rows between your current rows. Taking the previous examples, imagine the following situations: In the sold items dataset, every 10 items, you have to insert a row with the running quantity of items and running sold price from the first line until that line. In the temperature's dataset, you have to order the data by region and the last row for each region has to have the average temperature for that region. In the people's dataset, for each age range, you have to insert a header row just before the rows of people in that range. In general, the rows you need to intersperse can have fixed data, subtotals of the numbers in previous rows, header to the rows coming next, and so on. What they have in common is that they have a different structure or meaning compared to the rows in your dataset. Interspersing these rows is not a complicated task, but is a tricky one. In this recipe, you will learn how to do it. Suppose that you have to create a list of products by category. For each category, you have to insert a header row with the category description and the number of products inside that category. The final result should be as follows: Getting ready This recipe uses an outdoor database with the structure shown in Appendix, Data Structures (Download here). As source, you can use a database like this or any other source, for example a text file with the same structure. How to do it... Carry out the following steps: Create a transformation, drag into the canvas a Table Input step, select the connection to the outdoor database, or create it if it doesn't exist. Then enter the following statement: SELECT category , desc_product FROM products p ,categories c WHERE p.id_category = c.id_category ORDER by category Do a preview of this step. You already have the product list! Now, you have to create and intersperse the header rows. In order to create the headers, do the following: From the Statistics category, add a Group by step and fill in the grids, as shown in the following screenshot: From the Scripting category, add a User Defined Java Expression step, and use it to add two fields: The first will be a String named desc_product, with value ("Category: " + category).toUpperCase(). The second will be an Integer field named order with value 1. Use a Select values step to reorder the fields as category, desc_product, qty_product, and order. Do a preview on this step; you should see the following result: Those are the headers. The next step is mixing all the rows in the proper order. Drag an Add constants step into the canvas and a Sort rows step. Link them to the other steps as shown: Use the Add constants to add two Integer fields: qty_prod and order. As Value, leave the first field empty, and type 2 for the second field. Use the Sort rows step for sorting by category, order, and desc_product. Select the last step and do a preview. You should see the rows exactly as shown in the introduction. How it works... When you have to intersperse rows between existing rows, there are just four main tasks to do, as follows: Create a secondary stream that will be used for creating new rows. In this case, the rows with the headers of the categories. In each stream, add a field that will help you intersperse rows in the proper order. In this case, the key field was named order. Before joining the two streams, add, remove, and reorder the fields in each stream to make sure that the output fields in each stream have the same metadata. Join the streams and sort by the fields that you consider appropriate, including the field created earlier. In this case, you sorted by category, inside each category by the field named order and finally by the products description. Note that in this case, you created a single secondary stream. You could create more if needed, for example, if you need a header and footer for each category.
Read more
  • 0
  • 0
  • 8270

article-image-android-application-testing-adding-functionality-ui
Packt
27 Jun 2011
10 min read
Save for later

Android Application Testing: Adding Functionality to the UI

Packt
27 Jun 2011
10 min read
  Android Application Testing Guide Build intensively tested and bug free Android applications  The user interface is in place. Now we start adding some basic functionality. This functionality will include the code to handle the actual temperature conversion. Temperature conversion From the list of requirements from the previous article we can obtain this statement: When one temperature is entered in one field the other one is automatically updated with the conversion. Following our plan we must implement this as a test to verify that the correct functionality is there. Our test would look something like this: @UiThreadTest public final void testFahrenheitToCelsiusConversion() { mCelsius.clear(); mFahrenheit.clear(); final double f = 32.5; mFahrenheit.requestFocus(); mFahrenheit.setNumber(f); mCelsius.requestFocus(); final double expectedC = TemperatureConverter.fahrenheitToCelsius(f); final double actualC = mCelsius.getNumber(); final double delta = Math.abs(expectedC - actualC); final String msg = "" + f + "F -> " + expectedC + "C but was " + actualC + "C (delta " + delta + ")"; assertTrue(msg, delta < 0.005); } Firstly, as we already know, to interact with the UI changing its values we should run the test on the UI thread and thus is annotated with @UiThreadTest. Secondly, we are using a specialized class to replace EditText providing some convenience methods like clear() or setNumber(). This would improve our application design. Next, we invoke a converter, named TemperatureConverter, a utility class providing the different methods to convert between different temperature units and using different types for the temperature values. Finally, as we will be truncating the results to provide them in a suitable format presented in the user interface we should compare against a delta to assert the value of the conversion. Creating the test as it is will force us to follow the planned path. Our first objective is to add the needed code to get the test to compile and then to satisfy the test's needs. The EditNumber class In our main project, not in the tests one, we should create the class EditNumber extending EditText as we need to extend its functionality. We use Eclipse's help to create this class using File | New | Class or its shortcut in the Toolbars. This screenshot shows the window that appears after using this shortcut: The following table describes the most important fields and their meaning in the previous screen:     Field Description Source folder: The source folder for the newly-created class. In this case the default location is fine. Package: The package where the new class is created. In this case the default package com.example.aatg.tc is fine too. Name: The name of the class. In this case we use EditNumber. Modifiers: Modifiers for the class. In this particular case we are creating a public class. Superclass: The superclass for the newly-created type. We are creating a custom View and extending the behavior of EditText, so this is precisely the class we select for the supertype. Remember to use Browse... to find the correct package. Which method stubs would you like to create? These are the method stubs we want Eclipse to create for us. Selecting Constructors from superclass and Inherited abstract methods would be of great help. As we are creating a custom View we should provide the constructors that are used in different situations, for example when the custom View is used inside an XML layout. Do you want to add comments? Some comments are added automatically when this option is selected. You can configure Eclipse to personalize these comments. Once the class is created we need to change the type of the fields first in our test: public class TemperatureConverterActivityTests extends ActivityInstrumentationTestCase2<TemperatureConverterActivity> { private TemperatureConverterActivity mActivity; private EditNumber mCelsius; private EditNumber mFahrenheit; private TextView mCelsiusLabel; private TextView mFahrenheitLabel; ... Then change any cast that is present in the tests. Eclipse will help you do that. If everything goes well, there are still two problems we need to fix before being able to compile the test: We still don't have the methods clear() and setNumber() in EditNumber We don't have the TemperatureConverter utility class To create the methods we are using Eclipse's helpful actions. Let's choose Create method clear() in type EditNumber. Same for setNumber() and getNumber(). Finally, we must create the TemperatureConverter class. Be sure to create it in the main project and not in the test project. Having done this, in our test select Create method fahrenheitToCelsius in type TemperatureConverter. This fixes our last problem and leads us to a test that we can now compile and run. Surprisingly, or not, when we run the tests, they will fail with an exception: 09-06 13:22:36.927: INFO/TestRunner(348): java.lang. ClassCastException: android.widget.EditText 09-06 13:22:36.927: INFO/TestRunner(348): at com.example.aatg. tc.test.TemperatureConverterActivityTests.setUp( TemperatureConverterActivityTests.java:41) 09-06 13:22:36.927: INFO/TestRunner(348): at junit.framework. TestCase.runBare(TestCase.java:125) That is because we updated all of our Java files to include our newly-created EditNumber class but forgot to change the XMLs, and this could only be detected at runtime. Let's proceed to update our UI definition: <com.example.aatg.tc.EditNumber android_layout_height="wrap_content" android_id="@+id/celsius" android_layout_width="match_parent" android_layout_margin="@dimen/margin" android_gravity="right|center_vertical" android_saveEnabled="true" /> That is, we replace the original EditText by com.example.aatg.tc.EditNumber which is a View extending the original EditText. Now we run the tests again and we discover that all tests pass. But wait a minute, we haven't implemented any conversion or any handling of values in the new EditNumber class and all tests passed with no problem. Yes, they passed because we don't have enough restrictions in our system and the ones in place simply cancel themselves. Before going further, let's analyze what just happened. Our test invoked the mFahrenheit.setNumber(f) method to set the temperature entered in the Fahrenheit field, but setNumber() is not implemented and it is an empty method as generated by Eclipse and does nothing at all. So the field remains empty. Next, the value for expectedC—the expected temperature in Celsius is calculated invoking TemperatureConverter.fahrenheitToCelsius(f), but this is also an empty method as generated by Eclipse. In this case, because Eclipse knows about the return type it returns a constant 0. So expectedC becomes 0. Then the actual value for the conversion is obtained from the UI. In this case invoking getNumber() from EditNumber. But once again this method was automatically generated by Eclipse and to satisfy the restriction imposed by its signature, it must return a value that Eclipse fills with 0. The delta value is again 0, as calculated by Math.abs(expectedC – actualC). And finally our assertion assertTrue(msg, delta < 0.005) is true because delta=0 satisfies the condition, and the test passes. So, is our methodology flawed as it cannot detect a simple situation like this? No, not at all. The problem here is that we don't have enough restrictions and they are satisfied by the default values used by Eclipse to complete auto-generated methods. One alternative could be to throw exceptions at all of the auto-generated methods, something like RuntimeException("not yet implemented") to detect its use when not implemented. But we will be adding enough restrictions in our system to easily trap this condition. TemperatureConverter unit tests It seems, from our previous experience, that the default conversion implemented by Eclipse always returns 0, so we need something more robust. Otherwise this will be only returning a valid result when the parameter takes the value of 32F. The TemperatureConverter is a utility class not related with the Android infrastructure, so a standard unit test will be enough to test it. We create our tests using Eclipse's File | New | JUnit Test Case, filling in some appropriate values, and selecting the method to generate a test as shown in the next screenshot. Firstly, we create the unit test by extending junit.framework.TestCase and selecting com.example.aatg.tc.TemperatureConverter as the class under test: Then by pressing the Next > button we can obtain the list of methods we may want to test: We have implemented only one method in TemperatureConverter, so it's the only one appearing in the list. Other classes implementing more methods will display all the options here. It's good to note that even if the test method is auto-generated by Eclipse it won't pass. It will fail with the message Not yet implemented to remind us that something is missing. Let's start by changing this: /** * Test method for {@link com.example.aatg.tc. TemperatureConverter#fahrenheitToCelsius(double)}. */ public final void testFahrenheitToCelsius() { for (double c: conversionTableDouble.keySet()) { final double f = conversionTableDouble.get(c); final double ca = TemperatureConverter.fahrenheitToCelsius(f); final double delta = Math.abs(ca - c); final String msg = "" + f + "F -> " + c + "C but is " + ca + " (delta " + delta + ")"; assertTrue(msg, delta < 0.0001); } } Creating a conversion table with values for different temperature conversion we know from other sources would be a good way to drive this test. private static final HashMap<Double, Double> conversionTableDouble = new HashMap<Double, Double>(); static { // initialize (c, f) pairs conversionTableDouble.put(0.0, 32.0); conversionTableDouble.put(100.0, 212.0); conversionTableDouble.put(-1.0, 30.20); conversionTableDouble.put(-100.0, -148.0); conversionTableDouble.put(32.0, 89.60); conversionTableDouble.put(-40.0, -40.0); conversionTableDouble.put(-273.0, -459.40); } We may just run this test to verify that it fails, giving us this trace: junit.framework.AssertionFailedError: -40.0F -> -40.0C but is 0.0 (delta 40.0)at com.example.aatg.tc.test.TemperatureConverterTests. testFahrenheitToCelsius(TemperatureConverterTests.java:62) at java.lang.reflect.Method.invokeNative(Native Method) at android.test.AndroidTestRunner.runTest(AndroidTestRunner. java:169) at android.test.AndroidTestRunner.runTest(AndroidTestRunner. java:154) at android.test.InstrumentationTestRunner.onStart( InstrumentationTestRunner.java:520) at android.app.Instrumentation$InstrumentationThread.run( Instrumentation.java:1447) Well, this was something we were expecting as our conversion always returns 0. Implementing our conversion, we discover that we need some ABSOLUTE_ZERO_F constant: public class TemperatureConverter { public static final double ABSOLUTE_ZERO_C = -273.15d; public static final double ABSOLUTE_ZERO_F = -459.67d; private static final String ERROR_MESSAGE_BELOW_ZERO_FMT = "Invalid temperature: %.2f%c below absolute zero"; public static double fahrenheitToCelsius(double f) { if (f < ABSOLUTE_ZERO_F) { throw new InvalidTemperatureException( String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, f, 'F')); } return ((f - 32) / 1.8d); } } Absolute zero is the theoretical temperature at which entropy would reach its minimum value. To be able to reach this absolute zero state, according to the laws of thermodynamics, the system should be isolated from the rest of the universe. Thus it is an unreachable state. However, by international agreement, absolute zero is defined as 0K on the Kelvin scale and as -273.15°C on the Celsius scale or to -459.67°F on the Fahrenheit scale. We are creating a custom exception, InvalidTemperatureException, to indicate a failure providing a valid temperature to the conversion method. This exception is created simply by extending RuntimeException: public class InvalidTemperatureException extends RuntimeException { public InvalidTemperatureException(String msg) { super(msg); } } Running the tests again we now discover that testFahrenheitToCelsiusConversion test fails, however testFahrenheitToCelsius succeeds. This tells us that now conversions are correctly handled by the converter class but there are still some problems with the UI handling this conversion. A closer look at the failure trace reveals that there's something still returning 0 when it shouldn't. This reminds us that we are still lacking a proper EditNumber implementation. Before proceeding to implement the mentioned methods, let's create the corresponding tests to verify what we are implementing is correct.
Read more
  • 0
  • 0
  • 2689

article-image-android-application-testing-tdd-and-temperature-converter
Packt
27 Jun 2011
7 min read
Save for later

Android application testing: TDD and the temperature converter

Packt
27 Jun 2011
7 min read
Getting started with TDD Briefly, Test Driven Development is the strategy of writing tests along the development process. These test cases are written in advance of the code that is supposed to satisfy them. A single test is added, then the code needed to satisfy the compilation of this test and finally the full set of test cases is run to verify their results. This contrasts with other approaches to the development process where the tests are written at the end when all the coding has been done. Writing the tests in advance of the code that satisfies them has several advantages. First, is that the tests are written in one way or another, while if the tests are left till the end it is highly probable that they are never written. Second, developers take more responsibility for the quality of their work. Design decisions are taken in single steps and finally the code satisfying the tests is improved by refactoring it. This UML activity diagram depicts the Test Driven Development to help us understand the process: The following sections explain the individual activities depicted in this activity diagram. Writing a test case We start our development process with writing a test case. This apparently simple process will put some machinery to work inside our heads. After all, it is not possible to write some code, test it or not, if we don't have a clear understanding of the problem domain and its details. Usually, this step will get you face to face with the aspects of the problem you don't understand, and you need to grasp if you want to model and write the code. Running all tests Once the test is written the obvious following step is to run it, altogether with other tests we have written so far. Here, the importance of an IDE with built-in support of the testing environment is perhaps more evident than in other situations and this could cut the development time by a good fraction. It is expected that firstly, our test fails as we still haven't written any code! To be able to complete our test, we usually write additional code and take design decisions. The additional code written is the minimum possible to get our test to compile. Consider here that not compiling is failing. When we get the test to compile and run, if the test fails then we try to write the minimum amount of code necessary to make the test succeed. This may sound awkward at this point but the following code example in this article will help you understand the process. Optionally, instead of running all tests again you can just run the newly added test first to save some time as sometimes running the tests on the emulator could be rather slow. Then run the whole test suite to verify that everything is still working properly. We don't want to add a new feature by breaking an existing one. Refactoring the code When the test succeeds, we refactor the code added to keep it tidy, clean, and minimal. We run all the tests again, to verify that our refactoring has not broken anything and if the tests are again satisfied, and no more refactoring is needed we finish our task. Running the tests after refactoring is an incredible safety net which has been put in place by this methodology. If we made a mistake refactoring an algorithm, extracting variables, introducing parameters, changing signatures or whatever your refactoring is composed of, this testing infrastructure will detect the problem. Furthermore, if some refactoring or optimization could not be valid for every possible case we can verify it for every case used by the application and expressed as a test case. What is the advantage? Personally, the main advantage I've seen so far is that you focus your destination quickly and is much difficult to divert implementing options in your software that will never be used. This implementation of unneeded features is a wasting of your precious development time and effort. And as you may already know, judiciously administering these resources may be the difference between successfully reaching the end of the project or not. Probably, Test Driven Development could not be indiscriminately applied to any project. I think that, as well as any other technique, you should use your judgment and expertise to recognize where it can be applied and where not. But keep this in mind: there are no silver bullets. The other advantage is that you always have a safety net for your changes. Every time you change a piece of code, you can be absolutely sure that other parts of the system are not affected as long as there are tests verifying that the conditions haven't changed. Understanding the testing requirements To be able to write a test about any subject, we should first understand the Subject under test. We also mentioned that one of the advantages is that you focus your destination quickly instead of revolving around the requirements. Translating requirements into tests and cross-referencing them is perhaps the best way to understand the requirements, and be sure that there is always an implementation and verification for all of them. Also, when the requirements change (something that is very frequent in software development projects), we can change the tests verifying these requirements and then change the implementation to be sure that everything was correctly understood and mapped to code. Creating a sample project—the Temperature Converter Our examples will revolve around an extremely simple Android sample project. It doesn't try to show all the fancy Android features but focuses on testing and gradually building the application from the test, applying the concepts learned before. Let's pretend that we have received a list of requirements to develop an Android temperature converter application. Though oversimplified, we will be following the steps you normally would to develop such an application. However, in this case we will introduce the Test Driven Development techniques in the process. The list of requirements Most usual than not, the list of requirements is very vague and there is a high number of details not fully covered. As an example, let's pretend that we receive this list from the project owner: The application converts temperatures from Celsius to Fahrenheit and vice-versa The user interface presents two fields to enter the temperatures, one for Celsius other for Fahrenheit When one temperature is entered in one field the other one is automatically updated with the conversion If there are errors, they should be displayed to the user, possibly using the same fields Some space in the user interface should be reserved for the on screen keyboard to ease the application operation when several conversions are entered Entry fields should start empty Values entered are decimal values with two digits after the point Digits are right aligned Last entered values should be retained even after the application is paused User interface concept design Let's assume that we receive this conceptual user interface design from the User Interface Design team: Creating the projects Our first step is to create the project. As we mentioned earlier, we are creating a main and a test project. The following screenshot shows the creation of the TemperatureConverter project (all values are typical Android project values): When you are ready to continue you should press the Next > button in order to create the related test project. The creation of the test project is displayed in this screenshot. All values will be selected for you based on your previous entries:
Read more
  • 0
  • 0
  • 2755

article-image-how-create-lesson-moodle-2
Packt
24 Jun 2011
7 min read
Save for later

How to Create a Lesson in Moodle 2

Packt
24 Jun 2011
7 min read
  History Teaching with Moodle 2 Create a History course in Moodle packed with lessons and activities to make learning and teaching History interactive and fun  Approaching the lesson We plan to introduce our Year 7 History class to the idea of the Doomsday Book as a means by which William reinforced his control over the country. William was naturally curious about the country he had just conquered. He was particularly keen to find out how much it was worth. He despatched officials to every village with detailed questions to ask about the land that they worked on and the animals that they farmed with. He also sent soldiers who threatened to kill people who lied. All of the records from these village surveys were collated into the Doomsday Book. Many Saxons detested the process and the name of the book is derived from this attitude of loathing towards something they regarded as intrusive and unfair. William died before the process could be completed. Clear lesson objectives can be stated at the start of the lesson. Students would be expected to work through each page and answer questions identical to those found in the Quiz module. The lesson gives students the opportunity to return to a page if the required level of understanding has not been achieved. The lesson questions help students to reach an understanding at their own pace. The short video clips we intend to use will come from the excellent National Archive website. It has links to short sequences of approximately ninety seconds in which actors take on the role of villagers and commissioners and offer a variety of opinions about the nature and purpose of the survey that they are taking part in. At the end of the lesson, we want the students to have an understanding of: The purpose of the Domesday Book How the information was compiled A variety of attitudes towards the whole process Our starting point is to create a flow diagram that captures the routes a student might take through the lesson: The students will see the set of objectives, a short introduction to the Doomsday Book, and a table of contents. They can select the videos in any order. When they have watched each video and answered the questions associated with the content they will be asked to write longer answers to a series of summative questions. These answers are marked individually by the teacher who thus gets a good overall idea of how well the students have absorbed the information. The assessment of these questions could easily include our essay outcomes marking scale. The lesson ends when the student has completed all of the answers. The lesson requires: A branch table (the table of contents). Four question pages based upon a common template. One end of branch page. A question page for the longer answers. An end of lesson page. The lesson awards marks for the correct answers to questions on each page in much the same way as if they were part of a quiz. Since we are only adding one question per page the scores for these questions are of less significance than a student's answers to the essay questions at the end of the lesson. It is after all, these summative questions that allow the students to demonstrate their understanding of the content they have been working with. Moodle allows this work to be marked in exactly the same way as if it was an essay. This time it will be in the form of an online essay and will take up its place in the Gradebook. We are, therefore, not interested in a standard mark for the students' participation in the lesson and when we set the lesson up, this will become apparent through the choices we make.   Setting up a lesson It is important to have a clear idea of the lesson structure before starting the creation of the lesson. We have used paper and pen to create a flow diagram. We know which images, videos, and text are needed on each page and have a clear idea of the formative and summative questions that will enable us to challenge our students and assess how well they have understood the significance of the Doomsday Book. We are now in a position to create the lesson: Enter the Year 7 History course and turn on editing. In Topic 1, select Add an Activity and click Lesson. In the Name section, enter an unambiguous name for the lesson as this is the text that students will click on to enter the lesson. Enter the values as shown in the following screenshot: In the General section, we do not want to impose a time limit on the lesson. We do need to state how many options there are likely to be on each question page. For multiple choice questions, there are usually four options. In the Grade section, we want the essay that they compose at the end of the lesson to be marked in the same way that other essays have been marked. In the Grade options, our preference is to avoid using the lesson questions as an assessment activity. We want it to be a practice lesson where students can work through the activities without needing to earn a score. We have turned off scoring. The students' final essay submission will be marked in line with our marking policy. Students can retake it as many times as they want to. In the Flow control section, we have clicked the Show advanced button to see all of the options available. We want students to be able to navigate the pages to check answers and go back to review answers if necessary. They can take the lesson as often as they want as we intend it to be used for revision purposes for a timed essay or in the summer examination. We have ignored the opportunity to add features such as menus and progress bars as we will be creating our own navigation system. This section also concerns the look and feel of the pages if set to a slide show, an option we are not planning to use. We are planning to create a web link on each page rather than have students download files so we will not be using the Popup to file or web page option. If you are concerned about the stability of your Internet connection for the weblinks to videos you plan to show, there is an alternative option. This would involve downloading the files to your computer and converting them to .flv files. They can then be uploaded to the file picker in the usual way and a link can be created to each one using the Choose a file button shown here. Moodle's video player would play the videos and you would not be reliant on an unstable Internet connection to see the results. The Dependent on section allows further restrictions to be imposed that are not appropriate for this lesson. We do however, want to mark the essay that will be submitted in accordance with the custom marking scheme developed earlier in the course. The box in the Outcomes section must be checked. Clicking the Save and return to course button ensures that the newly created lesson, The Domesday Book, awaits in Topic 1.  
Read more
  • 0
  • 0
  • 2844
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 €18.99/month. Cancel anytime
article-image-pentaho-data-integration-4-understanding-data-flows
Packt
24 Jun 2011
12 min read
Save for later

Pentaho Data Integration 4: Understanding Data Flows

Packt
24 Jun 2011
12 min read
  Pentaho Data Integration 4 Cookbook Over 70 recipes to solve ETL problems using Pentaho Kettle         Read more about this book       This article by Adrián Sergio Pulvirenti and María Carina Roldán, authors of Pentaho Data Integration 4 Cookbook, focuses on the different ways for combining, splitting, or manipulating streams or flows of data using Kettle transformations. The main purpose of Kettle transformations is to manipulate data in the form of a dataset; this task is done by the steps of the transformation. In this article, we will cover: Splitting a stream into two or more streams based on a condition Merging rows from two streams with the same or different structure Comparing two streams and generating differences Generating all possible pairs formed from two datasets (For more resources on this subject, see here.) Introduction The main purpose of Kettle transformations is to manipulate data in the form of a dataset; this task is done by the steps of the transformation. When a transformation is launched, all its steps are started. During the execution, the steps work simultaneously reading rows from the incoming hops, processing them, and delivering them to the outgoing hops. When there are no more rows left, the execution of the transformation ends. The dataset that flows from step to step is not more than a set of rows all having the same structure or metadata. This means that all rows have the same number of columns, and the columns in all rows have the same type and name. Suppose that you have a single stream of data and that you apply the same transformations to all rows, that is, you have all steps connected in a row one after the other. In other words, you have the simplest of the transformations from the point of view of its structure. In this case, you don't have to worry much about the structure of your data stream, nor the origin or destination of the rows. The interesting part comes when you face other situations, for example: You want a step to start processing rows only after another given step has processed all rows You have more than one stream and you have to combine them into a single stream You have to inject rows in the middle of your stream and those rows don't have the same structure as the rows in your dataset With Kettle, you can actually do this, but you have to be careful because it's easy to end up doing wrong things and getting unexpected results or even worse: undesirable errors. With regard to the first example, it doesn't represent a default behavior due to the parallel nature of the transformations as explained earlier. There are two steps however, that might help, which are as follows: Blocking Step: This step blocks processing until all incoming rows have been processed. Block this step until steps finish: This step blocks processing until the selected steps finish. Both these steps are in the Flow category. This and the next article on Working with Complex Data Flows focuses on the other two examples and some similar use cases, by explaining the different ways for combining, splitting, or manipulating streams of data. Splitting a stream into two or more streams based on a condition In this recipe, you will learn to use the Filter rows step in order to split a single stream into different smaller streams. In the There's more section, you will also see alternative and more efficient ways for doing the same thing in different scenarios. Let's assume that you have a set of outdoor products in a text file, and you want to differentiate the tents from other kind of products, and also create a subclassification of the tents depending on their prices. Let's see a sample of this data: id_product,desc_product,price,category1,"Swedish Firesteel - Army Model",19,"kitchen"2,"Mountain House #10 Can Freeze-Dried Food",53,"kitchen"3,"Lodge Logic L9OG3 Pre-Seasoned 10-1/2-Inch RoundGriddle",14,"kitchen"... Getting ready To run this recipe, you will need a text file named outdoorProducts.txt with information about outdoor products. The file contains information about the category and price of each product. How to do it... Carry out the following steps: Create a transformation. Drag into the canvas a Text file input step and fill in the File tab to read the file named outdoorProducts.txt. If you are using the sample text file, type , as the Separator. Under the Fields tab, use the Get Fields button to populate the grid. Adjust the entries so that the grid looks like the one shown in the following screenshot: Now, let's add the steps to manage the flow of the rows. To do this, drag two Filter rows steps from the Flow category. Also, drag three Dummy steps that will represent the three resulting streams. Create the hops, as shown in the following screenshot. When you create the hops, make sure that you choose the options according to the image: Result is TRUE for creating a hop with a green icon, and Result is FALSE for creating a hop with a red icon in it. Double-click on the first Filter rows step and complete the condition, as shown in the following screenshot: Double-click on the second Filter rows step and complete the condition with price < 100. You have just split the original dataset into three groups. You can verify it by previewing each Dummy step. The first one has products whose category is not tents; the second one, the tents under 100 US$; and the last group, the expensive tents; those whose price is over 100 US$. The preview of the last Dummy step will show the following: How it works... The main objective in the recipe is to split a dataset with products depending on their category and price. To do this, you used the Filter rows step. In the Filter rows setting window, you tell Kettle where the data flows to depending on the result of evaluating a condition for each row. In order to do that, you have two list boxes: Send 'true' data to step and Send 'false' data to step. The destination steps can be set by using the hop properties as you did in the recipe. Alternatively, you can set them in the Filter rows setting dialog by selecting the name of the destination steps from the available drop-down lists. You also have to enter the condition. The condition has the following different parts: The upper textbox on the left is meant to negate the condition. The left textbox is meant to select the field that will be used for comparison. Then, you have a list of possible comparators to choose from. On the right, you have two textboxes: The upper textbox for comparing against a field and the bottom textbox for comparing against a constant value. Also, you can include more conditions by clicking on the Add Condition button on the right. If you right-click on a condition, a contextual menu appears to let you delete, edit, or move it. In the first Filter rows step of the recipe, you typed a simple condition: You compared a field (category) with a fixed value (tents) by using the equal (=) operator. You did this to separate the tents products from the others. The second filter had the purpose of differentiating the expensive and the cheap tents. There's more... You will find more filter features in the following subsections. Avoiding the use of Dummy steps In the recipe, we assumed that you wanted all three groups of products for further processing. Now, suppose that you only want the cheapest tents and you don't care about the rest. You could use just one Filter rows step with the condition category = tents AND price < 100, and send the 'false' data to a Dummy step, as in shown in the following diagram: The rows that don't meet the condition will end at the Dummy step. Although this is a very commonly used solution for keeping just the rows that meet the conditions, there is a simpler way to implement it. When you create the hop from the Filter rows toward the next step, you are asked for the kind of hop. If you choose Main output of step, the two options Send 'true' data to step and Send 'false' data to step will remain empty. This will cause two things: Only the rows that meet the condition will pass. The rest will be discarded. Comparing against the value of a Kettle variable The recipe above shows you how to configure the condition in the Filter rows step to compare a field against another field or a constant value, but what if you want to compare against the value of a Kettle variable? Let's assume, for example, you have a named parameter called categ with kitchen as Default Value. As you might know, named parameters are a particular kind of Kettle variable.   You create the named parameters under the Parameter tab from the Settings option of the Edit menu. To use this variable in a condition, you must add it to your dataset in advance. You do this as follows: Add a Get Variables step from the Job category. Put it in the stream after the Text file input step and before the Filter Rows step; use it to create a new field named categ of String type with the value ${categ} in the Variable column. Now, the transformation looks like the one shown in the following screenshot: After this, you can set the condition of the first Filter rows step to category = categ, selecting categ from the listbox of fields to the right. This way, you will be filtering the kitchen products. If you run the transformation and set the parameter to tents, you will obtain similar results to those that were obtained in the main recipe. Avoiding the use of nested Filter Rows steps Suppose that you want to compare a single field against a discrete and short list of possible values and do different things for each value in that list. In this case, you can use the Switch / Case step instead of nested Filter rows steps. Let's assume that you have to send the rows to different steps depending on the category. The best way to do this is with the Switch / Case step. This way you avoid adding one Filter row step for each category. In this step, you have to select the field to be used for comparing. You do it in the Field name to switch listbox. In the Case values grid, you set the Value—Target step pairs. The following screenshot shows how to fill in the grid for our particular problem: The following are some considerations about this step: You can have multiple values directed to the same target step You can leave the value column blank to specify a target step for empty values You have a listbox named Default target step to specify the target step for rows that do not match any of the case values You can only compare with an equal operator If you want to compare against a substring of the field, you could enable the Use string contains option and as Case Value, type the substring you are interested in. For example, if for Case Value, you type tent_ then all categories containing tent_ such as tent_large, tent_small, or best_tents will be redirected to the same target step. Overcoming the difficulties of complex conditions There will be situations where the condition is too complex to be expressed in a single Filter rows step. You can nest them and create temporary fields in order to solve the problem, but it would be more efficient if you used the Java Filter or User Defined Java Expression step as explained next. You can find the Java Filter step in the Flow category. The difference compared to the Filter Rows step is that in this step, you write the condition using a Java expression. The names of the listboxes—Destination step for matching rows (optional) and Destination step for non-matching rows (optional)—differ from the names in the Filter rows step, but their purpose is the same. As an example, the following are the conditions you used in the recipe rewritten as Java expressions: category.equals("tents") and price < 100. These are extremely simple, but you can write any Java expression as long as it evaluates to a Boolean result. If you can't guarantee that the category will not be null, you'd better invert the first expression and put "tents".equals(category) instead. By doing this, whenever you have to check if a field is equal to a constant, you avoid an unexpected Java error. Finally, suppose that you have to split the streams simply to set some fields and then join the streams again. For example, assume that you want to change the category as follows: Doing this with nested Filter rows steps leads to a transformation like the following: You can do the same thing in a simpler way: Replace all the steps but the Text file input with a User Defined Java Expression step located in the Scripting category. In the setting window of this step, add a row in order to replace the value of the category field: As New field and Replace value type category. As Value type select String. As Java expression, type the following: (category.equals("tents"))?(price<100?"cheap_tents":"expensive_tents"):category The preceding expression uses the Java ternary operator ?:. If you're not familiar with the syntax, think of it as shorthand for the if-then-else statement. For example, the inner expression price<100?"cheap_tents":"expensive_tents" means if (price<100) then return "cheap_tents" else return "expensive_tents". Do a preview on this step. You will see something similar to the following:
Read more
  • 0
  • 0
  • 15640

article-image-android-application-testing-getting-started
Packt
24 Jun 2011
9 min read
Save for later

Android Application Testing: Getting Started

Packt
24 Jun 2011
9 min read
We will avoid introductions to Android and the Open Handset Alliance (http://www.openhandsetalliance.com) as they are covered in many books already and I am inclined to believe that if you are reading this article covering this more advanced topic you have started with Android development before. However, we will be reviewing the main concepts behind testing and the techniques, frameworks, and tools available to deploy your testing strategy on Android. Brief history Initially, when Android was introduced by the end of 2007, there was very little support for testing in the platform, and for some of us very accustomed to using testing as a component intimately coupled with the development process, it was the time to start developing some frameworks and tools to permit this approach. By that time Android had some rudimentary support for unit testing using JUnit (https://junit.org/junit5/), but it was not fully supported and even less documented. In the process of writing my own library and tools, I discovered Phil Smith's Positron , an Open Source library and a very suitable alternative to support testing on Android, so I decided to extend his excellent work and bring some new and missing pieces to the table. Some aspects of test automation were not included and I started a complementary project to fill that gap, it was consequently named Electron. And although positron is the anti-particle of the electron, and they annihilate if collide, take for granted that that was not the idea, but more the conservation of energy and the generation of some visible light and waves. Later on, Electron entered the first Android Development Challenge (ADC1) in early 2008 and though it obtained a rather good score in some categories, frameworks had no place in that competition. Should you be interested in the origin of testing on Android, please find some articles and videos that were published in my personal blog (http://dtmilano.blogspot.co.uk/search/label/electron). By that time Unit Tests could be run on Eclipse. However, testing was not done on the real target but on a JVM on the local development computer. Google also provided application instrumentation code through the Instrumentation class. When running an application with instrumentation turned on, this class is instantiated for you before any of the application code, allowing you to monitor all of the interaction the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml file. Software bugs It doesn't matter how hard you try and how much time you invest in design and even how careful you are when programming, mistakes are inevitable and bugs will appear. Bugs and software development are intimately related. However, the term bugs to describe flaws, mistakes, or errors has been used in hardware engineering many decades before even computers were invented. Notwithstanding the story about the term bug coined by Mark II operators at Harvard University, Thomas Edison wrote this in 1878 in a letter to Puskás Tivadar showing the early adoption of the term: "It has been just so in all of my inventions. The first step is an intuition, and comes with a burst, then difficulties arise — this thing gives out and [it is] then that 'Bugs' — as such little faults and difficulties are called — show themselves and months of intense watching, study and labor are requisite before commercial success or failure is certainly reached." How bugs severely affect your projects Bugs affect many aspects of your software development project and it is clearly understood that the sooner in the process you find and squash them, the better. It doesn't matter if you are developing a simple application to publish on the Android Market, you are re-branding the Android experience for an operator, or creating a customized version of Android for a device manufacturer, bugs will delay your shipment and will cost you money. From all of the software development methodologies and techniques, Test Driven Development, an agile component of the software development process, is likely the one that forces you to face your bugs earlier in the development process and thus it is also likely that you will solve more problems up front. Furthermore, the increase in productivity can be clearly appreciated in a project where a software development team uses this technique versus one that is, in the best of the cases, writing tests at the end of the development cycle. If you have been involved in software development for the mobile industry, you will have reasons to believe that with all the rush this stage never occurs. It's funny because usually, this rush is to solve problems that could have been avoided. In a study conducted by the National Institute of Standards and Technology (USA) in 2002, it was reported that software bugs cost the country economy $59.5 billion annually. More than a third of this cost can be avoided if better software testing is performed. But please, don't misunderstand this message. There are no silver bullets in software development and what will lead you to an increase in productivity and manageability of your project is the discipline applying these methodologies and techniques to stay in control. Why, what, how, and when to test You should understand that early bug detection saves huge amount of project resources and reduces software maintenance costs. This is the best known reason to write software tests for your development project. Increased productivity will soon be evident. Additionally, writing the tests will give you a deeper understanding of the requirements and the problem to be solved. You will not be able to write tests for a piece of software you don't understand. This is also the reason behind the approach of writing tests to clearly understand legacy or third party code and having the infrastructure to confidently change or update it. The more the code is covered by your tests, the higher could be your expectations of discovering the hidden bugs. If during this coverage analysis you find that some areas of your code are not exercised, additional tests should be added to cover this code as well. This technique requires a special instrumented Android build to collect probe data and must be disabled for any release code because the impact on performance could severely affect application behavior. To fill in this gap, enter EMMA (http://emma.sourceforge.net/), an open-source toolkit for measuring and reporting Java code coverage, that can offline instrument classes for coverage. It supports various coverage types: class method line basic block Coverage reports can also be obtained in different output formats. EMMA is supported up to some degree by the Android framework and it is possible to build an EMMA instrumented version of Android. This screenshot shows how an EMMA code coverage report is displayed in the Eclipse editor, showing green lines when the code has been tested, provided the corresponding plugin is installed. (Move the mouse over the image to enlarge it.) Unfortunately, the plugin doesn't support Android tests yet, so right now you can use it for your JUnit tests only. Android coverage analysis report is only available through HTML. Tests should be automated and you should run some or all tests every time you introduce a change or addition to your code in order to ensure that all the conditions that were met before are still met and that the new code satisfies the tests as expected. This leads us to the introduction of Continuous Integration. It relies on the automation of tests and building processes. If you don't use automated testing, it is practically impossible to adopt Continuous Integration as part of the development process and it is very difficult to ensure that changes would not break existing code. What to test Strictly speaking you should test every statement in your code but this also depends on different criteria and can be reduced to test the path of execution or just some methods. Usually there's no need to test something that can't be broken, for example it usually makes no sense to test getters and setters as you probably won't be testing the Java compiler on your own code and the compiler would have already performed its tests. In addition to the functional areas you should test, there are some specific areas of Android applications that you should consider. We will be looking at these in the following sections. Activity lifecycle events You should test that your activities handle lifecycle events correctly. If your activity should save its state during onPause() or onDestroy() events and later be able to restore it in onCreate(Bundle savedInstanceState), you should be able to reproduce and test all these conditions and verify that the state was correctly saved and restored. Configuration-changed events should also be tested as some of these events cause the current Activity to be recreated, and you should test correct handling of the event and the newly created Activity preserves the previous state. Configuration changes are triggered even by rotation events, so you should test you application's ability to handle these situations. Database and filesystem operations Database and filesystem operations should be tested to ensure that they are handled correctly. These operations should be tested in isolation at the lower system level, at a higher level through ContentProviders, or from the application itself. To test these components in isolation, Android provides some mock objects in the android.test.mock package. Physical characteristics of the device Much before delivering your application you should be sure that all of the different devices it can be run on are supported or at less you should detect the situation and take pertinent measures. Among other characteristics of the devices, you may find that you should test: Network capabilities Screen densities Screen resolutions Screen sizes Availability of sensors Keyboard and other input devices GPS External storage In this respect Android Virtual Devices play an important role because it is practically impossible to have access to all of the devices with all of the possible combinations of features but you can configure AVD for almost every situation. However, as it was mentioned before, leave your final tests for actual devices where the real users will run the application to understand its behavior.
Read more
  • 0
  • 0
  • 2483

article-image-jquery-mobile-organizing-information-list-views
Packt
23 Jun 2011
8 min read
Save for later

jQuery Mobile: Organizing Information with List Views

Packt
23 Jun 2011
8 min read
jQuery Mobile First Look Discover the endless possibilities offered by jQuery Mobile for rapid Mobile Web Development You might have noticed that the vast majority of websites built using jQuery Mobile have their content laid out in very similar ways; sure, they differ in the design, colors, and overall feel, but they all have a list-based layout. There is a way in which we can organize our information and take advantage of each and every space in the browser: information is displayed vertically, one piece under another. There are no sidebars of any kind and links are organized in lists – for a cleaner and tidy look. But list views are also used to actually be a list of information. Some examples may be lists of albums, names, tasks, and so on: after all, our purpose is to build a mobile web application and the majority of services and pages can be organized in a way which closely resembles a list. Basics and conventions for list views Due to the particular nature of lists, list views are coded exactly the same way a standard HTML unordered list would. After all, the purpose of list views is to organize our information in a tidy way, presenting a series of links which are placed one under another; the easiest way to grasp their usefulness is, in my opinion, imagining a music player application. A music player would need a clean enough interface, listing the artists, albums, and songs by name. In order to play a song, the user would need to select an artist, and then choose the album in which the song he wishes to play has been released. To create our first view (artists), we would use the following code. Make sure you add the data-role="listview" attribute to the unordered list tag: <ul data-role="listview"> <li><a href="astra.html">Astra</a></li> <li><a href="zappa.html">Frank Zappa</a></li> <li><a href="tull.html">Jethro Tull</a></li> <li><a href="radiohead.html">Radiohead</a></li> <li><a href="who.html">The Who</a></li> </ul> The jQuery Mobile framework automatically styles the list elements accordingly, and adds a right arrow icon. List elements fill the full width of the browser window: Whenever an item is selected (click/tap event), jQuery Mobile will parse the code inside the list element and issue an AJAX request for the first URL found. The page (obtained via AJAX) is then inserted into the existing DOM and a page transition event is triggered. The default page transition is a slide-left animation; clicking the back button on the newly displayed page will result in a slide-right animation. Choosing the list type as per your requirements A somewhat large variety of lists are available for us to choose from in order to make use of the type of list view that is best suited to our needs. Below are listed (sorry, no pun intended!) the different types of list views along with a brief description of how to use them and what part of code we need to change in order to obtain a certain list view. Nested lists Bearing in mind that list views elements are based on the standard HTML unordered list element, we might be wondering what would happen if we try and create a second list inside a list view. By nesting a ul element inside list items, jQuery Mobile will adopt a different kind of behavior to our list items. Our first step toward the creation of a nested list is removing any link present in the list item, as a click event will show the nested list instead of redirecting to another page. The child list will be put into a new "page" with the title of the parent in the header. We're now implementing nested list elements into our sample music player interface by changing our markup to the following. This way, we are able to browse artists and albums. Please note that we have removed any links to external pages: <ul data-role="listview"> <li>Astra <ul> <li><a href="astra_weirding.html">The Weirding</a></li> </ul> </li> <li>Frank Zappa <ul> <li><a href="zappa_hotrats.html">Hot Rats</a></li> <li><a href="zappa_yellowshark.html">Yellow Shark</a></li> </ul> </li> <li>Jethro Tull <ul> <li><a href="tull_aqualung.html">Aqualung</a></li> <li><a href="tull_thick.html">Thick as a Brick</a></li> </ul> </li> <li>Radiohead <ul> <li><a href="radiohead_ok.html">OK Computer</a></li> <li><a href="radiohead_rainbows.html">In Rainbows</a></li> <li><a href="radiohead_kol.html">The King of Limbs</a></li> </ul> </li> <li>The Who <ul> <li><a href="who_next.html">Who's Next</a></li> <li><a href="who_q.html">Quadrophenia</a></li> <li><a href="who_tommy.html">Tommy</a></li> </ul> </li> </ul> If we clicked on the Radiohead element, we would then be able to see the following page: By default, child list will be given a Swatch B theme to indicate they are at a secondary level of navigation; we can select a different color swatch by specifying a data-theme attribute on the child list element. We can see the header turned blue, and the artist name is used as the header. We have a choice to go back to the previous page (artists) or click again onto a list item (album) to view more. Numbered lists Our music player interface has reached the point in which we need to list the tracks contained in an album. Of course, tracks have a sequence, and we want to give the user the possibility to see what track number is without having to count them all – and without writing numbers manually, that would be terrible! In a very similar fashion, we can use ordered list elements (ol) to obtain numbering: jQuery Mobile will try to use CSS to display numbers or, if not supported, JavaScript. The following code lists all of the tracks for an album: Note there is no limit to the number of lists you can nest. <ul> <!-- ... --> <li>Radiohead <ul> <li><a href="radiohead_ok.html">OK Computer</a></li> <li><a href="radiohead_rainbows.html">In Rainbows</a></li> <li>The King of Limbs <ol> <li><a href="play.html">Bloom</a></li> <li><a href="play.html">Morning Mr. Magpie</a></li> <li><a href="play.html">Little by Little</a></li> <li><a href="play.html">Feral</a></li> <li><a href="play.html">Lotus Flower</a></li> <li><a href="play.html">Codex</a></li> <li><a href="play.html">Give Up the Ghost</a></li> <li><a href="play.html">Separator</a></li> </ol> </li> </ul> </li> <!-- ... --> </ul>
Read more
  • 0
  • 0
  • 5269

article-image-iphone-javascript-installing-frameworks
Packt
23 Jun 2011
14 min read
Save for later

iPhone JavaScript: Installing Frameworks

Packt
23 Jun 2011
14 min read
  iPhone JavaScript Cookbook Clear and practical recipes for building web applications using JavaScript and AJAX without having to learn Objective-C or Cocoa         Read more about this book       (For more resources related to this subject, see here.) Introduction Many web applications implement common features independent of the final purpose for which they have been designed. Functionalities and features such as authentication, forms validation, retrieving records from a database, caching, logging, and pagination are very common in modern web applications. As a developer, surely you have implemented one or more of these features in your applications more than once. Good developers and software engineers insist on concepts, such as modularity, reusability, and encapsulation; as a consequence you can find a lot of books, papers, and articles talking about how to design your software using these techniques. In fact, modern and popular methodologies, such as Extreme Programming, Scrum, and Test-driven Development are based on those principles. Although this approach sounds very appealing in theory, it might be complicated to carry it out in practice. Developing any kind of software from scratch for running in any platform is undoubtedly a hard task. Complexity grows up when the target platform, operating system, or machine has its own specific rules and mechanisms. Some tools can make our job less complicated but only one kind of them is definitely a safe bet. It is here when we meet frameworks, a set of proven code that offers common functionality and standard structures for software development. This code makes our life much easier without reinventing the wheel and gives a skeleton to our applications, making sure that we're doing things correctly. In addition, frameworks avoid starting from scratch once more. From a technical point of view, most frameworks are a set of libraries implementing functions, classes, and methods. Using frameworks, we can save time and money, writing less code due to its code skeleton, and features implemented on it. Usually, frameworks force us to follow standards and they offer well-proven code avoiding common mistakes for beginners. Tasks such as testing, maintenance, and deployment are easier to do using frameworks due to the tools and mechanisms included. On the other hand, the learning curve could be a big and difficult drawback for beginners. Through this article, we'll learn how to install the main frameworks for JavaScript, HTML, and CSS development for iPhone. All of them offer a base to develop applications with a consistent and native look and feel using different methods. While some of them are focused on the user interface, others allow using AJAX in an efficient and easy way. Even some frameworks allow building native applications from the original code of the web application. We have the chance to choose which is better to fulfill our requirements; it is even possible to use more than one of these solutions for the same application. For our recipes, we'll use the following frameworks: iUI: This is focused on the look and feel of iPhone and consists of CSS files, images, and a small JavaScript library. Its objective is to get a web application running on the device with a consistent interface such as a native application. This framework establishes a correspondence between HTML tags and conventions used for developing native applications. UiUIKit: Using a set of CSS and image files, it provides a coherent system for building web applications with a graphic interface such as native iPhone applications. The features offered for this framework are very similar to iUI. XUI: This is a pure JavaScript library specific for mobile development. It has been designed to be faster and lighter than other similar libraries, such as jQuery, MooTools, and prototype. iWebKit: This is developed specifically for Apple's devices and is compatible with CSS3 standard; it helps to write web applications or websites with minimum HTML knowledge. Its modular design supports plugins for adding new features and we can build and use the themes for UI customization. WebApp.Net: This framework comes loaded with JavaScript, CSS, and image files for developing web application for mobile devices that uses WebKit engine in its web browsers. Besides building interfaces, this framework includes functionality to use AJAX in an easy and efficient way. PhoneGap: This is designed to minimize efforts for developing native mobile applications for different operating systems, platforms, and devices. It is based on the WORE (Write once, run anywhere) principle and it allows conversion from a web application into a native application. It supports many platforms and operating systems, such as iOS, Android, webOS, Symbian, and BlackBerry OS. Apple Dashcode: Formally, this is a software development tool for Mac OS X included in Leopard and Snow Leopard versions, and focused on widget development for these operating systems. However, the last versions allow you to write web applications for iPhone and other iOS devices offering a graphic interface builder. Installing the iUI framework This recipe shows how to download and install the iUI framework on different operating systems. Particularly, we'll cover Microsoft Windows, Mac OS X, and GNU/Linux. Getting ready The first step is to install and get ready; some tools need to be downloaded and decompressed. As computer users, we know how to decompress files using software such as WinZip, Ark, or the built-in utility on Mac OS X. You will surely have installed a web browser on your computer. If you are a Linux or Mac developer, you already know how to use curl or wget. These tools are very useful for quick download and you only need to use the command line through applications such as GNOME Terminal, Konsole, iTerm, or Terminal. iUI is an open source project, so you can download the code for free. The open source project releases some stable versions packed and ready to download, but it is also possible to download a development version. This one could be suitable if you prefer working with the latest changes made by the official developers contributing to the project. Due to this, developers are using Mercurial version control and thus we'll need to install a client for it to get access to this code. How to do it... iUI is an open source project so you can download the code for free. Open your favorite web browser and enter this URL: http://code.google.com/p/iui/downloads/list In that web page, you'll see a list with files that refer to different release versions of this framework. Clicking on the link corresponding to the latest release's drives takes you to a new web page that shows you a new link for the file. Click on it for instant downloading. (Move the mouse over the image to enlarge it.) If you are a GNU/Linux user or a Mac developer you will be used to command line. Open your terminal application and launch this command from your desired directory: $ wget http://iui.googlecode.com/files/iui-0.31.tar.gz Once you have downloaded the tarball file, it's time to extract its content to a specific folder on our computer. WinZip and WinRAR are the most popular tools to do this task on Windows. Linux distributions, by default, install similar tools such as File Roller and Ark. Double-clicking from the download window of the Safari browser will extract the files directly to your default folder on your Mac, which is usually called Downloads. For command-line enthusiasts, execute the following command: $ tar -zxvf iui-0.31.tar.gz How it works... After decompressing the downloaded file, you'll find a folder with different subfolders and files. The most important is a subfolder called iui that contains CSS, images, and JavaScript files for building our web applications for iPhone. We need to copy this subfolder to our working folder where other application files reside. Sharing this framework across different web applications is possible; you only need to put the iUI at a place where these applications have permissions to access. Usually, this place is a folder under the DocumentRoot of your web server. If you're planning to write a high load application, it would be a good idea to use a cloud or CDN (Content Delivery Network) service such as Amazon Simple Storage Services (Amazon S3) for hosting and serving static HTML, CSS, JavaScript, and image files. Installing the iUI framework is a straightforward process. You simply download and decompress one file, and then copy one folder into an other, which has permission to be accessed by the web server. Apache is one of the most used and extended web servers in the world. Other popular options are Internet Information Server (IIS), lighttpd, and nginx. Apache web server is installed by default on Mac OS X; most of the operating systems based on Linux and UNIX offer binary packages for easy installation and you can find binary files for installing on Windows as well. IIS was designed for Windows operating systems, meanwhile, lighttpd and nginx are winning popularity and are used on UNIX systems as Linux's distros, FreeBSD, and OpenBSD. Ubuntu Linux uses /var/www/ directory as the main DocumentRoot for Apache. So, in order to share iUI framework across applications, you can copy the folder to the other folder by executing this command: $ cp -r iui-0.31/ui /var/www/iui If you are a Mac user, your target directory will be /Library/WebServer/Documents/iui. There's more... Inside the samples subfolder, you'll find some files showing capabilities of this framework, including HTML and PHP files. Some examples need a web server with PHP support but you can test others using Safari web browser or an other WebKit's browser such as Safari or Google Chrome. Open index.html with a web browser and use it as your starting point. If you prefer to use the latest version in development from the version control, you'll need to install a Mercurial client. Most of the GNU/Linux distribution such as Fedora, Debian, and Ubuntu includes binary packages ready to install them. Usually, the name of the binary package is mercurial. The following command will install the client on Ubuntu Linux: $ sudo apt-get install mercurial Mercurial is an open source project and offers a binary file ready to install for Mac OS X and Windows systems. If you're using one of these, go to the following page and download the specific file for your operating system and version: http://mercurial.selenic.com/downloads/ After downloading, you can install the client using the regular process for your operating system. Mac users will find a ZIP file containing a binary package. For Windows, the distributed file is a MSI (Microsoft Installer), ready for self-installation after clicking on it. Despite that the client of this version control was developed for the command line, we can find some GUI tools online such as TortoiseHG for Windows. These tools are intuitive and user-friendly, allowing an interactive use between the user and the source files hosted in the version control system. TortoiseHG can be downloaded from the same web page as the Mercurial client. Finally, we'll download the version development of the iUI framework executing the following command: $ hg clone https://iui.googlecode.com/hg/ iui The new iui folder includes all files of the iUI framework. We should copy this folder to our DocumentRoot. If you want to know more about this framework, point your browser at the official wiki project: http://code.google.com/p/iui/w/list Also, taking a look at the complete code of the project may be interesting for advanced developers or just for people wanting to learn more about internal details: http://code.google.com/p/iui/source/browse Installing the UiUIKit framework UiUIKit is the short name of the Universal iPhone UI Kit framework. The development of this framework is carried out through an open source project hosted in Google Code and is distributed under the GNU Public License v3. Let's see how to install it on different operating systems. Getting ready As the main project file is distributed as a ZIP file, we'll need to use one tool for decompressing these kind of files. Most of the modern operating systems include tools for this process. As seen in the previous recipe, we can use wget or curl programs for downloading the files. If you are planning to read the source code or you'd like to use the current development version of the framework, you'll need a Subversion client as the UiUIKit project is working with this open source version control. How to do it... Open your web browser and type the following URL: http://code.google.com/p/iphone-universal/downloads/list After downloading, click on the link for the latest version from the main list, for instance, the link called UiUIKit-2.1.zip. The next page will show you a different link for this file that represents the version 2.1 of the UiUIKit framework. Click on the link and the file will start downloading immediately. Mac users will see how the Safari browser shows a window with the content of the compressed file, which is a folder called UiUIKit, which is stored in the default folder for downloads. Command line's fans can use these simple commands from their favorite terminal tool: $ cd ~$ curl -O http://iphone-universal.googlecode.com/files/UiUIKit-2.1.zip After downloading, don't forget to decompress the file on your web-specific directory. The commands given next execute this action on Linux and Mac OS X systems: $ cd /var/www/$ unzip ~/UiUIKit-2.1.zip How it works... The main folder of the UiUIKit framework contains two subfolders called images and stylesheets. The first one includes many images used to get a native look for web applications on the iPhone. The other one offers a CSS file called iphone.css. We only need the images subfolder with its graphic files and the CSS file. In order to use this framework in our projects, we need to allow our HTML files access to the images and the CSS file of the framework. These files should be in a folder with permissions for the web server. For example, we'll have a directory structure for our new web application for iPhone as follows: myapp/ index.html images/ actionButtons.png apple-touch-icon.png backButton.png toolButton.png whiteButton.png first.html second.html stylesheets/ iphone.css Remember that this framework doesn't include HTML files; we only need a bunch of the graphic files and one stylesheet file. The HTML files showed in the previous example will be our own files created for the web application. We'll also find a lot of examples on different HTML files located in the root directory, outside the mentioned subfolders. These files are not required for development but they can be very useful to show how to use some features and functionalities. There's more... For an initial contact with the capabilities of the framework it would be interesting to take a look at the examples included in the main directory of the framework. We can load the index.html in our browser. This file is an index to the different examples and offers a native interface for the iPhone. Safari could be used but is better to access from a real iPhone device. Subversion is a well-proven version control used by many developers, companies, and, of course, open source projects. UiUIKit is an example of these projects using this popular version control. So, to access the latest version in development, we'll need a client to download it. Popular Linux distributions, including Ubuntu and Debian have binary packages ready to install. For instance, the following command is enough to install it on Ubuntu Linux: $ sudo apt-get install subversion The last versions of Mac OS X, including Leopard and Snow Leopard, includes a Subversion client ready to use. For Windows, you can download Slik SVN available for 32-bit and 64-bits platforms; installation programs can be downloaded from: http://www.sliksvn.com/en/download. When you are sure that your client is running, you could execute it for getting the latest development version of the UiUIKit framework. Mac and Linux users will execute the following command: $ svn checkout http://iphone-universal.googlecode.com/svn/trunk/ UiUIKit All information related to the UiUIKit framework project could be found at: http://code.google.com/p/iphone-universal/
Read more
  • 0
  • 0
  • 8652
article-image-how-create-new-vehicle-cryengine-3
Packt
23 Jun 2011
12 min read
Save for later

How to Create a New Vehicle in CryENGINE 3

Packt
23 Jun 2011
12 min read
  CryENGINE 3 Cookbook Over 100 recipes written by Crytek developers for creating AAA games using the technology that created Crysis 2 Creating a new car mesh (CGA) In this recipe, we will show you how to build the basic mesh structure for your car to be used in the next recipe. This recipe is not to viewed as a guide on how to model your own mesh, but rather as a template for how the mesh needs to be structured to work with the XML script of the vehicle. For this recipe, you will be using 3DSMax to create and export your .CGA. .CGA (Crytek Geometry Animation): The .cga file is created in the 3D application and contains animated hard body geometry data. It only supports directly-linked objects and does not support skeleton-based animation (bone animation) with weighted vertices. It works together with .anm files. Getting ready Create a box primitive and four cylinders within Max and then create a new dummy helper. How to do it... After creating the basic primitives within Max, we need to rename these objects. Rename the primitives to match the following naming convention: Helper = MyVehicle Box = body Front Left Wheel = wheel1 Front Right Wheel = wheel2 Rear Left Wheel = wheel3 Rear Right Wheel = wheel4 Remember that CryENGINE 3 assumes that y is forward. Rotate and reset any x-forms if necessary. From here you can now set up the hierarchy to match what we will build into the script: In Max, link all the wheels to the body mesh. Link the body mesh to the MyVehicle dummy helper. Your hierarchy should look like the following screenshot in the Max schematic view: Next, you will want to create a proxy mesh for each wheel and the body. Be sure to attach these proxies to each mesh. Proxy meshes can be a direct duplication of the simple primitive geometry we have created. Before we export this mesh, make one final adjustment to the positioning of the vehicle: Move the body and the wheels up on the Z axis to align the bottom surface of the wheels to be flushed with 0 on the Z. Without moving the body or the wheels, be sure that the MyVehicle helper is positioned at 0,0,0 (this is the origin of the vehicle). Also, re-align the pivot of the body to 0,0,0. Once complete, your left viewport should look something like the following screenshot (if you have your body still selected): After setting up the materials, you are now ready to export the CGA: Open the CryENGINE Exporter from the Utilities tab. Select the MyVehicle dummy helper and click the Add Selected button. Change the export to: Animated Geometry (*.cga). Set Export File per Node to True. Set Merge All Nodes to False. Save this Max scene in the following directory: MyGameFolderObjectsvehiclesMyVehicle. Now, click on Export Nodes to export the CGA. How it works... This setup of the CGA is a basic setup of the majority of the four wheeled vehicles used for CryENGINE 3. This same basic setup can also be seen in the HMMWV provided in the included assets with the SDK package of CryENGINE 3. Even though the complete HMMWV may seem to be a very complicated mesh used as a vehicle, it can also be broken down into the same basic structure as the vehicle we just created. The main reason for the separation of the parts on the vehicles is because each part performs its own function. Since the physics of the vehicle code drives the vehicle forward in the engine, it actually controls each wheel independently, so it can animate them based on what they can do at that moment. This means that you have the potential for a four wheel drive on all CryENGINE 3 vehicles, all animating at different speeds based on the friction that they grip. Since all of the wheels are parented to the body (or hull) mesh, this means that they drive their parent (the body of the vehicle) but the body also handles where the wheels need to be offset from in order to stay aligned when driving. The body itself acts as the base mesh for all other extras put onto the vehicle. Everything else from Turrets to Doors to Glass Windows branch out from the body. The dummy helper is only the parent for the body mesh due to the fact that it is easier to export multiple LODs for that vehicle (for example, HMMWV, HMMWV_LOD1, HMMWV_LOD2, and so on). In the XML, this dummy helper is ignored in the hierarchy and the body is treated as the parent node. There's more... Here are some of the more advanced techniques used. Dummy helpers for modification of the parts A more advanced trick is the use of dummy helpers set inside the hierarchy to be used in later reference through the vehicle's mod system. How this works is that if you had a vehicle such as the basic car shown previously, but you wanted to add on an additional mesh just to have a modified type of this same car (something like adding a spoiler to the back), then you can create a dummy helper and align it to the pivot of the object, so it will line up to the body of the mesh when added through the script later on. This same method was used in Crysis 2 with the Taxi signs on the top of the Taxi cars. The Taxi itself was the same model used as the basic civilian car, but had an additional dummy helper where the sign needed to be placed. This allowed for a clever way to save on memory when rendering multiple vehicle props within a single area but making each car look different. Parts for vehicles and their limitless possibilities Adding the basic body and four wheels to make a basic car model is only the beginning. There are limitless possibilities to what you can make as far as the parts on a vehicle are concerned. Anything from a classic gunner turret seen on the HMMWV or even tank turrets, all the way to arms for an articulated Battlemech as seen in the Crysis 2 Total Conversion mod—MechWarrior: Living Legends. Along with the modifications system, you have the capabilities to add on a great deal of extra parts to be detached and exploded off through the damage scripts later on. The possibilities are limitless. Creating a new car XML In this recipe, we will show you how to build a new script for CryENGINE 3 to recognize your car model as a vehicle entity. For this recipe, you must have some basic knowledge in XML formatting. Getting ready Open DefaultVehicle.xml in the XML editor of your choice (Notepad, Notepad++, UltraEdit, and so on). This XML will be used as the basic template to construct our new vehicle XML. DefaultVehicle.xml is found at the following location: MyGameFolderScriptsEntitiesVehiclesImplementationsXml. Open the MyVehicle.max scene made from the previous recipe to use as a reference for the parts section within this recipe. How to do it... Basic Properties: First, we will need to rename the filename to what the vehicle's name would be. Delete filename = Objects/Default.cgf. Rename name = DefaultVehicle to name = MyVehicle. Add actionMap = landvehicle to the end of the cell. Save the file as MyVehicle.XML. Your first line should now look like the following: Downloading the example code You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you. <Vehicle name="MyVehicle" actionMap="landvehicle"> Now we need to add some physics simulation to the vehicle otherwise there might be some strange reactions with the vehicle. Insert the following after the third line (after the Buoyancy cell): <Simulation maxTimeStep="0.02" minEnergy="0.002" maxLoggedCollisions="2"/> Damages and Components: For now, we will skip the Damages and Components cells as we will address them in a different recipe. Parts: To associate the parts made in the Max file, the hierarchy of the geometry in 3DSMax needs to be the very same as is referenced in the XML. To do this, we will first clear out the class = Static cell and replace it with the following: <Part name="body" class="Animated" mass="100" component="Hull"> <Parts> </Parts> <Animated filename="objects/vehicles/MyVehicle/MyVehicle.cga" filenameDestroyed="objects/vehicles/HMMWV/HMMWV_damaged.cga"/> </Part> Now, within the <Parts> tag that is underneath the body, we will put in the wheels as the children: <Parts> <Part name="wheel1" class="SubPartWheel" component="wheel_1" mass="80"> <SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4" maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/> </Part> </Parts> Remaining within the <Parts> tag, add in wheels 2-4 using the same values as previously listed. The only difference is you must change the axle property of wheels 3 and 4 to the value of 1 (vehicle physics has an easier time calculating what the wheels need to if only two wheels are associated with a single axle). The last part that needs to be added in is the Massbox. This part isn't actually a mesh that was made in 3DSMax, but a generated bounding box, generated by code with the mass and size defined here in the XML. Write the following code snippet after the <body> tag: <Part name="massBox" class="MassBox" mass="1500" position="0,0,1." disablePhysics="0" disableCollision="0" isHidden="0"> <MassBox size="1.25,2,1" drivingOffset="-0.7"/> </Part> If scripted correctly, your script should look similar to the following for all of the parts on your vehicle: <Parts> <Part name="body" class="Animated" mass="100" component="Hull"> <Parts> <Part name="wheel1" class="SubPartWheel" component="wheel_1" mass="80"> <SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4" maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/> </Part> <Part name="wheel2" class="SubPartWheel" component="wheel_2" mass="80"> <SubPartWheel axle="0" density="0" damping="-0.7" driving="1" lenMax="0.4" maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/> </Part> <Part name="wheel3" class="SubPartWheel" component="wheel_3" mass="80"> <SubPartWheel axle="1" density="0" damping="-0.7" driving="1" lenMax="0.4" maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/> </Part> <Part name="wheel4" class="SubPartWheel" component="wheel_4" mass="80"> <SubPartWheel axle="1" density="0" damping="-0.7" driving="1" lenMax="0.4" maxFriction="1" minFriction="1" slipFrictionMod="0.3" stiffness="0" suspLength="0.25" rimRadius="0.3" torqueScale="1.1"/> </Part> </Parts> <Animated filename="objects/vehicles/MyVehicle/MyVehicle.cga" filenameDestroyed="objects/vehicles/HMMWV/HMMWV_damaged.cga"/> </Part> <Part name="massBox" class="MassBox" mass="1500" position="0,0,1." disablePhysics="0" disableCollision="0" isHidden="0"> <MassBox size="1.25,2,1" drivingOffset="-0.7"/> </Part> </Parts> Movement Parameters: Finally, you will need to implement the MovementParams needed, so that the XML can access a particular movement behavior from the code that will propel your vehicle. To get started right away, we have provided an example of the ArcadeWheeled parameters, which we can copy over to MyVehicle: <MovementParams> <ArcadeWheeled> <Steering steerSpeed="45" steerSpeedMin="80" steerSpeedScale="1" steerSpeedScaleMin="1" kvSteerMax="26" v0SteerMax="40" steerRelaxation="130" vMaxSteerMax="12"/> <Handling> <RPM rpmRelaxSpeed="2" rpmInterpSpeed="4" rpmGearShiftSpeed="2"/> <Power acceleration="8" decceleration="0.1" topSpeed="32" reverseSpeed="5" pedalLimitMax="0.30000001"/> <WheelSpin grip1="5.75" grip2="6" gripRecoverSpeed="2" accelMultiplier1="1.2" accelMultiplier2="0.5"/> <HandBrake decceleration="15" deccelerationPowerLock="1" lockBack="1" lockFront="0" frontFrictionScale="1.1" backFrictionScale="0.1" angCorrectionScale="5" latCorrectionScale="1" isBreakingOnIdle="1"/> <SpeedReduction reductionAmount="0" reductionRate="0.1"/> <Friction back="10" front="6" offset="-0.2"/> <Correction lateralSpring="2" angSpring="10"/> <Compression frictionBoost="0" frictionBoostHandBrake="4"/> </Handling> <WheeledLegacy damping="0.11" engineIdleRPM="500" engineMaxRPM="5000" engineMinRPM="100" stabilizer="0.5" maxTimeStep="0.02" minEnergy="0.012" suspDampingMin="0" suspDampingMax="0" suspDampingMaxSpeed="3"/> <AirDamp dampAngle="0.001,0.001,0.001" dampAngVel="0.001,1,0"/> <Eject maxTippingAngle="110" timer="0.3 "/> <SoundParams engineSoundPosition="engineSmokeOut" runSoundDelay="0" roadBumpMinSusp="10" roadBumpMinSpeed="6" roadBumpIntensity="0.3" maxSlipSpeed="11"/> </ArcadeWheeled> </MovementParams> After saving your XML, open the Sandbox Editor and place down from the Entities types: VehiclesMyVehicle. You should now be able to enter this vehicle (get close to it and press the F key) and drive around (W = accelerate, S = brake/reverse, A = turn left, D = turn right)! How it works... The parts defined here in the XML are usually an exact match to the Max scene that the vehicle is created in. As long as the naming of the parts and the name of the subobjects within Max are the same, the vehicle structure should work. The parts in the XML can themselves be broken down into their own properties: Name: The name of the part. Class: The classification of the part. Base (obsolete) Static: Static vehicle (should not be used). Animated: The main part for an active rigid body of a vehicle. AnimatedJoint: Used for any other part that's used as a child of the animated part. EntityAttachment (obsolete) Light: Light parts for headlights, rear light, and so on. SubPart (obsolete) SubPartWheel: Wheels. Tread: Used with tanks. MassBox: Driving Massbox of the vehicle. Mass: Mass of the part (usually used when the part is detached) Component: Which component this part is linked to. If the component uses useBoundsFromParts="1", then this part will also be included in the total bounding box size. Filename: If a dummy helper is created in Max to be used as a part, then an external mesh can be referenced and used as this part. DisablePhysics: Prevents the part from being physicalized as rigid. DisableCollision: Disables all collision. It is an useful example for mass blocks. isHidden: Hides the part from rendering. There's more... The def_vehicle.xml file found in MyGameFolderScriptsEntitiesVehicles, holds all the property's definitions that can be utilized in the XML of the vehicles. After following the recipes found in this article, you may want to review def_vehicle.xml for further more advanced properties that you can add to your vehicles.  
Read more
  • 0
  • 0
  • 17691

article-image-blender-25-rigging-torso
Packt
22 Jun 2011
9 min read
Save for later

Blender 2.5: Rigging the Torso

Packt
22 Jun 2011
9 min read
Blender 2.5 Character Animation Cookbook 50 great recipes for giving soul to your characters by building high-quality rigs This article is about our character's torso: we're going to see how to create hips, a spine, and a neck. Aside from what you'll learn from here, it's important for you to take a look at how some of those rigs were built. You'll see some similarities, but also some new ideas to apply to your own characters. It's pretty rare to see two rigs built the exact same way. How to create a stretchy spine A human spine, also called vertebral column, is a bony structure that consists of several vertebrae (24 or 33, if you consider the pelvic region). It acts as our main axis and allows us a lot of flexibility to bend forward, sideways, and backward. And why is this important to know? That number of vertebrae is something useful for us riggers. Not that we're going to create all those tiny bones to make our character's spine look real, but that information can be used within Blender. You can subdivide one physical bone for up to 32 logical segments (that can be seen in the B-Bone visualization mode), and this bone will make a curved deformation based on its parent and child bones. That allows us to get pretty good deformations on our character's spine while keeping the number of bones to a minimum. This is good to get a realistic deformation, but in animation we often need the liberty to squash and stretch our character: and this is needed not only in cartoony animations, but to emphasize realistic poses too. We're going to see how to use some constraints to achieve that. We're going to talk about just the spine, without the pelvic region. The latter needs a different setup which is out of the scope of this article. How to do it... Open the file 002-SpineStretch.blend from support files. It's a mesh with some bones already set for the limbs, as you can see in the next screenshot. There's no weight painting yet, because it's waiting for you to create the stretchy spine. Select the armature and enter into its Edit Mode (Tab). Go to side view (Numpad 3); make sure the 3D cursor is located near the character's back, in the line of what would be his belly button. Press Shift + A to add a new bone. Move its tip to a place near the character's eyes. Go to the Properties window, under the Object Data tab, and switch the armature's display mode to B-Bone. You'll see that this bone you just created is a bit fat, let's make it thinner using the B-Bone scale tool (Ctrl + Alt + S). With the bone still selected, press (W) and select Subdivide. Do the same to the remaining bones so we end up with five bones. Still, in side view, you can select and move (G) the individual joints to best fit the mesh, building that curved shape common in a human spine, ending with a bone to serve as the head, as seen in the next screenshot: Name these bones as D_Spine1, D_Spine2, D_Spine3, D_Neck, and D_Head. You may think just five bones aren't enough to build a good spine. And here's when the great rigging tools in Blender come to help us. Select the D_Neck bone, go to the Properties window, under the Bone tab and increase the value of Segments in the Deform section to 6. You will not notice any difference yet. Below the Segments field there are the Ease In and Ease Out sliders. These control the amount of curved deformation on the bone at its base and its tip, respectively, and can range from 0 (no curve) to 2. Select the next bone below in the chain (D_Spine3) and change its Segments value to 8. Do the same to the remaining bones below, with values of 8 and 6, respectively. To see the results, go out of Edit Mode (Tab). You should end up with a nice curvy spine as seen in the following screenshot: Since these bones are already set to deform the mesh, we could just add some shapes to them and move our character's torso to get a nice spine movement. But that's not enough for us, since we also want the ability to make this character stretch. Go back into Edit Mode, select the bones in this chain, press Shift + W, and select No Scale. This will make sure that the stretching of the parent bone will not be transferred to its children. This can also be accomplished under the Properties window, by disabling the Inherit Scale option of each bone. Still in Edit Mode, select all the spine bones and duplicate (Shift + D) them. Press Esc to make them stay at the same location of the original chain, followed by Ctrl + Alt + S to make them fatter (to allow us to distinguish both chains). When in Pose Mode, these bones would also appear subdivided, which can make our view quite cluttered. Change back the Segments property of each bone to 1 and disable their deform property on the same panel under the Properties Window. Name these new bones as Spine1, Spine2, Spine3, Neck, and Head, go out of Edit Mode (Tab) and you should have something that looks similar to the next screenshot: Now let's create the appropriate constraints. Enter in Pose Mode (Ctrl + Tab), select the bone Spine1, hold Shift, and select D_Spine1. Press Shift + Ctrl + C to bring up the Constraints menu. Select the Copy Location constraint. This will make the deformation chain move when you move the Spine_1 bone. The Copy Location constraint here is added because there is no pelvic bone in this example, since it's creation involves a different approach which we'll see in the next recipe, Rigging the pelvis. With the pelvic bone below the first spinal bone, its location will drive the location of the rest of the chain, since it will be the chain's root bone. Thus, this constraint won't be needed with the addition of the pelvis. Make sure that you check out our next recipe, dedicated to creating the pelvic bone. With those bones still selected, bring up the Constraints menu again and select the Stretch To constraint. You'll see that the deformation chain will seem to disappear, but don't panic. Go to the Properties Panel, under the Bone Constraints tab and look for the Stretch To constraint you have just created. Change the value of the Head or Tail slider to 1, so the constraint would be evaluated considering the tip of the Spine_1 bone instead of its base. Things will look different now, but not yet correct. Press the Reset button to recalculate the constraints and make things look normal again. This constraint will cause the first deformation bone to be stretched when you scale (S) the Spine_1 bone. Try it and see the results. The following screenshot shows the constraint values: This constraint should be enough for stretching, and we may think it could replace the Copy Rotation constraint. That's not true, since the StretchTo constraint does not apply rotations on the bone's longitudinal Y axis. So, let's add a Copy Rotation constraint. On the 3D View, with the Spine1 and D_Spine1 selected (in that order, that's important!), press Ctrl + Shift + C and choose the Copy Rotation constraint. Since the two bones have the exact same size and position in 3D space, you don't need to change any of the constraint's settings. You should add the Stretch To and Copy Rotation constraints to the remaining controller bones exactly the same way you did with the D_Spine1 bone in steps 9 to 12. As the icing on the cake, disable the X and Z scaling transformation on the controller bones. Select each, go to the Transform Panel (N), and press the lock button near the X and Z sliders under Scale. Now, when you select any of these controller bones and press S, the scale is just applied on their Y axis, making the deforming ones stretch properly. Remember that the controller bones also work as expected when rotated (R). The next screenshot shows the locking applied: Enter into Edit Mode (Tab), select the Shoulder.L bone, hold Shift, and select both Shoulder.R and Spine3 (in this order; that's important). Press Ctrl + P and choose Keep Offset to make both shoulder controllers children of the Spine3 bone and disable its scale inheriting either through Shift + W or the Bone tab on the Properties panel. When you finish setting these constraints and applying the rig to the mesh through weight painting, you can achieve something stretchy, as you can see in the next screenshot: The file 002-SpineStretch-complete.blend has this complete recipe, for your reference in case of doubts. How it works... When creating spine rigs in Blender, there's no need to create lots of bones, since Blender allows us to logically subdivide each one to get soft and curved deformations. The amount of curved deformation can also be controlled through the Ease In and Ease Out sliders, and it also works well with stretching. When you scale a bone on its local Y axis in Pose Mode, it doesn't retain its volume, thus the mesh deformed by it would be scaled without the stretching feeling. You must create controller bones to act as targets to the Stretch To constraint, so when they're scaled, the constrained bones will stretch and deform the mesh with its volume preserved. There's more... You should notice that the spine controllers will be hidden inside the character's body when you turn off the armature's X-Ray property. Therefore, you need to create some custom shapes for these controller bones in order to make your rig more usable.
Read more
  • 0
  • 0
  • 3618

article-image-flash-development-android-audio-input-microphone
Packt
22 Jun 2011
4 min read
Save for later

Flash Development for Android: Audio Input via Microphone

Packt
22 Jun 2011
4 min read
  Flash Development for Android Cookbook Introduction Camera and microphone are standard accessories on most mobile devices and Android devices are no exception to this. In the previous article we dealt with Visual Input via Camera. The present article will cover encoding raw audio captured from the device microphone and encoding it to WAV or MP3 for use on other platforms and systems. All of the recipes in this article are represented as pure ActionScript 3 classes and are not dependent upon external libraries or the Flex framework. Therefore, we will be able to use these examples in any IDE we wish. The reader is advised to refer to the first recipe of Flash Development for Android: Visual Input via Camera for detecting microphone support. Using the device microphone to monitor audio sample data By monitoring the sample data being returned from the Android device microphone through the ActionScript Microphone API, we can gather much information about the sound being captured, and perform responses within our application. Such input can be used in utility applications, learning modules, and even games. How to do it... We will set up an event listener to respond to sample data reported through the Microphone API: First, import the following classes into your project: import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.SampleDataEvent; import flash.media.Microphone; import flash.text.TextField; import flash.text.TextFormat; Declare a TextField and TextFormat object pair to allow visible output upon the device. A Microphone object must also be declared for this example: private var mic:Microphone; private var traceField:TextField; private var traceFormat:TextFormat; We will now set up our TextField, apply a TextFormat, and add the TextField to the DisplayList. Here, we create a method to perform all of these actions for us: protected function setupTextField():void { traceFormat = new TextFormat(); traceFormat.bold = true; traceFormat.font = "_sans"; traceFormat.size = 44; traceFormat.align = "center"; traceFormat.color = 0x333333; traceField = new TextField(); traceField.defaultTextFormat = traceFormat; traceField.selectable = false; traceField.mouseEnabled = false; traceField.width = stage.stageWidth; traceField.height = stage.stageHeight; addChild(traceField); } Now, we must instantiate our Microphone object and set it up according to our needs and preferences with adjustments to codec, rate, silenceLevel, and so forth. Here we use setSilenceLevel() to determine what the minimum input level our application should consider to be "sound" and the rate property is set to 44, indicating that we will capture audio data at a rate of 44kHz. Setting the setLoopBack () property to false will keep the captured audio from being routed through the device speaker: protected function setupMic():void { mic = Microphone.getMicrophone(); mic.setSilenceLevel(0); mic.rate = 44; mic.setLoopBack(false); } Once we have instantiated our Microphone object, we can then register a variety of event listeners. In this example, we'll be monitoring audio sample data from the device microphone, so we will need to register our listener for the SampleDataEvent.SAMPLE_DATA constant: protected function registerListeners():void { mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicData); } As the Microphone API generates sample data from the Android device input, we can now respond to this in a number of ways, as we have access to information about the Microphone object itself, and more importantly, we have access to the sample bytes with which we can perform a number of advanced operations: public function onMicData(e:SampleDataEvent):void { traceField.text = ""; traceField.appendText("activityLevel: " + e.target.activityLevel + "n"); traceField.appendText("codec: " + e.target.codec + "n"); traceField.appendText("gain: " + e.target.gain + "n"); traceField.appendText("bytesAvailable: " + e.data.bytesAvailable + "n"); traceField.appendText("length: " + e.data.length + "n"); traceField.appendText("position: " + e.data.position + "n"); } The output will look something like this. The first three values are taken from the Microphone itself, the second three from Microphone sample data: How it works... When we instantiate a Microphone object and register a SampleDataEvent.SAMPLE_DATA event listener, we can easily monitor various properties of our Android device microphone and the associated sample data being gathered. We can then respond to that data in many ways. One example would be to move objects across the Stage based upon the Microphone.activityLevel property. Another example would be to write the sample data to a ByteArray for later analysis. What do all these properties mean? activityLevel: This is a measurement indicating the amount of sound being received codec: This indicates the codec being used: Nellymoser or Speex gain: This is an amount of boosting provided by the microphone to the sound signal bytesAvailable: This reveals the number of bytes from the present position until the end of our sample data byteArray length: Lets us know the total length of our sample data byteArray position: This is the current position, in bytes, within our sample data byteArray  
Read more
  • 0
  • 0
  • 4042
article-image-cryengine-3-terrain-sculpting
Packt
21 Jun 2011
11 min read
Save for later

CryENGINE 3: Terrain Sculpting

Packt
21 Jun 2011
11 min read
CryENGINE 3 Cookbook Over 100 recipes written by Crytek developers for creating AAA games using the technology that created Crysis 2 Creating a new level Before we can do anything with the gameplay of the project that you are creating, we first need a foundation of a new level for the player to stand on. This recipe will cover how to create a new level from scratch. Getting ready Before we begin, you must have Sandbox 3 open. How to do it... At any point, with Sandbox open, you may create a new level by following these steps: Click File (found in the top -left of the Sandbox's main toolbar). Click New. From here, you will see a new dialog screen that will prompt you for information on how you want to set up your level. The most important aspect of a level is naming it, as you will not be able to create a level without some sort of proper name for the level's directory and its .cry file. You may name your level anything you wish, but for the ease of instruction we shall refer to this level as My_Level: In the Level Name dialog box, type in My_Level. For the Terrain properties, use the following values: Use Custom Terrain Size: True Heightmap Resolution:512x512 Meters Per Unit: 1 Click OK. Depending on your system specifications, you may find that creating a new level will require anywhere from a few seconds to a couple of minutes. Once finished, the Viewport should display a clear blue sky with the dialog in your console reading the following three lines: Finished synchronous pre-cache of render meshes for 0 CGF's Finished pre-caching camera position (1024,1024,100) in 0.0 sec Spawn player for channel 1 This means that the new level was created successfully. How it works... Let's take a closer look at each of the options used while creating this new level. Using the Terrain option This option allows the developer to control whether to have any terrain on the level to be manipulated by a heightmap or not. Sometimes terrain can be expensive for levels and if any of your future levels contain only interiors or only placed objects for the player to navigate on, then setting this value to false will be a good choice for you and will save a tremendous amount of memory and aid in the performance of the level later on. Heightmap resolution This drop-down controls the resolution of the heightmap and the base size of the play area defined. The settings can range from the smallest resolution (128 x 128) all the way up to the largest supported resolution (8192 x 8192). Meters per unit If the Heightmap Resolution is looked at in terms of pixel size, then this dialog box can also be viewed as the Meters Per Pixel. This means that each pixel of the heightmap will be represented by these many meters. For example, if a heightmap's resolution has 4 Meters Per Unit (or Pixel), then each pixel on the generated heightmap will measure four meters in length and width on the level. Even though this Meters Per Unit can be used to increase the size of your level, it will decrease the fidelity of the heightmap. You will notice that attempting to smoothen out the terrain may be difficult as there will be a wider minimum triangle size set by this value. Terrain size This is the resulting size of the level with the equation of (Heightmap Resolution) x (Meters Per unit). Here are some examples of the results you will see (m = meters): (128x128) x 4m = 512x512m (512x512) x 16m = 8192x8192m (1024x1024) x 2m = 2048x2048m There's more... If you need to change your unit size after creating the map, you may change it by going into the Terrain Editor | Modify | Set Unit Size. This will allow you to change the original Meters Per Unit to the size you want it to be.   Generating a procedural terrain This recipe deals with the procedural generation of a terrain. Although never good enough for a final product because you will want to fine tune the heightmap to your specifications, these generated terrains are a great starting point for anyone new to creating levels or for anyone who needs to set up a test level with the Sandbox. Different heightmap seeds and a couple of tweaks to the height of the level and you can generate basic mountain ranges or islands quickly that are instantly ready to use. Getting ready Have My_Level open inside of Sandbox. How to do it... Up at the top-middle of the Sandbox main toolbar, you will find a menu selection called Terrain. From there you should see a list of options, but for now you will want to click on Edit Terrain. This opens the Terrain Editor window. The Terrain Editor window has a multitude of options that can be used to manipulate the heightmap in your level. But first we want to set up a basic generated heightmap for us to build a simple map with. Before we generate anything, we should first set the maximum height of the map to something more manageable. Follow these steps: Click Modify. Then click Set Max Height. Set your Max Terrain Height to 256 (these units are in meters). Now, we may be able to generate the terrain: Click Tools. Then click Generate Terrain. Modify the Variation (Random Base) to the value of 15. Click OK. After generating, you should be able to see a heightmap similar to the following screenshot: This is a good time to generate surface texture (File | Generate surface texture | OK), which allows you to see the heightmap with a basic texture in the Perspective View. How it works... The Maximum Height value is important as it governs the maximum height at which you can raise your terrain to. This does not mean that it is the maximum height of your level entirely, as you are still able to place objects well above this value. It is also important to note that if you import a grey scale heightmap into CryENGINE then this value will be used as the upper extreme of the heightmap (255,255,255 white) and the lower extreme will always be at 0 (0,0,0 black). Therefore the heightmap will be generated within 0 m height and the maximum height. Problems such as the following are a common occurrence: Tall spikes are everywhere on the map or there are massive mountains and steep slopes: Solution: Reduce the Maximum Height to a value that is more suited to the mountains and slopes you want The map is very flat and has no hills or anything from my heightmap: Solution: Increase the Maximum Height to a value that is suitable for making the hills you want There's more... Here are some other settings you might choose to use while generating the terrain. Terrain generation settings The following are the settings to generate a procedural terrain: Feature Size: This value handles the general height manipulations within the seed and the size of each mound within the seed. As the size of the feature depends greatly on rounded numbers it is easy to end up with a perfectly rounded island, therefore it is best to leave this value at 7.0. Bumpiness / Noise (Fade): Basically, this is a noise filter for the level. The greater the value, the more noise will appear on the heightmap. Detail (Passes): This value controls how detailed the slopes will become. By default, this value is very high to see the individual bumps on the slopes to give a better impression of a rougher surface. Reducing this value will decrease the amount of detail/roughness in the slopes seen. Variation: This controls the seed number used in the overall generation of the Terrain Heightmap. There are a total of 33 seeds ranging from 0 – 32 to choose from as a starting base for a basic heightmap. Blurring (Blur Passes): This is a Blur filter. The higher the amount, the smoother the slopes will be on your heightmap. Set Water Level: From the Terrain Editor window, you can adjust the water level from Modify | Set Water Level. This value changes the base height of the ocean level (in meters). Make Isle: This tool allows you to take the heightmap from your level and automatically lowers the border areas around the map to create an island. From the Terrain Editor window, select Modify | Make Isle.   Navigating a level with the Sandbox Camera The ability to intuitively navigate levels is a basic skill that all developers should be familiar with. Thankfully, this interface is quite intuitive to anyone who is already familiar with the WASD control scheme popular in most First Person Shooters Games developed on the PC. Getting ready You should have already opened a level from the CryENGINE 3 Software Development Kit content and seen a perspective viewport displaying the level. The window where you can see the level is called the Perspective Viewport window. It is used as the main window to view and navigate your level. This is where a large majority of your level will be created and common tasks such as object placement, terrain editing, and in-editor play testing will be performed. How to do it... The first step to interacting with the loaded level is to practice moving in the Perspective Viewport window. Sandbox is designed to be ergonomic for both left and right-handed users. In this example, we use the WASD control scheme, but the arrow keys are also supported for movement of the camera. Press W to move forwards. Then press S to move backwards. A is pressed to move or strafe left. Finally, D is pressed to move or strafe right. Now you have learned to move the camera on its main axes, it's time to adjust the rotation of the camera. When the viewport is the active window, hold down the right mouse button on your mouse and move the mouse pointer to turn the view. You can also hold down the middle mouse button and move the mouse pointer to pan the view. Roll the middle mouse button wheel to move the view forward or backward. Finally, you can hold down Shift to double the speed of the viewport movements. How it works... The Viewport allows for a huge diversity of views and layouts for you to view your level; the perspective view is just one of many. The perspective view is commonly used as it displays the output of the render engine. It also presents you a view of your level using the standard camera perspective, showing all level geometry, lighting, and effects. To experiment further with the viewport, note that it can also render subsystems and their toolsets such as flow graph, or character editor. There's more... You will likely want to adjust the movement speed and how to customize the viewport to your individual use. You can also split the viewport in multiple different views, which is discussed further. Viewport movement speed control The Speed input is used to increase or decrease the movement speed of all the movements you make in the main Perspective Viewport. The three buttons to the right of the Speed: inputs are quick links to the .1, 1, and 10 speeds. Under Views you can adjust the viewport to view different aspects of your level Top View, Front, and Left views will show their respective aspects of your level, consisting of bounding boxes and line-based helpers. It should be noted that geometry is not drawn. Map view shows an overhead map of your level with helper, terrain, and texture information pertaining to your level. Splitting the main viewport to several subviewports Individual users can customize the layout and set viewing options specific to their needs using the viewport menu accessed by right-clicking on the viewports header. The Layout Configuration window can be opened from the viewport header under Configure Layout. Once selected, you will be able to select one of the preset configurations to arrange the windows of the Sandbox editor into multiple viewport configurations. It should be recognized that in multiple viewport configurations some rendering effects may be disabled or performance may be reduced.  
Read more
  • 0
  • 0
  • 9207

article-image-flash-development-android-visual-input-camera
Packt
21 Jun 2011
7 min read
Save for later

Flash Development for Android: Visual Input via Camera

Packt
21 Jun 2011
7 min read
Camera and microphone are standard accessories on most mobile devices and Android devices are no exception to this. The present article will cover everything from accessing the camera and taking photos to recording video data. All of the recipes in this article are represented as pure ActionScript 3 classes and are not dependent upon external libraries or the Flex framework. Therefore, we will be able to use these examples in any IDE we wish. Detecting camera and microphone support in Android Nearly all Android devices come equipped with camera hardware for capturing still images and video. Many devices now have both front and rear-facing cameras. It is important to know whether the default device camera is usable through our application. We should never assume the availability of certain hardware items, no matter how prevalent across devices. Similarly, we will want to be sure to have access to the device microphone as well, when capturing video or audio data. How to do it... We will determine which audio and video APIs are available to us on our Android device: First, import the following classes into your project: import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.media.Camera; import flash.media.CameraUI; import flash.media.Microphone; import flash.text.TextField; import flash.text.TextFormat; Declare a TextField and TextFormat object pair to allow visible output upon the device: private var traceField:TextField; private var traceFormat:TextFormat; We will now set up our TextField, apply a TextFormat, and add the TextField to the DisplayList. Here, we create a method to perform all of these actions for us: protected function setupTextField():void { traceFormat = new TextFormat(); traceFormat.bold = true; traceFormat.font = "_sans"; traceFormat.size = 44; traceFormat.align = "center"; traceFormat.color = 0x333333; traceField = new TextField(); traceField.defaultTextFormat = traceFormat; traceField.selectable = false; traceField.mouseEnabled = false; traceField.width = stage.stageWidth; traceField.height = stage.stageHeight; addChild(traceField); } Now, we must check the isSupported property of each of these objects. We create a method here to perform this across all three and write results to a TextField: protected function checkCamera():void { traceField.appendText("Camera: " + Camera.isSupported + "n"); traceField.appendText("CameraUI: " + CameraUI.isSupported + "n"); traceField.appendText("Microphone: " + Microphone.isSupported + "n"); } We now know the capabilities of video and audio input for a particular device and can react accordingly: How it works... Each of these three classes has a property isSupported, which we may invoke at any time to verify support on a particular Android device. The traditional Camera and mobile-specific CameraUI both refer to the same hardware camera, but are entirely different classes for dealing with the interaction between Flash and the camera itself, as CameraUI relies upon the default device camera applications to do all the capturing, and Camera works exclusively within the Flash environment. The traditional Microphone object is also supported in this manner. There's more... It is important to note that even though many Android devices come equipped with more than one camera, only the primary camera (and microphone) will be exposed to our application. Support for multiple cameras and other sensors will likely be added to the platform as Android evolves. Using the traditional camera API to save a captured image When writing applications for the web through Flash player, or for a desktop with AIR, we have had access to the Camera class through ActionScript. This allows us to access different cameras attached to whatever machine we are using. On Android, we can still use the Camera class to access the default camera on the device and access the video stream it provides for all sorts of things. In this example, we will simply grab a still image from the Camera feed and save it to the Android CameraRoll. How to do it... We will construct a Video object to bind the Camera stream to, and use BitmapData methods to capture and then save our rendered image using the mobile CameraRoll API: At a minimum, we need to import the following classes into our project: import flash.display.BitmapData; import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.TouchEvent; import flash.media.Camera; import flash.media.CameraRoll; import flash.media.Video; import flash.ui.Multitouch; import flash.ui.MultitouchInputMode; Now we must declare the object instances necessary for camera access and file reference: private var video:Video; private var camera:Camera; private var capture:BitmapData; private var cameraRoll:CameraRoll; private var videoHolder:Sprite; Initialize a Video object, passing in the desired width and height, and add it to the DisplayList: protected function setupVideo():void { videoHolder = new Sprite(); videoHolder.x = stage.stageWidth/2; videoHolder.y = stage.stageHeight/2; video = new Video(360, 480); videoHolder.addChild(video); video.x = -180; video.y = -240; videoHolder.rotation = 90; addChild(videoHolder); } Initialize a Camera object and employ setMode to specify width, height, and frames per second before attaching the Camera to our Video on the DisplayList: protected function setupCamera():void { camera = Camera.getCamera(); camera.setMode(480, 360, 24); video.attachCamera(camera); } We will now register a TouchEvent listener of type TOUCH_TAP to the Stage. This will enable the user to take a snapshot of the camera display by tapping the device screen: protected function registerListeners():void { Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; stage.addEventListener(TouchEvent.TOUCH_TAP, saveImage); } To capture an image from the camera feed, we will initialize our BitmapData object, matching the width and height of our Video object, and employ the draw method to translate the Video pixels to BitmapData. To save our acquired image to the device, we must initialize a CameraRoll object and invoke addBitmapData(), passing in the BitmapData object we have created using Video object pixels. We will also determine whether or not this device supports the addBitmapData() method by verifying CameraRoll. supportsAddBitmapData is equal to true: protected function saveImage(e:TouchEvent):void { capture = new BitmapData(360, 480); capture.draw(video); cameraRoll = new CameraRoll(); if(CameraRoll.supportsAddBitmapData){ cameraRoll.addBitmapData(capture); } } If we now check our Android Gallery, we will find the saved image: How it works... Most of this is performed exactly as it would be with normal Flash Platform development on the desktop. Attach a Camera to a Video, add the Video to the DisplayList, and then do whatever you need for your particular application. In this case, we simply capture what is displayed as BitmapData. The CameraRoll class, however, is specific to mobile application development as it will always refer to the directory upon which the device camera stores the photographs it produces. If you want to save these images within a different directory, we could use a File or FileReference object to do so, but this involves more steps for the user. Note that while using the Camera class, the hardware orientation of the camera is landscape. We can deal with this by either restricting the application to landscape mode, or through rotations and additional manipulation as we've performed in our example class. We've applied a 90 degree rotation to the image in this case using videoHolder.rotation to account for this shift when reading in the BitmapData. Depending on how any specific application handles this, it may not be necessary to do so. There's more... Other use cases for the traditional Camera object are things such as sending a video stream to Flash Media Server for live broadcast, augmented reality applications, or real-time peer to peer chat.
Read more
  • 0
  • 0
  • 4143
Modal Close icon
Modal Close icon