Add multiple prefabs at runtime with random scale? - random

I want to add prefabs to my scene at random positions at runtime. However only one prefab is added to the screen and then I get the error Cannot cast from source type to destination type. This is what I'm trying now:
private void generateLevel() {
GameObject cube;
for (int i = 1; i < 9; i++) {
// Generate at random position in sphere
cube = (GameObject) Instantiate(prefabPlanet, Random.onUnitSphere, Quaternion.identity); // Error
// Random scale
cube.transform.localScale = new Vector3(1, 1, 1) * Random.Range(1f, 10f);
}
}
What could be the reason for this?

I found a solution which is to instantiate the GameObject without a variable, by modifying the prefab before the instantiation.
I'm not very happy with this solution though, since it might be useful to save the object in a variable.
for (int i = 1; i < 9; i++) {
// Random Scale
prefabPlanet.localScale = new Vector3(1, 1, 1) * Random.Range(1f, 10f);
// Random position
Vector3 position = Random.onUnitSphere * Constants.radius;
// Instatiate
Instantiate(prefabPlanet, position, Quaternion.identity);
}

This script works fine for me, I'm not sure what your doing wrong. Unless its erroring on the random scale part due to Constantes.maxScale having an illegitimate value. Ensure errors and warnings are turned on in your console and check it for errors on that line.

Related

Creating Grid in as3

I am trying to make to grid to squares using as3.
I am using nested for loops to create the grid.
import flash.display.Shape;
import flash.display.MovieClip;
var n=10;
var myClip = new MovieClip;
stage.addChild(myClip);
for (var i = 0; i < n * 10; i += 10) {
for (var j = 0; j < n * 10; j += 10) {
var _shape = new Shape;
myClip.addChild(_shape);
_shape.graphics.lineStyle(1);
_shape.graphics.beginFill(0xcccccc);
_shape.graphics.drawRect(i, j, 10, 10);
_shape.graphics.endFill();
}
}
I am applying Zooming and Panning Gestures on myClip. For this Grid size everything works fine. As soon as I increase the value of n, it starts lagging
My game requires a bigger grid. Please help
I'll show some ideas as code, my AS3 is a bit rusty but perhaps it helps.
You can reduce the number of Shape instances or draw the vector based grid graphic to a Bitmap. Since you are zooming and panning it you'll want to smooth it. Depending on performance and how much you zoom you also may want to draw the bitmap at a higher resolution than initially used. See comments in the below.
import flash.display.Shape;
import flash.display.MovieClip;
var n=10;
// do you actually need dynamic binding or a timeline in this?
// if not (also if you don't know what it means) do use the Sprite class instead
var myClip = new MovieClip;
stage.addChild(myClip);
// if you don't need individual shapes move this out of the for loop
// your logic with all of the shapes having the same origin suggests this might be so
var _shape = new Shape;
myClip.addChild(_shape);
for (var i = 0; i < n * 10; i += 10) {
for (var j = 0; j < n * 10; j += 10) {
_shape.graphics.lineStyle(1);
_shape.graphics.beginFill(0xcccccc);
_shape.graphics.drawRect(i, j, 10, 10);
_shape.graphics.endFill();
}
}
// then we can draw the grid to a bitmap
// since you are scaling it I'm drawing it a 300% resolution
var _bmd:BitmapData = new BitmapData(_shape.width*3, _shape.height*3, true, 0);
var _bit:Bitmap = new Bitmap(_bmd);
myClip.addChild(_bit);
_shape.width*=3;
_shape.height*=3;
_bmd.draw(stage);
_bit.smoothing = true;
_bit.width/=3;
_bit.height/=3;
// and remove the vector shape so it won't be rendered
myClip.removeChild(_shape);
// if need be it can be redrawn later

Drawing image(PGraphics) gives unwanted double image mirrored about x-axis. Processing 3

