- Forum >
- Topic: Italian >
- "Lui mangia."
299 Comments
''He eats" is used for general time (may use ''often, usually, always etc) "He is eating.'' Is for right mow when I am speaking. ''He usually eats at home but today he is eating in a restaurant." Or for very s oon we can say : " They are coming in five minutes.'' For Italian similar tense see Emilee84 this page. /
236
You might've made a word in english or even one in german; it does that to me all the time.
Hi there guys,I'm not sure where to post this... Some of the audio is very soft... but only with certain words for example it would say La perfectly and Donna very softly... My phone's speakers work fine. I tested it to see if the technical difficulty is on my side,but it doesn't seem to be... And it's only with Italian... Spanish,German and French works fine. I'm sorry that I left this comment here...
http://www.accademiadellacrusca.it/it/lingua-italiana/consulenza-linguistica/domande-risposte/soggetto Scusate se rompo le uova nel paniere, ma per l'Accademia della Crusca "lui" non è corretto: il soggetto ( sottinteso) della frase è "EGLI". MA in realtà è accettato da chiunque "lui" , quindi va bene così. Per i veri ricercatori della "chicca" , andate a leggere quello che scrive un purista della lingua italiana. A proposito, sto studiando il tedesco: c'è qualche buona anima che vorrebbe parlare con me? I know English very well, and I can teach Italian in return
As a beginner, I'm starting from the bottom without knowing any Italian word. How would I know the meaning of "mangia" if I had never seen the word before? Besides, the course hasn't shown any previous explanation of the word like by a picture for instance. This one for me was hard to guess. I'd never know that haha
87
of course "he eats." and "he is eating." are both correct. They have the SAME English meaning.
tis I s a good game /* * READ! vvvvvvvvvvvvvvvvvv * To explain the "not proud to be most-voted": There are quite a few programs that I think deserve more vote than this. * I've gotten 6+ questions about this and I had the answer right here! ^^^ * I considered switching the code for the two tower defenses, but not yet. The comments would get all messed up. * * You can also play The Ultimate TD 2, which I only started on more like a year ago: http://www.khanacademy.org/cs/the-ultimate-td-2/6104174283718656 * * I also decided to feature someone else's amazing tower defense: * https://www.khanacademy.org/cs/tactical-defense/5312673338228736 /
/ One of the secret sentences on the win screen has been retired as it breaks the rules for vote soliciting. It used to say "You are awesome, v u". /
/ FAQ - Read this before asking questions! To read click the purple arrow thing. / / Q: How long did this take to make? A: Look on the menu screen, at the top. It's legit this time. Q: How many waves? A: I think 51. Q: Where's this second game? A: http://www.khanacademy.org/cs/the-ultimate-td-2/6104174283718656 Q: Your profile is nonexistent?!? A: Try khanacademy.org/profile/tn1b12p Q: The towers don't work! A: The blue laser (5) glitches if you change the code, this is KA's fault. The error buddy (6) does not shoot; it gives nearby towers damage boosts, and when upgraded it gives range and fire rate boosts as well. Effects do NOT stack. Q: I don't like this game, but I don't want to offend you. A: That's ok, just be specific. */ / I HAVE BEATEN THE GAME BEFORE. IT IS NOT IMPOSSIBLE! * For VERY old versions of this go to http://www.khanacademy.org/cs/td/1264694075 (or 1165484122) * * WHEN CHANGING THE CODE, PLEASE HIT RESTART AFTERWARD!! * * People are saying the laser doesn't work. It does for me. If you're changing the code, it might not work. However, you can always sell it. * I will not EVER change the laser again. There's too much conflict. / // ----- When making spin-offs, change this ----- \ var author = "The #1 Base 12 Proponent"; / To change the game constants, scroll down about 15-20 lines of code. / var badCanvasSize = (width === 400 && height === 400);
// Folded on purpose var invertImage=function(img,flip){ var gfx=createGraphics(img.width,img.height,JAVA2D);try{gfx.background(255,0);if(flip){gfx.translate(img.width,0);gfx.scale(-1,1);}gfx.image(img,0,0);gfx.filter(INVERT);return gfx;}catch(e){}}; var sounds = { coin: getSound("rpg/coin-jingle"), wave: getSound("rpg/battle-spell"), loselife: getSound("retro/boom2"), // when enemy gets through };
// 0 = playable, 1 = almost ready (don't change) var underConstruction = 0;
// ----- Colors. Don't change these! ----- \ var RED=color(255,0,0),GREEN=color(0,255,0),BLUE=color(0,0,255),WHITE=color(255,255,255),BLACK=color(0,0,0),YELLOW=color(255,255,0),TEAL=color(0,143,107),PURPLE=color(140,0,255),ORANGE=color(255,132,0) ;
// ----- Game constants. Try tweaking these! ----- \ var lives = 400; var money = 900;
// selling a tower gives you 75% of the cost. var SELLING_RATIO = 0.75;
// ----- Tower prototype objects ----- \
// Regular tower (red ship) var regTower = { name: "Regular Tower", damage: 10, delay: 30, cost: 120, range: 75, color: RED,
<pre>upgrades: {
1: {
message: "30% longer range",
cost: 120,
code: "range 1.3"
},
2: {
message: "50% more damage",
cost: 120,
code: "damage 1.5"
},
3: {
message: "30% faster fire rate",
cost: 110,
code: "delay 0.7"
},
final: {
message: "Sniper Tower",
cost: 800,
code: "delay 1.4285714; damage 5; range 4"
}
},
image: getImage("cute/Blank"),
// RENDER FUNCTION
// Takes in: x, y, size to draw it, and the tower (in case it's based on the delay, etc)
render: function(x, y, size, tower) {
pushMatrix();
translate(x, y);
rotate(tower.angle);
fill(255, 0, 0);
noStroke();
ellipse(0, 0, size, size);
// shading
for (var r = 0; r <= 1; r += 0.1) {
stroke(0, 0, 0, 64*r);
noFill();
strokeWeight(0.1*size);
ellipse(0, 0, size * (r - 0.05), size * (r - 0.05));
}
fill(0);
noStroke();
strokeWeight(1);
rect(size * 0.1, -5, size * 0.5, 10);
stroke(230, 230, 230);
line(size * 0.1, -5, size * 0.35, 0);
line(size * 0.1, 5, size * 0.35, 0);
line(size * 0.35, 0, size * 0.6, 0);
popMatrix();
},
description: "Basic tower: Medium power, range, and fire rate."
</pre>
};
<pre>// 360 tower. Shoots in all directions. (yellow ship)
</pre>
var the360Tower = { name: "360 tower", range: 70, delay: 40, damage: 6, cost: 220, maxHits: 1, color: color(237, 237, 23),
<pre> upgrades: {
1: {
message: "40% Longer range",
cost: 140,
code: "range 1.4"
},
2: {
message: "Faster fire rate",
cost: 100,
code: "delay 0.6"
},
3: {
message: "More bullets, 2 hits",
cost: 250,
code: "bullets 1.5; maxHits 2"
},
final: {
message: "Piercing Shots",
cost: 500,
code: "maxHits 2.5; range 1.4285; damage 1.5"
}
},
image: getImage("space/octopus"),
/*render: function(x, y, size, tower) {
pushMatrix();
translate(x, y);
rotate(tower.angle);
fill(255, 192, 0);
noStroke();
// draw the base
var angleChange = 360 / tower.bullets;
for (var i = 0; i < tower.bullets; i++) {
// WIP
}
popMatrix();
},*/
description: "Shoots in %(bullets)s directions but can be upgraded for more.",
// special properties
bullets: 8
},
fastTower = {
name: "Fast Tower",
damage: 6,
delay: 10, // Don't make the delay zero.
cost: 200,
range: 60,
color: color(0, 255, 0),
upgrades: {
1: {
message: "1.6x damage",
cost: 200,
code: "damage 1.6"
},
2: {
message: "Fire rate boost (30%)",
cost: 140,
code: "delay 0.7"
},
3: {
message: "35% bigger range",
cost: 200,
code: "range 1.35"
},
final: {
message: "Super blaster",
cost: 400,
code: "delay 0.5; range 1.1; damage 1.4"
}
},
image: getImage("space/rocketship"),
description: "Fast fire rate but lower damage.",
// special properties
spread: 3
},
winstonTower = {
name: "Winston",
damage: 10,
delay: 18,
cost: 250,
range: 80,
color: color(0, 0, 255),
upgrades: {
1: {
message: "More hits per shot + range",
cost: 140,
code: "maxHits 200; range 1.35"
},
2: {
message: "50% more damage",
cost: 125,
code: "damage 1.5"
},
3: {
message: "50% faster reload",
cost: 150,
code: "delay 0.5"
},
final: {
message: "Epic Damage",
cost: 400,
code: "damage 4; delay 0.8; range 1.25"
}
},
image: getImage("creatures/Winston"),
description: "Can hit multiple enemies with one shot!",
// special properties
maxHits: 3
},
errorBuddy = {
name: "Error Buddy",
// Error Buddy doesn't shoot and never will.
damage: 0,
delay: 999999999,
cost: 50,
range: 90,
color: color(0, 0, 0, 0),
upgrades: {
1: {
message: "Better damage boost",
cost: 50,
code: function(twr) {
twr.damageBoost = 1.25;
}
},
2: {
message: "Range Boost (20%)",
cost: 150,
code: function(twr) {
twr.rangeBoost += 0.2;
twr.range += 15;
}
},
3: {
message: "Fire Rate Boost (20%)",
cost: 180,
code: function(twr) {
twr.delayBoost += 0.2;
twr.range += 15;
}
},
final: {
message: "Increase Bonus to 40%",
cost: 360,
code: function(twr) {
twr.rangeBoost += 0.2;
twr.damageBoost += 0.15;
twr.delayBoost += 0.2;
twr.range += 30;
}
}
},
image: getImage("creatures/OhNoes"),
description: "DOES NOT SHOOT! Gives your OTHER nearby towers boosts in damage, range, and fire rate. UPGRADE!",
// special properties
damageBoost: 1.15,
rangeBoost: 1,
delayBoost: 1
},
/** This tower is not ready yet. */
oj = {
name: "Orange Juice Tower",
description: "Slows down enemies with orange juice. Does lower damage.",
damage: 6,
delay: 50,
cost: 200,
range: 70,
color: color(255, 128, 0),
upgrades: {
1: {
message: "Longer slowing",
cost: 160,
code: "slowTime 1.6"
},
2: {
message: "+Damage, +range, -reload",
cost: 170,
code: "damage 1.2; range 1.2; delay 0.833"
},
3: {
message: "Slow to 50%, not 70%",
cost: 240,
code: "slowTime 1.05; slowFactor 0.7"
},
final: {
message: "Long-range, extreme slowing",
cost: 600,
code: "range 42; slowFactor 0.5"
}
},
image: getImage("avatars/orange-juice-squid"),
maxHits: 1,
slowFactor: 0.7,
slowTime: 30
},
/** The ultimate tower! **/
laser = {
name: "Laser Tower",
damage: 2.5,
delay: 1,
cost: 1500,
range: 70,
color: color(255, 0, 0),
upgrades: {
1: {
message: "Huge range",
cost: 2250,
code: "range 1.75; damage 1.2"
},
2: {
message: "More shots + more damage",
cost: 2025,
code: "bullets 1.667; damage 2; spread 1.5; range 1.1"
},
3: {
message: "Lasers hit many enemies",
cost: 1725,
code: "maxHits 100; damage 1.2"
},
final: {
message: "360° of firing",
code: "bullets 4.8; damage 4; delay 2; range 1.1; spread 4",
cost: 5000
}
},
image: invertImage(getImage("space/beetleship")),
description: "Ultimate tower -- very fast fire rate and shoots multiple streams.",
spread: 60,
bullets: 3,
maxHits: 1
},
/** This is not done. */
/*gemUpgRange = 90,
gem = {
name: "gem",
damage: 5,
delay: 40,
cost: 600,
range: -10, // warning: don't change this!
waveGain: 20,
hitGain: 1,
upgrades: {
1: {
message: "Hit enemies to gain $1",
cost: 100,
code: "range -"+(gemUpgRange/10).toFixed(1)
},
2: {
message: "More gain per wave",
cost: 300,
code: "waveGain 1.75"
},
3: {
message: "Faster reload. More money per hit.",
cost: 180,
code: "delay 0.7; hitGain 2"
}
}
},*/
// ----- Enemies ----- \\
ENEMY_DELAY = 30,
rock = {
health: 50,
speed: 2.2,
moneyGain: 2.6,
image: getImage("cute/Rock")
},
bug = {
health: 32,
speed: 3.6,
moneyGain: 2.6,
image: getImage("cute/EnemyBug")
},
strong = {
health: 175,
speed: 1.8,
moneyGain: 6,
image: getImage("avatars/mr-pants")
},
star = {
health: 500,
speed: 1.0,
moneyGain: 20,
image: getImage("cute/Star")
},
// Backwards enemy has 300 health and 1.8 speed.
// It looks like a bug facing backwards. You see it on wave 14.
backwards = {
health: 300,
speed: 1.8,
moneyGain: 10,
image: getImage("cute/EnemyBug")
},
superspeeder = {
health: 1,
speed: 25, // yes, 25 speed!
moneyGain: 7,
image: getImage("avatars/leaf-green")
};
</pre>
var wave, fps; // defined here so EB doesn't complain var healing = { health: 150, speed: 2, moneyGain: 10, image: getImage("space/plus"),
<pre> range: 60,
amount: function() {
return (wave*2/5) / fps;
}
},
contest = {
health: 10,
speed: 15,
moneyGain: 10,
image: getImage("avatars/leaf-red"),
healthRate: 0.3
},
boss1 = {
health: 1.0e+6, // scientific notation
speed: 1.4,
moneyGain: 1000,
image: getImage("avatars/robot_male_3"),
special: {
regenRate: 30, // health per second
}
};
</pre>
var boss2 = { health: 1.0e+8, speed: 0.4, moneyGain: 2500, image: getImage("space/planet"),
<pre>special: {
immuneTime: 0,
nextImmune: 8
}
</pre>
};
<pre>// Difficulty ramps-how fast things get hard
</pre>
var ENEMY_HEALTH_MULTIPLIER = 1 + (6.0 / 100), // per wave
<pre>// the track!
// The system has been completely redesigned and uses the letters L, R, U, and D for left right up down.
enemyStartX = -22,
enemyStartY = 173,
track = "RRRDDDDRRRRRRUUUUULLLLDDDRRULURRDDDLLLLUUUUUURRRDLUUUU";
</pre>
var DEBUG = false;
fps = 30; // NEVER make this zero. frameRate(fps);
// image adjustments winstonTower.image.width = 100; winstonTower.image.height = 100;
var towerTypes = [regTower, the360Tower, fastTower, winstonTower, laser, errorBuddy, oj];
// Title var title = (author === "The #1 Base 12 Proponent" ? "" : "Spin-off of ")+" The Ultimate TD by "+author;
// Don't worry if you don't understand this var rawBug = getImage("cute/EnemyBug"); backwards.image = invertImage(rawBug);
/* DAILY BONUSES / // START OF FUNCTION
// DO NOT CHANGE THIS!!! // The 0 in the 6th entry is supposed to be there. var monthCodes = [null, 6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]; var yearCode = function(y) { if (!y) { y = year(); } // Our calendar repeats every 400 years. var mod = (round(y / 100) % 4); var modifiers = [0, 5, 3, 1]; var yy = y % 100; var yearCode = floor(yy / 4) + yy; return yearCode + modifiers[mod]; }; // Note: This returns the day of the week as a NUMBER. /* Return Code * 0: Sunday 1: Monday * 2: Tuesday 3: Wednesday * 4: Thursday 5: Friday * 6: Saturday / var dayOfWeek = function(m, d, y) { // If no parameters passed, get current date if (!m) {m = month();} if (!d) {d = day();} if (!y) {y = year();} if (m > 12) { m = (m - 1) % 12 + 1;// puts m in range [1, 12] } return (monthCodes[m] + d + yearCode(y)) % 7; };
var weekdayTexts = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; var bonuses = ["+80 lives", "360 towers shoot 20% faster", "Enemies have less HP", "Towers have longer range", "Towers are less expensive", "Fast towers shoot even faster", "Enemies are packed more closely.\nWinston has longer range."]; var makeBonus = function() { var value = dayOfWeek(); switch (value) { case 0: lives += 80; break; case 1: the360Tower.delay = 0.75; break; case 2: rock.health = 0.75; bug.health = 0.75; strong.health = 0.75; backwards.health = 0.8; break; case 3: regTower.range = 1.25; the360Tower.range = 1.2; fastTower.range = 1.2; winstonTower.range = 1.25; laser.range = 1.25; errorBuddy.range = 1.25; break; case 4: regTower.cost = 0.9; the360Tower.cost = 0.9; fastTower.cost = 0.9; winstonTower.cost = 0.9; laser.cost = 0.9; errorBuddy.cost = 0.9; break; case 5: fastTower.delay = 0.6; break; case 6: ENEMY_DELAY = 0.8; ENEMY_DELAY = round(ENEMY_DELAY); winstonTower.range = 1.4; break; } }; makeBonus();
// Don't EVER delete this. If you do, the game will likely not work anyway. if (underConstruction) { throw { message: "This game is under construction and IS NOT PLAYABLE AT THIS TIME. Please wait while I fix some glitches and add more features."+((underConstruction === 1) ? " It will be ready soon." : "") }; }
// Copied from Slither var reverseTrack = "";
var enemyEndX = enemyStartX, enemyEndY = enemyStartY;
// How far the path goes in each step var stepSize = 40;
// Set up an image that has the track, so we can't place towers on the track var trackImage = false; // false because it doesn't exist yet!
var createTrack = function() { var img = createGraphics(width, height, 1); if (!img) {return false;} // KA silliness (TODO: remove if they fix the bug?) img.background(255, 0); // clear the Background //println(img.get(200, 200)); var x = enemyStartX; var y = enemyStartY;
<pre>img.strokeWeight(20);
for (var i = 0; i < track.length; i += 1) {
var direction = track[i];
var hue = (i / track.length) * 300;
img.colorMode(HSB, 360, 100, 100, 255);
img.stroke(hue, 100, 100, 192);
var nextX = x;
var nextY = y;
if (direction === "D") {
nextY += stepSize;
} else if (direction === "R") {
nextX += stepSize;
} else if (direction === "U") {
nextY -= stepSize;
} else if (direction === "L") {
nextX -= stepSize;
}
img.line(x, y, nextX, nextY);
// update the position and start again!
x = nextX;
y = nextY;
}
img.colorMode(RGB, 255);
enemyEndX = x;
enemyEndY = y;
return img;
</pre>
};
var makeReverseTrack = function(track) { if (!track) { return ""; } var reverseTrack = ""; for (var i = track.length - 1; i >= 0; i--) { reverseTrack += ( (track[i] === "L") ? "R" : (track[i] === "R") ? "L" : (track[i] === "U") ? "D" : (track[i] === "D") ? "U" : "" ); } return reverseTrack; }; reverseTrack = makeReverseTrack(track); //reverseTrack2 = makeReverseTrack(track2);
trackImage = createTrack(); /////////////////////////////////////////////////////// // Game variables. Careful, changing these might break stuff! var mouseTicks = 0; var lastStand = false; var lastStandEnemyChances = { 0: 30, 1: 30, 2: 15, 3: 5, 4: 8, 5: 7, h: 5 }; var mobile = false; var sandbox = false; var gameState = "splash"; var towerToUpg = null; var fastForward = false; var waveActive = false; var enemiesOnField = false, messageShown = false; var messageClosed = true; var messageToShow = "";
var paused = false; var wave = 0; var t = 0; var currentWave = ""; var score = 0; // @noteToSelf: delete enemyCount? or is "score" different e.g. more for tougher enemies? var finalFrame = 0; var enemyCount = 0; // Number of enemies spawned so far var invertColors = false, gameOverMessages = {}, yyy; var sound;
// Fonts var regFont = createFont("Chalkboard", 20); var boldFont = createFont("Chalkboard Bold", 20);
var towerPicked = "";
var started = false; // Containers for game objects. Doesn't [] look like an empty box? var enemies = []; var towers = []; var missiles = []; var dark = false; // Dark Mode!
/******* * WAVES * * The strings are codes. Key: Rock = 0, Bug = 1, Strong = 2, Star = 3, Backwards = 4, Healing enemy = h. * ALL waves MUST end with "E". E is for End. * * Edit: now you don't have to type E at the end. * * Note: On waves with more than 40 enemies, I use a + to go to the next line. */ var waves = [ "", // Wave 0 is null // 5 10 15 20 25 30 35 40 "00000 00000E", // wave 1 "00000 00000 00111E",// wave 2 "00000 00000 00000 00000 11111E",//wave 3 "00000 00000 00000 00000 00000 00000 11111 11111E",/wave4*/ "00011 10001 11000 11100 01110 00111 00011 10001"+ "11000 11100 01110 001113E",//wave 5
"11111 11111 11111 11111 11111 11111 11111 11111E",//wave6 "11111 11111 11111 11111 11111 00000 00000 00000"+ "00000 00000E",//wave 7 "200000 00000 00000 00000 11111 11111 11E",//wave 8 "22111 11111 11111 11111E",//wave 9 "01222 22222 223E",//wave 10
"22000 00000 00000 00000 0022E",//wave 11 "00110 01100 11001 10011 00110 01100 11001 10011"+ "22200 00000 00000 000E",//wave 12 "11111 11111 11111 11111 11111 11111 11111 11111"+ "11111 11111 11111 11111 11111 11111 11111 11111E", //wave 13 "11111 11111 11111 11111 11111 11111 11111 11111"+ "44E",//wave 14 "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 000003"+ "E",//wave 15
"00000 00000 00000 00000 11111 11111 11111 111112"+ "00000 00000 00000 00000 11111 11111 11111 111112"+ "00000 00000 00000 00000 11111 11111 11111 111112"+ "00000 00000 00000 00000 11111 11111 11111 111112", //wave16 "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "11111 11111 11111 11111 00000 00000 00000 00000"+ "00000 00000E",//wave 17 "11111 22222 22222 222"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000",//wave 18 "22222 11111 22222 11111 22222 11111",//wave 19 "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 11111 11111 11111 11111"+ "11111 11111 11111 11111 11111 11111 11111 11111"+ "11111 11111 11111 111113E",//wave 20
"00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "11111 22222 21112 22222 22222 21112 11111 44444E",//wave 21 "00112 00112 00112 00112 00112 00112 00112 00112"+ "00112 00112 00112 00112 00112 00112 00112 00112"+ "00112 00112 00112 00112E",//wave 22 I used copy+paste "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "11111 11111 11111 11111 11111 11111 11111 11111"+ "11111 11111 22222 22222 22222 22222 22222 22222",//wave23 // wave 24 is sorted in groups of 6, not 5 "010010 022001 010010 022001 010010 022001 010010 022001"+ "010010 022001 010010 022001 010010 022001 010010 022001"+ "010010 022001 010010 022001 010010 022001 010010 022001"+ "010010 022001 010010 022001 010010h022001",//wave 24 "22222 00000 22222 22222 11111 22222 22222 00000"+ "22222 22222 11111 11111 11111 11111 00000 00000"+ "00000 00000 00000 00000 hhhhh hhhhh 3E",//wave 25
"22222 22222 00000 22222 11111 00000 22222 22222"+ "22222 22222 22222 22222 22222 22222 22222 22222",//wave26 "000001000001000001000001000001000001000001000001"+ "000001000001000001000001000001000001000001000001"+ "000001000001000001000001",//wave 27 "222220222221222220222221222220222221222220222221"+ "222220222221222220222221222220222221222220222221"+ "222220222221222220222221",//wave 28 "00011 00011 00011 00011 00011 00011 00011 00011"+ "00011 00011 6E",//wave 29 "00011 00011 00011 00011 00011 00011 00011 00011"+ "00011 00011 00011 0001134E",//wave 30
"012012 012012 012012 012012 012012 012012 012012h"+ "012012 012012 012012 012012 012012 012012 012012h"+ "012012 012012 012012 012012 012012 012012 66",//wave 31 "33333 22222 22222 22222 22222 55555 55555 555554", //wave 32 "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00004"+ "11111 11111 11111 11111 11111 11111 11111 11111"+ "11111 11111 11111 11111h11111 11111 11111 11144"+ "22222 22222 22222 22222 22222 22222 22222 22444",//wave33 "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000"+ "00000 00000 00000 00000 00000 00000 00000 00000 55555"+ "11111 11111 11111 11111 11111 11111 11111 11111"+ "11111 11111 11111 11111 11111 11111 11111 11111 55555"+ "22222 22222 22222 22222522222 22222 22222622222",//wave34 "00011 00011 00011 00011 00011 00011 00011 00011"+ "00011 00011 00011 00011 00011 000113E",//wave 35
"01201 01201 00000 01201 01201 11111 01201 22222",//wave36 "44444 44444 44444 22222 22222 22222 11111 00000",//wave37 "00000 11111 22222 44444 hhhhhE",//wave 38 "00000 00001 00011 00111 01111 11111 11112 11122"+ "11222 12222 22222 22220 22200 22000 20000 00000",//wave39 "00000 00100 10001 10101 11011 11111 22222 0123E",/*wave40/
"00000 00000 11111 11111 00000 00000 11111 11111 hhhhh"+ "00000 00000 11111 00000 11111 00000 11111 00000",//wave41 "22222 22222 22022 22122 21212 20202 22222 22222"+ "22222 22322522222 22422522222 22322 22222 22522",//wave42 "33333 33333 22222 22222 11111 11111 00000 00123",//wave43 "01234 01234 01234 01234 01234 01234",//wave44 "44444544444544444544444544444544444544444544444",/*wave45/
"22222 44444 22224 44422 24442 24424 66",//wave46 "00000 11111 22222 33333 44444 hhhhh 44444 33333"+ "22222 11111 00000 00000 00000 00000 01234 43210",//wave47 "00000000000100000200000300000400000h00000500000"+ "00000000000100000200000300000400000h00000500000",//wave48 "11111011111111111211111311111411111h11111511111"+ "11111011111111111211111311111411111h11111511111",//wave49 "22222022222122222222222322222422222h22222522222"+ "22222022222122222222222322222422222h22222522222",//wave50
/ The ultimate wave! / "33333 33333 24242 42424 24242 42424 24242 42424"+ "24242 42424 24242 42424 24242 42424 24242 42424"+ "24242 42424 24242 42424 24242 42424 55555 55555"+ "55555 55555 33333 33333 33333",
"0" ];
var calcEnemies = function() { var num = 0; for (var i = 0; i < waves.length; i++) { for (var j = 0; j < waves[i].length; j++) { if (" E".indexOf(waves[i][j]) === -1) { num++; } } } return num; };
/* WAVE MESSAGES * After you beat a wave, you get a message. / var messages = ["", "Next wave: 12 rocks and 3 bugs. Still easy.\nSpace to go to the next wave. If you don't know what the towers do, restart and read the help.", "Next wave: 20 rocks and 5 bugs. Hold shift to speed up", "Next wave: 30 rocks and 10 bugs.", "Next wave: 3 rocks and 3 bugs, repeats 10 times. If you wish upon a star...", "Remember, click 'close' on the right to close this bar.", // 5
"You can click or tap \"Buy X lives for $100\" to do just that. Note that the life gain increases by 5 each wave, so waiting gives you a better deal.", "There are "+(waves.length-2)+" waves.", "", "Tower upgrades are usually better than just adding more towers, but each tower can only be upgraded 4 times.", "You know, I can do anything I want since I programmed this game. I could make the enemies 100 times stronger. Or make them attack towers. But that's unfair to you!", // 10
"Sometimes you won't get these little messages.", "", "The next enemy moves backwards through the track. Watch out!", "", "", // 15
"", "Hold on! And since the enemies are stronger I doubled the number of lives you have.", "You are doing well!", "You might want to sell your weak towers sometime. To sell, click the tower and press S. You can also upgrade them.", "Winston can hit many enemies with one shot. Error Buddy makes nearby towers stronger.", // 20
"Did you know that Winston's \"more hits per shot\" upgrade also gives a range increase?", "", "Wave 24 will have an enemy that heals other enemies.", "The next wave will have a lot of healing enemies in a row, after all the others come.", "You've gotten to wave 25 already? Wow! Here, I'll give you +150 lives. (Seriously)", // 25
"I got the idea from Castle Defense, not Bloons TD. That one has level messages, too (but in a different form)", "There was an enemy contest, the winner is in the next wave.", "If you have any questions about the game, feel free to ask. There are "+calcEnemies()+" enemies total that will ever spawn.", "", "You passed wave 30? Here's another gift: I'll give you $50 on top of the normal wave bonus.", // 30
"Superspeeders incoming! They have very low health, but can you even hit them?", "Superspeeders usually go in groups of 5 or more.", "", "A fully upgraded Laser tower is powerful. But it costs $12,500 total!", "", // 35
"If you see any Ghost Bugs, they can only be hurt by lasers. I don't know if they exist, though...", "Another thing I've heard is that knights can appear which slay your towers! I hope that's just a myth...", "", "Okay, the ghost bugs and knights ARE just a myth. Don't worry.", "There are only "+(waves.length-2 - 40)+" waves left!",// 40
"You passed GO. Here's $200.", "42!! Life, the Universe, and EVERYTHING!!", "", "This sentence is false.", "", // 45
"After this, you can try Sandbox Mode!! Or, you can look in the code for some other tower defense games to try (which are also awesome)!", "", "Wave 50 is probably going to be something big, so here's +250 lives and $120.", "I was going to make a boss, but I got lazy and just added a lot of the strongest enemies.", "Wow! You beat the game! (Or maybe one more wave...)", // 50
"You're almost done! After this try Sandbox Mode to experiment or play The Ultimate TD 2 (me) or Tactical Defense (Infiltration)! (There's one more enemy, or else you wouldn't see this message)", "If you're seeing this, click Next Wave or press SPACE again to finish.", // Note that the message occurs AFTER you beat the wave.
];
// On certain waves, things happen (like wave 25). var waveActions = []; waveActions[17] = function() {lives *= 2;}; // double lives // On wave 25, add 150 lives waveActions[25] = function() {lives += 150;}; waveActions[30] = function() {money += 50;}; waveActions[41] = function() {money += 200;}; // On wave 48, gain $120 and 250 lives. waveActions[48] = function() {money += 120; lives += 250;};
// add "E" (should take out and just say end of wave) for (var i = 1; i < waves.length; i++) { var wavei = waves[i]; if (wavei[wavei.length - 1] !== "E") { waves[i] = waves[i] + "E"; } }
// Security mesures, don't mess with these! var error = function(text) { throw text; // changed due to KA security standards }; if (track.length < 3) { error("The path must have at least three segments."); } if (lives <= 0) { error("The game must start with some lives."); } if (money <= 0) { error("Start with at least some money."); } if (waves.length < 2) { error("Please do at least 1 wave, but probably more."); } if (the360Tower.bullets > 800) { error("Okay, thanks a lot for trying to crash the program. Please set the360Tower.bullets to something a little lower!"); } if (fastTower.delay <= 0) { error("Please set the fast tower delay to something positive."); }
/* MISSILES /
var createMissile = function(x, y, dx, dy, tower) { var missile = {};
<pre>// Set missile weapon and damage from tower type
missile.weapon = tower.type;
missile.color = tower.type.color;
missile.enemiesLeft = 1;
missile.range = tower.realRange + 25;
missile.damage = tower.realDmg;
if (tower.maxHits) {
missile.enemiesLeft = round(tower.maxHits);
}
if (tower.type === winstonTower) {
missile.range = tower.range + 100;
}
missile.x = x;
missile.y = y;
missile.dx = dx;
missile.dy = dy;
missile.enemiesHit = [];
missile.dist = 0;
missiles.push(missile);
return missile;
</pre>
};
var updateMissiles = function() { for (var i = 0; i < missiles.length; i += 1) { var missile = missiles[i]; var dx = missile.dx, dy = missile.dy; missile.x += dx; missile.y += dy;
<pre> missile.dist += sqrt(dx*dx + dy*dy);
if (missile.dist >= missile.range) {
missiles.splice(i, 1);
}
}
</pre>
};
var drawMissiles = function() { for (var i = 0; i < missiles.length; i += 1) { var missile = missiles[i]; noStroke(); if (missile.weapon.name === winstonTower.name) { noFill(); stroke(missile.color); strokeWeight(6); ellipse(missile.x, missile.y, 8, 8); } else { fill(missile.color); ellipse(missile.x, missile.y, 14, 14); } } };
/******** * Utility functions ********/ // obfuscated var $={ :function(n,l){l=l||{};if(typeof n==="object"&&n.messages){n=n.messages[0];}return n.replace(/%(([\w]+))s/g,function(n,r){var a=l[r];return a===undefined?n:a;});}};
var tooltip = function(message, x, y, w, h) { textSize(12); textLeading(14); textAlign(CENTER, CENTER); if (arguments.length === 3) { var a = 1; w = (textWidth(message) * 1.2) / (1 + floor(textWidth(message)/(70 + textWidth(message)/5))) + 8; h = 16 * (1 + floor(textWidth(message)/(70 + textWidth(message)/5))) + 8; }
<pre>if (w >= width || h >= height) {
throw "Sorry, but either your message is too long or your width and height are too big.";
}
fill(255, 255, 192);
stroke(128, 128, 128, 128);
strokeWeight(1);
x = constrain(x, 0, width - w);
y = constrain(y - h, 0, height - h);
rect(x, y, w, h);
fill(0, 0, 0);
text(message, x + 2, y + 2, w - 4, h - 4);
//status("tooltip("+message+", "+x+", "+y+", "+w+", "+h+");");
</pre>
};
var popups = []; var POPUP_AGE = 60;
var newPopup = function(text, x, y, maxAge) { if (!maxAge) { // throw {message: "You must pass 4 parameters to newPopup()."} maxAge = POPUP_AGE; } popups.push({ x: x, y: y, age: 0, text: text, maxAge: maxAge }); };
var drawPopup = function(popup) { textSize(16); pushMatrix(); translate(popup.x, popup.y); fill(0, 0, 0); var age = popup.age; if(age > popup.maxAge - 7) { fill(255, 255, 255); } if(age > popup.maxAge - 4) { scale((age - POPUP_AGE + 6) * 0.5, 1 / ((age - POPUP_AGE + 6) * 0.5)); } text(popup.text, 0, 0); popMatrix(); };
var drawPopups = function() { for (var i = 0; i < popups.length; i++) { drawPopup(popups[i]); } };
var updatePopups = function() { for (var i = 0; i < popups.length; i += 1) { popups[i].y -= ((popups[i].maxAge - popups[i].age) / 10); popups[i].age++; if(popups[i].age > popups[i].maxAge) { popups.splice(i, 1); } } }; // Since "textSize" is already defined, I added '_'s var overButton; var drawButton = function(buttonText, x, y, length, _color, buttonHeight, __textSize){ if (!length) { length = textWidth(buttonText) + 10; } overButton = false; var v = 180; var vb = 220; var val = v;
<pre>noStroke();
if (!buttonHeight) {
buttonHeight = 22;
}
if (!__textSize) {
__textSize = 12;
}
// Drop Shadow using Alpha
fill(0, 0, 0, 100);
rect(x - 2, y + 2, length, buttonHeight + 1, 3);
if(mouseX >= x && mouseX <= x + length && mouseY >= y && mouseY <= y + buttonHeight){
val = vb;
overButton = true;
if(mouseIsPressed){
x -= 2;
y += 2;
}
this.cursor(HAND);
}
strokeWeight(2);
// Button Outline Color
stroke(100, 0, 150);
fill(val);
rect(x, y, length, buttonHeight, 2);
textAlign(CENTER, CENTER);
if (!_color) {
_color = color(0, 0, 0);
}
fill(_color);
textSize(__textSize);
text(buttonText, x + length / 2, y + buttonHeight / 2);
</pre>
}; var buttonPressed = false;
var drawRange = function(tower) { var x = tower.x, y = tower.y, radius = tower.realRange; if (!radius) { radius = tower.range; } var sel = (tower === towerToUpg); stroke(255, 255, 255, sel ? 90 : 20); strokeWeight(max(2, radius / 12)); fill(255, 255, 255, sel ? 50 : 1); ellipse(x, y, radius * 2, radius * 2); };
var findClosest = function(x, y) { var closestDist = Infinity; var closestEnemy = null; for (var i = 0; i < enemies.length; i += 1) { var enemy = enemies[i]; var distance = dist(x, y, enemy.x, enemy.y); if (distance < closestDist) { closestDist = distance; closestEnemy = enemy; } }
<pre>return closestEnemy;
</pre>
}; var isValInArray = function(val, array) { if (typeof array !== "object") { return val === array; } for (var i = 0; i < array.length; i++) { if (val === array[i]) { return true; } } return false; }; var roundTo = function(num, a) { if (!a) { return num; } return (round(num / a) * a); };
/* Include this entire block when copying the function. getBrowser() 1.5 by The #1 Base 12 Proponent (Improved by Patrick Z.) * Gets the name of your browser. * It doesn't use .externals or anything crazy. * Just a simple try statement followed by if statements. * Only works on Safari, Firefox, IE, and Chrome. * Returns "I don't know!" otherwise. / var getBrowser = function() { var b = "unknown"; try { var e; var f = e.width; } catch (error) { var err = error.toString(); if (err.search("not an object") !== -1) { return "Safari"; } else if (err.search("Cannot read") !== -1) { return "Chrome"; } else if (err.search("e is undefined") !== -1) { return "Firefox"; } else if (err.search("Unable to get property 'width' of undefined or null reference") !== -1){ return "Internet Explorer"; } else if (err.search("cannot convert e into object") !== -1) { return "Opera"; } else { return "I don't know!"; } } };
/********
- @Enemies
********/ var Enemy = function(type) { this.success = false; // checks if the enemy was created successfully type = type.toString(); this.x = enemyStartX; this.y = enemyStartY; type = (type === "0") ? rock : (type === "1") ? bug : (type === "2") ? strong : (type === "3") ? star : (type === "4") ? backwards : (type === "5") ? superspeeder : (type === "6") ? contest : (type === "h") ? healing : 0; if (!type) { return; }
<pre>this.health = type.health *
pow(ENEMY_HEALTH_MULTIPLIER, max(0, wave));
if (type === star) {
// Round the star's health to 100s
this.health = round(this.health / 100) * 100;
}
this.speed = type.speed;
this.moneyGain = type.moneyGain;
this.type = type;
this.image = type.image;
enemyCount++; // increment the enemy count and set it as the id
this.id = enemyCount;
if (type === backwards) {
this.x = enemyEndX;
this.y = enemyEndY;
this.track = reverseTrack;
} else {
this.track = track;
}
if (type === healing) {
this.range = healing.range;
this.amount = healing.amount();
}
if (type === contest) {
this.amount = contest.healthRate;
}
// A few variables
this.distTraveled = 0;
this.distLeft = stepSize;
this.direction = this.track[0];
this.segment = 0;
// For the OJS tower.
this.slowed = false;
this.slowTime = 0;
this.slowFactor = 1;
this.success = true; // created successfully!
</pre>
}; Enemy.prototype.draw = function() { pushMatrix(); var img = this.image; translate(this.x, this.y-10); // draw orange juice if slowed if (this.slowTime > 0) { fill(255, 128, 0, 128); noStroke(); ellipse(0, 10, 60, 60); } scale(0.5, 0.5); imageMode(CENTER); // Offset the leaf on super-speeders image(img, 0, (this.type === superspeeder) ? 17 : 0); textSize(30); fill(0, 0, 0); textAlign(CENTER, CENTER); text(ceil(this.health), 0, 26);
<pre>if (this.type === healing) {
fill(0, 200, 255, 15);
ellipse(0, 0, this.range*4, this.range*4);
}
popMatrix();
textAlign(LEFT, DOWN);
</pre>
}; var createEnemy_old = function(enemyType) { enemyType = enemyType.toString(); var newEnemy = {x: enemyStartX, y: enemyStartY}, type = (enemyType === "0") ? rock : (enemyType === "1") ? bug : (enemyType === "2") ? strong : (enemyType === "3") ? star : (enemyType === "4") ? backwards : (enemyType === "5") ? superspeeder : (enemyType === "6") ? contest : (enemyType === "h") ? healing : 0; if (!type) { return; }
<pre>newEnemy.health = type.health *
pow(ENEMY_HEALTH_MULTIPLIER, max(0, wave));
if (type === star) {
newEnemy.health = round(newEnemy.health / 100) * 100;
}
newEnemy.speed = type.speed;
newEnemy.moneyGain = type.moneyGain;
newEnemy.type = type;
newEnemy.image = type.image;
enemyCount++;
newEnemy.id = enemyCount; // don't ask me why
if (type === backwards) {
newEnemy.x = enemyEndX;
newEnemy.y = enemyEndY;
newEnemy.track = reverseTrack;
} else {
newEnemy.x = enemyStartX;
newEnemy.y = enemyStartY;
newEnemy.track = track;
}
if (type === healing) {
newEnemy.range = healing.range;
newEnemy.amount = healing.amount();
}
if (type === contest) {
newEnemy.amount = contest.healthRate;
}
newEnemy.distTraveled = 0;
newEnemy.distLeft = stepSize;
newEnemy.direction = newEnemy.track[0];
newEnemy.segment = 0;
newEnemy.slowed = false;
newEnemy.slowTime = 0;
newEnemy.slowFactor = 1;
enemies.push(newEnemy);
//return newEnemy;
</pre>
}; var createEnemy_new = function(enemyType) { var e = new Enemy(enemyType); if (e.success) { delete e.success; enemies.push(e); return e; } }; var createEnemy = createEnemy_old;
var drawEnemies = function() { for (var count = 0; count < enemies.length; count++) { pushMatrix(); var enemy = enemies[count]; var img = enemy.image; translate(enemy.x, enemy.y-10); // draw orange juice if slowed if (enemy.slowTime > 0) { fill(255, 128, 0, 128); noStroke(); ellipse(0, 10, 60, 60); } scale(0.5, 0.5); imageMode(CENTER); image(img, 0, (enemy.type === superspeeder) ? 17 : 0 ); textSize(30); fill(0, 0, 0); textAlign(CENTER, CENTER); text(ceil(enemy.health), 0, 26);
<pre> if (enemy.type === healing) {
fill(0, 200, 255, 15);
ellipse(0, 0, enemy.range*4, enemy.range*4);
}
popMatrix();
textAlign(LEFT, DOWN);
}
</pre>
};
var debugEnemy = function(index) { var enemy = enemies[index]; var problem = false; if (typeof enemy !== "object") { println("Enemy #"+index+" is undefined."); enemies.splice(index, 1); return; }
<pre>if (typeof enemy.x === "undefined" ||
typeof enemy.y === "undefined") {
println("Problem has occured with enemy #"+index+": Position is undefined");
problem = 1;
}
if (!enemy.speed) {
println("Enemy speed is undefined.");
problem = 1;
}
if (!enemy.image) {
println("Enemy picture is undefined");
problem = 1;
}
if (!enemy.type) {
println("Enemy type is undefined");
problem = 1;
}
if (enemy.y < -150 || enemy.x < -150) {
println("The enemies are way off the screen in the"+
((enemy.y < -150) ? " y" : " x") +
" direction!");
problem = 1;
}
if (problem) {
enemies.splice(index, 1);
}
</pre>
}; var moveEnemy = function(enemy, dir, amt) { if (typeof enemy !== "object") { return; } if (!amt) {amt = enemy.speed;} switch (dir) { case "L": enemy.x -= amt; break; case "R": enemy.x += amt; break; case "U": enemy.y -= amt; break; case "D": enemy.y += amt; break; } }; Enemy.prototype.move = function(dir, amt) { if (!amt) {amt = this.speed;} switch (dir) { case "L": this.x -= amt; break; case "R": this.x += amt; break; case "U": this.y -= amt; break; case "D": this.y += amt; break; } };
var updateEnemy = function(enemy, speed) { var a = enemies.indexOf(enemy); var currentDir = enemy.direction; debugEnemy(a);
<pre>if (enemy.slowFactor !== undefined && enemy.slowTime > 0) {
speed *= enemy.slowFactor;
status("Enemy slowed from " + (speed / enemy.slowFactor) + " to " + speed);
enemy.slowTime--;
}
// If it's a healing enemy...
// They don't heal themselves...
if (enemy.type === healing) {
for (var b in enemies) {
if (a !== b &&
dist(enemy.x, enemy.y,
enemies[b].x, enemies[b].y) < enemy.range) {
enemies[b].health += enemy.amount;
}
}
}
if (enemy.type === contest) {
enemy.health += enemy.amount;
}
enemy.distTraveled += speed;
enemy.distLeft -= speed;
if (enemy.distLeft < 0) {
var nextDir = enemy.track[enemy.segment + 1];
// first go back, then turn, then go again
// Go back to the track
// distLeft is a negative number, so add it
moveEnemy(enemy, currentDir, enemy.distLeft);
// Take excess distance off the distTraveled
enemy.distTraveled += enemy.distLeft;
// Turn and go forward
enemy.direction = nextDir;
moveEnemy(enemy, nextDir, speed);
enemy.distLeft = stepSize;
enemy.segment++;
// ----- End of this case ----- \\
} else {
// standard moving
moveEnemy(enemy, currentDir, speed);
}
if (enemy.distTraveled >= track.length*stepSize){
lives -= enemy.health;
enemies.splice(a, 1);
}
</pre>
};
var updateEnemies = function() { for (var a = enemies.length - 1; a >= 0; a--) { var enemy = enemies[a]; if (enemy.speed > stepSize / 3) { // faster enemies are updated twice updateEnemy(enemy, enemy.speed/2); updateEnemy(enemy, enemy.speed/2); } else { updateEnemy(enemy, enemy.speed); } } };
/********\ * Towers **********/ var copyObject = function(obj) { var a = {}; for (var prop in obj) { a[prop] = Object.create(obj[prop]); } return a; };
// do not worry about this var Tower = function(x, y, type) { this.success = false; // This is a placement flag to check if the tower was created. if (!type || (towerTypes.indexOf(type) === -1)) { return false; } if (type === null || (!sandbox && money < type.cost)) { yyy = -800; newPopup("Not enough money!", x, y); return false; } var trackColor = trackImage.get(x, y); // gets the color of the pixel if (trackColor !== 0) { // not a perfect system but will suffice newPopup("Can't place towers\non the track!", x, y); return false; } // Properties // TODO: Reorganize
<pre>// The position, and if the tower has been used
this.used = false;
this.x = x;
this.y = y;
// Stats (damage, range, fire rate)
this.damage = type.damage;
this.range = type.range;
this.delay = type.delay;
// Image for display (TODO: Question: Use shapes?)
this.type = type;
this.image = type.image;
this.name = type.name;
// Laser towers shoot a spread of bullets
if (type === laser) {
this.spread = type.spread;
}
// Charge you for the tower (TODO: move this?)
if (sandbox) {
// Sandbox records money spent
money += type.cost;
} else {
money -= type.cost;
}
// If multi-bullet shots...
if (type.bullets) {
this.bullets = type.bullets;
}
// When the tower last fired
this.lastFired = t;
// Set up the upgrade info
this.upgrades = copyObject(type.upgrades);
// @noteToSelf: IS this needed?
this.upgrades[1].upgraded = false;
this.upgrades[2].upgraded = false;
this.upgrades[3].upgraded = false;
this.upgrades.final.upgraded = false;
// Error Buddy setup
if (type.name === errorBuddy.name) {
this.damageBoost = type.damageBoost;
this.delayBoost = type.delayBoost;
this.rangeBoost = type.rangeBoost;
}
//
this.damageBonus = this.rangeBonus = this.delayBonus = 1;
this.angle = 0;
this.totalCost = type.cost;
this.angle = 0;
this.totalCost = type.cost;
// Success! We finished making a tower. If this did not happen, there was an error or something prevented the placement of the tower.
this.success = true;
// OJS tower special case
if (type === oj) {
//this.slowTime = oj.slowTime;
//this.slowFactor = oj.slowFactor;
}
// Reset towerPicked
towerPicked = "";
</pre>
}; Tower.prototype.draw = function() { if (this.type.render) { // simply draw it from the render function // TODO: block the normal image this.type.render(this.x, this.y, 40, this); } imageMode(CENTER); pushMatrix(); translate(this.x, this.y); if (this.type === oj) {scale(0.25);} else {scale(0.32);} switch (this.name) { case regTower.name: case laser.name: rotate(this.angle); image(this.image, 15, -20); break; case the360Tower.name: translate(7, -4); image(the360Tower.image, 0, 0); break; case fastTower.name: rotate(this.angle); image(fastTower.image, 4.5, -13); break; case winstonTower.name: image(winstonTower.image, 0, 0); break; default: image(this.type.image, 0, 0); } popMatrix(); }; Tower.prototype.fire = function() { if (enemies.length === 0) { return; } if (t - this.lastFired < this.delay) { return; }
<pre>var x1 = this.x;
var y1 = this.y;
var dx, dy;
var enemy = findClosest(this.x, this.y);
if (enemy === null) {
return;
}
var x2 = enemy.x, y2 = enemy.y;
var distToEnemy = dist(this.x, this.y, x2, y2);
if (distToEnemy >= this.range + 10) {
return;
}
var angle = atan2(y2 - y1, x2 - x1);
if (this.name === the360Tower.name) {
if (this.bullets <= 0) {
return;
}
for (var j = 0; j < 360; j += (360 / this.bullets)) {
var speed = 15;
dx = speed * cos(j);
dy = speed * sin(j);
createMissile(this.x, this.y, dx, dy, this);
}
} else if (this.name === laser.name) {
var left = angle - this.spread/2,
right = left + this.spread;
var offset = this.spread / (this.bullets-1);
if (this.bullets === 1) {
offset = 360;
} else if (this.bullets === 0) {
return;
}
for (var a = left; a <= right; a += offset) {
if (this.bullets === 1) {
a = (left + right) / 2;
}
dx = 12 * cos(a);
dy = 12 * sin(a);
createMissile(this.x, this.y, dx, dy, this);
if (this.bullets === 1) {
return;
}
}
} else {
// this else takes in Reg tower, Pi tower, and Fast tower all at once!
dx = 15 * cos(angle);
dy = 15 * sin(angle);
createMissile(this.x, this.y, dx, dy, this);
}
this.lastFired = t;
this.used = true;
</pre>
};
var placeTower_new = function(x, y, type) { var tower = new Tower(x, y, type); if (tower.success) { // Successfully created. towers.push(tower); // Don't need the "success" flag anymore delete tower.success; } }; var placeTower = placeTower_new;
var drawTowers_new = function() { for (var i = 0; i < towers.length; i++) { towers[i].draw(); } imageMode(CORNER); }; var drawTowers = drawTowers_new;
var drawRanges = function() { for (var i in towers) { drawRange(towers[i]); } };
//////////////////////////////////////////////////////////// // Problem? var fireTowerMissiles = function() { if (enemies.length === 0) { return; } for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower.type.name === errorBuddy.name) { continue; // Error Buddy does not fire } // Wait for the next round to be chambered if (t - tower.lastFired < tower.realDelay) { continue; // Continue to next tower }
<pre> var x1 = tower.x;
var y1 = tower.y;
var dx, dy;
var enemy = findClosest(x1, y1);
if (enemy === null) {
continue;
}
var x2 = enemy.x, y2 = enemy.y;
var distToEnemy = dist(x1, y1, x2, y2);
if (distToEnemy >= tower.realRange + 10) {
continue;
}
var angle = atan2(y2 - y1, x2 - x1);
if (tower.name === the360Tower.name) {
if (tower.bullets <= 0) {
continue;
}
for (var j = 0; j < 360; j += (360 / tower.bullets)) {
var speed = 13.5;
dx = speed * cos(j);
dy = speed * sin(j);
createMissile(x1, y1, dx, dy, tower);
}
} else if (tower.name === laser.name &&
tower.bullets > 1) {
var left = angle - tower.spread/2,
right = left + tower.spread;
var offset = tower.spread/(tower.bullets-1);
for (var a = left; a <= right; a += offset) {
dx = 14 * cos(a);
dy = 14 * sin(a);
createMissile(x1, y1, dx, dy, tower);
}
} else {
dx = 12 * cos(angle);
dy = 12 * sin(angle);
createMissile(x1, y1, dx, dy, tower);
}
tower.lastFired = t;
tower.used = true;
}
</pre>
};
var updateTowers = function() { for (var count = 0; count < towers.length; count++) { var tower = towers[count]; var x1 = tower.x, y1 = tower.y; var range = tower.realRange + 10; if (tower.type !== the360Tower) { var closeEnemy = findClosest(tower.x, tower.y); if (closeEnemy === null) { continue; } var x2 = closeEnemy.x, y2 = closeEnemy.y; if (dist(x1, y1, x2, y2) < range) { var towerAngle = atan2(y2 - y1, x2 - x1); tower.angle = towerAngle; } }
<pre> tower.damageBonus = 1;
tower.rangeBonus = 1;
tower.delayBonus = 1;
for (var j = 0; j < towers.length; j++) {
if (j === count) {
// Error Buddy doesn't boost himself.
continue;
}
var twr = towers[j];
if (!twr.damageBoost) {
continue;
}
tower.damageBonus = max(tower.damageBonus, twr.damageBoost);
tower.rangeBonus = max(tower.rangeBonus, twr.rangeBoost);
tower.delayBonus = max(tower.delayBonus, twr.delayBoost);
}
tower.realDmg = tower.damage * tower.damageBonus;
tower.realDelay = tower.delay / tower.delayBonus;
tower.realRange = tower.range * tower.rangeBonus;
}
fireTowerMissiles();
</pre>
};
var upgradeTower = function(tower, code) { if (typeof(code) === "function") { code(tower); return; } if (code && code.split) { var multiUpg = code.split("; "); if (multiUpg.length >= 2) { for (var b in multiUpg) { upgradeTower(tower, multiUpg[b]); } return; } var a = code.split(" "); var property=a[0], multiplier = parseFloat(a[1]); tower[property] *= multiplier; } };
/* * Collisions * Need to check when a missile touches the enemy. /
/* This is the function that attacks an enemy... / var attackEnemy = function(enemy, damage) { enemy.health -= damage; if (enemy.health > 0) { return; }
<pre>// Gain money
if (!sandbox) {
money += enemy.moneyGain;
}
</pre>
};
/* ... and it's called in this function... / var checkEnemyCollisions = function() { for (var i = missiles.length - 1; i >= 0; i--) { var missile = missiles[i]; var mx = missile.x, my = missile.y; if (!mx || !my) { continue; } for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (isValInArray(enemy.id, missile.enemiesHit) || dist(mx, my, enemy.x, enemy.y) >= 25) { continue; } attackEnemy(enemy, missile.damage); // slow enemy? var twr = missile.weapon; if (twr === oj) { // If the enemy is already slowed, don't "slow" it again enemy.slowFactor = min(twr.slowFactor, enemy.slowFactor); enemy.slowTime = max(twr.slowTime, enemy.slowTime); debug(enemy); }
<pre> if (enemy.health <= 0) {
score++;
enemies.splice(j, 1);
}
missile.enemiesLeft--;
if (missile.enemiesLeft <= 0) {
missiles.splice(i, 1);
}
missile.enemiesHit.push(enemy.id);
}
}
</pre>
};
// Input // yyy and hhh are for the width and // height of the "selection rectangle". var upgrade = false; towerToUpg = null;
var mouseClicked = function() { if (mouseX < 80 && mouseY > (height - 40*towerTypes.length)) { return; } upgrade = false; towerToUpg = null; yyy = -100; for (var i = 0; i < towers.length; i++) { var tower = towers[i]; var x = tower.x, y = tower.y; if(dist(mouseX, mouseY, x, y) < 30) { upgrade = true; towerToUpg = tower; } } var messageOn = (!messageShown || messageClosed); if (!upgrade && messageOn) { placeTower(mouseX, mouseY, towerPicked); towerPicked = null; upgrade = false; towerToUpg = null; } };
var towerToUpg; var nextWave; var keyPressed = function() { if (mobile) { return; } if (keyCode === SHIFT) { fastForward = true; // Speed up game } else if (keyCode === 32 && !waveActive && wave !== waves.length - 2 && !enemiesOnField) { nextWave(); started = true; } else if (started && keyCode === 80) { // 80 is the key code for P paused = !paused; }
<pre>if (sandbox) {
var enemyTypes = {
48: 0,
49: 1,
50: 2,
51: 3,
52: 4,
53: "5",
54: "6",
72: "h"
};
if (enemyTypes[keyCode] !== undefined) {
createEnemy(enemyTypes[keyCode]);
}
if (keyCode === LEFT || keyCode === DOWN) {
wave--;
if (wave <= 0) {
wave = 1;
}
} else if (keyCode === RIGHT || keyCode === UP) {
wave++;
if (wave > waves.length-1) {
wave = waves.length-2;
}
}
}
</pre>
};
var keyReleased = function() { if (keyCode === SHIFT) { fastForward = false; // Back to normal } else if (keyCode === 73) { // switch invert mode on/off invertColors = !invertColors; } };
var startMonth = 11, startYear = 2012; // date I started work on this program var totalYears = (year() - startYear) + (month() - startMonth) / 12; var drawSplash = function() { textAlign(LEFT, DOWN); textSize(36); fill(255, 255, 255); text("The", width/2 - 114, height/2 - 126); pushMatrix(); translate(width/2 - 86, height/2 - 37); rotate(-20); fill(51, 255, 0); textSize(45); text("Ultimate TD", 0, 0); popMatrix(); fill(255, 255, 255); textSize(15); if (author === "The #1 Base 12 Proponent") { text("Made by The #1 Base 12 Proponent over the course of "+totalYears.toFixed(1)+" years.", 2, 2, width, height); } else { text("Original by The #1 Base-12 Proponent\nSpin-off by "+author, 3, 3, width, height); } textAlign(CENTER, CENTER); textSize(18); fill(150 + 92 * cos(6.23frameCount), 100 + 100 * sin(0.89126frameCount), 127.5 - 127.5sin(2.23019frameCount) ); textSize(30); text("5000+ (dozenal)\nvotes!", width*53/80, height/2);
<pre>var xpos = width/2 - 77, ypos = height/2 + 65;
pushMatrix();
translate(xpos, ypos - 50);
scale(0.4, 0.4);
image(fastTower.image, 0, 0);
image(rock.image, 380, 15);
popMatrix();
var offset = 11;
var size = 18;
noStroke();
var offset2 = 91;
for (var i = 0; i < 5; i++) {
fill(0, i*51 + 51, 0);
ellipse(xpos + offset2 + i*offset, ypos, size - (5-i), size - (5-i));
}
var y2 = height - 80;
var w = 70, h = 36;
offset = 80;
var x = (width/2 - offset*1.46875);
fill(255, 255, 255);
noStroke();
drawButton("Easy", x - offset, y2 - h/2, w, 0, h, 16, true);
if (mouseTicks === 1 && overButton) {
money += 25;
ENEMY_HEALTH_MULTIPLIER = pow(ENEMY_HEALTH_MULTIPLIER, 0.8);
gameState = "game";
}
drawButton("Medium", x, y2 - h/2, w, 0, h, 16, true);
if (mouseTicks === 1 && overButton) {
gameState = "game";
money *= 1.25;
rock.moneyGain *= 0.75;
bug.moneyGain *= 0.75;
strong.moneyGain *= 0.75;
}
drawButton("Cheats", x, y2 + h*3/4, w, 0, h, 18, true);
if (mouseTicks === 2 && overButton) {
gameState = "cheats";
}
drawButton("Hard", x + offset, y2 - h/2, w, 0, h, 18, true);
if (mouseTicks === 1 && overButton) {
gameState = "game";
rock.health *= 1.5;
bug.health *= 1.5;
strong.health *= 1.5;
backwards.health *= 1.5;
lives *= 0.75;
ENEMY_HEALTH_MULTIPLIER = pow(ENEMY_HEALTH_MULTIPLIER, 2);
}
drawButton("Sandbox\n(not mobile)", x + 2*offset, y2 - h/2, w, 0, h, 13);
if (overButton) {
fill(255, 255, 255, 128);
noStroke();
var xpos = x + 2*offset + w/2,
ypos = y2 - h/2;
rect(xpos - 100, ypos - 100, 130, 90, 15);
fill(0, 0, 0);
</pre>