I made this small game to prep for my web programming exam but it's not quite working out and I'm fairly stuck.
I basically have an object Star which has a property isCaught that is standard false and turns to true when it collides with another object (witch).
I want my program to always loop through my array of Star objects and check if every element inside the array has been caught (isCaught = true), if so it should alert the user.
However, it only returns false (and only 3 times).
I also tried to delete the objects from the array if they weren't caught and reached the end of the screen, but then I would get an indexation problem (that's the commented out part).
I'm probably doing something really stupid really wrong but I can't find it.
Here's the code:
function Star(x, y, vy){
this.x = x;
this.y = y;
this.vy = vy;
this.isCaught = false;
var starImg = new Image();
starImg.src = 'images/star.png';
$(starImg).load(function(){
});
this.drawStar = function(){
ctx.drawImage(starImg,this.x,this.y,20,20);
//context.beginPath();
}
}
function Witch(){
this.x = 10;
this.y = 300;
var witchImg = new Image();
witchImg.src = 'images/witch2.png';
$(witchImg).load(function(){
});
this.drawWitch = function(){
ctx.drawImage(witchImg,this.x,this.y,50,50);
}
}
var canvas;
var ctx;
var speed = 33;
var starsAmount = 6;
var stars = [];
var witch = new Witch();
$(function(){
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
$("body").mousemove(function(arg){
//witch.y = arg.pageY;
witch.x = arg.pageX;
});
for(var i=0;i<starsAmount;i++){
stars.push(new Star(Math.floor(Math.random()*canvas.width)+50,10,2));
}
Animate();
});
function Animate(){
ctx.clearRect(0,0,canvas.width,canvas.height);
var countCaught = 0;
for (var i = 0; i < stars.length; i++){
stars[i].y += stars[i].vy;
stars[i].drawStar();
witch.drawWitch();
}
//collision detection
for(var i=0; i<stars.length; i++){
var distanceX = (stars[i].x+10)-(witch.x+25);
var distanceY = (stars[i].y+10)-(witch.y+25);
var distance = Math.sqrt((distanceX*distanceX)+(distanceY*distanceY));
if(distance < 35){
stars[i].x = Math.floor(Math.random()*canvas.width);
stars[i].y = -20;
stars[i].vy += 1;
stars[i].isCaught = true;
}
var allCaught = checkCaught();
console.log(allCaught);
if(allCaught == true){
("You've lost!");
}
//if the stars reach the end of the screen and they are not caught, delete them from the array
/*
if((stars[i].y+10) == canvas.height && stars[i].isCaught == false){
console.log(stars[i].y);
stars.splice(i,1);
console.log("say something im giving up on you" + i);
}
console.log("array length " + stars.length);
*/
}
setTimeout(Animate,speed);
}
function checkCaught(){
var allCaught = true;
for(var i=0; i<stars.length; i++){
if(stars[i].isCaught == false){
allCaught = false;
}
else{
allCaught = true;
}
}
return allCaught;
}
Thanks in advance!
The ES5 way to write your allCaught function is using Array.prototype.every:
function checkCaught() {
return stars.every(function(star) {
return star.isCaught;
});
}
The ES6 way would be:
var checkCaught = () => stars.every(star => star.isCaught);
You could simplify this function like this:
function checkCaught(){
var allCaught = true;
for(var i=0; i<stars.length; i++){
if(stars[i].isCaught == false){
allCaught = false;
break;
}
}
return allCaught;
}
It looks ok, but you seem to have an object array, which might not be easily iteratable. Have you tried to iterate with a foreach loop?
for (key in stars) {
if (stars[key].isCaught === false) {
allCaught = false;
break;
}
}
If you really want some help please add a plunker or https://jsfiddle.net/ or whatever.
I did try to make a fiddle for you... but it seems to work out for me there, so I don't really know, what your problem is...
https://jsfiddle.net/zh0ybdho/
Related
I've tried different variations, using this (topMag) function. What i want, with the function is, when i call the getElem function for an example with all the paragraphs, i want the topMag to count every paragraph's height from the top of the paragraph to the top of the document. Please someone explain to me, what is happening here when the function is called, and how to solve it.
var elem, celElem, elemTop = [], elemMag = [], elemBot = [], elemCent = [], winTop, winMag, winBot, winCent, i;
function getElem(el, cEl, fn){
if(el.length === undefined){
el = [el];
cEl = [cEl]
};
elem = el;
celElem = cEl;
for (i = 0; i<elem.length; i++){
elemTop[i] = 0;
elemMag[i] = elem[i].offsetHeight;
elemBot[i] = elemTop[i]+elemMag[i];
elemCent[i] = elemTop[i]+(elemMag[i]/2);
topMag(elem[i], i);
}
winTop = window.pageYOffset;
winMag = window.innerHeight;
winBot = winTop+winMag;
winCent = winTop+(winMag/2);
};
//the reason, why i need x: when the function is executed,
//i want to remain elem[i] to elem[i], not the body
function topMag(x, i){
elem[i] = x
if (getComputedStyle(elem[i]).position === "fixed"){
elemTop[i] = elem[i].offsetTop;
}
else{
do{
elemTop[i] += elem[i].offsetTop;
elem[i] = elem[i].offsetParent;
}
while(elem[i] != "[object HTMLBodyElement]");
elem[i] = x;
}
};
I am using a script that uses a for loop to spawn objects within Unity. When the player object hits one of these spawned objects it calls a function that makes a boolean true. When this boolean is true it should subtract 1 from the for loop. Basically the for loop has a max of 10, when an object is spawned it adds one, and I want it to subtract 1 when an object is struck by the player. I am having issues trying to make this work. Any and all help, greatly appreciated.
var theObject:GameObject;
var maxPos:float = 500;
var minPos:float = -500;
var max = 10;
var switch1 = false;
function Start(){
StartCoroutine(spawn());
}
function spawn() : IEnumerator {
for (var i = 0; i < max;){
if (switch1 == true){
i--;
}
else if (switch1 == false){
i++;
//Debug.Log("spawn");
//Time between spawns
yield WaitForSeconds(0.4);
//Determines and spawns new object
var theNewPos = new Vector3(Random.Range(minPos,maxPos),0,Random.Range(minPos,maxPos));
var go : GameObject = Instantiate(theObject);
go.transform.position = theNewPos;
}
else{
switch1 = false;
}
}
}
function AtomHit(){
switch1 = true;
}
I guess you are trying to do this:?
var theObject:GameObject;
var maxPos:float = 500;
var minPos:float = -500;
var max = 10;
var switch1 = false;
function Start(){
StartCoroutine(spawn());
}
function spawn() : IEnumerator {
for (var i = 0; i < max;){
if (switch1){
i--;
}
else{
i++;
//Determines and spawns new object
var theNewPos = new Vector3(Random.Range(minPos,maxPos),0,Random.Range(minPos,maxPos));
var go : GameObject = Instantiate(theObject);
go.transform.position = theNewPos;
}
//Time between spawns
yield WaitForSeconds(0.4);
switch1 = false;
}
}
function AtomHit(){
switch1 = true;
}
[EDIT] Full application available at: http://bit.ly/1CGZzym
I'm receiving the error:
Uncaught TypeError: Cannot set property '0' of undefined
with the following code. I believe it is due to my not declaring the child array of the 2D array properly but I am really confused as to where I should be declaring this. Any ideas would be excellent.
// Create an array for the tiles we're about to draw
var tileArray = []
is declared out side of the function.
I assume it is because I am trying to create child elements within each [col] so I guess I need to declare each col number somewhere but nothing I attempt seems to be working.
function drawGrid()
{
// Draw diamond grid
var col = 0;
var row = 0;
topTileX = (viewWidth/2);
topTileY = 0;
var nextX = 0;
var nextY = 0;
var getCols = 0;
while (topTileX > -1)
{
tileArray[col][row] = new DiamondTile(topTileX, topTileY, tileWidth, true, col, row);
tileArray[col][row].draw();
while (tileArray[col][row].xPos + tileArray[col][row].tileWidth < (viewWidth) + tileWidth)
{
col++;
nextX = tileArray[col-1][row].xPos + tileArray[col-1][row].tileWidth / 2;
nextY = tileArray[col-1][row].yPos + tileArray[col-1][row].tileHeight / 2;
tileArray[col][row] = new DiamondTile(nextX, nextY, tileWidth, true, col, row);
tileArray[col][row].draw();
if (col == getCols)
{
break;
}
}
row++;
getCols = col;
col = 0;
topTileX = topTileX - tileWidth/2;
topTileY = topTileY + tileHeight/2;
}
};
For the purpose of demonstration, the DiamondTile function is as follows:
function DiamondTile(xPos,yPos,width,interactive,myCol,myRow)
{
// Set x and y position for this sprite
this.xPos = xPos;
this.yPos = yPos;
this.myRow = myRow;
this.myCol = myCol;
// Used for AI pathfinding
this.isObstacle = false;
this.isStart = false;
this.isEnd = false;
this.gValue = 0;
this.hValue = 0;
this.fCost = 0;
this.tileWidth = width;
this.tileHeight = this.tileWidth/2;
var self = this;
// Create sprite
this.spriteObj = new PIXI.Sprite(grass);
this.spriteObj.interactive = interactive;
this.spriteObj.anchor = new PIXI.Point(0.5,0);
this.spriteObj.hitArea = new PIXI.Polygon([
new PIXI.Point(0,0),
new PIXI.Point(100,50),
new PIXI.Point(0,100),
new PIXI.Point(-100,50)
]);
this.spriteObj.mouseover = function()
{
if (self.spriteObj.tint == 0xFFFFFF)
{
self.spriteObj.tint = 0xA7E846;
}
text2.setText(self.myCol + "," + self.myRow + " Start: " + self.isStart);
}
this.spriteObj.mouseout = function()
{
if (self.spriteObj.tint == 0xA7E846)
{
self.spriteObj.tint = 0xFFFFFF;
}
}
this.spriteObj.click = function()
{
if (startStage === true)
{
startStage = false;
self.isStart = true;
self.spriteObj.tint = 0x1AFF00;
text.setText("Now select an end point");
endStage = true;
return true;
}
if (endStage === true)
{
endStage = false;
self.isEnd = true;
self.spriteObj.tint = 0xFF0000;
text.setText("Now place some obstacles");
obsStage = true;
return true;
}
if (obsStage ===true)
{
self.isObstacle = true;
self.spriteObj.tint = 0x3B3B3B;
text.setText("Press 'C' to calculate path");
return true;
}
}
};
That is a multi-dimensional array and you have not initialized the first dimension array correctly. In the while loop you have to initialize the first dimension to be able to access a second dimension element with an index:
while (topTileX > -1)
{
if (tileArray[col] == null)
tileArray[col] = [];
tileArray[col][row] = new DiamondTile(topTileX, topTileY, tileWidth, true, col, row);
tileArray[col][row].draw();
// omitted other code for brevity
}
Javascript arrays are dynamic and it's enough to initialize the first dimension array elements in this case. You don't have to initialize the individual items in the second dimension.
Update: here is a fiddle with working code http://jsfiddle.net/0qbq0fts/2/
In addition your semantics is wrong. By the book, the first dimension of a 2-dimensional array should be rows, and the second dimension should be columns.
You have to explicit create the elements representing the second dimension, e.g.:
function make2DArray(rows, cols) {
var r = Array(rows);
for (var i = 0; i < rows; ++i) {
r[i] = Array(cols);
}
return r;
}
If you don't know in advance how many columns, just use this:
function make2DArray(rows) {
var r = Array(rows);
for (var i = 0; i < rows; ++i) {
r[i] = [];
}
return r;
}
The individual rows can each have independent lengths, and will grow as you add values to them.
Similarly, if you just need to add a new (empty) row, you can just do:
tileArray.push([]);
This should probably me a comment, but SO has crashed on my side. JavaScript might be throwing an exception on your stated line, but the problem may be with the 'DiamondTile' function.
I'm sure it should be discussed before by Photoshop scripters. I write a solution as following. I think it's logically right, but the result is not correct. Anybody can help to check where's wrong in the code, or have ideas for this topic? I want to get all the layers in a document.
Code:
function getAllLayersInLayerSets(layerNodes) {
var retList = [];
for (var i=0; i<layerNodes.length; i++) {
if(layerNodes[i].layerSets.length > 0)
{
var tmp = getAllLayersInLayerSets(layerNodes[i].layerSets);
var j = (tmp == null) ? -1 : tmp.length-1;
while(tmp && j>=0)
{
retList.push(tmp[i]);
j--;
}
}
for(var layerIndex=0; layerIndex < layerNodes[i].artLayers.length; layerIndex++)
{
var layer=layerNodes[i].artLayers[layerIndex];
retList.push(layer);
}
}
return retList;
}
Many thanks for any help or discussion.
I know this is an old thread, but this might be useful for someone.
I was looking for a function that would get me all the ArtLayers in a Photoshop comp, including layers nested in groups. The above function was returning undefined, so I modified it and got it to work.
var doc = app.activeDocument;
var allLayers = [];
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
Minor expansion on Ghoul Fool's post to only get all VISIBLE art layers in the active document. :P
// Get layers in a document
var sourceDocument = app.activeDocument;
var visibleLayers = [];
var visibleLayers = collectAllLayers(sourceDocument, visibleLayers);
// Print out total layers found
alert(visibleLayers.length);
// Recursively get all visible art layers in a given document
function collectAllLayers (parent, allLayers)
{
for (var m = 0; m < parent.layers.length; m++)
{
var currentLayer = parent.layers[m];
if (currentLayer.typename === "ArtLayer")
{
if(currentLayer.visible)
{
allLayers.push(currentLayer);
}
}
else
{
collectAllLayers(currentLayer, allLayers);
}
}
return allLayers;
}
To get all the layers (and sub layers) you have to have a recursive function
var allLayers = new Array();
var theLayers = collectAllLayers(app.activeDocument, 0);
function collectAllLayers (theParent, level)
{
for (var m = theParent.layers.length - 1; m >= 0; m--)
{
var theLayer = theParent.layers[m];
if (theLayer.typename != "ArtLayer")
{
allLayers.push(level + theLayer.name);
collectAllLayers(theLayer, level + 1)
}
}
}
function selectAllLayers() {
var desc29 = new ActionDescriptor();
var ref23 = new ActionReference();
ref23.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc29.putReference(charIDToTypeID('null'), ref23);
executeAction(stringIDToTypeID('selectAllLayers'), desc29, DialogModes.NO);
}
I have two almost identically classes written in js. I would like to make one of them extend the other one, in order to have less code. I'm a novice in javascript and I need a little help to make this.
I'm posting the classes here. Can anybody help?
//============================================================================================================================================
//Class1==================================================================================================================================
//============================================================================================================================================
function Class1(config){
var targetObj;
var copycanvas = null;
var copy = null;
var outputcanvas = null;
var draw = null;
var direction = config.direction || "lr";
var TILE_WIDTH = config.tileWidth || 100;
var TILE_HEIGHT = config.tileHeight || 100;
var SOURCERECT = {x:0, y:0, width:0, height:0};
var interval;
var tiles2 = [];
var cols = 0;
var rows = 0;
createTiles = function(){
tiles = [];
tiles2 = [];
var y=0;
while(y < SOURCERECT.height){
var x=0;
cols = 0;
while(x < SOURCERECT.width){
cols++;
x += TILE_WIDTH;
}
rows++;
y += TILE_HEIGHT;
}
var i, j;
if (direction == "tl"){
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++){
x = j * TILE_WIDTH;
y = i * TILE_HEIGHT;
var tile = new Tile();
tile.imageX = x;
tile.imageY = y;
tiles2.push(tile);
}
}
arrangeSquares();
};
arrangeSquares = function(){
var i, j, k;
var M, N;
M = rows;
N = cols;
i = j = 0;
var cnt = 0;
for (i = 0; i < N + M - 1; i++)
for (j = 0; j <= i; j++)
if (j < M && (i - j) < N){
tiles.push(tiles2[j * N + (i - j)]);
}
}
processFrame = function(){
copycanvas.width = outputcanvas.width = targetObj.width;
copycanvas.height = outputcanvas.height = targetObj.height;
copy.drawImage(targetObj, 0, 0, targetObj.width, targetObj.height);
for(var i=0; i < tiles.length; i++) {
var tile = tiles[i];
tile.alpha += 0.05;
var TH = Math.max(0, Math.min(TILE_HEIGHT, targetObj.height - tile.imageY));
var TW = Math.max(0, Math.min(TILE_WIDTH, targetObj.width - tile.imageX));
draw.save();
draw.translate(tile.imageX, tile.imageY);
draw.globalAlpha = Math.max(0, tile.alpha);
draw.drawImage(copycanvas, tile.imageX, tile.imageY, TW, TH, 0, 0, TW, TH);
draw.restore();
}
var ok = true;
for (i = 0; i < tiles.length; i++) {
if (tiles[i].alpha < 1) {
ok = false;
break;
}
}
if (ok)
{
clearInterval(interval);
showComplete();
}
};
function showComplete() {
$target.trigger("showComplete");
$img.show();
$(copycanvas).remove();
$(outputcanvas).remove();
if ($hideTarget)
$hideTarget.hide();
};
this.hide = function(target) {
};
var $target = null;
var $img = null;
var $hideTarget = null;
this.show = function(target, hideTarget){
$target = $("#" + target).show();
align($target);
if (hideTarget != undefined) {
$target.before($hideTarget = $("#" + hideTarget).show());
align($hideTarget);
}
$img = $("#" + target + " > img").filter(":first").hide();
$("<canvas/>").attr("id", "sourcecopy")
.css("position", "absolute")
.appendTo($target)
.hide();
copycanvas = document.getElementById("sourcecopy");
copy = copycanvas.getContext('2d');
$("<canvas/>").attr("id", "output")
.css("position", "absolute")
.appendTo($target);
outputcanvas = document.getElementById("output");
draw = outputcanvas.getContext('2d');
targetObj = document.getElementById($img.attr("id"));
clearInterval(interval);
SOURCERECT = {x:0, y:0, width: targetObj.width, height: targetObj.height};
createTiles();
for(var i=0; i<tiles.length; i++){
var tile = tiles[i];
tile.alpha = 0 - (i * (2 / tiles.length));
}
var intervalDelay = (config.duration * 1000) / (40 + rows + cols);
interval = setInterval(function() { processFrame(); }, intervalDelay);
};
function Tile(){
this.alpha = 1;
this.imageX = 0;
this.imageY = 0;
};
};
//============================================================================================================================================
//Class2===================================================================================================================================
//============================================================================================================================================
function Class2(config){
var targetObj;
var copycanvas = null;
var copy = null;
var outputcanvas = null;
var draw = null;
var direction = config.direction || "lr";
var TILE_WIDTH = config.barWidth || 50;
var TILE_HEIGHT = 100;
var SOURCERECT = {x:0, y:0, width:0, height:0};
var interval;
var tiles = [];
createTiles = function(){
tiles = [];
var y=0;
while(y < SOURCERECT.height){
var x=0;
while(x < SOURCERECT.width){
var tile = new Tile();
tile.imageX = x;
tile.imageY = y;
tiles.push(tile);
x += TILE_WIDTH;
}
y += TILE_HEIGHT;
}
};
processFrame = function(){
copycanvas.width = outputcanvas.width = targetObj.width;
copycanvas.height = outputcanvas.height = targetObj.height;
copy.drawImage(targetObj, 0, 0, targetObj.width, targetObj.height);
for(var i=0; i < tiles.length; i++) {
var tile = tiles[i];
tile.alpha += 0.05;
var TH = Math.max(0, Math.min(TILE_HEIGHT, targetObj.height - tile.imageY));
var TW = Math.max(0, Math.min(TILE_WIDTH, targetObj.width - tile.imageX));
draw.save();
draw.translate(tile.imageX, tile.imageY);
draw.globalAlpha = Math.max(0, tile.alpha);
draw.drawImage(copycanvas, tile.imageX, tile.imageY, TW, TH, 0, 0, TW, TH);
draw.restore();
}
var ok = true;
for (i = 0; i < tiles.length; i++) {
if (tiles[i].alpha < 1) {
ok = false;
break;
}
}
if (ok)
{
clearInterval(interval);
showComplete();
}
};
function showComplete() {
$target.trigger("showComplete");
$img.show();
$(copycanvas).remove();
$(outputcanvas).remove();
if ($hideTarget)
$hideTarget.hide();
};
this.hide = function(target) {
};
var $target = null;
var $img = null;
var $hideTarget = null;
this.show = function(target, hideTarget){
$target = $("#" + target).show();
align($target);
if (hideTarget != undefined) {
$target.before($hideTarget = $("#" + hideTarget).show());
align($hideTarget);
}
$img = $("#" + target + " > img").filter(":first").hide();
$("<canvas/>").attr("id", "sourcecopy")
.css("position", "absolute")
.appendTo($target)
.hide();
copycanvas = document.getElementById("sourcecopy");
copy = copycanvas.getContext('2d');
$("<canvas/>").attr("id", "output")
.css("position", "absolute")
.appendTo($target);
outputcanvas = document.getElementById("output");
draw = outputcanvas.getContext('2d');
targetObj = document.getElementById($img.attr("id"));
clearInterval(interval);
if (direction == "tb" || direction == "bt")
{
TILE_WIDTH = targetObj.width;
TILE_HEIGHT = config.barWidth;
}
else
{
TILE_WIDTH = config.barWidth;
TILE_HEIGHT = targetObj.height;
}
SOURCERECT = {x:0, y:0, width: targetObj.width, height: targetObj.height};
createTiles();
if (direction == "lr" || direction == "tb")
{
for(var i=0; i<tiles.length; i++){
var tile = tiles[i];
tile.alpha = 0 - (i * (1 / tiles.length));
}
}
else
{
for(var i=tiles.length - 1; i >= 0 ; i--){
var tile = tiles[i];
tile.alpha = 0 - ((tiles.length - i - 1) * (2 / tiles.length));
}
}
var intervalDelay = (config.duration * 1000) / (40 + tiles.length);
interval = setInterval(function() { processFrame(); }, intervalDelay);
};
function Tile(){
this.alpha = 1;
this.imageX = 0;
this.imageY = 0;
};
};
Try declaring the class like this.
var theClass = function theClass() {
....
to extend this class you can use the prototype method:
theClass.prototype.newMethodName = function () {
....
You have a couple of choices. You can isolate the common functionality into a third object that Class1 and Class2 share (aggregation), or you can actually create a hierarchy of objects (inheritance). I'll talk about inheritance here.
JavaScript doesn't have classes, it's a prototypical language. An object instance is "backed" by a prototype object. If you ask the instance for a property it doesn't have (and functions are attached to objects as properties), the JavaScript interpreter checks the prototype behind the object to see if it has the property (and if not, the prototype behind that object, etc., etc.). This is how prototypical inheritance works.
JavaScript is an unusual prototypical language in that, until recently, there was no way to create an object and assign its prototype directly; you had to do it through constructor functions. If you're using class-based terminology, you're probably going to be more comfortable with constructor functions anyway. :-)
Here's a basic inheritance setup (this is not how I would actually do this, more on that below):
// Constructs an Vehicle instance
function Vehicle(owner) {
this.owner = owner;
}
// Who's this Vehicle's owner?
Vehicle.prototype.getOwner = function() {
return this.owner;
};
// Constructs a Car instance
function Car(owner) {
// Call super's initialization
Vehicle.call(this, owner);
// Our init
this.wheels = 4;
}
// Assign the object that will "back" all Car instances,
// then fix up the `constructor` property on it (otherwise
// `instanceof` breaks).
Car.prototype = new Vehicle();
Car.prototype.constructor = Car;
// A function that drives the car
Car.prototype.drive = function() {
};
Now we can use Car and get the features of Vehicle:
var c = new Car("T.J.");
alert(c.getOwner()); // "T.J.", retrived via Vehicle.prototype.getOwner
The above is a bit awkward and it has a couple of issues with when things happen that can be tricky. It also has the problem that most of the functions are anonymous, and I don't like anonymous functions (function names help your tools help you). It's also awkward to call your prototype's version of a function if you also have a copy of it (e.g., a "supercall" — not an uncommon operation with hierarchies). For that reason, you see a lot of "frameworks" for building hierarchies, usually using class-based terminology. Here's a list of some of them:
The Class feature of Prootype, a general-purpose JavaScript library
Dean Edwards' base2
John Resig's Simple JavaScript Inheritance (Resig being the person who created jQuery)
Er, um, mine — which as far as I know is being used by about three people. I did it because I had issues with decisions each of the above made. I will be updating it to not use class terminology (and actually releasing it as a tiny library, rather than just a blog post), because none of these adds classes to JavaScript, and acting as though they do misses the point of JavaScript prototypical model.
Of those four, I'd recommend Resig's or mine. Resig's uses function decompilation (calling toString on function instances, which has never been standardized and doesn't work on some platforms), but it works even if function decompilation doesn't work, it's just slightly less efficient in that case.
Before jumping on any of those, though, I encourage you to look at the true prototypical approach advocated by Douglas Crockford (of JSON fame, also a big wig at YUI). Crockford had a great deal of input on the latest version of ECMAScript, and some of his ideas (most notably Object.create) are now part of the latest standard and are finding their way into browsers. Using Object.create, you can directly assign a prototype to an object, without having a constructor function.
I prefer constructor functions (with my syntactic help) for places where I need inheritance, but Crockford's approach is valid, useful, and gaining popularity. It's something you should know about and understand, and then choose when or whether to use.