The code is supposed to fade and copy the window's image to a buffer f, then draw f back onto the window but translated, rotated, and scaled. I am trying to create an effect like a feedback loop when you point a camera plugged into a TV at the TV.
I have tried everything I can think of, logged every variable I could think of, and still it just seems like image(f,0,0) is doing something wrong or unexpected.
What am I missing?
Pic of double image mirror about x-axis:
PGraphics f;
int rect_size;
int midX;
int midY;
void setup(){
size(1000, 1000, P2D);
f = createGraphics(width, height, P2D);
midX = width/2;
midY = height/2;
rect_size = 300;
imageMode(CENTER);
rectMode(CENTER);
smooth();
background(0,0,0);
fill(0,0);
stroke(255,255);
}
void draw(){
fade_and_copy_pixels(f); //fades window pixels and then copies pixels to f
background(0,0,0);//without this the corners dont get repainted.
//transform display window (instead of f)
pushMatrix();
float scaling = 0.90; // x>1 makes image bigger
float rot = 5; //angle in degrees
translate(midX,midY); //makes it so rotations are always around the center
rotate(radians(rot));
scale(scaling);
imageMode(CENTER);
image(f,0,0); //weird double image must have something not working around here
popMatrix();//returns window matrix to normal
int x = mouseX;
int y = mouseY;
rectMode(CENTER);
rect(x,y,rect_size,rect_size);
}
//fades window pixels and then copies pixels to f
void fade_and_copy_pixels(PGraphics f){
loadPixels(); //load windows pixels. dont need because I am only reading pixels?
f.loadPixels(); //loads feedback loops pixels
// Loop through every pixel in window
//it is faster to grab data from pixels[] array, so dont use get and set, use this
for (int i = 0; i < pixels.length; i++) {
//////////////FADE PIXELS in window and COPY to f:///////////////
color p = pixels[i];
//get color values, mask then shift
int r = (p & 0x00FF0000) >> 16;
int g = (p & 0x0000FF00) >> 8;
int b = p & 0x000000FF; //no need for shifting
// reduce value for each color proportional
// between fade_amount between 0-1 for 0 being totallty transparent, and 1 totally none
// min is 0.0039 (when using floor function and 255 as molorModes for colors)
float fade_percent= 0.005; //0.05 = 5%
int r_new = floor(float(r) - (float(r) * fade_percent));
int g_new = floor(float(g) - (float(g) * fade_percent));
int b_new = floor(float(b) - (float(b) * fade_percent));
//maybe later rewrite in a way to save what the difference is and round it differently, like maybe faster at first and slow later,
//round doesn't work because it never first subtracts one to get the ball rolling
//floor has a minimum of always subtracting 1 from each value each time. cant just subtract 1 ever n loops
//keep a list of all the pixel as floats? too much memory?
//ill stick with floor for now
// the lowest percent that will make a difference with floor is 0.0039?... because thats slightly more than 1/255
//shift back and or together
p = 0xFF000000 | (r_new << 16) | (g_new << 8) | b_new; // or-ing all the new hex together back into AARRGGBB
f.pixels[i] = p;
////////pixels now copied
}
f.updatePixels();
}
This is a weird one. But let's start with a simpler MCVE that isolates the problem:
PGraphics f;
void setup() {
size(500, 500, P2D);
f = createGraphics(width, height, P2D);
}
void draw() {
background(0);
rect(mouseX, mouseY, 100, 100);
copyPixels(f);
image(f, 0, 0);
}
void copyPixels(PGraphics f) {
loadPixels();
f.loadPixels();
for (int i = 0; i < pixels.length; i++) {
color p = pixels[i];
f.pixels[i] = p;
}
f.updatePixels();
}
This code exhibits the same problem as your code, without any of the extra logic. I would expect this code to show a rectangle wherever the mouse is, but instead it shows a rectangle at a position reflected over the X axis. If the mouse is on the top of the window, the rectangle is at the bottom of the window, and vice-versa.
I think this is caused by the P2D renderer being OpenGL, which has an inversed Y axis (0 is at the bottom instead of the top). So it seems like when you copy the pixels over, it's going from screen space to OpenGL space... or something. That definitely seems buggy though.
For now, there are two things that seem to fix the problem. First, you could just use the default renderer instead of P2D. That seems to fix the problem.
Or you could get rid of the for loop inside the copyPixels() function and just do f.pixels = pixels; for now. That also seems to fix the problem, but again it feels pretty buggy.
If somebody else (paging George) doesn't come along with a better explanation by tomorrow, I'd file a bug on Processing's GitHub. (I can do that for you if you want.)
Edit: I've filed an issue here, so hopefully we'll hear back from a developer in the next few days.
Edit Two: Looks like a fix has been implemented and should be available in the next release of Processing. If you need it now, you can always build Processing from source.
An easier one, and works like a charm:
add f.beginDraw(); before and f.endDraw(); after using f:
loadPixels(); //load windows pixels. dont need because I am only reading pixels?
f.loadPixels(); //loads feedback loops pixels
// Loop through every pixel in window
//it is faster to grab data from pixels[] array, so dont use get and set, use this
f.beginDraw();
and
f.updatePixels();
f.endDraw();
Processing must know when it's drawing in a buffer and when not.
In this image you can see that works

