-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathLesson-03.html
161 lines (129 loc) · 8.74 KB
/
Lesson-03.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
<script type="text/javascript" src="js/pageToc.js"></script>
<script type="text/javascript" src="js/sh/scripts/shCore.js"></script>
<script type="text/javascript" src="js/sh/scripts/shBrushJScript.js"></script>
<script type="text/javascript" src="js/sh/scripts/shBrushPhp.js"></script>
<script type="text/javascript" src="js/sh/scripts/shBrushPlain.js"></script>
<script type="text/javascript" src="js/sh/scripts/shBrushXml.js"></script>
<link type="text/css" rel="stylesheet" href="js/sh/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="js/sh/styles/shThemeDefault.css"/>
<script type="text/javascript">
SyntaxHighlighter.config.clipboardSwf = 'js/sh/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<title>PushButton Engine Lesson #3: Adding Control with a Custom Component</title>
</head>
<body>
<h1>PushButton Engine Lesson #3: Adding Control with a Custom Component</h1>
<p><center><em>"If you don't control your mind, someone else will."</em> - John Allston</center></p>
<p>The goal of this lesson is to guide the user through adding a custom component to move a simple shape around the screen.</p>
<p>These lessons are structured in a series of steps -- small milestones that will provide focused short-term goals for incrementally understanding PushButton Engine.</p>
<p>These lessons are targeted at someone who is new to PBEngine, but not necessarily new to programming.</p>
<div id="pageToc"></div>
<div id="contentArea">
<h2>Tutorial Resources:</h2>
<p>To follow along with the tutorial, you can download the starter project and use it as your base to implement the tutorial:
<ul>
<li><a href="downloads/Lesson3Base.zip">Lesson3Base.zip</a> (2KB)</li>
</ul>
The completed lesson files are available at the end of the tutorial.
</p>
<p>As covered in Lesson 1, extract the example .zip into a personal project folder, and ensure that it builds in your build environment.</p>
<p>The built .swf of the base starter project should display a blue circle in the upper left corner of the screen.</p>
<h2>Introduction to the Tutorial</h2>
<p><img src="images/Lesson3_Coordinates.png" alt="World Coordinates Diagram" align="right"></a></p>
<p>One of the strengths of PushButton Engine lies in the flexible way that components add functionality to a game. In this tutorial, we will make a relatively simple movement component. Later tutorials will deal with user input and handling collisions, but this lesson will keep things relatively basic.</p>
<p>The starter project for this lesson is <em>very close</em> to the previous lesson, except that the ball now spawns in the upper left corner of the screen. The location for the ball is (-375,-275). The reason for the odd number is to place the ball at half of its radius (25) from the edge of the screen, to be perfectly in the corner. You can refer to the diagram for an overview of this example's screen coordinates.</p>
<h2>Building a Component</h2>
<p>As in the previous example, we will set up a basic scene. Our Hero component will have three components: a render component, a spatial component, and a controller component (the new DemoControllerComponent).</p>
<p>This new controller component will make our entity move in a zig-zag fashion down the screen, similar to an Invaders enemy.</p>
<p>To build our new component, we must create a class for it. To get basic component features, you must inherit from one of the base component classes. For the type of component that we want in this example, we will inherit from TickedComponent. Components that descend from TickedComponent get their onTick() method called 30 times per second. This makes it a logical place to put movement logic.</p>
<p>So every 33 milliseconds, the onTick() method of the controller component is called. This method handles the housekeeping for checking boundaries, and moving the parent entity. It looks at the position of the parent entity (gotten from the spatial component), and then applies some rules to create some simple movement behavior:</p>
<p>
<ul>
<li>If we are on the left edge:
<ul>
<li>Turn to the right</li>
<li>Move down a notch</li>
</ul>
</li>
<li>If we are on the right edge:
<ul>
<li>Turn to the left</li>
<li>Move down a notch</li>
</ul>
</li>
<li>Move in the direction that we're heading</li>
</ul>
</p>
<p>Now that we know the basic plan, let's put it into action! Create a new source file in the project's source directory with the name DemoControllerComponent.as, and use the following code listing for the file:</p>
<p><strong>File: /Lesson3Base/Source/DemoControllerComponent.as</strong></p>
<pre class="brush: js">
package
{
import com.pblabs.engine.components.TickedComponent;
import com.pblabs.engine.entity.PropertyReference;
import flash.geom.Point;
// Make a ticked component so that it can update itself every frame with onTick()
public class DemoControllerComponent extends TickedComponent
{
// Keep a property reference to our entity's position.
public var positionReference:PropertyReference;
// Store the direction that our entity is traveling: 1 is to the right, -1 is to the left.
private var direction:int = 1;
// onTick() is called every frame
public override function onTick(tickRate:Number):void
{
// Copy the owner entity's position into a local Point structure
var position:Point = owner.getProperty(positionReference);
// If we are over the left edge...
if (position.x < -375) {
// ...then push ourselves to the right for the time being.
direction = 1;
// Move our entity down a notch
position.y += 20;
}
// If we are over the right edge...
else if (position.x > 375) {
// ...then push ourselves to the left for the time being.
direction = -1;
// Move our entity down a notch
position.y += 20;
}
// Move 5 units in the direction that we're headed
position.x += direction * 5;
// Set the spatial component's position based on our new value
owner.setProperty(positionReference, position);
}
}
}
</pre>
<h2>Connecting the Dots</h2>
<p>Now that we've created our component, it's time to add it into our game! We will add this component to our Hero entity in the same way that we added the other components in Lesson 2.</p>
<p>At the bottom of createHero(), after the last call to hero.AddComponent(), add the following lines:</p>
<p><strong>File: /Lesson3Base/Source/Lesson3Base.as</strong></p>
<pre class="brush: js">
var controller:DemoControllerComponent = new DemoControllerComponent();
// Point the controller component to this entity's Spatial component for position information
controller.positionReference = new PropertyReference("@Spatial.position");
// Add the demo controller component to the Hero entity with the name "Controller"
hero.addComponent( controller, "Controller" );
</pre>
<p>This creates an instance of the new DemoControllerComponent(), connects the position reference to the entity's spatial component, and adds the component to the entity.</p>
<p>And that's it! Only thing left now is to compile and run.</p>
<h2>Seeing it in action.</h2>
<p>After compilation, you should produce a .swf like the following (click to load):</p>
<p><a href="downloads/Lesson3Final.swf"><img src="images/Lesson3_1.png" width="204" height="159" alt="Our shiny circle!"></a></p>
<h2>Conclusion</h2>
<p>Congratulations! You have finished lesson #3, made your first custom component, and seen it in action.</p>
<p>You can download the completed project source files for this project.
<ul>
<li><a href="downloads/Lesson3Final.zip">Lesson3Final.zip</a> (3KB)</li>
</ul>
</p>
</div>
</body>
</html>