The Process

Comments

Transcription

The Process
TANKER
Flash Game Design with ActionScript 3.0
by Xai Lao
Introduction
Tanker is a 2D single player flash game demo coded in
ActionScript 3.0. The gamepaly in terms of movement is based around
a floor-tile-layout system. In other words, the player is able to only
move the hero character accordingly to floor tiles shown on each level.
To give a better idea of the game, Tanker is not a Mario game in which
a player can pick up and learn how to play in seconds. Unlike Mario
where movement plays a lot with physics, the movement in Tanker is
more similar to the classic “Frogger game” (Fig 1.0). A player uses the
four arrow keys on the keyboard to move the hero avatar (Fig 1.1). In
Tanker, a player may only move up, down, left, and right. And unlike
Mario, where the player can defeat enemies by jumping on top of
them, Tanker requires the player to carefully time and press the attack
button to deplete an enemy’s health points down to zero at a rate that
constantly changes from enemy to enemy. The details of how health
points work and how to defeat an enemy in Tanker will later be explain.
Fig 1.1
Frog
Fig 1.0
But before I explain about my game any further, I want to first
get the reader familiarize with Role Playing Games (RPG) and what they
are because Tanker is influenced by the RPG style. In a typical RPG, a
player will be role-playing a game avatar or hero that mimics real life
in a way. The hero has health points to be aware of as it will usually
determine whether the game should continue or not. The hero also
has clothes or gears it can wear and which when worn, will increase/
decrease defense armor. The armor plays a role in reducing incoming
damages from enemy attacks. Furthermore, the hero has some sort of
weapon, like a sword, club, or knife to wield with. Without a weapon,
the hero would not be able to attack and even if the hero can attack
without a weapon, the game would be quite boring if a player could only
attack by relying on hero’s bare hands throughout the entire game. So
this is why in RPG games, a game hero needs to carry a weapon and
make use of its power to help the player attack.
Then there are enemies the hero has to engage epic battles with
in a RPG game. Without enemies to fight, the game would be pointless
when there is a hero that carries a weapon. RPG games does not end
there. Each enemy also carries a certain amount of health points that a
player needs to deplete in order to defeat or kill it. If the term “health
points” is still confusing, think of simple mathematics. RPGs use a lot
of point adding and subtracting which require a player to understand
basic math in order to understand how the point system works. Of
course however, different RPG games will use different formulas to
calculate health points and such.
Here is a simple mathematic
scenario (Fig 1.2) that is apply in
most RPGs. A hero has 50 health
points. If the hero gets attack by an
enemy and takes in 25 damage, the
hero will now have 25 health points
Fig 1.2
remaining. If the hero were to take
another incoming 26 damage from
an enemy, the hero would now have -1 health points. The game would
end as soon as the health point reaches 0 or less than 0.
The above scenario works with enemies as well too. Each enemy
has its own health points and when the hero depletes an enemy’s health
points to zero, the hero defeats the enemy. And upon a successful
enemy defeat or kill, the enemy will randomly drop an item, which
the hero can then keep and put it into its inventory to use later on
as the hero progresses further through the game. This explains the
complexity of RPG games and that is why games like these become a
challenge to learn if you want to enjoy RPGs. Furthermore in most RPG
games, a player is given a game avatar to journey throughout the game
world while interacting with computer controlled characters. While a
player journeys across the game world, a player will often come across
random missions or game story missions that connects to the game’s
main storyline. And when that happens the player would simply take
on the missions by accepting it. Whether the missions ask the player to
find something, to deliver an item, or to defeat a foe, upon a mission’s
success the player is awarded with gold or some type of money to be
used with the game’s monetary system. Players may even be awarded
a type of item or weapon, which that can be equip onto their game
avatar to help them advance further into the game.
The above explainations almost matches how Tanker works
and is why my game falls under one of the “hard fun” genre as defined
by Nicole Lazarro that would require a little patience before a player
can really start to enjoy all the aspects the game offers. Tanker would
not fit for a player who only wants to play games like Mario. Although
I’m not saying Tanker isn’t a fast pace game, it actually is once you
learn the basics of a typical RPG. Tanker is also similar in a way to
one of today’s modern Massive Multiplayer Online Role Playing Games
(MMORPG) like World of Warcraft, Star Craft, Final Fantasy XI (Fig 2.0),
or Diablo due to the similar attributes my game incorporates. MMORPG
games usually can take players anywhere from months or to even
years to beat. Sometimes an RPG game is never won but instead the
storyline ends and the player is welcome to continue and explore the
world until they are satisfy. The big difference between the mentioned
MMORPG games and my Tanker game is that it is just a single player
RPG game and can be completed within a 30-minute timeframe at the
max. The reason I’ve decided to keep the game short is because I will
be building a demo version rather than a fully developed RPG game.
The main reason why I’ve brought up MMOPRG is because my game will
incorporate some attributes and game-play-styles from MMORPG such
as health points, attack power, attack speed, weapon, and etc.
This is why I believe RPG games can be challenging but at the
same time fun to play once you get the hang of it. The whole RPG
concept about combats stytems, selling/buying items, equipping items;
and the list can go on forever, are what that inspired me to create this
game. Although RPG game styles are more complicated to play for
newcomers, most people have come to love RPGs after understanding
the game flow.
Fig 2.0
MMORPG Highlights
Common Functions
- Over 1000 players per
individual game server
- Many game servers
- Spawning Enemy
- Day & Night Time
- Team/Party Battles
Intensive Attribtues
- Gears/Armor/Clothes
- Defense Armor Points
- Weapons
- Elemental Attack Status
- Different Class/Race
- Human, Eleves, Orcs
- Health & Magic Bar
The images sources are from
http://ffxi.allakhazam.com
Pre-initial Game Plans and Ideas
Before I began the journey to create and program this game, I
was forced to really think about my experiences and capabilities. I knew
I had experience with Flash and was quite familiar with actionscript
3.0. But what I didn’t have much knowledge in was the fact that I
didn’t know much about game development, especially when it comes
to professional game development. However I do not have intentions
to compare my game against games like Call of Duty, Mario, or World
of Warcraft. I am aware that professional games have many people
working together as a team. Although knowing most of the time I will
be working alone, I didn’t want this to stop me from creating a RPG
game in flash using actionscript 3.0 due to my passion to learn.
With all that being said, I am not going to be making a full
functioning RPG game that will have a complete storyline with zero
technical issues. Although it will try to have some kind of a story,
the story will be brief and broad just so that I can program my game
around a story. Again with the amount of teamwork I have, my initial
plans will be to create a short demo rather than a full version. The
demo version will still try to incorporate as much elements from an RPG
game as possible and in doing so I want to challenge myself as much
as I can.
Attributes I want to incorporate into the game are health points,
energy points, attack power, speed attack, and gold. Although not every
attribute will be fully implemented I will try my best to include them so
users can get a better grasp at the idea of my game. Health points will
play against the player determining if a hero/enemy has been defeated
or not. Energy points will allow a player to unleash special attacks that
will do more damage then normal attacks. Attack power serves as
the damage point that will be dealt to either the hero or the enemy to
deplete health points. Speed attack serves for the purpose of how fast
a game character can attack during battle. Without speed attack in the
game, each player or enemy would be able to spam attacks which would
ruin the game. Then lastly I want to incorporate gold as the foundation
of keeping track of the player’s score points. Gold can be looked at as
an achievement earned by the player throughout the game.
Other functions I will want to include will be text dialogues.
These text will be loaded from an external XML data file in flash as it
will be easier to correct and add changes to. I also want to be able to
load external fonts and use them rather than embedding fonts straight
into the flash game file. The game will evolve around my own flash
game engine as I will at the same time create from scratch as I program
the game.
Since I will want many elements to be random into the scene,
such as floor tiles, enemies, points, and etc., I will depend on the
flash’s random script function with some minor modifications. As for
graphics for my hero, enemies, and backgrounds, I will plan to import
the graphics straight into flash file since I know I probably won’t be
having a lot of characters in the game.
Equipping and switching items is one of the main things I will
want to explore and implement in this game. I want the user to be
able to find a weapon by defeating an enemy or monster and equip the
weapon. The weapon should help the user become strong as it attack
stronger enemies with larger health points.
Although I have many things I want to incorporate into the
game, I know I will probably have time to implement so many, but these
will be the main ideas I want to implement first before implementing
anything additional to the game.
Tanker - Story Synopsis
Tanker is a warrior who has just returned from a long journey.
The hero comes back home to find only that his village is in chaos. Not
only is his village being overthrown by some evil force, but eventually
finds out his entire world is at stake too. If nothing is done this will
be the last of his world. The hero will then be led by a Shine Guardian
who communicates to the hero through telepathy. The Shine Guardian
is one of the last survivors to survive the village attack. The Shine
Guardian will serve as the guide to the player and explain how the
game works. Tanker’s job is go find whoever is causing this chaos in
his village and stop it before it is too late. When the game ends, the
player will learn more of the secrets behind the story line such as that
the Hero’s name is actually Faith. Tanker is actually a title given to high
class warriors whom have completed difficult missions.
Characters
Character designs by
Nou Chee Her
Bomblister
A dark green creature that lives inside a golden shell. They can
spit red acid to its prey disabling vision temporarily if caught in the
eyes. Though slow, they bring disaster to an oponent if is engaged in
battle (see Appendix A.3).
Psycho Sensei
These little creatures have a strange behavior. They constantly
gaggle noises and walk in funny patterns. When engaged in battly,
they become furiuos little foes that go beserk.
Tanker
A young warrior who seeks to find the truth and destroy all
evil. He lives in a small village call Shamals hidden within two large
mountains. He doesn’t speak much but rather tends to get straight to
the point in conversations.
Tuskom
These powerful beast can do serious damage with a single blow
from their horns. They are easily provoked and when mad will confront
their oponent with a ragging stempede force. They are known to travel
in herds of 200 or more at a time.
Mad Bunny
A These creatures come out at night to hunt. Their red eyes
glow and helps them see in the dark. Although they are not strong
creatures, they are quick and fast.
Squwi
Although little, they can easily navigate around their oponent
with ease by bouncing with maximum precision and speed. They are
usually found in the day time around tall grasses.
Breathom
These are one of the most feared creatures. Anyone who
contacts with these should avoid being seen. They have a form of a
dragon but are without wings. It is believe they are part of the evil act
that is causing chaos throughout the world.
There is currently a total of six
enemies in Tanker, however not
all the characters will be seen in
the game for demo purposes.
Character Setup In Flash
Each character is made up of three or more frames that were
created in flash. The purpose of having three frames per character is to
simulate the attack phase during combat in the game. Fig 3.0 shows
how the layers were set up in Flash for the hero. Fig 3.1 shows the layer
setup for the enemies.
Fig 3.0
Fig 3.1
Collision Detection
The collision detection I decided to go with is a hidden point
detection. Each object in the game that will be used for collision will
have an invisible square with a opacity of 0%. This invisible square will
be used to detect if it is hitting another invisible square.
The Main Actionscript Classes
TankerEngine.as - The engine is built for a decent performance.
This means modification can be easily done to some extent without
having to re-write or delete an entire code. In other words, the engine
is dynamic and flexible. The Tanker engine is written in actionscript
3.0. It is the main class file that is called in the beginning of the game
during startup. The engine will load all fonts, graphics, classes at
game assets. The engine has one EnterFrame function that runs every
movement in the game such as characters movements down to a ticking
clock timer (see Appendix A28.0).
TankerPreloader.as - The pre-loader helps load all necessary
items before the game can load itself. It basically calls all the classes
and prepares them for the game (see Appendix A30.0).
TankerStartMenu.as - Once the pre-loader is done loading, the
start menu loads and displays a simple graphic interface for the player
to click start to play the game (see Appendix 31.0).
Hero.as - The hero class controls the main hero in the game.
It provides the foundation of how the hero can move and what it can
interact with (see Appendix A14.0).
M0001.as - The monster classes are name coded so that
future monsters can be easily incorporated into the game engine when
creating new monsters. The idea is to name all monster classes in this
manner: M0001, M0002, ..., M0023, and so on rather than naming the
each monster class by the monster’s name. This is purposely for good
programming practices (see Appendix A4.0).
W0001.as - The weapon classes are name coded so that
future weapons can be easily incorporated into the game engine when
creating new weapons. The idea is to name all weapon classes in this
manner: W0001, W0002, ..., W0101, and so on rather than naming the
each weapon class by the weapon’s name. This is purposely for good
programming practices (see Appendix A33.0).
HelpMenu.as - The help menu is available for the player at the
top right of the game screen. It describes the game play and will give
the player information on the attributes in the game (see Appendix
A13.0).
IFStat.as - The stat interface will be located on the left side of
the screen and give the player real-time updates on their stats. It will
display health points, equipment, and weapon stats to the player (see
Appendix A16).
IFStatEquip.as - The equipment interface will display the player’s
current items/weapons that they have collected from defeating foes.
The player is allow to browse through the equipment slots and equip
whatever is selected (see Appendix A17.0).
There is a total of over 50
actionscript classes in Tanker.
Start Menu
The start menu has simply one button that allows the player to
start the game once they click on the “Start” button.
Starting The Game
Once the game has started, the game interface will open. On
the left side, there are the stats information about the player. On the
right is the game stage that the player can move around in and is where
enemies will randomly spawn.
The Help Menu
The help menu is design to help players understand the game.
It is located in the upper right hand corner of the screen.
The Dialogue Box
The dialogue box will pop up every so often to help guide the
player in the game on what to do. It plays as a major role in the game
to display game character dialogues.
The RPG Battle System
When the player attacks an enemy, numbers will come flying
above the enemy and will dissapear after a few seconds. These
numbers indicate the amount of damage that the hero is dealing to
the enemy. The stronger the weapon the player has equip, the higher
these damage numbers will increase. In other words, strong weapons
will make defeating enemies easier.
Once the player starts attacking an enemy, enemies will start to
attack back. Each enemy carries a speed attack bar just like the hero
on its right side. Each attack will deplete the speed attack bar and
will automatically fill up gradually depending on their speed recovery
stats of the enemy. When this bar fills up, the enemy is allow to attack
the player again. This attacking process will repeat until the enemy is
either killed or the player disengages in battle. A player can run away
from battle moving to the another floor tile where there is no enemy
occupying it.
The battle system works similar to other RPGs. In order to
initiate an attack, the player must move into an enemy’s location. Once
inside, the player will have to continuously press the attack button to
attack an enemy. Players will only be able to attack when the attack
speed bar fills up (indicated by the blue bar on the left of the hero. This
is to prevent spaming and will make the game more challenging. The
green bar on the right indicates the enemy’s health points. Once the
health point is depleted, then the enemy will be consider destroyed and
the player will automatically recieve gold and if lucky an item, which is
base off a random math expression.
Battle Close Up View
How A Player Can Get Better
Speed: Fast
Strength: Easy
Speed: Slow
Strength: Medium
Speed: Slow
Strength: Medium
Speed: Slow
Strength: Hard
Speed: Fast
Strength: Hard
Speed: Slow
Strength: Hard
Learning how to analyze each
enemy is the key to winning
Gold
Gold is the score a player gets each them they defeat an enemy.
The amount of gold depends on the type and difficulty of the enemy.
The future plan is to use gold for buying and selling items in the game
monetary system.
Health
Health is the player’s life bar. When it reaches zero the player
will be penalize. The little scouts that wander the plain will come take
away the player if their life bar depletes. In other words, the game
demo will end.
Energy
Energy is the player’s extra power. Each time the player moves
across a floor tile, they will collect the indicated amount of energy on
that specific tile. When the player has collect enough and their energy
fills up, they can unleash a powerful attack that does more damage
then your normal attack.
Attack
Attack is the player’s attack power. The strong attack power,
the faster the player can take down an enemy. If the hero is equipped
with a weapon, their attack will be modify. Take advantage of equiping
weapons whenever possible. There are two numbers that represents
a player’s attack power. Each attack to the eneymy will be randomed
between the two numbers. So every attack may have a different damage.
Atk Spd
ATK SPD is short for attack speed. This is a number in
miliseconds. The higher the number, the longer the interval between
each attack. It controls the rate at which the player can attack.
Item Sack
The item sack holds all the items that drop from defeated
enemies. A player can only carry 6 items at a time. Future update will
allow players to switch items around in the sack and also delete items
so new items can be collected. The item slot allows a player to toggle
around their items and read the effects an item has.
Item Numbers
Each item or weapon has a level number. The upper left hand
corner of an item is where the level number is located. There is a
maximum of 3 levels, [0-3]. The higher the level the stronger the item.
For example if two weapons of the same name is obtained and one is
level 0 while the other is level 3, the level 3 weapon will have a higher
attack power.
Summary
Creating simple games flash has been a hobby of mine since I
picked up actionscript 3.0. I wanted to create a flash game and put it
on the web for others to play and enjoy. However, the more I got into
programing flash games, the more I realize I would have to have a team
of two or more, especially if I’m going to tackle an RPG game style.
Through out my process of creating Tanker from scratch, I have learned
a lot about actionscript 3.0 and have improve my understanding of
creating flash games.
It didn’t take long to notice that in order to run a complex game,
I was going to need a game engine. But I didn’t know how complex my
game was going to be so I decided not to go with a pre-existing game
engine created by others. Instead I created my own game engine,
specifically just for Tanker. I coded the engine from scratch following
basic tutorials on lynda.com and flash forum sites. I got help mostly
from the online flash forum sites however.
Fortunately, I already learned java and c++ programming skills
from my other computer science classes. Without those classes, I don’t
think I would have been able to create the Tanker game demo. By
the time I figure I was close to finishing the game demo, I realized I
have already wrote over 50 classes. I was surprise I wrote all of those
classes by myself, but of course with a little help here and there from
the online flash forum sites.
I was also able to incorporate programing methods such as
polymorphism and creating interface classes in my game as well. I
am really grateful I took the time grasp these concepts well during
my computer science classes. Without these methods, I wouldn’t
have been able to make my enemy classes inherit attributes from preexisting ones and would have ended up with a lot more complicated
unorganized classes.
The more I coded, I started to appreciate math, algorithms,
and expressions. I used a lot of these to generate things such as the
random spawning, drop rate percentage of each enemy, and much
more. I believe the more random a game is, the more exciting it’ll be
for the players. If everything is too linear the game would be boring
and was why I tried to incorporate a random game environment for the
players.
Although I ran out of time to incorporate everything I was
planning to, I will definitely finish up this game demo with the things
I’ve planned. Because what makes an RPG game fun is the way how it
tries to mimic real life in a way. There are so much things I could’ve
included but I could only do so much. Therefore when creating
complex games, teamwork and a smooth system workflow between
team members is the key.
Overall, I enjoyed the challenge of learning actionscript 3.0 and
programming an RPG game. The experience has definitely uplifted my
coding and programing abilities. I’ve gained a higher respect for all
programers who codes day to day to invent games for the public. In
the future I wouldn’t mind programing another game like this, but one
thing for sure is that I would make sure I have a bigger team to work
with.
The game can be played at
www.xaiLao.com/tanker.php
However, the game is only available
for a time period.
Credits
Game Design Programmer
Xai Lao
Character and Game Design Artist
Nou Chee Her
UW-Stout Faculty Advisor
Uttam Kokil
APPENDIX
Appendix A1.0
Clock.as
package com.Lao.tanker {
/*
created by Xai Lao - free to use and modify
This is a clock dependent on the game’s main enterframe
You must change the gameFrameRate variable to match your game’s
FPS for this clock to be accurate
*/
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.Event;
public class Clock extends ClockWeekend {
private var hr:int=0, min:int=0, sec:int=0;
private var tHr:String=”00”, tMin:String=”00”,
tSec:String=”00”;
private var MAXHR:int = 23, MAXMIN:int = 59, MAXSEC:int =
59;
private var amPm:String = “AM”;
// CHANGE gameFrameRate to match your game’s fps
private var gameFrameRate:int = 30;
private var counter:int;
private var tTxt:TextField = new TextField();
private var f:TextFormat = new TextFormat();
private var tColor:uint = 0xffffff;
public function Clock(h:int, m:int, s:int, fr:int,
startDay:int, rand:Boolean) {
super(startDay, rand);
// if rand is true,
super will generate the startDay, else startDay will be use
hr = h; min = m; sec = s;
gameFrameRate = fr;
addEventListener(Event.ADDED_TO_STAGE, loadClock );
}
// initial values and displays
private function loadClock(e:Event){
f.size = 16;
f.color = tColor;
tTxt.defaultTextFormat = f;
tTxt.border = false;
tTxt.selectable = false;
tTxt.width = 120;
tTxt.height = 20;
tTxt.text = “00:00:00 am”;
addChild(tTxt)
removeEventListener(Event.ADDED_TO_STAGE, loadClock
Appendix
);
}
// The main enterframe should call this
public function updateClock(){
counter++;
if(counter%gameFrameRate == 0){
sec++; // increment sec every time the last max FPS is hit
if(sec > MAXSEC){
// reset sec and increment min
min++;
sec = 0;
}
if(min > MAXMIN){
// reset min and increment hr
hr++;
min = 0;
}
if(hr > MAXHR){
// reset hr base on a 24 hour clock
hr = 0;
changeDay();
}
// modify the sec, min, hr if they are below 10
// mod sec
if(sec < 10){
tSec = “0”+ sec;
}else{
tSec = String(sec);
}
// mod min
if(min < 10){
tMin = “0”+ min;
}else{
tMin= String(min);
}
// mod hr
if(hr < 10){
tHr = “0”+ hr;
}else{
tHr = String(hr);
}
// AM PM
if(hr < 13){
amPm = “AM”;
}else{
amPm = “PM”;
}
Appendix A1.1
Clock.as
// ----- end of modification
// display the current time
tTxt.text = “”+tHr + “:” + tMin + “:” +
tSec + “ “+ amPm;
counter = 0;
}
}
// getters
public function getTime():String{
return tTxt.text;
}
public function getHr():int{
return hr;
}
public function getMin():int{
return min;
}
public function getSec():int{
return sec;
}
}
}
Appendix
Appendix A2.0
Clock2.as
package com.Lao.tanker {
/*
created by Xai Lao - free to use and modify
This is a clock2 dependent on the game’s main enterframe
This clock extrends ClockWeekend if you want the weekend name otherwise this class can extends Sprite instead
Clock2 is a modify version of Clock.as. For game time purposes a
real time clock would be too slow.
So Clock 2 makes every sec a minute and every minute an hour.
If you want a real time 24 hr clock with sec, use Clock1.as
Other objects can use this class to check:
- getDayTime:Boolean --> isDayTime
- getTime
- getHr
- getMin
*/
import flash.display.Sprite;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.Event;
public class Clock2 extends ClockWeekend {
private var hr:int=0, min:int=0;
private var tHr:String=”00”, tMin:String=”00”;
private var MAXHR:int = 23, MAXMIN:int = 59;
private var amPm:String = “AM”;
// controls graphic
// at 6 and until 18, game is consider daylight time
// these two numbers control the graphic if moon should
appear or sun
private var dayTimeStart:int = 6, dayTimeEnd:int = 18;
private var dayTimeCounter:int = 0; // when dayTimeCounter hits dayTimeStart or dayTimeEnd MINUS 1, then turns on canCreateSunMoon
private var canCreateSunMoon:Boolean = true;
public var isDayTime:Boolean = true;
// make sure you crate this class passing the correct game
framerate of your game
private var gameFrameRate:int = 24;
private var counter:int;
private var tTxt:TextField;
private var f:TextFormat;
private var tColor:uint = 0xffffff;
Appendix
public function Clock2(h:int, m:int, fr:int, startDay:int,
rand:Boolean) {
// hour, min, frameRate
super(startDay, rand);
hr = h; min = m;
gameFrameRate = fr;
addEventListener(Event.ADDED_TO_STAGE, loadClock );
}
// initial values and displays
private function loadClock(e:Event){
tTxt = new TextField();
f = new TextFormat(“Segoeb”);
f.size = 16;
f.color = tColor;
tTxt.defaultTextFormat = f;
tTxt.embedFonts = true;
tTxt.border = false;
tTxt.selectable = false;
tTxt.width = 120;
tTxt.height = 20;
tTxt.x = 50;
addChild(tTxt)
var s:Sprite = new Sprite();
C_Holder.push(s);
// index 1
C_Holder[1].x = tTxt.width + 40;
C_Holder[1].y = 5;
addChild(s);
//createMoon(false);
removeEventListener(Event.ADDED_TO_STAGE, loadClock);
}
private function createMoon(moon:Boolean){
if(moon){
C_Holder[1].graphics.clear();
C_Holder[1].graphics.lineStyle(1, 0x00ccff);
C_Holder[1].graphics.beginFill(0xffffff);
C_Holder[1].graphics.lineTo(0,0);
C_Holder[1].graphics.curveTo(10,10, 0, 15);
C_Holder[1].graphics.curveTo(5, 10, 0, 0);
C_Holder[1].graphics.endFill();
}else{
C_Holder[1].graphics.clear();
C_Holder[1].graphics.lineStyle(2,
0xffffff);
C_Holder[1].graphics.beginFill(0xffff00);
C_Holder[1].graphics.drawCircle(0,8, 8);
C_Holder[1].graphics.endFill();
}
Appendix A2.1
Clock2.as
}
// The main enterframe should call this
public function updateClock(){
counter++;
if(counter%gameFrameRate == 0){
min++; // increment sec every time the last max FPS is hit
if(min > MAXMIN){
// reset min and increment hr
hr++;
dayTimeCounter = hr;
canCreateSunMoon = true;
min = 0;
}
if(hr > MAXHR){
// reset hr base on a 24 hour clock
hr = 0;
changeDay();
}
// create sun or moon depending on time
if(hr >= dayTimeStart && hr < dayTimeEnd &&
canCreateSunMoon ){
createMoon(false);
canCreateSunMoon = false;
isDayTime = false;
}else if(canCreateSunMoon){
createMoon(true);
canCreateSunMoon = false;
isDayTime = true;
}
// modify the min, hr if they are below 10
// mod min
if(min < 10){
tMin = “0”+ min;
}else{
tMin= String(min);
}
// mod hr
if(hr < 10){
tHr = “0”+ hr;
}else{
tHr = String(hr);
}
// AM PM
if(hr < 12){
Appendix
amPm = “AM”;
}else{
amPm = “PM”;
}
// ----- end of modification
// display the current time
tTxt.text = “”+tHr + “:” + tMin + “ “+
amPm;
counter = 0;
}
}
// getters
public function getTime():String{
return tTxt.text;
}
public function getHr():int{
return hr;
}
public function getMin():int{
return min;
}
public function getDayTime():Boolean{
return isDayTime;
}
/*
public function setWoldName():void{
var worldTxt:TextField = new TextField;
C_Holder.push(woldTxt);
}*/
}
}
Appendix A3.0
ClockWeekend.as
package com.Lao.tanker {
/*
created by Xai Lao - free to use and modify
This is a clock dependent on the game’s main enterframe
You must change the gameFrameRate variable to match your game’s
FPS for this clock to be accurate
*/
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.Event;
public class ClockWeekend extends Sprite {
public var C_Holder:Array = new Array();
private var day:Array = new Array(“MON”, “TUE”, “WED”,
“THU”, “FRI”, “SAT”, “SUN”);
public function ClockWeekend(startDay:int, rand:Boolean) {
//super(h,m,s);
if(rand){
// if use wants to start
this clock with a random day generated or not
counterDay = Math.floor(Math.random() * day.
length);
}else{
counterDay = startDay;
// otherwise
use the given startng day
}
addEventListener(Event.ADDED_TO_STAGE, loadDay );
}
// initial values and displays
private function loadDay(e:Event){
var f:TextFormat = new TextFormat(“Segoeb”);
var tTxt:TextField = new TextField();
f.size = 16;
f.color = 0xffffff;
tTxt.defaultTextFormat = f;
tTxt.embedFonts = true;
tTxt.border = false;
tTxt.selectable = false;
tTxt.width = 120;
tTxt.height = 20;
tTxt.text = day[counterDay];
//tTxt.x = 100;
C_Holder.push(tTxt);
addChild(tTxt)
removeEventListener(Event.ADDED_TO_STAGE, loadDay
);
}
private var counterDay:int = 0;
protected function changeDay(){
counterDay++;
if(counterDay > 6){
counterDay = 0;
}
C_Holder[0].text = day[counterDay];
}
}
}
Appendix
Appendix A4.0
M0001.as
package com.Lao.tanker.enemy {
import com.Lao.tanker.Monster;
import com.Lao.tanker.IItem;
import com.Lao.tanker.weapon.*;
public class M0001 extends Monster {
// attributes
private var hp:int = 10;
private var minGold:int = 1;
private var maxGold:int = 3;
private var atkSpd:int = 2000;
private var minAtk:int = 3;
private var maxAtk:int = 5;
private var itemDropPercent:Number = 1;
// 30%
chance drop an item
// constructor
public function M0001(num:int) {
super(hp, minGold, maxGold, atkSpd, minAtk, maxAtk,
itemDropPercent);
}
override public function dropItem():IItem{
var par = parent;
var rand:Number = Math.floor(Math.random()*10);
if( rand > 8){
par.parent.parent.summonTutorial(“Weapon”);
return new W0001(2); // drop a bone club
}else if(rand > 5){
par.parent.parent.summonTutorial(“Weapon”);
return new W0001(1);
}else{
par.parent.parent.summonTutorial(“Weapon”);
return new W0001(0);
}
} // end of dropItem
} // end of class
}
Appendix
Appendix A5.0
M0002.as
package com.Lao.tanker.enemy {
import com.Lao.tanker.IItem;
import com.Lao.tanker.Monster;
import com.Lao.tanker.weapon.*;
// Rabbit
public class M0002 extends Monster {
// attributes
private var mname:String = “Dull Rabbit”;
private var hp:int = 50;
private var minGold:int = 1;
private var maxGold:int = 3;
private var atkSpd:int = 2000;
private var minAtk:int = 3;
private var maxAtk:int = 5;
private var itemDropPercent:Number = .5;
// 30%
chance drop an item
// constructor
public function M0002(num:int) {
super(hp, minGold, maxGold, atkSpd, minAtk, maxAtk,
itemDropPercent);
}
override public function dropItem():IItem{
var par = parent;
var rand:Number = Math.floor(Math.random()*10);
if( rand > 8){
return new W0001(2); // drop a bone club
}else if(rand > 5){
return new W0001(1);
}else{
return new W0001(0);
}
} // end of dropItem
} // end of class
}
Appendix
Appendix A6.0
M0003.as
package com.Lao.tanker.enemy {
import com.Lao.tanker.Monster;
import com.Lao.tanker.IItem;
import com.Lao.tanker.weapon.*;
public class M0003 extends Monster {
// attributes
private var mName:String = “Dull Turtle”;
private var hp:int = 100;
private var minGold:int = 5;
private var maxGold:int = 8;
private var atkSpd:int = 3000;
private var minAtk:int = 3;
private var maxAtk:int = 5;
private var itemDropPercent:Number = .50;
// 30%
chance drop an item
// constructor
public function M0003(num:int) {
super(hp, minGold, maxGold, atkSpd, minAtk, maxAtk,
itemDropPercent);
}
override public function dropItem():IItem{
var rand:Number = Math.floor(Math.random()*10);
if( rand > 8){
return new W0002(2); // drop a bone club
}else if(rand > 5){
return new W0002(1);
}else{
return new W0001(1);
}
} // end of dropItem
} // end of class
}
Appendix
Appendix A7.0
FloorTiles.as
package com.Lao.tanker {
import flash.display.Sprite;
import flash.display.Graphics;
public class FloorTiles extends Sprite {
// data tile
private var dataTile:Tile;
private var C_AI:Array;
public var C_Holder:Array = new Array();
//
data tile
public var C_Holder2:Array = new Array();
//
floor tile
private var availableTiles:Array = new Array();
//Enemy
private var MAX_ENEMY:int = 5;
// loop variables
private var i:int=0;
private var tile:Sprite;
private var MAX_TILES:int = 50;
private var MAX_TILE_PER_LINE:int = 10;
private var limitReachCounter:int = 0;
// tile appearence
private var tColor = 0x733345;
private var tBorderThickness = 1;
private var tRoundness = 15;
// tile demensions and spacing
private var wid:int = 50;
private var hei:int = 50;
private var COL_GAP:int = 9; // column gap between each
block
private var ROW_GAP:int = 9; // gap between rows
private var xReset:int = 0;
private var xOffset:int = 140;
// each tile starts
with this x offset so it doesn’t overlap any menus
private var yOffset:int = 45;// each tile starts with
this x offset so it doesn’t overlap any menus
// border attribute
private var border_X_offset:int = 180;
private var bLineThickness:int = 1;
private var bColor = 0x733345;
//
border color
private var bWid:Number = 600;
private var bHei:Number = 370;
private var bRoundCorner:Number = 15;
Appendix
public function FloorTiles(C_AI_sub:Array) {
C_AI = C_AI_sub;
// create top banner
createTopBanner();
// create tiles
for(i=0; i<MAX_TILES; i++){
createTile(i);
}
// create border for tiles
createBorder();
// populate level (enemies, items, etc)
createEnemies();
}
private function createTopBanner(){
tile = new Sprite();
tile.graphics.beginFill(tColor);
tile.graphics.drawRoundRect(10,10,bWid, 20, bRoundCorner, bRoundCorner);
tile.graphics.endFill();
addChild(tile);
tile.x = border_X_offset;
// fix block
tile = new Sprite();
tile.graphics.beginFill(tColor);
tile.graphics.drawRect(10,18,bWid, 20);
tile.graphics.endFill();
addChild(tile);
tile.x = border_X_offset;
}
private function createTile(tileCount:int){
if( (tileCount % MAX_TILE_PER_LINE) == 0 && tileCount != 0){ // detect whenever the limit tile is reach
limitReachCounter ++; // counts every time
the limit is reach
xReset = 0;
// reset the x offset so tiles get lay down on most left again
}
tile = new Sprite();
xReset ++;
//tile.graphics.beginFill(0x987878);
//tile.graphics.drawRoundRect(10,10,wid,hei,15,15);
//tile.graphics.endFill();
tile.graphics.lineStyle(tBorderThickness, tColor);
tile.graphics.drawRoundRect(0,0,wid,hei,tRoundness,
tRoundness);
// data tile
dataTile = new Tile();
// create a new data
Appendix A7.1
FloorTiles.as
tile
C_Holder.push(dataTile);
// Main array
holder for this class
tile.addChild(dataTile);
// for each tile created, nest a new data tile inside each tile
C_Holder2.push(tile);
addChild(tile);
// add
tile to class to be diplay
tile.x = xOffset + ((wid+COL_GAP)*xReset);
tile.y = yOffset + ((hei+ROW_GAP) * limitReachCounter ) ;
}
private function createBorder(){
tile = new Sprite();
tile.graphics.lineStyle(bLineThickness, bColor);
tile.graphics.drawRoundRect(10,10,bWid,bHei,bRoundC
orner,bRoundCorner);
addChild(tile);
tile.x = border_X_offset;
}
private function createEnemies(){
// -------------------------- //
// Enemies - populate each enemy onto each floor
tiles, two enemies can’t be on same floor tile
// -------------------------- //
// push all floor tiles into array, like powerballs
being put inside a plastic bubbles
for(i=0; i<if_floorTiles.C_Holder2.length; i++){
availableTiles.push(i);
}
availableTiles.splice(0,1); // to prevent enemy
from spawning on the first tile where hero is also on
//populate enemey onto level
for(i=0; i<MAX_ENEMY; i++){
// pick one random number from the array
randomNum = Math.floor(Math.random() *
availableTiles.length );
// note: if array length is 50, you can’t
get random # 50, random max would be 49
e1 = new Rabbit(i);
//
availableTiles[randomTile]
tankerWorld.addChild(e1);
C_AI.push(e1);
}
}
}
}
Appendix
Appendix A8.0
Font001.as
package
com.Lao.tanker {
import
import
import
import
flash.display.Loader;
flash.events.Event;
flash.text.TextField;
flash.text.TextFormat;
import
import
import
import
import
import
import
flash.display.Sprite;
flash.text.TextField;
flash.text.TextFormat;
flash.text.Font;
flash.text.TextFieldAutoSize;
flash.text.AntiAliasType;
flash.utils.getDefinitionByName;
public class Font001 extends Sprite{
public function Font001() {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.
INIT, fontLoaded);
loader.load(new URLRequest(“Font001.swf”));
// method 3 - works but is not for run time
/*
var myFont:Font1 = new Font1();
var f:TextFormat = new TextFormat();
f.font = myFont.fontName;
f.size = 24;
var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
myTextField.antiAliasType = AntiAliasType.ADVANCED;
myTextField.defaultTextFormat = f;
myTextField.embedFonts = true;
myTextField.text = “The quick brown fox jumped over
the lazy dog.”;
addChild(myTextField)
*/
}
private function fontLoaded(e:Event){
var txt:TextField = new TextField();
txt.width = 600;
txt.embedFonts = true;
var f:TextFormat = new TextFormat(“Segoe”);
f.size = 24; f.color = 0x00ff00;
txt.defaultTextFormat = f;
txt.text = “RUNTIME FONTkS oh yeah 123 baby”;
addChild(txt);
}
}
}
Appendix
Appendix A9.0
FontLoader.as
package com.Lao.tanker {
/*
This class loads all the fonts for the applications
*/
import flash.display.Loader;
import flash.events.Event;
import flash.display.Sprite;
import flash.net.URLRequest;
/*
import
import
import
import
import
import
*/
public
flash.text.TextField;
flash.text.TextFormat;
flash.text.Font;
flash.text.TextFieldAutoSize;
flash.text.AntiAliasType;
flash.utils.getDefinitionByName;
class FontLoader extends Sprite{
private var isReady:Boolean = false;
private var loader:Loader = new Loader();
public function FontLoader() {
loader.contentLoaderInfo.addEventListener(Event.
INIT, fontLoaded);
loader.load(new URLRequest(“Font001.swf”));
// method 3 - works but is not for run time fonts
/*
var myFont:Font1 = new Font1();
var f:TextFormat = new TextFormat();
f.font = myFont.fontName;
f.size = 24;
var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
myTextField.antiAliasType = AntiAliasType.ADVANCED;
myTextField.defaultTextFormat = f;
myTextField.embedFonts = true;
myTextField.text = “The quick brown fox jumped over
the lazy dog.”;
addChild(myTextField)
*/
}
private function fontLoaded(e:Event):void{
dispatchEvent(new Event(“loadComplete”));
// make sure any class that use this class listens
to loadComplete before you start
// making textFields with thiese fonts
loader.contentLoaderInfo.removeEventListener(Event.
INIT, fontLoaded);
}
}
}
Appendix
Appendix A10.0
FontLoader.as
package com.Lao.tanker {
/*
This class loads all the fonts for the applications
*/
import flash.display.Loader;
import flash.events.Event;
import flash.display.Sprite;
import flash.net.URLRequest;
/*
import
import
import
import
import
import
*/
public
flash.text.TextField;
flash.text.TextFormat;
flash.text.Font;
flash.text.TextFieldAutoSize;
flash.text.AntiAliasType;
flash.utils.getDefinitionByName;
class FontLoader extends Sprite{
private var isReady:Boolean = false;
private var loader:Loader = new Loader();
public function FontLoader() {
loader.contentLoaderInfo.addEventListener(Event.
INIT, fontLoaded);
loader.load(new URLRequest(“Font001.swf”));
// method 3 - works but is not for run time fonts
/*
var myFont:Font1 = new Font1();
var f:TextFormat = new TextFormat();
f.font = myFont.fontName;
f.size = 24;
var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
myTextField.antiAliasType = AntiAliasType.ADVANCED;
myTextField.defaultTextFormat = f;
myTextField.embedFonts = true;
myTextField.text = “The quick brown fox jumped over
the lazy dog.”;
addChild(myTextField)
*/
}
private function fontLoaded(e:Event):void{
dispatchEvent(new Event(“loadComplete”));
// make sure any class that use this class listens
to loadComplete before you start
// making textFields with thiese fonts
loader.contentLoaderInfo.removeEventListener(Event.
INIT, fontLoaded);
}
}
}
Appendix
Appendix A11.0
FramerateTracker.as
package com.Lao.tanker
{
// This class is a textarea that displays the fps
/*
// framerate tracker - copy and paste this comment code in .fla
where it is created
var fr:FramerateTracker = new FramerateTracker();
fr.x = 10;
fr.y =10;
fr.scaleX = 2;
fr.scaleY = 2;
stage.addChild(fr);
*/
import flash.utils.getTimer;
import flash.events.Event;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
public class FramerateTracker extends Sprite
{
// vars
private var time:int;
private var prevTime:int = 0;
private var fps:int;
private var fps_txt:TextField;
private var avg_fps_txt:TextField;
private var myFormat:TextFormat;
private var avg_fps:int = 0;
public var counter:int = 0;
private var max_frame:int = 30;
// constructor
public function FramerateTracker()
{
//
myFormat = new TextFormat();
myFormat.size = 15;
fps_txt = new TextField();
fps_txt.defaultTextFormat = myFormat;
avg_fps_txt = new TextField();
avg_fps_txt.defaultTextFormat = myFormat;
fps_txt.x = 0;
fps_txt.y = 0;
addChild(fps_txt);
// add textfield to this
class only, not to yet to stage
avg_fps_txt.x = 0;
avg_fps_txt.y = 20;
addChild(avg_fps_txt);// add textfield to this
Appendix
class, note that the class still needs
// to
be added to stage when the class is created
//
//addEventListener(Event.ENTER_FRAME, getFps);
}
// methods
public function getFps():void
{
//
time = getTimer();
fps = 1000 / (time - prevTime);
//
fps_txt.text = “fps: “ + fps;
avg_fps += fps;
//
prevTime = getTimer();
// update avg_fps
counter++;
if(counter % max_frame == 0){
avg_fps_txt.text = “avg_fps: “ + (avg_fps /
max_frame).toFixed(2);
avg_fps = 0;
}
}
} // end class
} // end package
Appendix A12.0
GaugeBar.as
package
com.Lao.tanker {
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
public class GaugeBar extends Sprite {
public var C_Holder:Array = new Array();
private var wid:int = 4;
private var hei:int = 40;
private var barC = 0x33FF00;
private var borderThick = 1;
private var borderC = 0x999999;
private var rot:int = 180;
// to trick the registration
point so height can shrink down
public function GaugeBar(rotat:int, colr:uint, w:int,
h:int, border:Boolean) {
rot = rotat;
barC = colr;
wid = w;
hei = h;
// constructor code
var s:Shape= new Shape();
C_Holder.push(s);
s.graphics.beginFill(barC);
s.graphics.drawRect(0,0, wid, hei);
s.graphics.endFill();
//s.x = 50; s.y = 50;
s.rotation = rot;
addChild(s);
s = null;
if(border){
var t:Shape = new Shape();
t.graphics.lineStyle(borderThick,borderC);
t.graphics.drawRect(0,0, wid, hei);
//t.x = 50; t.y = 50;
t.rotation = rot;
addChild(t);
t = null;
}
}
public function updateBar(num:Number){
C_Holder[0].scaleY = num;
}
}
}
Appendix
Appendix A13.0
HelpMenu.as
package com.Lao.tanker {
/*
This class loads the help menu list so users can read help infomation.
*/
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.AntiAliasType;
// xml
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextFieldType;
public class HelpMenu extends Sprite{
private var C_Holder:Array = new Array();
// holds the
menu list
private var C_Holder2:Array = new Array(); // holds the
description text box field, just 1 element for now
// help var - use xml for this
private var xmlLoader:URLLoader = new URLLoader();
private var help1:Array = new Array();
private var help2:Array = new Array();
private var maxList:int = 0;
private var S_Holder:Sprite = new Sprite();
public function HelpMenu() {
// constructor code
xmlLoader.addEventListener(Event.COMPLETE, showXML);
xmlLoader.load(new URLRequest(“xml/help.xml”));
}
private function showXML(e:Event):void {
XML.ignoreWhitespace = false;
var helpList:XML = new XML(e.target.data);
//trace(helpList.list.title.length());//Result is
4
var i:Number;
maxList = helpList.list.title.length();
// for use with textFields
for (i=0; i < helpList.list.title.length(); i++) {
help1.push( helpList.list.title[i].text()
);
help2.push( helpList.list.desc[i].text() );
Appendix
}
createMenuButton();
createMenuLists();
}
private function createMenuButton():void{
var s:Sprite = new Sprite();
var txt:TextField = new TextField();
var f:TextFormat = new TextFormat(“Segoeb”);
s.graphics.beginFill(0xffffff, 0);
// turn alpha
zero for now
s.graphics.drawRect(0,0,200,20);
s.graphics.endFill();
f.size = 16;
f.color = 0xffffff;
txt.defaultTextFormat = f;
txt.embedFonts = true;
// so it can use embeded fonts
txt.text = “HELP”;
txt.selectable = false;
txt.width = 100;
txt.height = 30;
txt.x = 50; txt.y = 0;
s.addChild(txt);
s.x = 30;
addChild(s);
s.addEventListener(MouseEvent.CLICK, showMenu);
}
private function showMenu(e:Event):void{
if(S_Holder.visible == true){
S_Holder.visible = false;
}else{
S_Holder.visible = true;
}
}
private function createMenuLists():void{
var f:TextFormat = new TextFormat(“Segoe”); // frank
var txt:TextField;
var s:Sprite;
var wid:int = 200;
var hei:int = 20;
//format
f.size = 12;
f.color = 0x333333;
for(var i:int=0; i<maxList; i++){
// block
Appendix A13.1
HelpMenu.as
s = new Sprite();
s.graphics.lineStyle(1, 0x666666);
s.graphics.beginFill(0xffffff, .9);
s.graphics.drawRect(0,0, wid, hei);
s.graphics.endFill();
s.y = 30+(hei*i);
// txt
txt = new TextField();
txt.defaultTextFormat = f;
txt.embedFonts = true;
txt.width = wid-6;
txt.height = hei-3;
txt.text = “”+help1[i];
txt.border = false;
txt.selectable = false;
txt.mouseEnabled = false;
// so mouse
can’t affect it since bg is mouseclickable
txt.condenseWhite = true;
txt.x = 3; txt.y = 1;
txt.doubleClickEnabled = false;
// add
s.addChild(txt);
C_Holder.push(s);
S_Holder.addChild(s);
s.addEventListener(MouseEvent.CLICK, loadDesc);
}
// -------------------------
// description box textfield
var dWid:int = 380;
var dHei:int = 290;
f = new TextFormat(“Frank”);
f.size = 12;
f.color = 0x333333;
txt = new TextField();
txt.embedFonts = true;
txt.antiAliasType = AntiAliasType.ADVANCED;
txt.defaultTextFormat = f;
txt.selectable = false;
txt.mouseEnabled = false;
txt.width = dWid-6;
txt.height = dHei-6;
txt.wordWrap = true;
txt.border = false;
//txt.condenseWhite = true; // only works when
setting text with txt.htmlText = “this is html text”;
txt.htmlText = “Choose a topic on the right to read
description”;
txt.x = 3; txt.y = 3;
//
Appendix
s = new Sprite();
s.graphics.lineStyle(1, 0x666666);
s.graphics.beginFill(0xffffff, 1);
s.graphics.drawRect(0,0, dWid, dHei);
s.graphics.endFill();
//
C_Holder2.push(txt);
s.addChild(txt);
s.x = -390; s.y = 30;
S_Holder.addChild(s);
addChild(S_Holder);
S_Holder.x = 30;
S_Holder.visible = false;
}
private function loadDesc(e:MouseEvent):void{
var newStr:String = help2[C_Holder.indexOf(e.target)];
//newStr = newStr.split(“bb”).;
C_Holder2[0].text = newStr;
//trace(num);
}
}
}
Appendix A14.0
Hero.as
package com.Lao.tanker {
// imports
import flash.display.Sprite;
import flash.display.MovieClip;
/*
import flash.display.BitmapData;
import flash.display.Bitmap;
*/
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Stage;
import flash.ui.Keyboard;
public class Hero extends MovieClip {
public var C_Holder:Array = new Array();
// holds speed attack bar created from stage.
// reason why spdAtkBar is not added here is becuase hero will be flipped around using move arrows
// we don’t want speed bar to be fliped as well
//private var hero:HeroA;
// call bitmapdata
from library
//public var bmpHero:Bitmap; // to put hero bitmapdata
into
//Hero Controls
private var left:Number = 37,
right:Number = 39,
up:Number = 38,
down:Number = 40;
//Hero stage boundary for a 10x5 stage
private var MAX_RIGHT:int = 9;
private var MAX_DOWN:int = 4;
private var r_count:int = 0;
private var d_count:int = 0;
//Hero Stats
private var speed:int = 59; // default 59
public function Hero(xPos:int, yPos:int) {
/*
hero = new HeroA();
bmpHero = new Bitmap(hero);
bmpHero.x = xPos;
bmpHero.y = yPos;
addChild(bmpHero);
*/
this.x = xPos;
this.y = yPos;
Appendix
// add bmpHero to be displayed in this class
//stage.addEventListener(KeyboardEvent.KEY_DOWN,
moveHero);
//addEventListener(Event.ENTER_FRAME, moveHero);
}
public function moveHero(e:KeyboardEvent):Boolean{
// trace(“Hero button”);
//bmpHero.x ++;
var par:* = parent;
if(e.keyCode == left){
if(r_count != 0){
r_count--;
//bmpHero.x -= speed;
//this.x -= speed;
gotoAndStop(2);
// switch controls on engine class
par.parent.parent.startPosX = x;
par.parent.parent.heroCanMove =
true;
par.parent.parent.goLeft = true;
//scaleY *= -1;
return true; }
return false;
}
if(e.keyCode == right){
if(r_count != MAX_RIGHT){
r_count++;
//bmpHero.x += speed;
//this.x += speed;
gotoAndStop(1);
// switch controls on engine class
par.parent.parent.startPosX = x;
par.parent.parent.heroCanMove =
true;
par.parent.parent.goRight = true;
return true;
}
return false;
}
if(e.keyCode == up){
if(d_count != 0){
d_count--;
//bmpHero.y -= speed;
//this.y -= speed;
Appendix A14.1
Hero.as
// switch controls on engine class
par.parent.parent.startPosY = y;
par.parent.parent.heroCanMove =
true;
par.parent.parent.goUp = true;
return true;
}
return false;
}
if(e.keyCode == down){
if(d_count != MAX_DOWN){
d_count++;
//bmpHero.y += speed;
//this.y += speed;
// switch controls on engine class
par.parent.parent.startPosY = y;
par.parent.parent.heroCanMove =
true;
par.parent.parent.goDown = true;
return true;
}
return false;
}
return false; // if other non-registered keys are
press return false and do nothing
// trace(“”+e.keyCode);
}
public function updateSpdAtkBar(refreshPercent:Number){
// updates the display spdAtkBar
C_Holder[0].updateBar(refreshPercent)
}
// removes the damage display when the hero attacks
public function removeStatusWindow(dmgWindow:Sprite){
removeChild(dmgWindow);
}
}
}
Appendix
Appendix A15.0
IFStart.as
package com.Lao.tanker {
/*
this is the start menu
it puts a textfield “Start” non-selectable inside a block sprite.
The block is then given an
addEventListener(MouseEvent.CLICK)
on click the user will be able to proceed to play the game or
start the game.
The game logo is inserted underneath the Start Button
*/
//imports
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.*;
import flash.display.BitmapData;
// to represent logo bitmapdata
import flash.display.Bitmap; // to put logo bitmapdata
into in order to display the logo
import flash.events.Event;
public class IFStart extends Sprite{
//public var startButton:Sprite;
public var C_Holder:Array = new Array();
// display
objects using addChild
private var C_Holder2:Array = new Array(); // non-display objects
public function IFStart(xPos:int, yPos:int) {
// addEventListener(Event.REMOVED, clearOutAllContents, false, 0, true);
// constructor code
var wid:int = 300;
var hei:int = 100;
var startButton:Sprite = new Sprite();
C_Holder.push(startButton);
startButton.graphics.beginFill(0x666666);
startButton.graphics.drawRoundRect(0,0, wid, hei,
20, 20);
startButton.graphics.endFill();
var myFormat:TextFormat = new TextFormat(“Segoeb”);
C_Holder2.push(myFormat);
myFormat.size = 50;
myFormat.color = 0xffffff;
myFormat.align = “center”;
var myT:TextField = new TextField();
myT.embedFonts = true;
C_Holder2.push(myT);
myT.defaultTextFormat = myFormat;
Appendix
myT.selectable = false;
myT.text = “START”;
myT.width = wid;
myT.height = hei;
myT.y = 10;
startButton.addChild(myT);
addChild(startButton);
startButton.x = xPos-(startButton.width/2);
startButton.y = yPos;
// startButton.addEventListener(MouseEvent.CLICK,
startGame);
// display logo on start menu as well
var logo:Logo = new Logo(0,0);
C_Holder2.push(logo);
var logoBitmap:Bitmap = new Bitmap(logo);
C_Holder.push(logoBitmap);
logoBitmap.x = xPos-(logoBitmap.width/2);
logoBitmap.y = 200;
addChild(logoBitmap);
}
private function clearOutAllContents(){
// remove display objects in this class
for(var i:int=0; i< this.C_Holder.length; i++){
//removeChild(C_Holder[i]);
C_Holder[i] = null;
}
C_Holder.splice(0)
C_Holder = null;
for(var k:int=0; k< C_Holder2.length; k++){
this.C_Holder2[k] = null;
}
C_Holder2.splice(0);
C_Holder2 = null;
//removeEventListener(Event.REMOVED, clearOutAllContents);
}
}
}
Appendix A16.0
IFStat.as
package com.Lao.tanker {
//imports here in this class doesn’t need to be imported in the
parent class
// for these imports to work, unless the parent class also creates
objects
// that require these imports
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.*;
import flash.events.Event;
import flash.display.Stage;
import flash.display.Graphics;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.utils.getTimer;
public class IFStat extends Sprite {
// Holders
public var C_Holder:Array = new Array();
the data as hero plays the game
public var C_Holder2:Array = new Array();
ence the textField data
public var C_Holder3:Array = new Array();
pement slot interface
public var C_Holder4:Array = new Array(); sual shrinking bars
private var valHolder:int = 0;
// Parent Target References
private var par;
// display classes
private var logo:Logo;
mapData class from library
private var logoBitmap:Bitmap;
private var bgBdata:BgIMG;
private var bgBitmap:Bitmap;
/*
private var statBdata:StatIMG;
in library class
private var statBitmap:Bitmap;
bitmapdata
private var stat1Bdata:Stat1IMG;
in library class
private var stat1Bitmap:Bitmap;
bitmapdata
*/
// to change
// to refer// hold equi// hold vi-
// logo bit-
// bitmapData
// to hold
// bitmapData
// to hold
Appendix
private var block:Sprite;
private var block1:Sprite;
private var blockArr:Array = new Array();
private var attr:Array = new Array(“HEALTH”, “ENERGY”,
“ATTACK”, “ATK SPD”, “GOLD”); // adding or subtracting will affect height
of menu
// hero stats
private var maxHp:int = 50;
private var hp:int = maxHp;
private var maxEnergy:int = 25;
private var energy:int = 0; // start with
zero energy
private var minAtk:int = 1;
private var maxAtk:int = 3;
private var def:int = 1;
private var atkSpd:int = 3000;
private var gold:int = 0;
private var timer:Timer = new Timer(atkSpd,1);
private var spdAtkBarUpdateTimer:Timer = new Timer(100);
// controls the frame rate at which hero
// spdAtkBar updates, 100 is
decent
private var startTime;
// display spacing
private var MAX:int = attr.length;
private var wid:int = 170;
private var hei:int = 23;
private var lineGap:int = 25;// space between the blocks
private var startX:int = 20;
private var startY:int = 30;
// colors
private var headerColor = 0xB03535; // redTan
private var subColor = 0xECF5FF;
// yellowOrange 0xFDC68F
private var menuBorderColor = 0x733345;
// maroon
private var attrColor = 0xffffff; // white
private var bHei = 370;
// border height
// text
private var attrNameTxt:TextField; // titles and sub
menu titles
private var formatTitle:TextFormat; // text formatter
private var formatSub:TextFormat;
// text formatter
private var myFont:Font;
// constructor code
public function IFStat() {
//addEventListener(Event.REMOVED, cleanOutAllCon-
Appendix A16.1
IFStat.as
tents, false, 0, true);
// empty this class and clear upon removal
addEventListener(Event.ADDED_TO_STAGE, loadIFStatAssets, false, 0, true);
// true = use weak reference
addEventListener(Event.REMOVED_FROM_STAGE, isRemoved, false, 0, true);
}
public function loadIFStatAssets(e:Event){
par = parent; // reference parent
createBG();
createBlock();
// lay out the blocks for
hp, atk, def, etc..’
C_Holder[0].alpha = 1;// turn this off if
you want to see the number display of HP again
C_Holder[1].alpha = 1;// turn this off if
you want to see the number display of ENERGY again
createEquipments();
// lay out equipment blocks
//createBorder(); // put border around stats
interface
//createLogo();
// put logo below
stat menu
createVisualHP_ENGY_Bar();
timer.addEventListener(TimerEvent.TIMER, toggleAtkOn, false, 0, true);
spdAtkBarUpdateTimer.addEventListener(TimerEvent.
TIMER, updateSpdAtkBar, false, 0, true);
removeEventListener(Event.ADDED_TO_STAGE, loadIFStatAssets);
}
private function createVisualHP_ENGY_Bar():void{
var hei:int = 10;
var wid:int = 100;
var i:int = 0;
var xOffset:int = 90;
// -----// HP Bar
// -----
// small squares
for(i=0; i<hei; i++){
var bgBar:Shape = new Shape();
bgBar.graphics.lineStyle(1, 0x2A2E3B);
bgBar.graphics.drawRect(0,0, hei,hei);
bgBar.x = xOffset+(i*hei); bgBar.y = 52;
addChildAt(bgBar, 1);
}
// visual bar
var hpBar:RectGaugeBar = new RectGaugeBar(270,
Appendix
0x52C24C, hei, wid, false); // (rotate degree, bgColor, height, wid)
C_Holder4.push(hpBar);
hpBar.x = xOffset; hpBar.y = 62;
addChildAt(hpBar, 1);
// background
bgBar = new Shape();
bgBar.graphics.beginFill(0x52c24c, .5);
bgBar.graphics.drawRect(0,0, wid, hei);
bgBar.x = xOffset; bgBar.y = 52;
addChildAt(bgBar, 1);
// ----------
// Energy Bar
// ----------
// small squares
for(i=0; i<hei; i++){
bgBar = new Shape();
bgBar.graphics.lineStyle(1, 0x2A2E3B);
bgBar.graphics.drawRect(0,0, hei,hei);
bgBar.x = 90+(i*hei); bgBar.y = 78;
addChildAt(bgBar, 1);
}
// visual energy bar
hpBar = new RectGaugeBar(270, 0x46ACDC, hei, wid,
false);// (rotate degree, bgColor, height, wid)
C_Holder4.push(hpBar);
hpBar.x = 90; hpBar.y = 88;
addChildAt(hpBar, 1);
hpBar.updateBar(0);
// cause hero starts
with zero energy
// background
bgBar = new Shape();
bgBar.graphics.beginFill(0x46ACDC, .5);
bgBar.graphics.drawRect(0,0, wid, hei);
bgBar.x = 90; bgBar.y = 78;
addChildAt(bgBar, 1);
}
private function createBlock(){
var i:int = 0;
// create blocks and define colors shapes
for(i=0; i<MAX; i++){
block = new Sprite();
// block.graphics.lineStyle(2, 0xFDC68F);
block.graphics.drawRect(0,0, wid,hei);
block.graphics.beginFill(subColor, 0);
// invis for now
block.graphics.drawRect(0,0, wid, hei);
block.graphics.endFill();
// text inside blocks
attrNameTxt = new TextField();
Appendix A16.2
IFStat.as
//attrNameTxt.border = true;
formatSub = new TextFormat(“Segoeb”);
// set font family
//myFont = new Font1();
// embedded font in library, not run-time font
//formatSub.font = myFont.fontName;
formatSub.size = 12;
formatSub.color = 0xffffff;
attrNameTxt.defaultTextFormat = formatSub;
// have to use before inserting text into textfield
attrNameTxt.embedFonts = true;
// to display the custom font correctly
//attrNameTxt.embedFonts = true;
//attrNameTxt.antiAliasType = AntiAliasType.ADVANCED;
attrNameTxt.height = 15;
attrNameTxt.width = 80;
attrNameTxt.border = false;
attrNameTxt.selectable = false;
switch(i){
case 0:
attrNameTxt.text =
attr[i];
break;
case 1:
attrNameTxt.text =
attr[i]; //”ENERGY”;
break;
case 2:
attrNameTxt.text =
attr[i]; // “DEF”;
break;
case 3:
attrNameTxt.text =
attr[i];// “ATK”;
break;
case 4:
attrNameTxt.text =
attr[i];// “ATK”;
break;
}
//attrNameTxt.text = “”+i;
attrNameTxt.x = 5;
attrNameTxt.y = 5;
block.addChild(attrNameTxt); // add
attribute name
block.addChild(loadAttrDisplay());
// add
attribute visual data display, will return a block:sprite
addChild(block);
blockArr.push(block);
//trace(“i’m here”);
} // end of for loop
//position title “Stats” block
Appendix
block = new Sprite();
block.graphics.beginFill(headerColor, 0);
block.graphics.drawRoundRect(10,10,170,20,15,15);
block.graphics.endFill();
addChild(block);
block = new Sprite();
block.graphics.beginFill(headerColor, 0);
// invis for now
block.graphics.drawRect(0,0, wid, hei-10);
block.graphics.endFill();
block.x = startX;
block.y = startY;
attrNameTxt = new TextField();
attrNameTxt.border = false;
attrNameTxt.width = 160;
attrNameTxt.height = 30;
formatTitle = new TextFormat(“Segoeb”);
formatTitle.size = 20;
formatTitle.color = 0xffffff;
formatTitle.align = TextFormatAlign.LEFT;
attrNameTxt.defaultTextFormat = formatTitle;
attrNameTxt.embedFonts = true;
attrNameTxt.selectable = false;
attrNameTxt.text = “HERO STATS”;
// attrNameTxt.setTextFormat(format,
-1);// = format;
// can only setTextFormat after text
has been inserted
attrNameTxt.x = 5;
attrNameTxt.y = -16;
block.addChild(attrNameTxt); // add text
to block
addChild(block);
// position sub-Stats blocks
for(var k:int=0; k<blockArr.length; k++){
blockArr[k].x = startX //
((wid+10)*k) + 50;
blockArr[k].y = startY+13+lineGap*k;
}
}
// attribute text fields that displays the hero stats
private function loadAttrDisplay(){
var myW:int = 80;
var myH:int = 15;
var xOffset:int = 85;
var yOffset:int = 4;
block1 = new Sprite();
// block.graphics.lineStyle(2, 0xFDC68F);
//block1.graphics.drawRect(0,0, myW,myH);
Appendix A16.3
IFStat.as
block1.graphics.beginFill(attrColor,0);
// block1.graphics.drawRoundRect(0,0, myW,
myH, 10, 10);
block1.graphics.drawRect(0,0, myW, myH);
block1.graphics.endFill();
block1.x = xOffset;
block1.y = yOffset;
var tf:TextFormat = new
TextFormat(“Segoe”);
tf.size = 12;
tf.color = 0xffffff;
attrNameTxt = new TextField();
attrNameTxt.defaultTextFormat = tf;
attrNameTxt.embedFonts = true;
attrNameTxt.width = 80;
attrNameTxt.height = 15;
attrNameTxt.border = false;
attrNameTxt.selectable = false;
attrNameTxt.text = “Not Set”;
attrNameTxt.x = 5;
C_Holder.push(attrNameTxt);
block1.addChild(attrNameTxt);
return block1;
}
private function createEquipments(){
var equipBox:IfStatEquip = new IfStatEquip();
addChild(equipBox);
C_Holder3.push(equipBox);
//trace(C_Holder3[0].x);
equipBox.x = 40;
equipBox.y = 200;
equipBox = null;
}
private function createBorder(){
// create border around left side menu
block = new Sprite();
block.graphics.lineStyle(1, menuBorderColor);
block.graphics.drawRoundRect(10,10,170,bHei,15,15);
// *MAX
addChild(block);
//trace(“IFStat border loaded”);
}
private function createBG():void{
bgBdata = new BgIMG(0,0);
bgBitmap = new Bitmap(bgBdata);
bgBitmap.x = -20; bgBitmap.y = -25;
addChild(bgBitmap);
/*
statBdata = new StatIMG(0,0);
Appendix
statBitmap = new Bitmap(statBdata);
statBitmap.x = 0; statBitmap.y = 0;
addChild(statBitmap);
stat1Bdata = new Stat1IMG(0,0);
//C_Holder4.push(bgBdata);
stat1Bitmap = new Bitmap(stat1Bdata);
stat1Bitmap.x = 3; stat1Bitmap.y = 180;
addChild(stat1Bitmap);
*/
}
private function createLogo(){
logo = new Logo(0,0);
C_Holder2.push(logo);
logoBitmap = new Bitmap(logo)
C_Holder2.push(logoBitmap);
logoBitmap.x = 0; logoBitmap.y = 300;
addChild(logoBitmap);
}
// setters - exact set
// -------------------------------------------
public function setHP(num:int){ maxHp = num; hp = num; C_
Holder[0].text = hp; }
// HP
public function setEnergy(num:int){ energy = num; C_Holder[1].text = energy; }// Energy
public function setAtk(min:int, max:int){
minAtk = min; maxAtk = max;
C_Holder[2].text = “”+minAtk + “ - “ + maxAtk;
}// atk
public function setAtkSpd(num:int){ atkSpd = num; C_Holder[3].text = atkSpd; }
public function setDef(num:int){def = num; C_Holder[3].
text = def;} // Def
public function setGold(num:int){ gold = num; C_Holder[4].
text = gold; }
// Gold
public function checkEnergy():int{
return energy;
}
public function checkHP():int{
return hp;
}
// setters - modifiers
// ----------------------------------------
public function changeHP(num:int){
hp += num;
if(hp <=0)
hp = 0;// can’t be negative
C_Holder[0].text = hp;
Appendix A16.4
IFStat.as
// update visual hp bar
C_Holder4[0].updateBar( hp/maxHp );
}
public function changeEnergy(num:int){
// taking
damage or gaining damage
energy += num;
if(energy <=0){
energy = 0;
// can’t be negative
}
if(energy > maxEnergy){
energy = maxEnergy;
// can’t go above
maxEnergy
}
C_Holder[1].text = energy;
// update visual energy bar
C_Holder4[1].updateBar( energy/maxEnergy );
}
public function changeGold(num:int){ // taking damage or
gaining damage
gold += num;
C_Holder[4].text = gold;
}
public function changeAtkSpd(num:int){
atkSpd += num;
C_Holder[3].text = atkSpd;
}
// When Hero Attack Functions
// ---------------------------------------
public function getAtkSpd(){
return atkSpd;
}
public function getHeroAtk():int{
atk_is_ready = false; // hero can
no longer attack until ready again
// start attack delay timer
timer.delay = atkSpd;
timer.start();
// start the spdAtk bar timer
spdAtkBarUpdateTimer.start();
startTime = getTimer();
//return Math.floor(Math.random()* (maxAtk-minAtk) )
+ minAtk;
// normal random
var atkNum = Math.floor(Math.random()* ( (maxAtk+1)minAtk ) ) + (minAtk);
// +1 so if atk range is 12-15, 15 can be generated
Appendix
return atkNum;
}
private var atk_is_ready = true;
// starts hero with
allow to attack
public function checkHeroAtkStatus(){// called from main
engine
return atk_is_ready;
}
private function toggleAtkOn(e:TimerEvent){
atk_is_ready = true;
timer.reset();
//timer.removeEventListener(TimerEvent.Timer, toggleAtkOn);
//timer = null;
}
private function updateSpdAtkBar(e:TimerEvent){
// update the spd display bar on hero
//par.parent.C_Holder[0].updateBar();
if(atk_is_ready == false){
var newTime = getTimer();
var curTime = newTime - startTime;
newTime = null;
par.parent.C_Interface[1].C_Holder3[0].
updateSpdAtkBar(curTime/atkSpd);
curTime = null;
//trace(par.parent.C_Interface[1].C_Holder3[0]);
}else{
spdAtkBarUpdateTimer.reset();
par.parent.C_Interface[1].C_Holder3[0].updateSpdAtkBar(1)
// fill up the spdAtkBar to full
}
}
// ifStatEquip.as calls this function when user tries to
equip an empty slot, goes to default barehands
public function useBareHands(){
setAtk(1,2);
setAtkSpd(800);
}
private function isRemoved(e:Event){
timer.removeEventListener(TimerEvent.TIMER, toggleAtkOn);
spdAtkBarUpdateTimer.
removeEventListener(TimerEvent.TIMER, updateSpdAtkBar);
removeEventListener(Event.REMOVED_FROM_STAGE, isRemoved);
}
Appendix A16.5
IFStat.as
// For Garbage Collection purposes clear out all variables
public function cleanOutAllContents(){
var i:int = 0;
for(i=0; i<C_Holder.length; i++){
C_Holder[i] = null;
}
C_Holder.splice(0);
C_Holder = null;
// other array ref
for(i=0; i<blockArr.length; i++){
blockArr[i] = null;
}
blockArr.splice(0);
blockArr = null;
for(i=0; i<attr.length; i++){
attr[i] = null;
}
attr.splice(0);
attr = null;
for(i=0; i<C_Holder2.length; i++){
C_Holder2[i] = null;
}
C_Holder2.splice(0);
C_Holder2 = null;
removeChild(C_Holder3[0]);
for(i=0; i<C_Holder3.length; i++){
C_Holder3[i] = null;
}
C_Holder3.splice(0);
C_Holder3 = null;
}
}
}
Appendix
Appendix A17.0
IfStatEquip.as
package com.Lao.tanker {
/*
This class gets called from IFStat.as to be placed inside of it
This class are the equipment/item slots below the hero stats
*/
import
import
import
import
import
import
flash.display.Sprite;
flash.display.Graphics;
flash.events.Event;
flash.text.TextField;
flash.text.TextFormat;
flash.display.Shape;
public class IfStatEquip extends Sprite{
private var C_Holder:Array = new Array();
// holds slot
boxes
private var C_Holder2:Array = new Array(); // holds
items dropped and items picked up
private var C_Holder3:Array = new Array(); // holds text
display items - reads item
private var availableSlots:Array = new Array();
private var occupySlots:Array = new Array();
// display var
//private var mColor = 0x00033f;
// dark blue
//private var mColor2 = 0xffffff;
// white
//private var mColor3 = 0xff99ff;
private var selectC = 0xECF5FF;
// lightGreen 33CCFF
private var equipC = 0x00033f;
// blue 0x00033f
private var unSelectC = 0xD6D6D6;
// grey 0xD6D6D6
private var selectBorderC = 0xffffff; //
0x777777
private var selectBorderThick = 2;
private var wid:int = 42;
private var hei:int = 42;
private var corner:int = 10;
private var bC = 0x000000;
private var bThick = 1;
// layout - how the slots will be layed out
private var MAX_SLOTS:int = 6;
private var MAX_SLOTS_PER_LINE:int = 3;
private var limitReachCounter:int = 0;
private var xReset:int = 0;
private var COL_GAP:int = 10;
private var ROW_GAP:int = 10;
//interactive slot selection var
private var counter:int = 0;
private var equip:int = 0;
Appendix
public function IfStatEquip() {
addEventListener(Event.REMOVED, cleanOutAllContents, false, 0, true);
// if this class if removed, clear it’s
contents
// text box
createTextBox();
// will display item names
// constructor code
for(var i:int=0;i<MAX_SLOTS;i++){
createSlot(i);// pass the count
}
for(var j:int=0; j<C_Holder.length; j++){
// extract all slots
availableSlots.push(j);
// populate available slots, like powerball
}
// then go back and set the first slot to be highlighted
//C_Holder[0].alpha = transE;
markSlotAsEquip(0);
}
private function createTextBox(){
var s:Shape = new Shape();
s.graphics.beginFill(0xECF5FF, 0);
//
light blue
s.graphics.drawRect(0,0,169,95);
s.graphics.endFill();
addChild(s);
s.graphics.beginFill(0xECF5FF,0);
//
light blue
s.graphics.drawRoundRect(0,0,169,95,15,15);
s.graphics.endFill();
addChild(s);
s.y = 100;
s.x = -10;
var txt:TextField = new TextField();
var f:TextFormat = new TextFormat(“Segoeb”);
f.size = 12; f.color = 0xffffff;
txt.defaultTextFormat = f;
txt.embedFonts = true;
txt.width = 150;
txt.height = 15;
txt.border = false;
txt.selectable = false;
txt.text = “No Item Selected”;
C_Holder3.push(txt);
addChild(txt);
txt.x = -10;
Appendix A17.1
IfStatEquip.as
txt.y = 95;
// box 2 for item description -- is turned off
for now, alpha 0
txt = new TextField();
f = new TextFormat(“Segoe”);
f.size = 10; f.color = 0xffffff;
txt.embedFonts = true;
txt.defaultTextFormat = f;
txt.border = false;
txt.selectable = false;
txt.width = 150;
txt.height = 50;
txt.text = “Item Description”;
txt.wordWrap = true;
txt.alpha = 0;
addChild(txt);
C_Holder3.push(txt);
txt.y = 105;
// box 2 for item description
txt = new TextField();
txt.embedFonts = true;
f.size = 9; f.leading = 2;
txt.defaultTextFormat = f;
txt.border = false;
txt.selectable = false;
txt.width = 200;
txt.height = 100;
txt.text = “Attributes”;
txt.wordWrap = true;
txt.x = -10;
addChild(txt);
C_Holder3.push(txt);
txt.y = C_Holder3[1].y + 15;
txt = null;
f = null;
}
private function createSlot(slotCount:int){
if( (slotCount % MAX_SLOTS_PER_LINE) == 0 && slotCount != 0){ // detect whenever the limit tile is reach
limitReachCounter ++; // counts every time
the limit is reach
xReset = 0;
// reset the x offset so tiles get lay down on most left again
}
var block:Sprite = new Sprite();
block.graphics.beginFill(unSelectC);
block.graphics.drawRoundRect(0,0,wid,hei,corner,cor
ner);
Appendix
C_Holder.push(block);
addChild(block);
block.x = ((wid+COL_GAP)*xReset);
block.y = ((hei+ROW_GAP) * limitReachCounter );
block = null; // GC
xReset ++;
// xReset is like the counter so
each loop gives the counter ++
}
// used when this class is removed
private function cleanOutAllContents(e:Event){
for(var i:int=0;i<C_Holder.length;i++){
C_Holder[i] = null;
}C_Holder = null;
removeEventListener(Event.REMOVED, cleanOutAllContents);
}
// change slot
public function changeSlot(){
counter++;
// reset counter so if counter is at 6 or MAX_
SlotS, make it 0
if(counter >= MAX_SLOTS){
counter = 0;
}
// read selected item if there’s anything under selection
updateItemName();
// put all other slots into unselected mode
for(var k:int=0;k<C_Holder.length;k++){
if(k != equip){
C_Holder[k].graphics.clear();
C_Holder[k].graphics.
beginFill(unSelectC);
C_Holder[k].graphics.drawRoundRect(0
,0,wid,hei,corner,corner);
//C_Holder[k].alpha = trans;
}
}
// highlight selected slot
if(counter == equip){
C_Holder[counter].graphics.clear();
C_Holder[counter].graphics.
lineStyle(2,unSelectC,1, true);
C_Holder[counter].graphics.drawRoundRect(0,
0,wid,hei,corner,corner);
Appendix A17.2
IfStatEquip.as
C_Holder[counter].graphics.
beginFill(selectC);
C_Holder[counter].graphics.drawRoundRect(0,
0,wid,hei,corner,corner);
C_Holder[counter].graphics.endFill();
}else if(counter != equip){
// put equip slot back to normal
C_Holder[equip].graphics.clear();
C_Holder[equip].graphics.
lineStyle(2,equipC, 1, true);
//var k:Sprite = newSprite();
//k.graphics.lineStyle(1, 0x000000, 1,
false, “normal”, null, null, 1);
C_Holder[equip].graphics.drawRoundRect(0,0,
wid,hei,corner,corner);
C_Holder[equip].graphics.
beginFill(selectC);
C_Holder[equip].graphics.drawRoundRect(0,0,
wid,hei,corner,corner);
C_Holder[equip].graphics.endFill();
// change next selected slot
C_Holder[counter].graphics.clear();
C_Holder[counter].graphics.
beginFill(unSelectC);
C_Holder[counter].graphics.drawRoundRect(0,
0,wid,hei,corner,corner);
C_Holder[counter].graphics.endFill();
C_Holder[counter].graphics.lineStyle(select
BorderThick,selectBorderC, 1, true);
C_Holder[counter].graphics.drawRoundRect(0,
0,wid,hei,corner,corner);
}
}
// update textField to display item info upon selection
change
private function updateItemName(){
var par:* = parent;
if(C_Holder2.length != 0){
// if not empty
//trace(C_Holder2[counter]);
if(C_Holder2[counter] is IItem){
C_Holder3[0].text = C_
Holder2[counter].getName();
C_Holder3[1].text = C_
Holder2[counter].getDesc();
C_Holder3[2].text = C_
Holder2[counter].getDesc2();
}else{
C_Holder3[0].text = “No Item Selected”;
C_Holder3[1].text = “Item Descrip-
Appendix
tion”;
C_Holder3[2].text = “Attributes”;
}
}else{
C_Holder3[0].text = “No Item Selected”;
C_Holder3[1].text = “Item Description”;
C_Holder3[2].text = “Attributes”;
}
}
// display previous selected slot as un-equipped
// then display selected slot as an equipped slot
public function equipItem():void{
// change previous equipped slot back to unequip
display status
// currently only 1 item can be equipped at a time
C_Holder[equip].graphics.clear();
C_Holder[equip].graphics.beginFill(unSelectC);
C_Holder[equip].graphics.drawRoundRect(0,0,wid,hei,
corner,corner);
C_Holder[equip].graphics.endFill();
// target the new selected slot and prepare it to
be equipped
equip = counter;
// display selected slot as equipped
C_Holder[equip].graphics.clear();
C_Holder[equip].graphics.lineStyle(2,equipC);
C_Holder[equip].graphics.drawRoundRect(0,0,wid,hei,
corner,corner);
C_Holder[equip].graphics.beginFill(selectC);
C_Holder[equip].graphics.drawRoundRect(0,0,wid,hei,
corner,corner);
C_Holder[equip].graphics.endFill();
/*
C_Holder[counter].graphics.lineStyle(2,equipC);
C_Holder[counter].graphics.drawRoundRect(0,0,wid,he
i,corner,corner);
C_Holder[counter].graphics.beginFill(selectC);
C_Holder[counter].graphics.drawRoundRect(0,0,wid,he
i,corner,corner);
C_Holder[counter].graphics.endFill();
*/
// transfer this item’s stats to hero’s stats for
equipping this item or using it
var par:* = parent;
if(C_Holder2.length != 0){
// if not empty
if(C_Holder2[equip] is IWeapon){
par.setAtk( C_Holder2[equip].getMinAtk(), C_Holder2[equip].getMaxAtk());
Appendix A17.3
IfStatEquip.as
par.setAtkSpd( C_Holder2[equip].getAtkSpd() );
}else{
//do nothing
par.useBareHands();
// if
no items unser selection go back to bare hands
//setAtk(1,3);
}
}else{
par.useBareHands();
//setAtk(1,3);
}
}
private function markSlotAsEquip(slotNum:int){
C_Holder[slotNum].graphics.clear();
C_Holder[slotNum].graphics.lineStyle(2,unSelectC,
1, true);
C_Holder[slotNum].graphics.drawRoundRect(0,0,wid,he
i,corner,corner);
//fill
C_Holder[slotNum].graphics.beginFill(selectC);
C_Holder[slotNum].graphics.drawRoundRect(0,0,wid,he
i,corner,corner);
C_Holder[slotNum].graphics.endFill();
}
// add item to open slots from left to right when enemy
drops item,
// else if slots full, queue item for a certain time period before deposing it
public function addItem(item:IItem):void{
if(availableSlots.length != 0){
// if there is an open slots
//pop an open slot
var openSlot = availableSlots[0];
// store open slot
occupySlots.push( availableSlots.
splice(0,1)); // use up slot and make open slot now occupy
//addChild(DisplayObject(item);
//Sprite(item).x = 10; Sprite(item).y = 10;
// need to cast sprite in order to target item
C_Holder[openSlot].addChild(item);
C_Holder2.push(item); // push item into holder 2
// we may not have to cast
Sprite when using addChild by doing Sprite(item)
// although item is implementing from Weapon Interface: IWeapon
// sometimes we need to have
Appendix
cast Sprite to display the object using addChild
// sometimes you may not
have to cast MovieClip, Bitmap, depending on what object it is
// when implementing an object is an interface
openSlot = null;
//read item name when item is put into sack
updateItemName()
}
}
}
}
Appendix A18.0
IFTopMenu.as
package
com.Lao.tanker {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
public class IFTopMenu extends Sprite{
public var C_Holder:Array = new Array();
public function IFTopMenu() {
createWorldName();
createTimeClock();
createHelpMenu();
}
// -----------------
// CREATE
// -----------------
private function createWorldName():void{
var f:TextFormat = new TextFormat(“Segoeb”);
var txt:TextField = new TextField();
f.size = 16;
f.color = 0xffffff;
txt.defaultTextFormat = f;
txt.embedFonts = true;
txt.width = 140;
txt.height = 20;
txt.border = false;
txt.text = “No Name”;
txt.selectable = true;
addChild(txt);
C_Holder.push(txt);
}
private function createTimeClock():void{
var clock:Clock2 = new Clock2(5,50,30, 6,
true);
// (hr, min, gameframerate, startDay betwen 0-6,
random a startDay?);
addChild(clock);
clock.x = 100;
C_Holder.push(clock);
}
private function createHelpMenu():void{
var menuList:HelpMenu = new HelpMenu();
menuList.x = 350;
addChild(menuList);
C_Holder.push(menuList);
}
public function cleanOutAllContents():void{
for(var i:int=0;i<C_Holder.length; i++){
}
}
}
}
Appendix
removeChild(C_Holder[i]);
C_Holder.splice(0);
Appendix A19.0
IItem.as
package com.Lao.tanker {
// Interfaces that extends this interface
// IWeapon, ISupply, IArmor
public interface IItem {
// you don’t define public, private, protected
// but classes must implement these functions as public
only
function getName():String;
function getDesc():String;
function setGold(g:int):void;
function drawLetter(n:String):void // weapon: lvl
0,1,2,3,R
// Craft: LQ, MQ, HQ
// Potion: S, M, L
//function getDesc2():String;
}
}
Appendix
Appendix A20.0
IMonster.as
package com.Lao.tanker {
/*
Interface Class
* You have to list all public methods that will be common for the
classes that implements this interface;
* You do so by writing the definition of the function, its name, its
parameters and its return type;
* You don’t have to open and close curly braces after the method definition
* You don’t specify if the method is private, public or protected
(that’s kind of obvious but I did that mistake)
* But any class that use this interface must implement the functions
as “PUBLIC” only, not private
* interface can only extend other interfaces
* a class can implement more than one interface
An interface is for the purpose of polymorphism, so that a var interface can hold an object of that interface
Also an interface helps all your classes that implements an interface, keep a structure or else an error will generate
var m:FruitInterface = new Orange();
var m:FruitInterface = new Apple();
function getCalorie(fruit:FruitInterface); // it can accept can
fruit as a parameter
*/
import flash.display.Sprite;
import flash.events.Event;
public interface IMonster {
// you don’t define public, private, protected, but these
functions below should only be used in class
// as public
//function takeHit(heroAtkDmg:int, enemyID:int);
function getGold():int;
function dropItem():IItem;
function setDropPercent(num:Number):void;
function animate();
}
}
Appendix
Appendix A21.0
IStage.as
package com.Lao.tanker {
/*
Interface Class
* You have to list all public methods that will be common for the
classes that implements this interface;
* You do so by writing the definition of the function, its name, its
parameters and its return type;
* You don’t have to open and close curly braces after the method definition
* You don’t specify if the method is private, public or protected
(that’s kind of obvious but I did that mistake)
* interface can only extend other interfaces
* a class can implement more than one interface
An interface is for the purpose of polymorphism, so that a var interface can hold an object of that interface
Also an interface helps all your classes that implements an interface, keep a structure or else an error will generate
var m:FruitInterface = new Orange();
var m:FruitInterface = new Apple();
function getCalorie(fruit:FruitInterface); // it can accept can
fruit as a parameter
*/
public interface IStage {
// you don’t define public, private, protected
//function createTopBanner();
//function createTile(tileCount:int):void;
}
}
Appendix
Appendix A22.0
IWeapon.as
package com.Lao.tanker {
/*
Interface Class
* You have to list all public methods that will be common for the
classes that implements this interface;
* You do so by writing the definition of the function, its name, its
parameters and its return type;
* You don’t have to open and close curly braces after the method definition
* You don’t specify if the method is private, public or protected
(that’s kind of obvious but I did that mistake)
* interface can only extend other interfaces
* a class can implement more than one interface
An interface is for the purpose of polymorphism, so that a var interface can hold an object of that interface
Also an interface helps all your classes that implements an interface, keep a structure or else an error will generate
var m:FruitInterface = new Orange();
var m:FruitInterface = new Apple();
function getCalorie(fruit:FruitInterface); // it can accept can
fruit as a parameter
*/
public interface IWeapon extends IItem {
// you don’t define public, private, protected
function setAtk(min:int,max:int):void;
function getMinAtk():int;
function getMaxAtk():int;
//function setGold():void;
}
}
Appendix
Appendix A23.0
Monster.as
package com.Lao.tanker {
import flash.events.Event;
import flash.display.MovieClip;
import flash.display.Sprite;
import com.Lao.tanker.weapon.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.utils.getTimer;
public class Monster extends MovieClip implements IMonster{
// array holder
public var C_Holder:Array = new Array();
//
holds hp bar and spdAtkBar
public var C_Holder2:Array = new Array();
//
holds the pop-up window displaying attack dmg
public var hitBox:Sprite;
// attributes
private var maxHp:int = 0;
private var hp:int = 0;
private var gold:int = 0;
// attacks
private var atkSpd:int = 3000;
// default value
private var minAtk:int = 1; // default value
private var maxAtk:int = 1; // default value
// drops
private var itemDropPercent:Number = 0.0;
//
item drop percentage
// targets
//private var par:* = parent; // target parent
variable
private var par;
private var stageLvl;
private var I_stat;
// stat interface
private var I_stat_slot;
// slot interface
private var timer:Timer;
private var spdTimer:Timer;
private var startTime;
public function Monster(health:int, minG:int, maxG:int,
atkS:int, minA:int, maxA:int, dropPer:Number) {
addEventListener(Event.ADDED_TO_STAGE, build);
addEventListener(Event.REMOVED_FROM_STAGE, isRemoved);
//addEventListener(Event.ENTER_FRAME, updateSpdAtkBar, false, 0, true);
maxHp = health; hp = maxHp; // hp
gold = Math.floor(Math.random()* (maxG-minG) ) +
minG; // gold
Appendix
atkSpd = atkS;
minAtk = minA;
maxAtk = maxA;
itemDropPercent = dropPer;
// create health bar
createHPBar();
// create atkSpd bar
createSpdAtkBar();
// create hitBox so hero can hit this enemey
createHitBox();
// create timer for attacking hero
timer = new Timer(atkSpd,1); //
atks hero according to speed
timer.addEventListener(TimerEvent.TIMER, atkHero,
false, 0, true);
spdTimer = new Timer(100);
// updates the spdBar
display every 100 miliseconds
spdTimer.addEventListener(TimerEvent.TIMER, updateSpdAtkBar);
}
private function build(e:Event){
par = parent; // target parent variable
stageLvl = par;
I_stat = par.parent.parent.C_Interface[0];
I_stat_slot = par.parent.parent.C_Interface[0].C_
Holder3[0];
gotoAndStop(1);
// start all monster in
frame 1 state
removeEventListener(Event.ADDED_TO_STAGE, build);
}
private function isRemoved(e:Event){
timer.removeEventListener(TimerEvent.TIMER, atkHero);
spdTimer.removeEventListener(TimerEvent.TIMER, updateSpdAtkBar);
removeEventListener(Event.REMOVED_FROM_STAGE, isRemoved);
}
// life bar
public function createHPBar(){
// add life bar display
var lifeBar:RectGaugeBar = new RectGaugeBar(180,
0x00ff00,4, 40, true);// lifebar rotation
C_Holder.push(lifeBar);
lifeBar.alpha = 0;
Appendix A23.1
Monster.as
lifeBar.x = 44;
lifeBar.y = 35;
addChild(lifeBar);
lifeBar = null;
}
public function createSpdAtkBar(){
var spBar:RectGaugeBar = new RectGaugeBar(180,
0x99CCFF, 3, 40, true);
// lifebar rotation
C_Holder.push(spBar);
spBar.alpha = 0;
spBar.x = 39;
spBar.y = 35;
addChild(spBar);
spBar = null;
}
private function createHitBox(){
hitBox = new Sprite();
hitBox.graphics.beginFill(0x00ff22, 0);
hitBox.graphics.drawRect(0,0,30,30);
hitBox.graphics.endFill();
addChild(hitBox);
}
private function updateSpdAtkBar(e:TimerEvent){
var newTime = getTimer();
var cur = newTime - startTime;
newTime = null;
C_Holder[1].updateBar(Math.floor((cur/atkSpd)*100)/100 );
//trace(time);
}
// TakeHite
private var atkInitiated = false;
// (dmg from hero, enemy’s id so it can be removed from
parent stage1)
public function takeHit(heroAtkDmg:int){
// start monster timer so monster can start attacking hero
timer.start();
spdTimer.start();
toggleDisplay(1);
// turn on visibility for
the hp and spdAtk bar
if(!atkInitiated){
// only get startTime once
if enemy hasn’t started attacking yet
startTime = getTimer();
atkInitiated = true;
}
hp -= heroAtkDmg;
Appendix
C_Holder[0].updateBar(hp/maxHp);
// update
lifebar
if(hp <=0){
// check if enemy is dead
//var par:* = parent;
//par.parent.parent.C_Interface[0].changeGold( getGold() );
// reward gold
//par.parent.parent.C_Interface[0].C_Holder3[0].addItem( dropItem() );
// reward item
//par.removeEnemy(enemyID); // call
stage1 to remove this enemey because it is a child of stage1
I_stat.changeGold( getGold() );
// reward gold
if( itemDrop() ){
// check if monster dropped any item when killed
I_stat_slot.addItem( dropItem() );
// then return a randomed dropped item
}
//par.removeEnemy(enemyID); // call
stage1 to remove this enemey because it is a child of stage1
par.removeEnemy(this);// call stage1 to remove this enemey because it is a child of stage1
}
}
private function toggleDisplay(alphaNum:Number){
C_Holder[0].alpha = alphaNum;
C_Holder[1].alpha = alphaNum;
}
public function getGold():int{
return gold;
}
// percent that this mob will drop an item when killed
protected function itemDrop():Boolean{
var randN:Number = Math.round(Math.random()*100)/100;
if( randN <= itemDropPercent){
return true;
}
return false;
}
// drop item - many monsters will override this method
public function dropItem():IItem{
var rand:Number = Math.floor(Math.random()*10);
if( rand > 5){
return new W0001(2); // drop a bone club
}else if(rand > 5){
return new W0001(1);
}else{
return new W0001(0);
}
Appendix A23.2
Monster.as
}
// modify drop percent
public function setDropPercent(num:Number):void{
itemDropPercent = num;
}
// movement - not in use at the moment
public function animate(){
/*
if(currentFrame == 1)
gotoAndStop(2);
else if(currentFrame == 2)
gotoAndStop(1);
*/
}
private function atkHero(e:TimerEvent){
var par = parent;
if( par.parent.parent.game_is_ready){// if main
engine is ready
startTime = getTimer();
// generate monster’s attack, the minAtk #
and maxAtk # is a possibile random in this formula below
var randAtk = Math.floor(Math.random()* (
(maxAtk+1)-minAtk ) ) + (minAtk)
I_stat.changeHP( randAtk * -1);
//
send data to stat interface and update
gotoAndPlay(“atk”);
// display atk dmg - calls parent or the
stage level’s function to display dmg atk
par.displayAtkDmg(this.x, this.y,
String(randAtk));
// this below will determine if monster
should keep attacking hero or not
canAtkHero();
}else{ // end of game_is_ready - reset the timers
so the monsters stop attacking if they are already
timer.reset();
spdTimer.reset();
atkInitiated = false;
toggleDisplay(0);
}// end of game_is_ready else
}
private function canAtkHero(){
if(par.heroIsStillHere() ){ // call stage to see
if hero is still next to recent attacked enemy
ever go up to infinite
can keep attacking
}else{
ible
}
}
}
}
Appendix
timer.reset();// reset timer so it doesn’t
timer.start();// start timer so monster
spdTimer.reset();
spdTimer.start();
timer.reset();
spdTimer.reset();
atkInitiated = false;
toggleDisplay(0);
// make window invis-
Appendix A24.0
RectGaugeBar.as
package com.Lao.tanker {
public class RectGaugeBar extends GaugeBar {
public function RectGaugeBar(rotateDegree:int, colr:uint,
wid:int, hei:int, border:Boolean) {
super(rotateDegree, colr, wid, hei, border);
}
}
}
Appendix
Appendix A25.0
Stage1.as
package com.Lao.tanker {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.Event;
import com.Lao.tanker.enemy.*;
public class Stage1 extends Sprite implements IStage{
// Floor Tile
private var dataTile:Tile;
// Array Reference Holder
public var C_Holder:Array = new Array();
//
floor tile
public var C_Holder2:Array = new Array();
//
data tile
public var C_Holder3:Array = new Array();
// enemies and hero
public var C_Holder4:Array = new Array();
// atk
dmg display - holds all the displays so it can be reuse
public var C_Holder5:Array = new Array();
private var availableTiles:Array = new Array();
// stagename
private var worldName:String = “WORLD 1”;
// Hero Variables
private var hero:Hero;
//Enemy variables
private var MAX_ENEMY:int = 6;
private var randomNum:int = 0;
// hold random generator
private var tilePick:int = 0;
private var xPos:Number;
// temp x position
holder
private var yPos:Number;
// temp y posistion holder
// Loop variables
private var i:int=0;
// Floor tile layout control var
private var tile:Sprite;
private var MAX_TILES:int = 50;
private var MAX_TILE_PER_LINE:int = 10;
private var limitReachCounter:int = 0;
// Individual tile appearence
Appendix
private var tColor = 0x733345;
private var tBorderThickness = 1;
private var tRoundness = 15;
// Individual tile demensions and spacing
private var wid:int = 50;
private var hei:int = 50;
private var COL_GAP:int = 9; // column gap between each
block left and right side
private var ROW_GAP:int = 9; // gap between rows - above
and below each tile
private var xReset:int = 0; // reset all new
tile’s x pos at the begining of each new row
private var xOffset:int = 140;
// each tile starts
with this x offset so it doesn’t overlap any menus
private var yOffset:int = 45;// each tile starts with
this x offset so it doesn’t overlap any menus
// Stage main border attribute
private var border_X_offset:int = 180;
private var bLineThickness:int = 1;
private var bColor = 0x733345;
//
border color
private var bWid:Number = 600;
private var bHei:Number = 370;
private var bRoundCorner:Number = 15;
public function Stage1() {
//addEventListener(Event.REMOVED, cleanOutAllContents, false, 0, true);
// create top banner
//createTopBanner();
// create floor tiles
for(i=0; i<MAX_TILES; i++){
createTile(i);
}
// create stage border for tiles
//createBorder();
// populate level with stuff (enemies, items, etc)
createEnemies();
// load hero
createHero();
// create atk dmg display (not only atk but other
status upon attack)
// these are pre-made windows to display atk dmg,
they will be hidden offstage when not in use
createAtkDmgDisplays(8);
// pass the
Appendix A25.1
Stage1.as
amount of max windows you would like to create
// 5-8 is usually a good number
}
private function createTopBanner(){
tile = new Sprite();
tile.graphics.beginFill(tColor);
tile.graphics.drawRoundRect(10,10,bWid, 20, bRoundCorner, bRoundCorner);
tile.graphics.endFill();
addChild(tile);
tile.x = border_X_offset;
// fix block
tile = new Sprite();
tile.graphics.beginFill(tColor);
tile.graphics.drawRect(10,18,bWid, 20);
tile.graphics.endFill();
addChild(tile);
tile.x = border_X_offset;
tile = null;
}
private function createTile(tileCount:int):void{
if( (tileCount % MAX_TILE_PER_LINE) == 0 && tileCount != 0){ // detect whenever the limit tile is reach
limitReachCounter ++; // counts every time
the limit is reach
xReset = 0;
// reset the x offset so tiles get lay down on most left again
}
tile = new Sprite();
xReset ++;
//tile.graphics.beginFill(0x987878);
//tile.graphics.drawRoundRect(10,10,wid,hei,15,15);
//tile.graphics.endFill();
//tile.graphics.lineStyle(tBorderThickness, tColor);
//tile.graphics.drawRoundRect(0,0,wid,hei,tRoundnes
s,tRoundness);
// data tile
dataTile = new Tile(1);
// create a
new data tile, these tiles have values and info in them
C_Holder.push(dataTile);
// Main array
holder for this class
tile.addChild(dataTile);
// for each tile created, nest a new data tile inside each tile
C_Holder2.push(tile);
Appendix
addChild(tile);
// add
tile to class to be diplay
tile.x = xOffset + ((wid+COL_GAP)*xReset);
tile.y = yOffset + ((hei+ROW_GAP) * limitReachCounter ) ;
tile = null;
}
private function createBorder(){
tile = new Sprite();
tile.graphics.lineStyle(bLineThickness, bColor);
tile.graphics.drawRoundRect(10,10,bWid,bHei,bRoundC
orner,bRoundCorner);
addChild(tile);
tile.x = border_X_offset;
}
private function createEnemies(){
// POWERBALL PICK METHOD
// -------------------------- //
// Enemies - populate each enemy onto each floor
tiles, two enemies can’t be on same floor tile
// -------------------------- //
// extract all floor tiles on this stage into a new
array
// then like the powerball game, randomly select
each tile once
// to hold an enemy or item
for(i=0; i<C_Holder2.length; i++){
// extract all stage tiles
availableTiles.push(i);
// into array
}
// this next line is important, it takes out the
first tile as a possibility when randomming tiles
// to prevent enemy from spawning on the first tile
where hero is also on
availableTiles.splice(0,1);
// set so one tutorial monster is created
var enemyTutorialCount:int = 0;
//populate enemey onto stage layout
for(i=0; i<MAX_ENEMY; i++){
// the percentage of what enemies get spawn
// you look at 100% bar and 2 levels deep
// each monster has a % of being spawn
//
var e1;
// method 1 for spawning enemies
Appendix A25.2
Stage1.as
var randNum = Math.floor(Math.random()*10);
// turn random spawn off for not
if(randNum < 8){
if(enemyTutorialCount==0){
e1 = new M0001(i);
//80% of being spawn
}else{
e1 = new M0002(i);
//
dull rabbit
}
enemyTutorialCount++;
}else if(randNum < 9){
e1 = new M0002(i);
}else{
e1 = new M0003(i);
// 20%
of being spawn
}
// method 2 for spawning enemies
/*
if( Math.floor(Math.random()*2) == 0){
e1 = new Rabbit(i);
//
availableTiles[randomTile]
}else{
e1 = new Turtle(i);
}
*/
addChild(e1); // add enemy to this class, not the tankerWorld
C_Holder3.push(e1);
// Put each enemy on random tiles
// pick one random number from the array
randomNum = Math.floor(Math.random() *
availableTiles.length );
// note: if array length is 50, you can’t
get random # 50, random max would be 49
tilePick = availableTiles[randomNum];
availableTiles.splice(randomNum,1); //
take out each tile number as it gets selected
//position enemies
xPos = C_Holder2[tilePick].x;// store x
pos
yPos = C_Holder2[tilePick].y;// store y
pos
Appendix
e1.x = xPos+10;
e1.y = yPos+10;
} // end of for loop
} // end of createEnemies
// create hero and spdAtkBar
private function createHero(){
hero = new Hero(200,61);
addChild(hero); // add hero to the world
C_Holder3.splice(0,0,hero); // (start at index, remove amount, insert object)
// create spdBar gauge bar attach it inside hero
var spBar:RectGaugeBar = new RectGaugeBar(180,
0x99CCFF, 3, 40, true);
// lifebar rotation
hero.C_Holder.push(spBar);
spBar.x = 3;
spBar.y = 30;
hero.addChild(spBar);
spBar = null;
}
public function detectEnergyCost():int{
for (var n:int=0; n < C_Holder.length; n++) {
if (C_Holder[n].hitTestObject(C_Holder3[0])
){
// tile against hero object
//if (C_Holder[i].hitTestPoint(C_
Holder3[0].x,C_Holder3[0].y, true)){ // tile against hero point
return C_Holder[n].getVal(); // energy value
}
} // end of hit test for loop
return 0;
}
public function detectBoxID():int{
for (i=0; i < C_Holder.length; i++) {
//if (C_Interface[2].C_Holder[i].
hitTestPoint(hero.x, hero.y)){
if (C_Holder[i].hitTestPoint(C_
Holder3[0].x,C_Holder3[0].y, true)){ // tile agains hero point
return i;
// box value
}
} // end of hit test for loop
return 0;
Appendix A25.3
Stage1.as
}
// makes hero atk enmey or pick up items if there’s item
public function checkHeroCollision(){// is only checked
when action button is pressed
// run through enemy and item array to see if hero
collided with anything
for (i=1; i < C_Holder3.length; i++) {
if ( C_Holder3[i].hitBox.hitTestObject(C_
Holder3[0]) ){// check for collision with enemies
// C_Holder3[0] is hero reference,
[1] and up are enemies and items
var par:* = parent;
//
target parent
//1. if collision, what type is the
collision? enemy or item?
if( C_Holder3[i] is IMonster){
par.parent.
summonTutorial(“Attack”);
// Get Hero AtkDmg and store
it
C_Holder3[0].
gotoAndPlay(“attack”);
var heroAtk:int = par.
parent.C_Interface[0].getHeroAtk();
// DISPLAY ATK DMG
// important - display atk
dmg before you call the takeHit
// because if enemy is remove, enemy array decrease will
// cause in targeting wrong
enemy x,y coordinate
// display atk dmg done by
hero, pass in monster’s x and y coord and hero atk
displayAtkDmg( C_
Holder3[i].x + 20, C_Holder3[i].y, String(heroAtk) );
C_Holder3[i].takeHit(
heroAtk );
// enemy take
hit
}else if(C_Holder3[i] is IItem){
trace(“item interface
found”);
}
Appendix
} // end if hittest
} // end for loop
//return null;
}
public function heroIsStillHere():Boolean{
// monster who just got attack calls this each time
after it attacks to see if they should keep attacking hero
for (var i:int=1; i < C_Holder3.length; i++) {
if(C_Holder3[i].hitBox.hitTestObject(C_
Holder3[0]) ){
return true;
}
}
return false;
}
public function removeEnemy(enemy:MovieClip){
C_Holder3.splice(C_Holder3.indexOf(enemy),1);
// take out of enemylist
removeChild(enemy);
// remove child or enemey
}
// -----------------//
// Atk Dmg Display //
// -----------------//
// these displays are like bullets that will get re-use
over and over again
private var atkWinX:int = 850, atkWinY:int = 300;
private var counter:int = 0;
private function createAtkDmgDisplays(MAX_WINDOW:int){
for(var i:int=0; i<MAX_WINDOW; i++){
var atkWindow:StatusWindow = new StatusWindow(“100”);
C_Holder4.push(atkWindow);
// put these off stage to the right
var par = parent;
atkWindow.x = atkWinX;
atkWindow.y = atkWinY;
addChild(atkWindow);
}
}
public function displayAtkDmg(newX:int, newY:int,
newAtkDmgNumber:String){
C_Holder4[counter].y = newY;
C_Holder4[counter].x = newX;
C_Holder4[counter].turnOn( newAtkDmgNumber );
counter++;
// increase counter
Appendix A25.4
Stage1.as
so next bullet can be used
if(counter > C_Holder4.length-1){
counter = 0; // reset counter
}
}
// does not actually removeChild but insted puts the window offstage
public function removeWindow(obj:Sprite){
C_Holder4[C_Holder4.indexOf(obj)].y = atkWinY;
C_Holder4[C_Holder4.indexOf(obj)].x = atkWinX;
}
public function getWorldName():String{
return worldName;
}
// ----------------------// Garbage Collection
// --------------------
public function cleanOutAllContents(){
var i:int=0;
for(i=0; i<C_Holder4.length; i++){
display windows
//removeChild(C_Holder3[i]);
C_Holder4[i] = null; reference all objects null
}
C_Holder4.splice(0);
C_Holder4 = null;
for(i=0; i<C_Holder3.length; i++){
emies and hero
//removeChild(C_Holder3[i]);
C_Holder3[i] = null; reference all objects null
}
C_Holder3.splice(0);
C_Holder3 = null;
for(i=0;i<C_Holder2.length; i++){
data tiles
//removeChild(C_Holder2[i]);
C_Holder2[i] = null; // turn all references to null for GC
}
C_Holder2.splice(0);
C_Holder2 = null;
for(i=0; i<C_Holder.length; i++){
//removeChild(C_Holder[i]);
C_Holder[i] = null;
// remove atk
//
// remove en-
//
// remove
Appendix
}
C_Holder.splice(0);
C_Holder = null;
//removeEventListener(Event.REMOVED, cleanOutAllContents);
}
}
}
Appendix A26.0
StatContainer.as
package
com.Lao.tanker {
import
import
import
import
import
import
import
flash.display.MovieClip;
flash.display.Sprite;
flash.text.TextField;
flash.text.TextFormat;
flash.display.Graphics;
flash.display.Stage;
flash.events.Event;
public class StatContainer extends MovieClip {
// Left Side Menu
// define blocks
private var statContainer:Sprite;
private var block:Sprite;
private var blockArr:Array = new Array();
private var MAX:int = 4;
private var wid:int = 170;
private var hei:int = 23;
private var lineGap:int = 25;
private var startX:int = 10;
private var startY:int = 25;
private var headerColor = 0xB03535; // redTan
private var subColor = 0xFDC68F;
// yellowOrange
private var menuBorderColor = 0x733345;
// maroon
public function StatContainer() {
// constructor code
addEventListener(Event.ADDED, loadMenu);
}
public function loadMenu(e:Event){
trace(“menu added”);
//text
var countTxt:TextField;
var format:TextFormat = new TextFormat();
format.size = 20;
format.color = 0xffffff;
// create blocks and define colors shapes
for(var i:int=0; i<MAX; i++){
block = new Sprite();
// block.graphics.lineStyle(2, 0xFDC68F);
block.graphics.drawRect(0,0, wid,hei);
block.graphics.beginFill(subColor);
block.graphics.drawRect(0,0, wid, hei);
block.graphics.endFill();
// text
countTxt = new TextField();
countTxt.selectable = false;
Appendix
switch(i){
case 0:
countTxt.text = “HP”;
break;
case 1:
countTxt.text = “ENERGY”;
break;
case 2:
countTxt.text =
“DEF”;
break;
case 3:
countTxt.text =
“ATK”;
break;
}
//countTxt.text = “”+i;
countTxt.x = 5;
countTxt.y = 5;
block.addChild(countTxt);
statContainer.addChild(block);
blockArr.push(block);
}
//position title “Stats” block
block = new Sprite();
block.graphics.beginFill(headerColor);
block.graphics.drawRoundRect(10,10,170,20,15,15);
block.graphics.endFill();
statContainer.addChild(block);
block = new Sprite();
block.graphics.beginFill(headerColor);
block.graphics.drawRect(0,0, wid, hei-10);
block.graphics.endFill();
block.x = startX;
block.y = startY;
countTxt = new TextField();
countTxt.selectable = false;
countTxt.text = “Hero Stats”;
countTxt.setTextFormat(format, -1);// =
format;
countTxt.x = 5;
countTxt.y = -10;
block.addChild(countTxt);// add text to
block
statContainer.addChild(block);
// position sub-Stats blocks
for(var k:int=0; k<blockArr.length; k++){
blockArr[k].x = startX // ((wid+10)*k) +
50;
blockArr[k].y = startY+13+lineGap*k;
}
Appendix A26.1
StatContainer.as
// create border
var b1:Sprite = new Sprite();
b1.graphics.lineStyle(1, menuBorderColor);
b1.graphics.drawRoundRect(10,10,170,200,15,15);
statContainer = new Sprite();
statContainer.addChild(b1);
addChild(statContainer);
}
}
}
Appendix
Appendix A27.0
StatusWindow.as
package com.Lao.tanker {
/*
Like bullets, instead of creating new bullets each time anything
attcks
This class uses a pool method to lower memory leaks, like bullets
in a pool
this class displays the damage using textField when hero or enemy
attacks
When the class moves a certain distance, this class should be
moved off stage
and be reused once the last bullet is used
*/
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
import flash.display.Graphics;
import flash.display.Shape;
import flash.text.TextFormat;
public class StatusWindow extends Sprite {
private var C_Holder:Array = new Array();
private var txt:TextField;
private var distLimit:int = 40;
private var origY:int = 0;
private var isActive:Boolean = false;// this class starts
with the off trigger
public function StatusWindow(stat:String) {
// constructor code
txt = new TextField();
var f:TextFormat = new TextFormat(“Segoe”);
txt.defaultTextFormat = f;
txt.embedFonts = true;
txt.width = 50;
txt.height = 20;
txt.selectable = false;
txt.border = false;
txt.text = “5”;
C_Holder.push(txt);
addChild(txt);
addEventListener(Event.ADDED_TO_STAGE, added);
//addEventListener(Event.REMOVED_FROM_STAGE, isRemoved);
}
// Event added
private function added(e:Event){
origY = this.y;
// record start position upon creation or when added
//trace(this.y);
Appendix
removeEventListener(Event.ADDED_TO_STAGE, added);
}
// Enterframe
// ----------- Main engine enterframe calls this function
if this class is in use
public function updatePos(){
this.y --;
// move this class obj up the stage
// once this obj moves a certain distance, call
parent to move it offstage (not removeChild)
if( Math.abs(this.y-origY) > distLimit){
var par:* = parent;
par.removeWindow(this);
isActive = false;
}
}
// constant checker - called from main engine
public function isUse():Boolean{
return isActive;
}
// reuses an old attack window but displays the new atk
dmg
// this class only cares about the y coordinate it ignores
x coord
public function turnOn(newDmg:String){
C_Holder[0].text = newDmg;
origY = this.y;
// record new y start pos so it can calculate distance travel
again
isActive = true;
// allow main enterframe to update this class
}
}
}
Appendix A28.0
TankerEngine.as
Appendix
package com.Lao.tanker {
/*
Tanker Engine
- specifically design to run the Tanker RPG game
*/
/*
INDEX
c1.0 ................... Imports
c1.1 ................... Main class
c1.2
................... Main public/private variables
c1.3
................... Class Constructor
c1.4
................... Test objects and variables
c1.5
................... EnterFrame update - game ticker
c1.6
................... Keyboard update - game ticker
c1.7
................... Pre-loader complete - Load game interface
c1.8
................... Return to menu button functions
c1.9
................... Top Menu Bar [WorldName, Clock, Help
Menu]
c1.91 ................... Window Popper
C3.0
................... Garbage Collection
*/
// c1.0
import com.asgamer.snipergame.ThePreloader;
import flash.display.MovieClip;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.display.Sprite;
import flash.text.TextField;
//sound
import flash.media.Sound;
import flash.media.SoundLoaderContext;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.system.System;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.utils.setTimeout;
// c1.1
public class TankerEngine extends MovieClip {
// private var fr:FramerateTracker; // for fps testing
///private var testTxt:TextField = new TextField(); // for
memory testing
private var testArr:Array = new Array();
// hold the testing objects
// var
// test variables
// c1.3
// ----------------
// ---------------
// GAME BUTTON CONTROLS & TRIGGER STATES
// ---------------
private var btn_quit = 81;
// ‘Q’ key
private var btn_slot = 16;
// “SHIFT” key
private var btn_equip = 90; // ‘Z’ key
private var btn2_equip = 191;// ‘/’ key
private var btn_atk
= 65; // ‘a’ key
private var btn_action = 32; // ‘spacebar’ key
// Senital Values
public var game_is_ready:Boolean = false;
public var user_input = false;
// For simple “Yes” “No” window pop ups - holds user input
// ---------------
// GAME WORLD
// ---------------
public var tankerWorld:MovieClip = new MovieClip(); //
holds all types of display in the game
// ---------------
// TURN ON / OFF variables
// ---------------
private var allowGameTestDisplays:Boolean = false; // show test objects (FPS, game objects, etc)
// ---------------
// The Main Array - references all interface so you can
access all other contents in the game
public var C_Interface:Array = new Array(); // to reference and hold all the interface objects
// Note* each interface will have a public var C_
Holder array
// C_Holder references editable objects so you can
access child’s contents
// index
// 0 = preloader
// 0 = IFStat [replace preloader]
// 1 = stage level
// 2 = window pop up
// 3 = time menu [time clock, help menu]
Appendix A28.1
TankerEngine.as
// CONSTRUCTOR
// ---------------
public function TankerEngine() {
// the main stage/canvas
addChild(tankerWorld);// container that holds all
display objects in this game
// load preloader
var preloader = new ThePreloader(474, this.loaderInfo);
C_Interface.push(preloader); // reference preloader
tankerWorld.addChild(preloader);
// display preloader
preloader.addEventListener(“loadComplete”, loadAssets, false, 0, true);
// about eventListener:
// use true for weak reference so Garbage
Coolection will collect it when not being referenced
preloader.addEventListener(“preloaderFinished”,
loadAllFonts, false, 0, true);
// GAME ENGINE UPDATE FUNCTIONS
addEventListener(Event.ENTER_FRAME, updateGameTicker, false, 0, true); // enterFrame updater
// use weak reference because every time
you run this flash game, memory will be reset
stage.addEventListener(KeyboardEvent.KEY_DOWN, updateGameKeyboard, false, 0, true); // keyboard updater : must add keyboardEvent to stage
// make sure to not allow key inputs till
eveyrthing is loaded, including hero
//c1.4
if(allowGameTestDisplays){
// turn it off/false
when game is finalize
var i:int = 0;
// framerate tracker
var fr:FramerateTracker = new FramerateTracker();
addChild(fr); // add class object to stage
testArr.push(fr);
fr = null;
// delete one reference
testArr[0].x = stage.stageWidth-120; // position in far left corner
testArr[0].y = 5;
// memory tracker
var extraTestItems:int = 7;
for(i = 1; i<extraTestItems; i++){
var testTxt:TextField = new TextField();
// create text tester
Appendix
testArr.push(testTxt);
testTxt = null;
testArr[i].width = 200;
addChild(testArr[i]);
testArr[i].x = stage.stageWidth-120;
// auto re-position each tester text field below the previous
testArr[i].y = 30+(20*i);//50
}
}
}
// c1.5
// ------------------------------------------------------// ------------------------------------------------------// ENTER FRAME FUNCTION
// ------------------------------------------------------// ------------------------------------------------------//
//
//
//
so use it wisely
----------------------------------------------Game Update - 1 - 30fps ticker
----------------------------------------------this function updates the game at 30fps consecutively -
public var heroCanMove:Boolean, goLeft:Boolean,
goRight:Boolean, goUp:Boolean, goDown:Boolean;
public var startPosX;
public var startPosY;
private var spd:int = 4;
private var maxDistance:int = 59;
// amount of distance
hero can move
private var animateCounter:int = 0;
private function updateGameTicker(e:Event){
updateGameTestDisplays();
//
turn off when not needed
// Hero movement update - the initiator is in the
Hero.as class
if(game_is_ready){
//C_Interface[1].C_Holder5[0].updateClock();
C_Interface[3].C_Holder[1].updateClock();
updateHeroMovement();
checkHp();
updateAtkDmgDisplays();
Appendix A28.2
TankerEngine.as
} // end of gameIsReady
}
// ENTERFRAME UPDATE FUNCTIONS
private function updateGameTestDisplays(){
//tankerWorld.hero.x -= speed;
// update Game Test Data if turned on
if(allowGameTestDisplays){
testArr[0].getFps();
testArr[1].text = “MEM USE: “ + Number(System.totalMemory/1024).toFixed(2);
testArr[2].text = “C_Interface: “ + C_Interface.length;
testArr[3].text = “tankerWorld: “ + tankerWorld.numChildren;
if(game_is_ready){
// to prevent errors for var that don’t exist till
game is fully running
testArr[4].text = “Hero & ENEMY: “ + C_
Interface[1].C_Holder3.length;
}
}
}
private function updateHeroMovement():void{
if(heroCanMove){
// go right
if(goRight){
C_Interface[1].C_Holder3[0].x += spd;
if( Math.abs( C_Interface[1].C_Holder3[0].x startPosX ) >= maxDistance){
goRight = false;
heroCanMove = false;
C_Interface[1].C_Holder3[0].x --;
// to
offset hero slightly back into position
performUpdate();
}
// go left
}else if(goLeft){
C_Interface[1].C_Holder3[0].x -= spd;
if( Math.abs( C_Interface[1].C_Holder3[0].x startPosX ) >= maxDistance){
goLeft = false;
heroCanMove = false;
C_Interface[1].C_Holder3[0].x ++;
// to
offset hero slightly back into position
performUpdate();
}
// go up
}else if(goUp){
C_Interface[1].C_Holder3[0].y -= spd;
if( Math.abs( C_Interface[1].C_Holder3[0].y startPosY ) >= maxDistance){ // stop once max distance reach
goUp = false;
Appendix
heroCanMove = false;
C_Interface[1].C_Holder3[0].y ++;
// to
offset hero slightly back into position
performUpdate();
}
// go down
}else if(goDown){
C_Interface[1].C_Holder3[0].y += spd;
if( Math.abs( C_Interface[1].C_Holder3[0].y startPosY ) >= maxDistance){
goDown = false;
heroCanMove = false;
C_Interface[1].C_Holder3[0].y --;
// to
offset hero slightly back into position
performUpdate();
}
}
} // end of heroCanMove
}
private function updateAtkDmgDisplays():void{
//update Attack Dmg Windows - targets the stage level class then targets
atkDmg Windows
if(C_Interface[1].C_Holder4.length != 0){
for(var i:int =0; i<C_Interface[1].C_Holder4.length; i++){
if(C_Interface[1].C_Holder4[i].isUse()){
C_Interface[1].C_Holder4[i].updatePos();
}
}
}
}
private function checkHp(){
if( C_Interface[0].checkHP() <= 20){
summonTutorial(“LowHealth”);
}
if( C_Interface[0].checkHP() <= 0){
summonTutorial(“Health”);
// finish implementing the HP zero penalty
}
}
// perfrom heroUpdate after hero moves - look at code
above inside updateHeroMovement
// such as energy loss
private function performUpdate(){
var eCost = C_Interface[1].detectEnergyCost();
// times negative to indicate neg #
C_Interface[0].changeEnergy( eCost );
// test display
if(allowGameTestDisplays){
Appendix A28.3
TankerEngine.as
testArr[5].text = “Energy Val: “+
eCost;//C_Holder[i].getVal();// turn off when done testing
testArr[6].text = “Box “ + C_Interface[1].detectBoxID();// turn off when done testing
}
}
// ------------------------------------------------------// ------------------------------------------------------// END OF ENTER FRAME FUNCTION
// ------------------------------------------------------// ------------------------------------------------------// c1.6
// ----------------------------------------------// GAME UPDATE - 2 - Keyboard
// ----------------------------------------------// this function will update the game only when a button is press
private function updateGameKeyboard(e:KeyboardEvent){
if(game_is_ready){
// only if game is ready and
everything is loaded will it enable keyboard detection
// start first tutorial
summonTutorial(“Intro”);
// hero move detection
if( !heroCanMove ){
// only if
hero is not currently moving can user press move btn
// returns true false upon
movement
C_Interface[1].C_Holder3[0].
moveHero(e);
if( C_Interface[0].checkEnergy() >= 1){
summonTutorial(“Energy”);
}
// attack
if( C_Interface[0].checkHeroAtkStatus() ){
// if hero atk is ready
if(e.keyCode == btn_
atk){ // can only atk or pick items once hero is not moving
C_Interface[1].checkHeroCollision();// does everything from minus hp, to kill,
get gold, etc.
}
}
}else{
Appendix
// do nothing if hero cannot
move, it is probably on the map’s edge
}
// Game interactive button controls
if(e.keyCode == btn_slot){
// browse
through equipments
C_Interface[0].C_Holder3[0].changeSlot(); //trace(e.keyCode);
}
if(e.keyCode == btn_equip || e.keyCode ==
btn2_equip){ // equip current selected equipment
C_Interface[0].C_Holder3[0].equipItem(); //trace(e.keyCode);
}
// -------------------------------------------------------
// important to put goToStartMenu controls
last // or error will occur //
// because above functions may still some
var needed to run before the var gets set to null
// GAME MENU CONTROLS -- see above for controls re-mapping
if(e.keyCode == btn_quit){
// Q button
--> Start Menu
returnToStartMenu();
}
//trace(e.keyCode);
}
//trace(windowTut1_energy.status);
startGCCycle();
// call Garbage Collect every time game button is press to free memory
//trace(e.keyCode);
}
// c1.7
// ----------------------------------------------// ----------------------------------------------// THE MAIN LOADER
// ----------------------------------------------
// load all assests - will help the preloader load correctly
private function loadAssets(e:Event) : void{
this.play();
C_Interface[0].removeEventListener(“loadComplete”,
loadAssets);
}
// Game is done loading all assets, load start menu
private function loadAllFonts(e:Event) : void{
// remove event
Appendix A28.4
TankerEngine.as
C_Interface[0].removeEventListener(“preloaderFinish
ed”, loadAllFonts);
// remove preloader
tankerWorld.removeChild(C_Interface[0]);
C_Interface[0] = null;
C_Interface.pop();
// remove first item and
clear C_Interface again
// load all text fonts for the game
var FL:FontLoader = new FontLoader();
// will load a invisible external font swf
// you can now use the text fonts
FL.addEventListener(“loadComplete”, beginStartMenu,
false, 0, true);
// when safe to use font, begin startMenu
}
private function beginStartMenu(e:Event){
startMenu();
//e.target.removeEventListener(“loadComplete”, beginStartMenu);
//remove
//e.removeEventListener(“loadComplete”, beginStartMenu);
}
// Start Menu
private function startMenu(){
var middle:int = stage.stageWidth/2;
var if_start = new IFStart(middle,100); //
TankerStartMenu(x,y)
tankerWorld.addChild(if_start);
C_Interface.push(if_start); // 1st statMenu item
C_Interface[0].C_Holder[0].
addEventListener(MouseEvent.CLICK, playGame, false, 0, true);
}
// Play Game
public function playGame(e:MouseEvent){
// remove event
C_Interface[0].C_Holder[0].
removeEventListener(MouseEvent.CLICK, playGame);
tankerWorld.removeChild(C_Interface[0]);
// remove start menu
//C_Interface[0].clearOutAllContents();
C_Interface[0] = null;
C_Interface.splice(0,1);
// remove from array
//trace(“Game Loaded, now loading interface”);
Appendix
// load user game interface
loadGameInterface();
}
private function loadGameInterface(){
// -------------------------- //
// The Hero Stat Menu
// -------------------------- //
var if_stat = new IFStat(); // consider passing in hero stats
tankerWorld.addChild(if_stat);
C_Interface.push(if_stat);
// interface 1
// set stats
if_stat.setHP(50);
if_stat.setEnergy(0);
if_stat.setAtk(1,2);
if_stat.setAtkSpd(800);
//if_stat.setDef(5);
if_stat.setGold(0);
// -------------------------- //
// Load Stage1
// -------------------------- //
//C_Interface[1] = new FloorTiles(C_AI);
//
consider calling this class a level name, so you can do differen lvls
var if_stage1 = new Stage1();// consider calling
this class a level name, so you can do differen lvls
if_stage1.x = 20; if_stage1.y = 13;
tankerWorld.addChild(if_stage1);
C_Interface.push(if_stage1); // C_Interface[1]
if_stage1 = null;
stage.focus = this;
// to help force focus the
stage so buttons can work
// target stage levels by using the
C_Interface[1] name
// because each time a new stage is
load
// it will be given C_Interface[1]
as a reference over writting the old stage
// -------------------------
// Load PopWindow - a textfield displaying user with
info upon triggering an event
// -------------------------
createPopWindow()
// C_Interface[2]
// ------------------------
// Load assets on top of stage banner - (clock and
world name and help menu)
Appendix A28.5
TankerEngine.as
// ------------------------
createTopAssets();
// C_Interface[3]
// music test
//loadSound();
game_is_ready = true; // after all contents loads,
set game_is_ready marker to true
}
/* -- Music Sound
private var soundClip:Sound, sndChannel:SoundChannel;
private function loadSound():void{
//Create an instance of the Sound class
soundClip=new Sound();
//Create a new SoundChannel Object
sndChannel=new SoundChannel();
//Load sound using URLRequest
soundClip.load(new URLRequest(“sound/theme.mp3”));
//Create an event listener that wll update once
sound has finished loading
soundClip.addEventListener(Event.COMPLETE,
playSound,false,0,true);
}
private function playSound(evt:Event):void {
//Play loaded sound
sndChannel=soundClip.play(0,999);
}
*/
// c1.8
// --------------------------------// Return To Menu Buttons
// -------------------------------
public function returnToStartMenu(){
game_is_ready = false;
//unload all interfaces (if_stat, if_start, if_money, ...)
for(var i:int=0; i<C_Interface.length; i++){
C_Interface[i].cleanOutAllContents();// every interface class should have this function
tankerWorld.removeChild(C_Interface[i]);
C_Interface[i] = null;// null all referenced objects for GC (garbage collection)
}
C_Interface.splice(0);// clear entire array starting with index 0 to end of array
// no not null C_Interface because this var
get’s used even when user goes back to start menu again
Appendix
// load startMenu
startMenu();
}
//
//
//
//
c1.9
----------------------------------------------top assests that goes ontop of stage display
----------------------------------------------
private function createTopAssets():void{
var ifTopMenu:IFTopMenu = new IFTopMenu();
tankerWorld.addChild(ifTopMenu);
ifTopMenu.x = 225;
ifTopMenu.y = 20;
C_Interface.push(ifTopMenu); // C_Interface is now index
3, index 2 is the window poper holder
getStageName();
// world name
}
private function getStageName():void{
C_Interface[3].C_Holder[0].text = C_Interface[1].getWorldName();
// index 3
}
// c1.91
// ---------------------------------------// Window Popers that pop up warnings upon an event trigger
// ----------------------------------------public var windowCount:int = 0;
// doesn’t really do anthing at the
moment
private function createPopWindow():void{
// prepare it
and set it invisible at start of game
var win:WindowTutorial = new WindowTutorial();
win.x = 198; win.y = 134;
tankerWorld.addChild(win);
C_Interface.push(win);
// this object should now be in the 2nd index of C_Interface
}
// whenever you want to call upon a tutorial, use thi
function
public function summonTutorial(tutorial:String):void{
// 1. find the tutorial you want to use, referencing
the <title> in the getIndex()
// - look in the tutorial.xml to know what tutorial
reference
var newIndex:int = C_Interface[2].tutTitle.
getIndex(tutorial);
Appendix A28.6
TankerEngine.as
if(newIndex == -1){
throw new Error(“No such tutorial exist
yet. Add \’”+ tutorial+”\’ to the tutorial.xml first”);
}
if(C_Interface[2].C_Holder2[newIndex].status){
// check if window should still run again
game_is_ready = false;
C_Interface[2].popWindow(C_Interface[2].
tutDesc[newIndex], newIndex);
}
}
// any class can utilize the engine’s popWindow()
/*
public function popWindow(newTxt:String,
windowRef:Object):void{
if( C_Interface[2] is Window){
//
check if is Window object
C_Interface[2].setText(newTxt);
C_Interface[2].visible = true;
C_Interface[2].setWindowRef(windowRef);
windowCount++;
// max out the window
so only 1 window can pop up at a time
}else{
throw new Error(“C_Interface[2] is either
not a window, is null, or does not exist inside engine.as”);
}
}
*/
// c2.0
// --------// prototype functions
// search for a value in an array and return that index
Array.prototype.getIndex = function(data) {
for (var i:int=0; i<this.length; ++i) {
if (this[i] == data) {
return i;
}
}
return -1;
};
// c3.0
// --------------------------------------// Manual Garabage Collection Function
// --------------------------
private var gcCount:int;
private function startGCCycle():void{
gcCount = 0;
addEventListener(Event.ENTER_FRAME, doGC);
}
Appendix
private function doGC(evt:Event):void{
flash.system.System.gc();
// first time
will only sweep for references
if(++gcCount > 1){
removeEventListener(Event.ENTER_FRAME,
doGC); // 2nd time will free memory
//setTimeout(lastGC, 40);
// seem to
create memory leak, turn it off for now
}
}
/*private function lastGC():void{
flash.system.System.gc();
}*/
}
}
Appendix A29.0
TankerFont.as
package
com.Lao.tanker {
import
import
import
import
import
import
flash.display.Sprite;
flash.text.TextField;
flash.text.TextFormat;
flash.text.Font;
flash.text.TextFieldAutoSize;
flash.text.AntiAliasType;
public class TankerFont extends Sprite{
public function TankerFont() {
// constructor code
var myFont:Font1 = new Font1();
var f:TextFormat = new TextFormat();
f.font = myFont.fontName;
f.size = 24;
var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
myTextField.antiAliasType = AntiAliasType.ADVANCED;
myTextField.defaultTextFormat = f;
myTextField.embedFonts = true;
myTextField.text = “The quick brown fox jumped over
the lazy dog.”;
addChild(myTextField)
}
}
}
Appendix
Appendix A30.0
TankerPreloader.as
package com.Lao.tanker {
/*
This class is Tanker game engine
It runs all the other classes together to make the game run
*/
//imports
// import com.Lao.IFStat;
// don’t need to include this import because IFStat is already
// under com.Lao the package url
import com.asgamer.snipergame.ThePreloader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class TankerPreloader extends MovieClip {
//var
private var preloader:ThePreloader;
private var target:Stage;
public function TankerPreloader() {
// constructor code
// load preloader
preloader = new ThePreloader(474, this.loaderInfo);
stage.addChild(preloader);
preloader.addEventListener(“loadComplete”, loadAssets);
preloader.addEventListener(“preloaderFinished”,
loadGame);
}
private function loadAssets(e:Event) : void
{
this.play();
}
private function loadGame(e:Event) : void
{
stage.removeChild(preloader);
trace(“Game Loaded, now loading interface”);
loadGameInterface();
}
private function loadGameInterface(){
// left side stat menu
var ifStat:IFStat = new IFStat(target);
addChild(ifStat);
}
}
}
Appendix
Appendix A31.0
TankerStartMenu.as
package com.Lao.tanker {
/*
this is the start menu
it puts a textfield “Start” non-selectable inside a block sprite.
The block is then given an
addEventListener(MouseEvent.CLICK)
on click the user will be able to proceed to play the game or
start the game.
The game logo is inserted underneath the Start Button
*/
//imports
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.*;
import flash.display.BitmapData;
// to represent logo bitmapdata
import flash.display.Bitmap; // to put logo bitmapdata
into in order to display the logo
public class TankerStartMenu extends Sprite{
public var startButton:Sprite;
// put this var here
so other calss can access this button
public function TankerStartMenu(xPos:int, yPos:int) {
// constructor code
var wid:int = 300;
var hei:int = 100;
startButton = new Sprite();
startButton.graphics.beginFill(0x666666);
startButton.graphics.drawRoundRect(0,0, wid, hei,
20, 20);
startButton.graphics.endFill();
var myFormat:TextFormat = new TextFormat();
myFormat.size = 50;
myFormat.color = 0xffffff;
myFormat.align = “center”;
var myT:TextField = new TextField();
myT.defaultTextFormat = myFormat;
myT.selectable = false;
myT.text = “START”;
myT.width = wid;
myT.height = hei;
myT.y = 30;
startButton.addChild(myT);
addChild(startButton);
startButton.x = xPos-(startButton.width/2);
startButton.y = yPos;
// startButton.addEventListener(MouseEvent.CLICK,
Appendix
startGame);
// display logo on start menu as well
var logo:Logo = new Logo(0,0);
var logoBitmap:Bitmap = new Bitmap(logo)
logoBitmap.x = xPos-(logoBitmap.width/2);
logoBitmap.y = 200;
addChild(logoBitmap);
}
}
}
Appendix A32.0
Tile.as
package com.Lao.tanker {
/*
This class is the data tile that get’s nested inside the FloorTiles.as class.
This class holds the individual unique data for each tile when
hero contacts tile.
*/
import flash.display.Sprite;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFormat;
public class Tile extends Sprite {
private var tile:Sprite;
// tile appearence
private var tColor = 0xFDC68F;
private var tBorderThickness = 1;
private var tRoundness = 10;
// tile demensions and spacing
private var wid:int = 40;
private var hei:int = 40;
private var energyValue:int = 0;
public function Tile(maxEnergy:int) {
tile = new Sprite();
tile.graphics.beginFill(tColor, 0);
tile.graphics.drawRoundRect(5,5,wid,hei,tRoundness,
tRoundness);
tile.graphics.endFill();
// create text
var txt:TextField = new TextField();
var f:TextFormat = new TextFormat(“Segoe”);
txt.defaultTextFormat = f;
txt.embedFonts = true;
txt.width = 40;
//
width and height will affect parent sprite’s size
txt.height = 20;
// set heigh
and width as it will auto give each txtfield 100x100 pixel
//txt.border = true; // good to turn on
when testing to see how big textfield is
txt.selectable = false;
// 90 means it’ll random from 0-90 and math.floor
will make whole numbers
// so 5.55 will be 5 and 5.87 will still be 5
Appendix
energyValue = Math.floor(Math.random() * maxEnergy);
// random text number
txt.text = “”+energyValue;
txt.x = 5;
txt.y = 0;
tile.addChild(txt);
// add text field to tile
addChild(tile);
// add tile to be display in
this class
}
public function getVal(){
return energyValue;
}
}
}
Appendix A33.0
W0001.as
package com.Lao.tanker.weapon {
import com.Lao.tanker.Weapon;
//import com.Lao.tanker.Weapon;
// not necessary to
import this class is in same directory as Weapon
/*
In an inherited class, W0002 will have all properties and methods
of it’s parent
So you can call a parent’s function without needing the “super” in
front of the function
But if you override a function of a parent (meaning a child has
the same name method as parent)
you must use “public override method1” then use super.method1()
child can call parent’s method, but parent cannot call child’s
method
*/
public class W0001 extends Weapon{
private var wName:String = “Bone Club”;
private var desc:String = “A heavy collar bone commonly
found on large animals.”;
private var minAtk:int = 2;
private var maxAtk:int = 5;
private var atkSpd:int = 1000;
private var gold:int = 20;
public function W0001(lvl:int) {
// pass in 0,1,2, or 3 for lvl
// # greater than 0 will enhance default weapon attribute and gold
super(wName, desc, gold, lvl, minAtk, maxAtk, atkSpd);
}
}
}
Appendix
Appendix A34.0
W0002.as
package com.Lao.tanker.weapon {
import com.Lao.tanker.Weapon;
//import com.Lao.tanker.Weapon;
// not necessary to
import this class is in same directory as Weapon
/*
In an inherited class, W0002 will have all properties and methods
of it’s parent
So you can call a parent’s function without needing the “super” in
front of the function
But if you override a function of a parent (meaning a child has
the same name method as parent)
you must use “public override method1” then use super.method1()
child can call parent’s method, but parent cannot call child’s
method
*/
public class W0002 extends Weapon{
private var wName:String = “Sharp Shell”;
private var desc:String = “A rare hard piece of shell broken off from a giant turtle.”
private var minAtk:int = 2;
private var maxAtk:int = 10;
private var atkSpd:int = 2500;
private var gold:int = 100;
public function W0002(lvl:int) {
// pass in 0,1,2, or 3 for lvl
// # greater than 0 will enhance default weapon attribute and gold
super(wName, desc, gold, lvl, minAtk, maxAtk, atkSpd);
}
}
}
Appendix
Appendix A35.0
Weapon.as
package com.Lao.tanker {
// This is the parent class for weapons
import flash.display.Graphics;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
public class Weapon extends Sprite implements IWeapon{
//
IWeapon extends IItem
private var type:String = “Weapon”;
private var wName:String = “parent Weapon”;
private var desc:String = “parent description”;
private var minAtk:int = 0;
private var maxAtk:int = 0;
private var atkSpd:int = 0;
private var gold:int = 0;
private var defaultGold:int = 0;
// holds the initial
gold value of default weapon’s gold
// atk power mod increase per lvl
private var level:int = 0;
private var lvl1:Number = 1.2, lvl2:Number = 1.4,
lvl3:Number = 1.8;
private var RARE:String = “R”;
// spd atk mod increase per lvl
private var sp1:Number=1.05, sp2:Number=1.1,
sp3:Number=1.15;
// letter box display size to display weapon lvl power or
indicate RARE
private var bg:Sprite = new Sprite();
private var wid:int = 14;
private var corn:int = 5;
/*
public function setAtk(min:int,max:int):void;
public function getInformation();
*/
public function Weapon(n:String, d1:String, g:int,
lvl:int, min:int, max:int, atkSp:int){
wName = n; desc = d1;
defaultGold = g;
gold = defaultGold;
minAtk = min; maxAtk = max;
atkSpd = atkSp;
level = lvl;
levelMod(lvl);
}
public function levelMod(lvl:int){ // so weapon can be
Appendix
upgraded
// upon weapon creation, a lvl number should always
be passed
switch(lvl){
case 0:
// no modification if lvl 0
take default weapon attribute
drawLetter( String(lvl) );
break;
case 1:
setAtk( Math.floor(minAtk*lvl1),
Math.floor(maxAtk*lvl1) );
setAtkSpd( atkSpd - ( Math.
floor(atkSpd*sp1) - atkSpd ) );
drawLetter( String(lvl) );
setGold(defaultGold*2);
break;
case 2:
setAtk( Math.floor(minAtk*lvl2),
Math.floor(maxAtk*lvl2) );
setAtkSpd( atkSpd - ( Math.
floor(atkSpd*sp2) - atkSpd ) );
drawLetter( String(lvl) );
setGold(defaultGold*3);
break;
case 3:
setAtk( Math.floor(minAtk*lvl3),
Math.floor(maxAtk*lvl3) );
setAtkSpd( atkSpd - ( Math.
floor(atkSpd*sp3) - atkSpd ) );
drawLetter( RARE );
setGold(defaultGold*4);
break;
default:
// do nothing
}
}
// IWeapon
public function setAtk(min:int, max:int):void{
minAtk = min;
maxAtk = max;
}
public function setAtkSpd(sp:int){
atkSpd = sp;
}
public function setGold(g:int):void{
gold = g;
}
public function getMinAtk():int{
return minAtk;
}
public function getMaxAtk():int{
return maxAtk;
Appendix A35.1
Weapon.as
}
public function getAtkSpd():Number{
return Number(atkSpd);
}
// IItem
public function getName():String{
return wName; //+super.getInfo(subName));
}
public function getDesc():String{
return desc;
}
public function getDesc2():String{
return “[Type] “+ type + “ [Speed] “+atkSpd
+ “\n[Effect] Atk “+ minAtk + “ - “
+ maxAtk
+ “\n[Gold] “ + gold;
}
public function drawLetter(n:String):void{
bg.graphics.clear();
bg.graphics.beginFill(0x000000);
bg.graphics.drawRoundRect(0,0,wid,wid,corn,corn);
bg.graphics.endFill();
var txt:TextField = new TextField();
var f:TextFormat = new TextFormat();
f.size = 10; f.color = 0xffffff;
txt.defaultTextFormat = f;
txt.width = 20; txt.height = 20;
txt.text = n;
txt.selectable = false;
bg.addChild(txt);
addChild(bg);
txt = null;
bg = null;
}
}
}
Appendix
Appendix A36.0
WeaponInterface.as
package com.Lao.tanker {
/*
Interface Class
* You have to list all public methods that will be common for the
classes that implements this interface;
* You do so by writing the definition of the function, its name, its
parameters and its return type;
* You don’t have to open and close curly braces after the method definition
* You don’t specify if the method is private, public or protected
(that’s kind of obvious but I did that mistake)
* interface can only extend other interfaces
* a class can implement more than one interface
An interface is for the purpose of polymorphism, so that a var interface can hold an object of that interface
Also an interface helps all your classes that implements an interface, keep a structure or else an error will generate
var m:FruitInterface = new Orange();
var m:FruitInterface = new Apple();
function getCalorie(fruit:FruitInterface); // it can accept can
fruit as a parameter
*/
public interface WeaponInterface {
// you don’t define public, private, protected
function setAtk(min:int,max:int):void;
function getInformation():void;
}
}
Appendix
Appendix A37.0
Window.as
package com.Lao.tanker{
import flash.display.Sprite;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.AntiAliasType;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
public class Window extends Sprite{
public var C_Holder:Array = new Array();
private var myTxt:String = “string not defined”;
private var wid:int = 400;
private var hei:int = 200;
private var corner:int = 15;
private var bgColor = 0xEAF7FF;
private var bColor = 0x000000;
private var txtColor = 0x333333;
public function Window(newTxt:String, w:int, h:int) {
wid = w;
hei = h;
// constructor code
myTxt = newTxt;
createWindow();
}
private function createWindow(){
var block:Sprite = new Sprite();
block.graphics.lineStyle(2, bColor, .9);
block.graphics.drawRoundRect(0,0,
wid,hei,corner,corner);
block.graphics.beginFill(bgColor, .95);
block.graphics.drawRoundRect(0,0, wid, hei,
corner,corner);
block.graphics.endFill();
addChild(block);
//create main textfield
var format:TextFormat = new TextFormat(“Frank”);
// Segoe, Segoeb, Footlight
format.size = 16;
format.color = txtColor;
var txt:TextField = new TextField();
txt.embedFonts = true;
txt.antiAliasType = AntiAliasType.ADVANCED;
txt.defaultTextFormat = format;
Appendix
txt.wordWrap = true;
txt.border = false;
txt.htmlText = myTxt;
txt.width = wid-12;
txt.height = hei-50;
txt.x = 6;
txt.y = 6;
C_Holder.push(txt);
addChild(C_Holder[0]);
}
// change the text box to the incoming new text
public function setText(newTxt:String):void{
//newTxt = newTxt.split(“-b”).join(“<b>”);
C_Holder[0].htmlText = newTxt;
}
// turn the visibility of this window off/on
public function setVisible(Switch:Boolean){
this.visible = Switch;
var par:* = parent;
par.game_is_ready = !Switch;
}
public function cleanOutAllContents():void{
for(var i:int = 0; i<C_Holder.length; i++){
removeChild(C_Holder[i]);
C_Holder[i] = null;
C_Holder.splice(0);
}
}
}
}
Appendix A38.0
WindowNotice.as
package com.Lao.tanker{
/*
Will be use to pop up tutorials by the Shine Gaurdian
- includes a prev, next, and okay button
- okay btn will not become visible untill the maxPage is
reach
- parent:Window is what that displays the the text
*/
import flash.display.Sprite;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
public class WindowNotice extends Window{
//public var C_Holder:Array = new Array();
private var myTxt:String = “string not defined”;
private var wid:int = 400;
private var hei:int = 300;
private var corner:int = 15;
private var bgColor = 0xEAF7FF;
private var bColor = 0x000000;
private var txtColor = 0xff0066;
private var windowRef:Object;// when set to false, that
window will not get trigger again
public function WindowNotice(newTxt:String, wid:int,
hei:int) {
super(newTxt, wid, hei);
// constructor code
createButton();
createNextBackButton();
}
private function createButton(){
// buttons
var block:Sprite = new Sprite();
C_Holder.push(block); // in
parent
block.graphics.beginFill(0x000033);
block.graphics.drawRoundRect(0,0,100,30, corner,
corner);
block.graphics.endFill();
var txt:TextField = new TextField();
var format:TextFormat = new TextFormat(“Segoeb”);
format.size = 12;
format.color = 0xffffff;
txt.defaultTextFormat = format;
txt.embedFonts = true;
Appendix
txt.x = 6;
txt.y = 6;
txt.selectable = false;
txt.text = “OKAY”;
txt.width = 100;
txt.height = 30;
block.addChild(txt);
addChild(block);
block.x = 10;
block.y = 160;
C_Holder[1].addEventListener(MouseEvent.CLICK, passAnswer, false, 0, true);
}
private var C_Holder2:Array= new Array();
// to hold
page text field
private function createNextBackButton():void{
for(var i:int=0; i<2; i++){
var block:Sprite = new Sprite();
C_Holder.push(block); // in parent
block.graphics.beginFill(0x000033);
block.graphics.drawRoundRect(0,0,50,30,
corner, corner);
block.graphics.endFill();
var txt:TextField = new TextField();
var format:TextFormat = new
TextFormat(“Segoeb”);
format.size = 12;
format.color = 0xffffff;
txt.defaultTextFormat = format;
txt.embedFonts = true;
txt.border = false;
txt.x = 6;
txt.y = 6;
txt.selectable = false;
switch(i){
case 0:
txt.text = “Back”;
break;
case 1:
txt.text = “Next”;
break
}
txt.width = 40;
txt.height = 25;
block.addChild(txt);
addChild(block);
block.x = C_Holder[0].width-160+(i*110);
block.y = 160;
}
C_Holder[2].addEventListener(MouseEvent.CLICK, go-
Appendix A38.1
WindowNotice.as
Back, false, 0, true);
C_Holder[3].addEventListener(MouseEvent.CLICK, goNext, false, 0, true);
// creat page
txt = new TextField();
format = new TextFormat(“Segoeb”);
format.size = 14;
format.color = 0x000033;
txt.defaultTextFormat = format;
txt.embedFonts = true;
txt.border = false;
txt.x = C_Holder[0].width-100;
txt.y = 160;
txt.selectable = false;
txt.text = “1/1”;
txt.width = 50;
txt.height = 25;
C_Holder2.push(txt);
addChild(txt);
}
public function passAnswer(e:MouseEvent){
//trace(this.parent.parent);
var par:* = parent;
// to call the parent’s parent, you use a 2nd var
// okay press
if(e.currentTarget.x == C_Holder[1].x){
// almost don’t need this if you just have one button
turnOff();
}
}
private function turnOff(){
this.visible = false;
var par:* = parent;
par.parent.parent.windowCount --;
// engine << windowTutorial << WindowNotice
par.parent.parent.game_is_ready = true;
windowRef.status = false;
pages.splice(0);
// clean array
}
public function setWindowRef(newWindowRef:Object){
windowRef = newWindowRef;
}
public function setMaxPage(count:int):void{
maxPage = count;
currPage = 0;
// determine if okay button should be visible or
Appendix
not if there’s only one page to browse through
if( currPage+1 == maxPage){
C_Holder[1].visible = true;
}else{
C_Holder[1].visible = false;
}
C_Holder2[0].text = “”+(currPage+1)+”/”+maxPage;
}
// set pages
private var pages:Array = new Array();
public function setPageStr(pageArr:Array):void{
pages = pageArr;
}
// previous page
private var currPage:int =0, maxPage:int=0;
private function goBack(e:MouseEvent):void{
currPage--;
if(currPage <=0){
// can’t go below zero
currPage=0;
}
C_Holder2[0].text = “”+(currPage+1)+”/”+maxPage;
// update current page number display
// not yet working, a way to format the text to
bold using css
/*
var str:String = pages[currPage];
// modify string
str = str.split(“-b”).join(“<b>”);
// find bold
str = str.split(“--b”).join(“</b>”); // find end of bold
*/
// update text
setText(pages[currPage]);
// display current page text
}
// next page
private function goNext(e:MouseEvent):void{
currPage++;
if(currPage >= maxPage-1){
// can’t go above max
page
currPage=maxPage-1;
}
// display the okay button once user is on last
page.
if( currPage+1 >= maxPage){
Appendix A38.2
WindowNotice.as
C_Holder[1].visible = true;
}
C_Holder2[0].text = “”+(currPage+1)+”/”+maxPage;
// update page number
setText(pages[currPage]);
// display current page text
}
/*
public function answerNo(e:MouseEvent){
//trace(this.parent.parent);
C_Holder[2].removeEventListener(MouseEvent.CLICK,
answerNo);
C_Holder[1].removeEventListener(MouseEvent.CLICK,
answerYes);
for(var i:int=0; i<C_Holder.length; i++){
removeChild(C_Holder[i]);
C_Holder[i] = null;
}
C_Holder.splice(0);
C_Holder = null;
trace(“no : “ + e.currentTarget);
var par:* = parent;
par.parent.userNo(this);
// re
//par.parent.tankerWorld.removeChild(this);
}
*/
}
}
Appendix
Appendix A39.0
WindowTutorial.as
package com.Lao.tanker {
/*
This class is made up of WindowNotice (extends Window), XML tutorials
*/
import flash.display.Sprite;
// xml
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
public class WindowTutorial extends Sprite{
public var C_Holder:Array = new Array();
holds WindowNotice, currently just one item
public var C_Holder2:Array = new Array();
holds boolean tutorial objects, so the tutorial won’t repeat
private var xmlLoader:URLLoader = new URLLoader();
public var tutTitle:Array = new Array();
public var tutDesc:Array = new Array();
//
//
public function WindowTutorial() {
// load windowNotice
createWindowNotice();
// load xml
xmlLoader.addEventListener(Event.COMPLETE, populateXML);
xmlLoader.load(new URLRequest(“xml/tutorial.xml”));
// create back forward buttons to flip through text
createForwardBackButton();
}
private function createWindowNotice():void{ // prepare it
and set it invisible at start of game
var win:WindowNotice = new WindowNotice(“nothing”,
400, 200);
addChild(win);
C_Holder.push(win);
// this object should now be in the 2nd index of C_Interface
win.visible = false; // this window starts
off invisible till trigger
}
private function populateXML(e:Event):void{
XML.ignoreWhitespace = false;
var tutXML:XML = new XML(e.target.data);
//trace(helpList.list.title.length());//Result is
4
var i:Number;
for (i=0; i < tutXML.list.title.length(); i++) {
Appendix
tutTitle.push( tutXML.list.title[i].text()
);
tutDesc.push( tutXML.list.desc[i].text() );
}
// create the boolean objects, they have to be objects in order to use pass by reference
// just in case these booleans needs to be pass by
reference outside of this class
var count:int = tutXML.list.title.length(); // to
know how many objects to create
for(i=0; i<count; i++){
var winBooleanObj = {status:true};
C_Holder2.push(winBooleanObj);
}
/*public var windowTut1_energy =
{status:true},
windowTut2_hp = {status:true},
windowTut3_weapon = {status:true},
windowTut4_intro = {status:true};
*/
}
// pop window test
public function popWindow(oldTxt:String,
winIndex:int):void{
if( C_Holder[0] is Window){ // check if
is Window object
// split string into sections
var strArr:Array = oldTxt.split(“//”);
var pageCount:int = strArr.length;
// get the page count
C_Holder[0].setMaxPage(pageCount);
// set the max page count in windowNotice
C_Holder[0].setPageStr(strArr);
// send all the pages in an array
var newTxt:String = strArr[0];
C_Holder[0].setText(newTxt);
C_Holder[0].visible = true;
C_Holder[0].setWindowRef(C_
Holder2[winIndex]);
//windowCount++;
// max out
the window so only 1 window can pop up at a time
}else{
throw new Error(“C_Interface[2] is either
not a window, is null, or does not exist inside engine.as”);
}
}
private function createForwardBackButton():void{
}
Appendix A39.1
WindowTutorial.as
// GC
public function cleanOutAllContents():void{
for(var i:int=0;i<C_Holder.length; i++){
removeChild(C_Holder[i]);
C_Holder.splice(0);
}
}
}
}
Appendix