Vector out of range

I am trying to draw a bounding box around contours using OpenCV. This is a real time application where all the images are grabbed from a camera real time, and Following is the important part of the code
RTMotionDetector.h
vector<vector<Point>> *contours;
vector<vector<Point>> *contoursPoly;
RTMotionDetector.cpp
RTMotionDetector::RTMotionDetector(void)
{
current = new Mat();
currentGrey = new Mat();
canny = new Mat();
next = new Mat();
absolute = new Mat();
cam1 = new VideoCapture();
cam2 = new VideoCapture();
contours = new vector<vector<Point>>();
contoursPoly = new vector<vector<Point>>();
boundRect = new vector<Rect>();
}
double RTMotionDetector::getMSE(Mat I1, Mat I2)
{
Mat s1;
//Find difference
cv::absdiff(I1, I2, s1); // |I1 - I2|
imshow("Difference",s1);
//Do canny to get edges
cv::Canny(s1,*canny,30,30,3);
imshow("Canny",*canny);
//Find contours
findContours(*canny,*contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
//System::Windows::Forms::MessageBox::Show(""+contours->size());
//Draw contours
drawContours(*current,*contours,-1,Scalar(0,0,255),2);
for(int i=0;i<contours->size();i++)
{
cv::approxPolyDP(Mat((*contours)[i]),(*contoursPoly)[i],3,true);
//boundRect[i] = boundingRect(contoursPoly[i]);
}
}
As soon as the following part gets executed, I am getting an error
cv::approxPolyDP(Mat((*contours)[i]),(*contoursPoly)[i],3,true);
Here is the error I am getting.
If I comment out that piece of code, then no issues. I know this is ArrayIndexOutOfBounds issue but I really can't find a fix. May be because I am new to Windows Programming.
It is very important that contours stay as a pointer instead of local variable, because local variable slowed the program in an unbelievable way.
You need to find which access to which vector has gone beyond its bounds.
You loop til the size of contours,
for(int i=0;i<contours->size();i++)
but then access (*contoursPoly)[i]
I would hazard a guess that the contoursPoly has gone beyond its bounds, which you can check by breaking into the debugger as suggested.
Changing the loop to
for(int i=0;i<contours->size() && i<contoursPoly->size();i++)
might solve the immediate problem.
Here
(*contoursPoly)[i]
you try to access something that doesn't exist.
What's more, the documentation says:
C++: void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
...
approxCurve - (...) The type should match the type of the input curve (...)
Here you have input - Mat and output - vector< Point >. Maybe that works too, IDK.

How do I get a random number to stay fixed with slick?

I'm a beginner in Java as well as with the slick tools. I want to make a game that has different coloured cubes randomly placed within a certain area of the window.
I use two for-loops and call for a random number in render. I get the cubes placed exactly as I want, but the problems is that they flicker in all colours. I guess it has to do with how I call for a random number and that it gets updated with FPS?!
Please help me!!
public void render(GameContainer gc, StateBasedGame sdg, Graphics g) throws SlickException {
//set background
Image background = (new Image("res/background.png")).getScaledCopy(800, 500);
g.drawImage(background, 0, 0);
//set gamescape
blue = (new Image("res/blue.png")).getScaledCopy(20,20);
green = (new Image("res/green.png")).getScaledCopy(20,20);
red = (new Image("res/red.png")).getScaledCopy(20,20);
int xvalue = 300;
int yvalue = 400;
for (int a = 1; a < 20; a++) {
for (int i = 1; i < 10; i++) {
r = rand.nextInt(3);
if(r==0){g.drawImage(blue,xvalue,yvalue);}
else if(r==1){g.drawImage(red, xvalue, yvalue);}
else{g.drawImage(green, xvalue, yvalue);}
xvalue = xvalue+20;
}
yvalue = yvalue - 20;
xvalue = xvalue -180;
}
}
Your problem is that you generate a new random number each time you redraw the scene.
To resolve this, you may have to create an array in which you store the generated color of each cube. And each time you redraw your images, you just read each color value in the array.

OpenCV cvblob - Render Blob

I'm trying to detect a object using cvblob. So I use cvRenderBlob() method. Program compiled successfully but when at the run time it is returning an unhandled exception. When I break it, the arrow is pointed out to CvLabel *labels = (CvLabel *)imgLabel->imageData + imgLabel_offset + (blob->miny * stepLbl); statement in the cvRenderBlob() method definition of the cvblob.cpp file. But if I use cvRenderBlobs() method it's working fine. I need to detect only one blob that is the largest one. Some one please help me to handle this exception.
Here is my VC++ code,
CvCapture* capture = 0;
IplImage* frame = 0;
int key = 0;
CvBlobs blobs;
CvBlob *blob;
capture = cvCaptureFromCAM(0);
if (!capture) {
printf("Could not initialize capturing....\n");
return 1;
}
int screenx = GetSystemMetrics(SM_CXSCREEN);
int screeny = GetSystemMetrics(SM_CYSCREEN);
while (key!='q') {
frame = cvQueryFrame(capture);
if (!frame) break;
IplImage* imgHSV = cvCreateImage(cvGetSize(frame), 8, 3);
cvCvtColor(frame, imgHSV, CV_BGR2HSV);
IplImage* imgThreshed = cvCreateImage(cvGetSize(frame), 8, 1);
cvInRangeS(imgHSV, cvScalar(61, 156, 205),cvScalar(161, 256, 305), imgThreshed); // for light blue color
IplImage* imgThresh = imgThreshed;
cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN, 9, 9);
cvNamedWindow("Thresh");
cvShowImage("Thresh", imgThresh);
IplImage* labelImg = cvCreateImage(cvGetSize(imgHSV), IPL_DEPTH_LABEL, 1);
unsigned int result = cvLabel(imgThresh, labelImg, blobs);
blob = blobs[cvGreaterBlob(blobs)];
cvRenderBlob(labelImg, blob, frame, frame);
/*cvRenderBlobs(labelImg, blobs, frame, frame);*/
/*cvFilterByArea(blobs, 60, 500);*/
cvFilterByLabel(blobs, cvGreaterBlob(blobs));
cvNamedWindow("Video");
cvShowImage("Video", frame);
key = cvWaitKey(1);
}
cvDestroyWindow("Thresh");
cvDestroyWindow("Video");
cvReleaseCapture(&capture);
First off, I'd like to point out that you are actually using the regular c syntax. C++ uses the class Mat. I've been working on some blob extraction based on green objects in the picture. Once thresholded properly, which means we have a "binary" image, background/foreground. I use
findContours() //this function expects quite a bit, read documentation
Descriped more clearly in the documentation on structural analysis. It will give you the contour of all the blobs in the image. In a vector which is handling another vector, which is handling points in the image; like so
vector<vector<Point>> contours;
I too need to find the biggest blob, and though my approach can be faulty to some extend, I won't need it to be different. I use
minAreaRect() // expects a set of points (contained by the vector or mat classes
Descriped also under structural analysis
Then access the size of the rect
int sizeOfObject = 0;
int idxBiggestObject = 0; //will track the biggest object
if(contours.size() != 0) //only runs code if there is any blobs / contours in the image
{
for (int i = 0; i < contours.size(); i++) // runs i times where i is the amount of "blobs" in the image.
{
myVector = minAreaRect(contours[i])
if(myVector.size.area > sizeOfObject)
{
sizeOfObject = myVector.size.area; //saves area to compare with further blobs
idxBiggestObject = i; //saves index, so you know which is biggest, alternatively, .push_back into another vector
}
}
}
So okay, we really only measure a rotated bounding box, but in most cases it will do. I hope that you will either switch to c++ syntax, or get some inspiration from the basic algorithm.
Enjoy.

Resources