I am making a companion app for a Monopoly-esque game I'm designing. My goal is to have all the properties have a MovieClip that displays who owns it and how much it has been upgraded. There are literally hundreds of properties, and each one bogs down my run time by about a second (I set up a 1-sec timer to see how long it takes to run).
I have a MovieClip that will "spawn in" each property as I need. The idea being, I have a button that tells this MC to go to frame 10, and frame 10 will have code that adds the child for Property 10, and then that child contains all the necessary code. This child spawning MC looks like this:
import flash.events.MouseEvent;
import flash.events.Event;
stop();
// I used a "fakeChild" as a placeholder to get something spawned in so that there is something to be removed
var fake_Child: fakeChild = new fakeChild();
var property_Pale15: propertyPale15 = new propertyPale15();
var property_Red15: propertyRed15 = new propertyRed15();
removeChildAt(1);
addChildAt(fake_Child, 1);
And every subsequent frame for a given property looks like this (the property in this case is "Pale 15")
removeChildAt(1);
addChildAt(property_Pale15, 1);
property_Pale15.newData();
property_Pale15.propertyOwner();
I currently only have two test properties, and each one bogs down my timer by about a second, which is very bad. The properties themselves have an immense amount of code, which looks like this:
import flash.events.MouseEvent;
import flash.ui.Mouse;
import flash.events.Event;
stop();
var myPropertyData:SharedObject = SharedObject.getLocal("myLocalData");
var propertyName: String = ("Pale 15");
propertyDisplay.text = propertyName;
var propertyValue: int;
var propertyRent: int;
var activePlayer: int;
var currentRank: int;
loadData();
btnProperty.addEventListener(MouseEvent.CLICK, activateProperty);
function activateProperty(e:MouseEvent):void{
propertyValue = MovieClip(root).valuePale15;
if(MovieClip(root).buyupgradeAction == true && loanedProperty.visible == false){
buyupgradeProperty();
}else if(MovieClip(root).paycostAction == true && bridgeProperty.visible == false && loanedProperty.visible == false){
paycostProperty();
}
}
function buyupgradeProperty(e:MouseEvent = null){
// Active Player (if Owner) Upgrades Property
if(activePlayer == 1 && MovieClip(root).activePlayer == 1 && currentRank < 10){
MovieClip(root).myLocalData.data.moneyDisplay1 -= propertyValue * 0.8;
currentRank = 1;
currentRankDisplay.text = currentRank;
propertyRent = propertyValue * currentRank * currentRank * 0.1;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay1 " upgraded " propertyName " to Rank " currentRank " for $" propertyValue * 0.8 " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(activePlayer == 2 && MovieClip(root).activePlayer == 2 && currentRank < 10){
MovieClip(root).myLocalData.data.moneyDisplay2 -= propertyValue * 0.8;
currentRank = 1;
currentRankDisplay.text = currentRank;
propertyRent = propertyValue * currentRank * currentRank * 0.1;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay2 " upgraded " propertyName " to Rank " currentRank " for $" propertyValue * 0.8 " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(activePlayer == 3 && MovieClip(root).activePlayer == 3 && currentRank < 10){
MovieClip(root).myLocalData.data.moneyDisplay3 -= propertyValue * 0.8;
currentRank = 1;
currentRankDisplay.text = currentRank;
propertyRent = propertyValue * currentRank * currentRank * 0.1;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay3 " upgraded " propertyName " to Rank " currentRank " for $" propertyValue * 0.8 " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(activePlayer == 4 && MovieClip(root).activePlayer == 4 && currentRank < 10){
MovieClip(root).myLocalData.data.moneyDisplay4 -= propertyValue * 0.8;
currentRank = 1;
currentRankDisplay.text = currentRank;
propertyRent = propertyValue * currentRank * currentRank * 0.1;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay4 " upgraded " propertyName " to Rank " currentRank " for $" propertyValue * 0.8 " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}
// Active Player buys Property
if(MovieClip(root).activePlayer == 1 && currentFrame == 1){
MovieClip(root).myLocalData.data.moneyDisplay1 -= propertyValue;
MovieClip(root).myLocalData.data.propertyDisplay1 = 1;
gotoAndStop(2);
MovieClip(root).stageProperties.propertyColor.color = (0xFF0000);
colorChange();
propertyRent = 0;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay1 " purchased " propertyName " for $" propertyValue " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 2 && currentFrame == 1){
MovieClip(root).myLocalData.data.moneyDisplay2 -= propertyValue;
MovieClip(root).myLocalData.data.propertyDisplay2 = 1;
gotoAndStop(3);
MovieClip(root).stageProperties.propertyColor.color = (0x0000FF);
colorChange();
propertyRent = 0;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay2 " purchased " propertyName " for $" propertyValue " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 3 && currentFrame == 1){
MovieClip(root).myLocalData.data.moneyDisplay3 -= propertyValue;
MovieClip(root).myLocalData.data.propertyDisplay3 = 1;
gotoAndStop(4);
MovieClip(root).stageProperties.propertyColor.color = (0x00FF00);
colorChange();
propertyRent = 0;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay3 " purchased " propertyName " for $" propertyValue " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 4 && currentFrame == 1){
MovieClip(root).myLocalData.data.moneyDisplay4 -= propertyValue;
MovieClip(root).myLocalData.data.propertyDisplay4 = 1;
gotoAndStop(5);
MovieClip(root).stageProperties.propertyColor.color = (0xFFFF00);
colorChange();
propertyRent = 0;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay4 " purchased " propertyName " for $" propertyValue " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}
saveData();
}
function paycostProperty(e:MouseEvent = null){
if(MovieClip(root).activePlayer == 1 && activePlayer == 2){
MovieClip(root).myLocalData.data.moneyDisplay1 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay2 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay1 " paid " MovieClip(root).myLocalData.data.nameDisplay2 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 1 && activePlayer == 3){
MovieClip(root).myLocalData.data.moneyDisplay1 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay3 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay1 " paid " MovieClip(root).myLocalData.data.nameDisplay3 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 1 && activePlayer == 4){
MovieClip(root).myLocalData.data.moneyDisplay1 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay4 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay1 " paid " MovieClip(root).myLocalData.data.nameDisplay4 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 2 && activePlayer == 1){
MovieClip(root).myLocalData.data.moneyDisplay2 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay1 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay2 " paid " MovieClip(root).myLocalData.data.nameDisplay1 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 2 && activePlayer == 3){
MovieClip(root).myLocalData.data.moneyDisplay2 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay3 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay2 " paid " MovieClip(root).myLocalData.data.nameDisplay3 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 2 && activePlayer == 4){
MovieClip(root).myLocalData.data.moneyDisplay2 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay4 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay2 " paid " MovieClip(root).myLocalData.data.nameDisplay4 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 3 && activePlayer == 1){
MovieClip(root).myLocalData.data.moneyDisplay3 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay1 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay3 " paid " MovieClip(root).myLocalData.data.nameDisplay1 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 3 && activePlayer == 2){
MovieClip(root).myLocalData.data.moneyDisplay3 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay2 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay3 " paid " MovieClip(root).myLocalData.data.nameDisplay2 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 3 && activePlayer == 4){
MovieClip(root).myLocalData.data.moneyDisplay3 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay4 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay3 " paid " MovieClip(root).myLocalData.data.nameDisplay4 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 4 && activePlayer == 1){
MovieClip(root).myLocalData.data.moneyDisplay4 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay1 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay4 " paid " MovieClip(root).myLocalData.data.nameDisplay1 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 4 && activePlayer == 2){
MovieClip(root).myLocalData.data.moneyDisplay4 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay2 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay4 " paid " MovieClip(root).myLocalData.data.nameDisplay2 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}else if(MovieClip(root).activePlayer == 4 && activePlayer == 3){
MovieClip(root).myLocalData.data.moneyDisplay4 -= propertyRent;
MovieClip(root).myLocalData.data.moneyDisplay3 = propertyRent;
MovieClip(root).transactionLog = (MovieClip(root).myLocalData.data.nameDisplay4 " paid " MovieClip(root).myLocalData.data.nameDisplay3 " $" propertyRent " for landing on " propertyName " (" MovieClip(root).Time_txt.text ")")
MovieClip(root).updateLogs();
}
saveData();
}
function saveData(e:MouseEvent = null){
myPropertyData.data.Pale15Rent = propertyRent;
myPropertyData.data.Pale15Rank = currentRank;
myPropertyData.data.Pale15Frame = currentFrame;
myPropertyData.data.Pale15Loan = loanedProperty.visible;
myPropertyData.data.Pale15Bridge = bridgeProperty.visible;
myPropertyData.flush();
}
function loadData(e:Event = null){
propertyRent = myPropertyData.data.Pale15Rent;
currentRank = myPropertyData.data.Pale15Rank;
gotoAndStop(myPropertyData.data.Pale15Frame);
loanedProperty.visible = myPropertyData.data.Pale15Loan;
bridgeProperty.visible = myPropertyData.data.Pale15Bridge;
}
function newData(e:Event = null){
if(MovieClip(root).gameSave == 1){
myPropertyData.data.Pale15Rent = 0;
myPropertyData.data.Pale15Rank = 0;
myPropertyData.data.Pale15Frame = 1;
myPropertyData.data.Pale15Loan = false;
myPropertyData.data.Pale15Bridge = false;
loadData();
}
}
function propertyOwner(e:Event = null){
if(activePlayer == 1){
MovieClip(root).stageProperties.propertyColor.color = (0xFF0000);
colorChange();
}else if(activePlayer == 2){
MovieClip(root).stageProperties.propertyColor.color = (0x0000FF);
colorChange();
}else if(activePlayer == 3){
MovieClip(root).stageProperties.propertyColor.color = (0x00FF00);
colorChange();
}else if(activePlayer == 4){
MovieClip(root).stageProperties.propertyColor.color = (0xFFFF00);
colorChange();
}
}
function colorChange (e:MouseEvent = null){
MovieClip(root).stageProperties.Pale15.transform.colorTransform = MovieClip(root).stageProperties.propertyColor;
}
I tried to keep the code as general as possible so I could copy and paste for the other properties. Currently, this property is able to be purchased, upgraded, and dish out rent to the proper players based on what buttons are active, as well as tell a "Property Display" to change colors on the board based on who owns what.
Note: I have used AS3 for a very long time, but have no formal training, it is all self taught. I have tried many many times to understand how "parent/child/private class/etc" work, and I cannot grasp it. I wonder if there is a better way to do what I'm trying to do.
CodePudding user response:
Ok, let me write some scripts in order to explain what OOP-thinking is about. Also, I strongly advise you to read and understand the idea of MVC pattern because scripts below represent [M] and [C], while [V] is not really important and adding it later on is not too difficult too as long as you have the architecture of your application straight.
First, let's define the gameboard cell, a place the players can pass by or visit.
package
{
// A data [M]odel class.
public class Place
{
// What do we call this place.
public var title:String = "";
// A guest list.
public var visitors:Array = new Array;
// The Person class will be defined later.
public function visit(who:Person):void
{
// Add the guest to the list of visitors.
visitors.push(who);
}
public function leave(who:Person):void
{
// Remove the visitor and remove its location record.
var anIndex:int = visitors.indexOf(who);
visitors.splice(anIndex, 1);
}
}
}
Person class so it would be able to visit and leave places.
package
{
// A data [M]odel class.
public class Person
{
// Personal name.
public var title:String = "";
// A place of residence.
public var stayingAt:Place;
}
}
To glue them together we need some controller that allows to move people from place to place. The idea is to NEVER address the [M] objects Person and Place directly, so the [C] script below ensures that a Person is always leaving and visiting properly, doesn't sit over 10 Places, etc.
package
{
// A [C]ontroller class.
public class City
{
// City name.
public var title:String = "";
public function move(who:Person, where:Place):void
{
// Remove the guest from where it is currently staying.
if (who.stayingAt)
{
who.stayingAt.leave(who);
who.stayingAt = null;
}
where.visit(who);
who.stayingAt = where;
}
}
}
Now, in terms of Monopoly, what a Building is? It is a kind of Place, but with more complicated behavior. Then a Player is a Person who has money, can own buildings ant take turns to do things.
package
{
// A data [M]odel class.
public class Player extends Person
{
public var money:int;
public var color:uint;
public var turnsToAct:int;
// A list of owned buildings.
public var owns:Array = new Array;
// Charges money from the Player
// then returns how much was actually charged.
public function charge(value:int):int
{
var acharge:int = 0;
if (value <= 0)
{
// You cannot charge non-positive sums.
}
else if (money - value < 0)
{
// Bankruptcy handling block.
acharge = Math.max(0, money);
turnsToAct = 1000000;
money -= value;
}
else
{
acharge = value;
money -= value;
}
return acharge;
}
}
}
So, a Building be like...
package
{
// A data [M]odel class.
public class Building extends Place
{
public var owner:Player;
public var color:uint;
public var cost:int;
public var rent:int;
public function purchase(who:Player):void
{
who.charge(cost);
owner = who;
color = owner.color;
}
// Building can take rent from a visiting Player.
// So, the "visit" method needs some additional behavior.
override public function visit(who:Person):void
{
// Invoke previously defined visit logic.
super.visit(who);
// If the Building is not owned, there's no rent.
// There's also no rent, if the owner visits.
if (!owner || who == owner) return;
// Person class does not have "charge" method. Read up "typecasting".
// The following one line is actually that HORRIBLE block
// of code named "paycostProperty" in your question.
owner.money = (who as Player).charge(rent);
// Seriously.
}
}
}
So, there are some things left to do (I am getting lazy and not going to program here the whole Monopoly thing):
- Devise City.init() method so that it creates an ordered list of Players, an ordered list of Places and Buildings and moves all the Players to the first cell.
- Compose the logic to control turns and the flow of the Player taking its turn: cast a die, move, make decisions, complete its turn.
- Design the [V] components to display Players' stats, Places and Buildings with all their possible states, the City to visualise the overall state of things.