Closure compiler number getting undefined in advanced optimization - google-closure-compiler

I have the following line of code
frame = self.spriteData['backgroundps.png'];
self.bgBoard = new gg.casino.game.sprite(self.spriteSheet, frame, 0, 0, frame.w, frame.h);
console.log(frame);
console.log(self.bgBoard.x + ' ' + self.bgBoard.y + ' ' + self.bgBoard.w + ' ' + self.bgBoard.h);
and gg.casino.game.sprite is defined as
gg.casino.game.sprite = function(sheet, frame, x, y, twidth, theight) {
this.sheetRef = sheet;
this.frame = frame;
this.x = x;
this.y = y;
this.w = twidth;
this.h = theight;
console.log(this.x + ' ' + this.y + ' ' + this.w + ' ' + this.h);
}
when compiling with simpleoptimization, everything works well and I get the following log:
0 0 800 480
(frame object)
0 0 800 480
but when I compile with advanced optimization, log shows
0 0 undefined undefined
(frame object) - with correct values
0 0 undefined undefined
what could have gone wrong with this code?
EDIT:
added a log after frame = self.spriteData['backgroundps.png'];
console.log('ps ' + frame.w + ' ' + frame.h);
and it prints w and h as undefined !!!!!!
ps undefined undefined
where as console.log(frame) in next line prints the object with correct values
Edit 2:
more on self.spriteData:
I have a json file exported from texturepacker. It has an array of objects where each object is represented as
{
"filename": "backgroundps.png",
"frame": {"x":105,"y":304,"w":800,"h":480},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":800,"h":480},
"sourceSize": {"w":800,"h":480}
}
I loop through that json array and assign the values to self.spriteData as follows:
var respData = xhr.getResponseJson();
self.spriteData = {};
for(var i = 0, len = respData.frames.length; i < len; i++) {
self.spriteData[respData.frames[i].filename] = respData.frames[i].frame;
}
so frame will having the following structure, which gets printed on console:
Object
h: 480
w: 800
x: 105
y: 304
so in advanced compilation, there is no problem if I print the frame as console.log(frame). But when I try accessing its members console.log(frame.h) it prints as undefined. Just tried adding #expose comment to var frame = {};, hoping it wont get renamed, but didnt help.
Edit:
changed frame assignment as
frame.x = self.spriteData['backgroundps.png'].x;
frame.y = self.spriteData['backgroundps.png'].y;
frame.w = self.spriteData['backgroundps.png'].w;
frame.h = self.spriteData['backgroundps.png'].h;
and declared frame.w and frame.h with comment `#type {number} (didnt do for x and y as the were working fine already).
Now console.log(frame) shows
Object
a: undefined
b: undefined
x: 105
y: 304
but why?
EDIT (Solved) :D :-)
I explicitly declared frame's members as
/**
* #type {number}
* #expose
*/
frame.w = 0;
/**
* #type {number}
* #expose
*/
frame.h = 0;
/**
* #type {number}
* #expose
*/
frame.x = 0;
/**
* #type {number}
* #expose
*/
frame.y = 0;
and now it works :-)
thanks to Kayhr, Ross and Chad for you help. but now I wonder whose answer should I mark the right one?

What is the definition of self.spriteData['backgroundps.png']?
I would be willing to bet that the 'w' and 'h' keys of self.spriteData['backgroundps.png'] are defined with strings. If so, things will usually break when you access such properties with dot-syntax, because the compiler will leave strings untouched but optimize the names of properties written in dot-syntax.
For example:
foo['bar'] => a['bar']
foo.bar => a.b
...where a and b are hypothetical compiler output tokens.
See: https://developers.google.com/closure/compiler/docs/api-tutorial3#propnames

Can't reproduce it. I have faked the missing code with simple objects to get your code running. The output is the same, doesn't matter if I use SIMPLE or ADVANCED optimization. I guess your problem is in the code which you did not mention here (Maybe in the definition of this spriteData stuff). Please give us a complete example and the exact compiler options you used.
Here is the code I'm compiling, maybe you can see a crucial difference to your REAL code:
// Faked code (The stuff you didn't include in the question):
var gg, self;
gg = {};
gg.casino = {};
gg.casino.game = {};
self = { spriteData: { 'backgroundps.png': { w: 800, h: 480 } } };
// Your code (unchanged):
gg.casino.game.sprite = function(sheet, frame, x, y, twidth, theight) {
this.sheetRef = sheet;
this.frame = frame;
this.x = x;
this.y = y;
this.w = twidth;
this.h = theight;
console.log(this.x + ' ' + this.y + ' ' + this.w + ' ' + this.h);
}
frame = self.spriteData['backgroundps.png'];
self.bgBoard = new gg.casino.game.sprite(self.spriteSheet, frame, 0, 0, frame.w, frame.h);
console.log(frame);
console.log(self.bgBoard.x + ' ' + self.bgBoard.y + ' ' + self.bgBoard.w + ' ' + self.bgBoard.h);

Related

Neither adding a SKShapeNode nor adding a SKLabelNode to a SKScene appears to work?

Neither adding a SKShapeNode nor adding a SKLabelNode to a SKScene appears to work?
My gut guesses that I have a coordinate problem .. so here's the short code snippet which I have placed in my GameViewController class:
Note: I've added print statements below to debug.
FYI: I believe the values are wrong because they appear to be Frame coordinates, not Scene Coordinates. Frankly, I'm at a loss how to correct this error.
func addScoreLabelToScene(toScene: SKScene) {
if thisSceneName == "GameScene" {
let circleRadius = Double(100),
circleOffset = Double(30),
labelOffset = Double(10),
//
circlePosX = toScene.frame.size.width/2 - circleRadius - circleOffset,
labelPosX = circlePosX - labelOffset,
circlePosY = toScene.frame.size.height/2 + circleRadius + circleOffset,
labelPosY = circlePosY + labelOffset
// frame.size = 818, 1340
print("circlePosX = \(circlePosX)") // 279
print("circlePosY = \(circlePosY)") // 800
print("labelPosX = \(labelPosX)") // 269
print("labelPosY = \(labelPosY)") // 810
let circle = SKShapeNode(circleOfRadius: circleRadius)
circle.position = CGPoint(x: circlePosX, y: circlePosY)
circle.strokeColor = SKColor.red
circle.lineWidth = 2.0
circle.fillColor = SKColor.white
toScene.addChild(circle)
itsScoreLabel = SKLabelNode(fontNamed: "HelveticaNeue-Bold")
itsScoreLabel!.position = CGPoint(x: labelPosX, y: labelPosY)
itsScoreLabel!.text = "\(thisScore)"
itsScoreLabel!.fontSize = 20
itsScoreLabel!.fontColor = SKColor.blue
toScene.addChild(itsScoreLabel!)
}
} // addScoreLabelToScene
WRT to the above guess about a coordinate problem, I have hard-wired values for the PosX and PosY variables, but no success there.
In addition I have commented out both toScene.addChild() calls (one at a time) with no luck.
To complete the problem description, I have code elsewhere that adds several SKSpriteNodes with no problem.
So, what mammoth error am I committing?
As already commented above, I owe kelin above immeasurable thanks for motivating me to check my code again!
The central issue centers on specifying .zPosition = 10 or any very large number so the 2 Objects are not buried under everything.
So ... the NEW code which does it right:
func addScoreLabelToScene(toScene: SKScene) {
if thisSceneName == "GameScene" {
let circleRadius = Double(50), // lots of messing with #s involved
circleOffsetX = Double(25)
#if os(iOS)
let circleOffsetY = Double(105)
#elseif os(tvOS)
let circleOffsetY = Double(25)
#endif
// NR because we've centered the label within the circle.
// Nevertheless, as noted below, we still have to position it
// for horizontal + vertical alignment to take effect.
let labelOffsetX = Double(0),
labelOffsetY = Double(0),
//
circlePosX = toScene.frame.size.width/2 - circleRadius - circleOffsetX,
labelPosX = circlePosX - labelOffsetX,
circlePosY = toScene.frame.size.height/2 - circleRadius - circleOffsetY,
labelPosY = circlePosY - labelOffsetY
// added these print statements to debug:
// frame.size = 818, 1340
print("circlePosX = \(circlePosX)") // 334 = 818/2 - 50 - 25
print("circlePosY = \(circlePosY)") // 515 = 1340/2 - 50 - 105
print("labelPosX = \(labelPosX)") // 334 = 334 - 0
print("labelPosY = \(labelPosY)") // 515 = 515 - 0
let circle = SKShapeNode(circleOfRadius: circleRadius)
circle.zPosition = 10 // otherwise, the Object will be buried at the bottom
circle.position = CGPoint(x: circlePosX, y: circlePosY)
circle.strokeColor = SKColor.red
circle.lineWidth = 6.0
circle.fillColor = SKColor.white
toScene.addChild(circle)
itsScoreLabel = SKLabelNode(fontNamed: "HelveticaNeue-Bold")
itsScoreLabel!.zPosition = 10
// still gotta position it for alignment to take affect
itsScoreLabel!.position = CGPoint(x: labelPosX, y: labelPosY)
itsScoreLabel!.horizontalAlignmentMode = .center
itsScoreLabel!.verticalAlignmentMode = .center
itsScoreLabel!.text = "\(thisScore)"
itsScoreLabel!.fontSize = 30
itsScoreLabel!.fontColor = SKColor.blue
toScene.addChild(itsScoreLabel!)
}
} // addScoreLabelToScene

How do I sample isampler3d in webgl2?

two question. first off, how could I set a particular value in a 3d texture to 1, lets say the y coordinate of the element at index 1,1,1 in the following Int16Array so I could later read it. I think it'd go something like this:
var data = new Int16Array(size * size * size);
data.fill(0);
// ??? (somehow I'd set values of the data array at index 1,1,1 but I'm unsure how)
data ??? = 1;
gl.texImage3D(
gl.TEXTURE_3D,
0,
gl.R16I,
size,
size,
size,
0,
gl.RED_INTEGER,
gl.SHORT,
data);
secondly, later in my fragment shader, how could I grab that value using the GLSL texture function. I think it'd go something like this:
uniform isampler3d t_sampler;
...
ivec4 value = texture( t_sampler , vec3( 1.0 , 1.0 , 1.0 ) );
if( value.y == 1 ){
// do some special stuff
}
any help would be appreciated. again I'm just trying to create my texture using a data array I create and then read that value in the frag shader.
fyi this code is running but failing to get to the "do some special stuff" part.
thanks
// ??? (somehow I'd set values of the data array at index 1,1,1 but I'm unsure how)
data ??? = 1;
const width = ??
const height = ??
const depth = ??
const numChannels = 1; // 1 for RED, 2 for RG, 3 for RGB, 4 for RGBA
const sliceSize = width * height * numChannels;
const rowSize = width * numChannels;
const x = 1;
const y = 1;
const z = 1;
const offset = z * sliceSize + y * rowSize + x;
data[offset] = redValue;
If there are more channels, for example RGBA then
data[offset + 0] = redValue;
data[offset + 1] = greenValue;
data[offset + 2] = blueValue;
data[offset + 3] = alphaValue;
how could I grab that value using the GLSL texture function
To get a specific value from a texture you can use texelFetch with pixel/texel coordinates.
uniform isampler3d t_sampler;
...
int x = 1;
int y = 1;
int z = 1;
int mipLevel = 0;
ivec4 value = texelFetch(t_sampler, ivec3(x, y, z), mipLevel);
if( value.y == 1 ){
// do some special stuff
}
Be sure to check the JavaScript console for errors. In your case you probably need to set filtering to NEAREST since you're not providing mips and since integer textures can not be filtered.

Repeating Value Unity

It should give me a random value missing. It either gives me -.75 or .75 as missing however instead of any value from the list of outputs.
var Rando : float;
function Start () {
Amount = Random.Range(8,9);
while (Amount > 0) { //CREATING THE BLOCKS
Rando = (-27.0f + (Random.Range(0,9) * 6.0f)) / 4.0f;
while (AmountArray.Contains(Rando)) {
Rando = (-27.0f + (Random.Range(0,9) * 6.0f)) / 4.0f;
}
AmountArray.Add (Rando);
Amount--;
}
AmountArray.Clear();
}

Object reference not set to an instance of an object - but it is?

I am creating a Sudoku Puzzle in asp and I'm having trouble with some classes. When I create a function to display all the numbers in the text box, I get this error: Object reference not set to an instance of an object. I know that it means that my object is null, but here is my code. The line that I am getting the error on is the line that says: stbNumber.setNumber(currentSolution[3 * i + m, 3 * k + n]);
private SudokuTextBox stb;
private Puzzle puzzle;
private Box box;
private Number stbNumber;
public void displayAll(object sender,EventArgs e)
{
puzzle = new Puzzle();
for (int i = 0; i < 3; i++)
{
for (int k = 0; k < 3; k++)
{
box = new Box();
for (int m = 0; m < 3; m++)
{
for (int n = 0; n < 3; n++)
{
stbNumber = new Number();
stb = new SudokuTextBox();
stbNumber.setNumber(currentSolution[3 * i + m, 3 * k + n]);
stb.setTextBoxValue(stbNumber);
stb.setVisibility(true);
box.setItem(stb, m, n);
}// end forth for
}//end third for
puzzle.setItem(box, i, k);
}//end second for
}//end first for
generateBoxes();
}
I have initialized stbNumber at the very top of my code, and I have made sure that currentSolution is not null or empty. I'm therefore unsure as to what I am doing wrong. I also should mention that I have this exact code elsewhere to generate new puzzles and it works just fine, but this section of code specifically gets called when I click a button.
you essentially have 3 possibilities:
stbNumber.setNumber(currentSolution[3 * i + m, 3 * k + n]);
stbNumber could be null
currentSolution could be null
the element you are trying to index could be null--just because currentSolution is not null does not mean the item is at that index is not null--so new one up or take appropriate action
since you new up an instance of stbNumber, it is unlikely to be the culprit (but it could be)
you say you are checking currentSolution is null, I don't see the code for that and from the code you did post it is most likely the culprit here. what you COULD do is add a check for null before you access it, and if your test fails writing an error message somewhere:
stbNumber = new Number();
stb = new SudokuTextBox();
if ( currentSolution != null )
{
// if the item does not exist, new it up
if ( currentSolution[3 * i + m, 3 * k + n] == null ) currentSolution[3 * i + m, 3 * k + n] = new someObject()
stbNumber.setNumber(currentSolution[3 * i + m, 3 * k + n]);
stb.setTextBoxValue(stbNumber);
}
else
{
WriteSomeErrorMessage("currentSolution is null");
}

Quadratic Bézier Curve: Calculate Points

I'd like to calculate a point on a quadratic curve. To use it with the canvas element of HTML5.
When I use the quadraticCurveTo() function in JavaScript, I have a source point, a target point and a control point.
How can I calculate a point on the created quadratic curve at let's say t=0.5 with "only" knowing this three points?
Use the quadratic Bézier formula, found, for instance, on the Wikipedia page for Bézier Curves:
In pseudo-code, that's
t = 0.5; // given example value
x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x;
y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y;
p[0] is the start point, p[1] is the control point, and p[2] is the end point. t is the parameter, which goes from 0 to 1.
In case somebody needs the cubic form:
//B(t) = (1-t)**3 p0 + 3(1 - t)**2 t P1 + 3(1-t)t**2 P2 + t**3 P3
x = (1-t)*(1-t)*(1-t)*p0x + 3*(1-t)*(1-t)*t*p1x + 3*(1-t)*t*t*p2x + t*t*t*p3x;
y = (1-t)*(1-t)*(1-t)*p0y + 3*(1-t)*(1-t)*t*p1y + 3*(1-t)*t*t*p2y + t*t*t*p3y;
I created this demo :
// x = a * (1-t)³ + b * 3 * (1-t)²t + c * 3 * (1-t)t² + d * t³
//------------------------------------------------------------
// x = a - 3at + 3at² - at³
// + 3bt - 6bt² + 3bt³
// + 3ct² - 3ct³
// + dt³
//--------------------------------
// x = - at³ + 3bt³ - 3ct³ + dt³
// + 3at² - 6bt² + 3ct²
// - 3at + 3bt
// + a
//--------------------------------
// 0 = t³ (-a+3b-3c+d) + => A
// t² (3a-6b+3c) + => B
// t (-3a+3b) + => c
// a - x => D
//--------------------------------
var A = d - 3*c + 3*b - a,
B = 3*c - 6*b + 3*a,
C = 3*b - 3*a,
D = a-x;
// So we need to solve At³ + Bt² + Ct + D = 0
Full example here
may help someone.
I edited talkhabis answer (cubic curve) so the curve is displayed with the right coordinates. (Couldn't comment)
The Y-coordinates needed to be changed (-p[].y+150). (A new variable for that might be a nicer and more efficient solution, but you get the idea)
// Apply points to SVG and create the curve and controllers :
var path = document.getElementById('path'),
ctrl1 = document.getElementById('ctrl1'),
ctrl2 = document.getElementById('ctrl2'),
D = 'M ' + p0.x + ' ' + (-p0.y+150) +
'C ' + c0.x + ' ' + (-c0.y+150) +', ' + c1.x + ' ' + (-c1.y+150) + ', ' + p1.x + ' ' + (-p1.y+150);
path.setAttribute('d',D);
ctrl1.setAttribute('d','M'+p0.x+','+(-p0.y+150)+'L'+c0.x+','+(-c0.y+150));
ctrl2.setAttribute('d','M'+p1.x+','+(-p1.y+150)+'L'+c1.x+','+(-c1.y+150));
// Lets test the "Bezier Function"
var t = 0, point = document.getElementById('point');
setInterval(function(){
var p = Bezier(p0,c0,c1,p1,t);
point.setAttribute('cx',p.x);
point.setAttribute('cy',-p.y+150);
t += 0.01;
if(t>=1) t=0;
},50);
// OK ... Now tring to get "y" on cruve based on mouse "x" :
var svg = document.getElementById('svg'),
point2 = document.getElementById('point2');
svg.onmousemove = function(e){
var x = (e.pageX - 50)/2,
y = (e.pageY - 50)/2;
// "-50" because of "50px margin" on the left side
// and "/2" because the svg width is 300 units and 600 px => 300 = 600/2
// Get the x,y by mouse x
var p = YBX(p0,c0,c1,p1,x);
point2.setAttribute('cx',p.x);
point2.setAttribute('cy',-p.y+150);
}
http://jsfiddle.net/u214gco8/1/
I also created some C-Code to test the results for the cubic curve. Just enter the X and Y coordinates in the main function.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void bezierCurve(int x[] , int y[])
{
double xu = 0.0 , yu = 0.0 , u = 0.0 ;
int i = 0 ;
for(u = 0.0 ; u <= 1.0 ; u += 0.05)
{
xu = pow(1-u,3)*x[0]+3*u*pow(1-u,2)*x[1]+3*pow(u,2)*(1-u)*x[2]
+pow(u,3)*x[3];
yu = pow(1-u,3)*y[0]+3*u*pow(1-u,2)*y[1]+3*pow(u,2)*(1-u)*y[2]
+pow(u,3)*y[3];
printf("X: %i Y: %i \n" , (int)xu , (int)yu) ;
}
}
int main(void) {
int x[] = {0,75,50,300};
int y[] = {0,2,140,100};
bezierCurve(x,y);
return 0;
}
https://ideone.com/glLXcB
Just a note: If you are using the usual formulas presented here then don't expect t = 0.5 to return the point at half of the curve's length.. In most cases it won't.
More on this here under "§23 — Tracing a curve at fixed distance intervals" and here.

Resources