Random Image and get winner (Processing) - processing

Hi I'm building a slot machine game and am having a few problems I'm pretty new with processing.
I've made this code and need the "wheels" to be random but they all have the same image (vertically)
I realise you won't be able to see the images so here's some links if you want them.
http://tinypic.com/r/i1jq7t/6 (diamond1)
http://tinypic.com/r/29fe5cg/6 (cherry1)
http://tinypic.com/r/sen1jo/6 (bell1)
int numFrames = 3; // The number of frames in the animation
int frame = 0;
int spincount = 0;
int state = 0;
PImage[] images1 = new PImage[3];
PImage[] images2 = new PImage[3];
PImage[] images3 = new PImage[3];
void setup() {
size(1080, 720);
frameRate(12);
// wheel 1
images1[0] = loadImage("bell1.png");
images1[1] = loadImage("cherry1.png");
images1[2] = loadImage("diamond1.png");
// wheel 3
images3[0] = loadImage("cherry1.png");
images3[1] = loadImage("bell1.png");
images3[2] = loadImage("diamond1.png");
// wheel 2
images2[0] = loadImage("diamond1.png");
images2[1] = loadImage("bell1.png");
images2[2] = loadImage("cherry1.png");
}
void draw() {
background(o);
//test state to see if I should be spinning
if(state == 1) {
spin();
}
}
//if a key is pressed then set the wheel to spin
void keyReleased() {
state = 1;
}
void spin() {
//spin for 5 times the break out
if (frame == 3) {
frame = 0;
spincount ++;
if (spincount == 10) {
state = 0;
spincount = 0;
//check if its a win and do stuff
winner();
}
}
// wheel 1
image(images1[frame], 20, 0);
image(images1[frame], 20, 170); //this is the image to test
image(images1[frame], 20, 340);
// wheel 2
image(images3[frame], 200, 0);
image(images3[frame], 200, 170); //this is the image to test
image(images3[frame], 200, 340);
// wheel 3
image(images2[frame], 400, 0);
image(images2[frame], 400, 170); //this is the image to test
image(images2[frame], 400, 340);
frame ++;
}
void winner() {
//are the names of the images the same
//if ((images3[frame].get(0,0)) == (images2[frame].get(0,0)) == (images1[frame].get(0,0))) {
// display a question from you list of questions by generating a random number and selecting the text
// wait for an answer
for (int i = 0; i < 400; i = i+1) {
if (keyPressed == true) {
// whats the key is it correct
}
if (i > 400) {
//display times up
}
}
}
// }
I'm also having issues with getting the "winner" (if the horizontal images's pixel in the left hand corner match go onto "winner".
I'd really appreciate any help anyone can offer.

There are a few problems with your code.
In the draw function, you are probably wanting to draw a black background, but you currently have the letter "o" instead of the number 0 (zero).
You probably want to draw the current wheel state to the screen in your draw function, right now you just have a black window unless you are spinning.
You can't compare colors directly.
Here is some modified code to get it working:
int numFrames = 3; // The number of frames in the animation
int maxSpin = 10;
int frame = 0;
int spincount = 0;
boolean spinning = false;
boolean checkWinner = false;
PImage[] images1 = new PImage[3];
PImage[] images2 = new PImage[3];
PImage[] images3 = new PImage[3];
void setup() {
size(1080, 720);
frameRate(12);
// wheel 1
images1[0] = loadImage("bell1.png");
images1[1] = loadImage("cherry1.png");
images1[2] = loadImage("diamond1.png");
// wheel 3
images3[0] = loadImage("cherry1.png");
images3[1] = loadImage("bell1.png");
images3[2] = loadImage("diamond1.png");
// wheel 2
images2[0] = loadImage("diamond1.png");
images2[1] = loadImage("bell1.png");
images2[2] = loadImage("cherry1.png");
}
void draw() {
background(0);
//test state to see if I should be spinning
// wheel 1
image(images1[frame], 20, 0);
image(images1[frame], 20, 170); //this is the image to test
image(images1[frame], 20, 340);
// wheel 2
image(images3[frame], 200, 0);
image(images3[frame], 200, 170); //this is the image to test
image(images3[frame], 200, 340);
// wheel 3
image(images2[frame], 400, 0);
image(images2[frame], 400, 170); //this is the image to test
image(images2[frame], 400, 340);
if (spinning) {
spin();
}
//this draws circles stroked in the color of the pixel at their center
//this is just to show how the code works, you can remove this
noFill(); // make the circles transparent
loadPixels(); // required before using pixels[]
color wheel1 = pixels[170*width+20];
color wheel2 = pixels[170*width+200];
color wheel3 = pixels[170*width+400];
stroke(wheel1);
ellipse(20, 170, 10, 10);
stroke(wheel2);
ellipse(200, 170, 10, 10);
stroke(wheel3);
ellipse(400, 170, 10, 10);
}
//if a key is pressed then set the wheel to spin
void keyReleased() {
if(!spinning) spinning = !spinning;
}
void spin() {
//spin for maxSpin times then break out
if (frame == numFrames-1) {
spincount ++;
if (spincount == maxSpin) {
spinning = !spinning;
spincount = 0;
//check if its a win and do stuff
winner();
}
else frame = 0;
}
else frame++;
}
void winner() {
loadPixels();
color wheel1 = pixels[171*width+21];
color wheel2 = pixels[171*width+201];
color wheel3 = pixels[171*width+401];
if(hue(wheel1) == hue(wheel2) && hue(wheel2) == hue(wheel3)) println("winner");
else println("not a winner");
}
This inclues your desired method of checking the corner colors on the images, but I would recommend just keeping track of which image is currently being displayed in the center.
I hope this at least gets you moving in the right direction.

Related

Why does my code only check for an if statement once and then stop?

I am currently working on a game in Processing and I have split it up into 3 parts so far. The start screen, the level selection screen, and the game screen. The start screen seems to be working fine but when the user gets to the level selection screen it only checks for an if statement once and then stops. Here is the relevant code:
int level = 0;
Player myPlayer;
Floor[] level1Floors = new Floor[5];
Selector levelSelector1;
Selector levelSelector2;
Selector levelSelector3;
Selector levelSelector4;
Selector levelSelector5;
Selector levelSelector6;
Selector levelSelector7;
Selector levelSelector8;
Selector levelSelector9;
Selector levelSelector10;
void setup () {
size(800, 600);
myPlayer = new Player(width/2, 500, 50, 50, 15, 0, 9, true, false, false, false, false);
level1Floors[0] = new Floor(0, 525, width);
level1Floors[1] = new Floor(width, 485, width/2);
startButton = loadImage("playButton.png");
startButtonHover = loadImage("playButtonHover.png");
star = loadImage("Star.png");
starUnlit = loadImage("StarUnlit.png");
levelSelector1 = new Selector(1, 110, 210);
levelSelector2 = new Selector(2, 255, 210);
levelSelector3 = new Selector(3, 400, 210);
levelSelector4 = new Selector(4, 545, 210);
levelSelector5 = new Selector(5, 690, 210);
levelSelector6 = new Selector(6, 110, 390);
levelSelector7 = new Selector(7, 255, 390);
levelSelector8 = new Selector(8, 400, 390);
levelSelector9 = new Selector(9, 545, 390);
levelSelector10 = new Selector(10, 690, 390);
}
void draw () {
if (gamestate == 0) {
startScreen();
}
if (gamestate == 1) {
println("eh");
levelSelection();
levelSelector1.displaySelector();
levelSelector2.displaySelector();
levelSelector3.displaySelector();
levelSelector4.displaySelector();
levelSelector5.displaySelector();
levelSelector6.displaySelector();
levelSelector7.displaySelector();
levelSelector8.displaySelector();
levelSelector9.displaySelector();
levelSelector10.displaySelector();
}
if (gamestate == 2) {
if (level == 1) {
background(54);
level1();
}
}
}
void collision () {
int trueY = myPlayer.y + myPlayer.yOffset;
if (trueY > level1Floors[0].y) {
myPlayer.y = level1Floors[0].y - myPlayer.yOffset;
myPlayer.yvel = 0;
myPlayer.flag = false;
}else {
myPlayer.yvel++;
}
}
void keyPressed () {
if (key == ' ' && !myPlayer.flag && gamestate == 2) {
myPlayer.isJump = true;
}
if (key == 'a' && myPlayer.left == false && gamestate == 2) {
myPlayer.left = true;
}
if (key == 'd' && myPlayer.right == false && gamestate == 2) {
myPlayer.right = true;
}
if (key == 'g') {
exit();
}
}
void keyReleased () {
if (key == ' ') {
myPlayer.isJump = false;
}
if (key == 'a') {
myPlayer.left = false;
}
if (key == 'd') {
myPlayer.right = false;
}
}
class Floor {
int x1;
int y;
int x2;
Floor (int tempX1, int tempY, int tempX2) {
x1 = tempX1;
y = tempY;
x2 = tempX2;
}
void display () {
strokeWeight(3);
line(x1, y, x2, y);
}
}
------------- this code is in a different tab ----------------
PImage star;
PImage starUnlit;
int starSize = 75;
void levelSelection () {
background(130);
}
class Selector {
int value;
int x;
int y;
int sizeX;
int sizeY;
int radius;
int fillValue;
int strokeValue;
Selector(int tempVal, int tempX, int tempY) {
value = tempVal;
x = tempX;
y = tempY;
sizeX = 120;
sizeY = 120;
radius = 20;
fillValue = 70;
strokeValue = 55;
}
void displaySelector () {
fill(fillValue);
stroke(strokeValue);
strokeWeight(6);
rectMode(CENTER);
rect(x, y, sizeX, sizeY, radius);
fill(255);
textSize(40);
textAlign(CENTER,CENTER);
text(value, x, (y-20));
imageMode(CENTER);
image(starUnlit, (x - 30), (y + 20), starSize, starSize);
image(starUnlit, x, (y + 30), starSize, starSize);
image(starUnlit, (x + 30), (y + 20), starSize, starSize);
if (mouseX > (x - 60) && mouseX < (x + 60) && mouseY > (y - 60) && mouseY < (y + 60)) {
println("wow ur computer is a potato");
sizeX = 130;
sizeY = 130;
fillValue = 90;
strokeValue = 75;
}else {
println("u succ");
sizeX = 120;
sizeY = 120;
fillValue = 70;
strokeValue = 55;
}
if (mouseX > (x - 60) && mouseX < (x + 60) && mouseY > (y - 60) && mouseY < (y + 60) && mousePressed) {
gamestate = 2;
level = value;
}
}
}
------------ this is also in a different tab idk if it is relevant though ---------------
PImage startButton;
PImage startButtonHover;
int startButtonx = 400;
int startButtony = 350;
void startScreen () {
background(130);
imageMode(CENTER);
image(startButton, startButtonx, startButtony, 100, 100);
textAlign(CENTER,CENTER);
textSize(60);
text("OBJECTIVE: BREAK OUT", width/2, height/6);
if (dist(mouseX, mouseY, startButtonx, startButtony) < 43) {
imageMode(CENTER);
image(startButtonHover, startButtonx, startButtony, 110, 110);
}
if (dist(mouseX, mouseY, startButtonx, startButtony) < 43 && mousePressed) {
gamestate = 1;
}
}
void level1 () {
background(54);
myPlayer.display();
level1Floors[0].display();
level1Floors[1].display();
collision();
myPlayer.jump();
}
class Player {
int x;
int y;
int vSide;
int hSide;
int yOffset;
int speed;
int yvel;
int xvel;
boolean isCollide;
boolean isJump;
boolean right;
boolean left;
boolean flag;
Player (int tempX, int tempY, int tempVSide, int tempHSide, int tempSpeed, int tempyvel, int tempxvel, boolean tempIsCollide, boolean tempIsJump, boolean tempRight, boolean tempLeft, boolean tempFlag) {
x = tempX;
y = tempY;
vSide = tempVSide;
hSide = tempHSide;
speed = tempSpeed;
yvel = tempyvel;
xvel = tempxvel;
isCollide = tempIsCollide;
isJump = tempIsJump;
right = tempRight;
left = tempLeft;
flag = tempFlag;
yOffset = 25;
}
void display() {
fill(0);
strokeWeight(2);
stroke(255);
rectMode(CENTER);
rect(x, y, hSide, vSide);
y += yvel;
}
void jump () {
if (isJump) {
y -= 20;
flag = true;
}
if (left && x >= 25) {
x -= xvel;
}
if (right && x <= (width - 25)) {
x += xvel;
}
}
}
I know the code is pretty disorganized and Im planning on fixing the problem later. The problem lies in the Selector class if I am correct as that is where the 2 if statements are that don't keep checking if the condition is met. Any help would be appreciated, thank you for your time.
Your problem was harder to diagnose than it looks. As you had guesses, there is a problem in the level selection screen. But the problem is also in the startScreen() method, and the symptom you can see, the "freeze", is a consequence of these things in relation with the level selection logic implemented.
It took me some time to see the problem because at first it missed a lot of functions, and even later I still didn't have the images, so I had to tweak the code to see stuff, which made me this half guesswork and half analysis.
You may wonder why I'm saying all these things. There's a good reason: I want you to be able to ask your next question in a manner which will help people to answer it. If you had asked a question about a specific functionality, it would have been easy enough, but this is debugging. To debug code without being to run it is much harder than it could. That's why I told you about posting a Minimal, Reproducible Example. If you need help with a bug, being able to reproduce it is a powerful tool for those who willing to help. That I have been the only one to answer may be linked to this deficiency.
The problem is mousePressed. If you read a little bit on it in the the Processing documentation, you'll see this: "The mousePressed variable stores whether or not a mouse button is currently being pressed".
This also means that the mousePressed will be true as long as a mouse button is down. The user can click on a random spot, keep the button down and drag the mouse toward a level selector and it will register in your code as if he had clicked on this level.
Here's what happens:
In the startScreen(), the user clicks on the image to start.
The gamestate goes into "level selection" faster than the eye can see, and waaay faster than the finger on the mouse can release the button.
The level selector which appears right where the mouse is registers this as a click.
The gamestate change to "2", but the level the user choose by mistake isn't available yet. The game seems to freeze because it's stuck there.
As you can see, you have to figure out a way to differentiate "holding a button down" and the user actually clicking on something. For now this is just a small glitch, but as you build on this program it'll become a problem increasingly frustrating.
There are many, many ways to deal with this. I'll give you code for one of them which I think is simple and efficient. Still, if you are ambitious enough, to create a class which only exists to manage the user inputs would be a cleaner and better structured way to do this.
But let's take the easy road for now (step by step for clarity):
Add this global variable:
boolean leftMouseButtonClicked = false;
It will replace the problematic mousePressed later.
Add this method to your project:
void mouseClicked() {
if (mouseButton == LEFT) {
leftMouseButtonClicked = true;
}
}
This will turn on the boolean we added in point 1 when the user click then releases the LEFT mouse button. mouseClicked is a built in Processing function. You can read more about it here.
Change your draw() method for this one:
void draw () {
switch (gamestate) {
case 0:
startScreen();
break;
case 1:
levelSelection();
levelSelector1.displaySelector();
levelSelector2.displaySelector();
levelSelector3.displaySelector();
levelSelector4.displaySelector();
levelSelector5.displaySelector();
levelSelector6.displaySelector();
levelSelector7.displaySelector();
levelSelector8.displaySelector();
levelSelector9.displaySelector();
levelSelector10.displaySelector();
break;
case 2:
switch (level) {
case 1:
level1();
break;
default:
gamestate = 1;
}
}
leftMouseButtonClicked = false;
}
It's about the same thing, with a couple important changes:
3.1. I took the liberty of using a switch statement instead of the handful of if statements there was before. The switch is easy to read and the cases need to be mutually exclusives for this to work. You could have used the if - else if - else if... form instead, but I like the switch better for readability.
3.2. I added a default case to the level switch, so when you misclick on a level which doesn't exist yet instead of freezing it'll go back to the level selection gamestate.
3.3. I turn off the leftMouseButtonClicked boolean so it doesn't stay "on" all the time.
Change every place where you wrote mousePressed so you use leftMouseButtonClicked instead.
That's all there is to do to correct the situation. I tried not to optimize your code so it stays yours (except for those switch which I couldn't resist). Your code makes sense and is much better structured than a many others. Sure, it could be improved a lot, but that's the kind of stuff that you'll learn while getting better. And I'm confident that you'll be good.
I hope I made everything clear. Good coding and have fun!

PHASER ALTARA Struggling with motion paths, enemy ai and animations

Basically I want to make my sprite follow a motion path and depending on its direction it is going, it will play a particular animation. i.e. moving up will display its back, moving left will display the left side of the sprite and so on.
I've tried for hours but to no avail in trying to make this work. I had some luck using prototype but the final game will be using the structure below. ANY help will be appreciated.
/*
* initalise Phaser framework with width:960px, height:540px
*/
var game = new Phaser.Game(960, 540, Phaser.AUTO, 'gameContainer', { preload: preload, create: create, update: update, });
/*
* Preload runs before the game starts. Assets such as images and sounds such be preloaded here.
* A webserver is required to load assets.
*
* Also in this function we set game scale so it full browser width.
*/
function preload() {
// set to scale to full browser width
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.parentIsWindow = true;
//set the background color so can confirm the game renders in the browser
this.stage.backgroundColor = '#4488cc';
this.game.renderer.renderSession.roundPixels = true;
//preload images & sounds
//game.load.image('key', 'folder/filename.png');
//this.load.image('nazi', 'image/nazi.png');
game.load.spritesheet('nazi', 'images/nazi.png', 128, 128, 6);
this.bmd = null;
this.alien = null;
this.mode = 0;
//Use this website to set enemy movements http://phaser.io/waveforms. Export save data from the console log.
this.points = {
"type":0,"closed":true,"x":[120,120,260,260,200,180,120],"y":[368,108,108,308,308,368,368]
};
this.pi = 0;
this.path = [];
}
/*
* Add game variables here
*/
var nazi;
/*
* Create runs once only when Phaser first loads
* create the game scene by adding objects to the stage
*/
function create() {
bmd = this.add.bitmapData(this.game.width, this.game.height);
bmd.addToWorld();
/*
For testing
this.alien = this.add.sprite(0, 0, 'alien');
this.alien.anchor.set(0.5);
*/
this.nazi = this.add.sprite(0, 0, 'nazi');
this.nazi.anchor.set(0.5);
var py = this.points.y;
/*Original Code
//define the animation
nazi.animations.add('walk');
//start the animation at 30fps
nazi.animations.play('walk', 3, true);
*/
//define the animation
this.nazi.animations.add('walkDown', [2, 3]);
//start the animation at 30fps
this.nazi.animations.play('walkDown', 3, true);
//define the animation
this.nazi.animations.add('walkLR', [4, 5]);
//start the animation at 30fps
this.nazi.animations.play('walkLR', 3, true);
//define the animation
this.nazi.animations.add('walkUp', [0, 1]);
//start the animation at 30fps
this.nazi.animations.play('walkUp', 3, true);
}
function plot() {
this.bmd.clear();
this.path = [];
/*ROTATION CODE*/
var ix = 0;
/**/
//Sets the speed of the sprite
var x = 0.5 / game.width;
//looping through plotting points from x and y array
for (var i = 0; i <= 1; i += x) {
var px = this.math.linearInterpolation(this.points.x, i);
var py = this.math.linearInterpolation(this.points.y, i);
/* ROTATION CODE to follow direction of path*/
var node = { x: px, y: py, angle: 0 };
if (ix > 0)
{
node.angle = this.math.angleBetweenPoints(this.path[ix - 1], node);
}
this.path.push(node);
ix++;
/**/
//this.path.push( { x: px, y: py });
this.bmd.rect(px, py, 1, 1, 'rgba(255, 255, 255, 1)');
}
for (var p = 0; p < this.points.x.length; p++) {
this.bmd.rect(this.points.x[p]-3, this.points.y[p]-3, 6, 6, 'rgba(255, 0, 0, 1)');
}
}
/*
* Update runs continuously. Its the game loop function.
* Add collision detections and control events here
*/
function update() {
plot();
// Reset the players velocity (movement)
//this.nazi = 'nazi';
/* For Testing
this.alien.x = this.path[this.pi].x;
this.alien.y = this.path[this.pi].y;
//ROTATION CODE:
this.alien.rotation = this.path[this.pi].angle;
*/
this.nazi.x = this.path[this.pi].x;
this.nazi.y = this.path[this.pi].y;
//this.nazi.rotation = this.path[this.pi].angle;
this.pi++;
if (this.pi >= this.path.length)
{
this.pi = 0;
}
/*
// Flipping the player image based on the velocity
if(nazi.body.velocity.x > 0){
//player is moving right
nazi.scale.x = -1;
nazi.animations.play('walkLR');
}
else if(nazi.body.velocity.x < 0){
//player is moving left
nazi.scale.x = 1; //flip the image
nazi.animations.play('walkLR');
}
else if (nazi.body.velocity.y < 0){
nazi.animations.play('walkUp');
}
else if(nazi.body.velocity.y > 0){
//player is not moving
nazi.animations.play('walkDown');
}
*/
}

How to run processing script on multiple frames in a folder

Using processing I am trying to run a script that will process a folder full of frames.
The script is a combination of PixelSortFrames and SortThroughSeamCarving.
I am new to processing and what I want does not seems to be working. I would like the script to run back through and choose the following file in the folder to be processed. At the moment it stops at the end and does not return to start on next file (there are three other modules also involved).
Any help would be much appreciated. :(
/* ASDFPixelSort for video frames v1.0
Original ASDFPixelSort by Kim Asendorf <http://kimasendorf.com>
https://github.com/kimasendorf/ASDFPixelSort
Fork by dx <http://dequis.org> and chinatsu <http://360nosco.pe>
// Main configuration
String basedir = ".../Images/Seq_002"; // Specify the directory in which the frames are located. Use forward slashes.
String fileext = ".jpg"; // Change to the format your images are in.
int resumeprocess = 0; // If you wish to resume a previously stopped process, change this value.
boolean reverseIt = true;
boolean saveIt = true;
int mode = 2; // MODE: 0 = black, 1 = bright, 2 = white
int blackValue = -10000000;
int brightnessValue = -1;
int whiteValue = -6000000;
// -------
PImage img, original;
float[][] sums;
int bottomIndex = 0;
String[] filenames;
int row = 0;
int column = 0;
int i = 0;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
if (resumeprocess > 0) {i = resumeprocess - 1;frameCount = i;}
size(1504, 1000); // Resolution of the frames. It's likely there's a better way of doing this..
filenames = folder.list(extfilter);
size(1504, 1000);
println(" " + width + " x " + height + " px");
println("Creating buffer images...");
PImage hImg = createImage(1504, 1000, RGB);
PImage vImg = createImage(1504, 1000, RGB);
// draw image and convert to grayscale
if (i +1 > filenames.length) {println("Uh.. Done!"); System.exit(0);}
img = loadImage(basedir+"/"+filenames[i]);
original = loadImage(basedir+"/"+filenames[i]);
image(img, 0, 0);
filter(GRAY);
img.loadPixels(); // updatePixels is in the 'runKernals'
// run kernels to create "energy map"
println("Running kernals on image...");
runKernels(hImg, vImg);
image(img, 0, 0);
// sum pathways through the image
println("Getting sums through image...");
sums = getSumsThroughImage();
image(img, 0, 0);
loadPixels();
// get start point (smallest value) - this is used to find the
// best seam (starting at the lowest energy)
bottomIndex = width/2;
// bottomIndex = findStartPoint(sums, 50);
println("Bottom index: " + bottomIndex);
// find the pathway with the lowest information
int[] path = new int[height];
path = findPath(bottomIndex, sums, path);
for (int bi=0; bi<width; bi++) {
// get the pixels of the path from the original image
original.loadPixels();
color[] c = new color[path.length]; // create array of the seam's color values
for (int i=0; i<c.length; i++) {
try {
c[i] = original.pixels[i*width + path[i] + bi]; // set color array to values from original image
}
catch (Exception e) {
// when we run out of pixels, just ignore
}
}
println(" " + bi);
c = sort(c); // sort (use better algorithm later)
if (reverseIt) {
c = reverse(c);
}
for (int i=0; i<c.length; i++) {
try {
original.pixels[i*width + path[i] + bi] = c[i]; // reverse! set the pixels of the original from sorted array
}
catch (Exception e) {
// when we run out of pixels, just ignore
}
}
original.updatePixels();
}
// when done, update pixels to display
updatePixels();
// display the result!
image(original, 0, 0);
if (saveIt) {
println("Saving file...");
//filenames = stripFileExtension(filenames);
save("results/SeamSort_" + filenames + ".tiff");
}
println("DONE!");
}
// strip file extension for saving and renaming
String stripFileExtension(String s) {
s = s.substring(s.lastIndexOf('/')+1, s.length());
s = s.substring(s.lastIndexOf('\\')+1, s.length());
s = s.substring(0, s.lastIndexOf('.'));
return s;
}
This code works by processing all images in the selected folder
String basedir = "D:/things/pixelsortframes"; // Specify the directory in which the frames are located. Use forward slashes.
String fileext = ".png"; // Change to the format your images are in.
int resumeprocess = 0; // If you wish to resume a previously stopped process, change this value.
int mode = 1; // MODE: 0 = black, 1 = bright, 2 = white
int blackValue = -10000000;
int brightnessValue = -1;
int whiteValue = -6000000;
PImage img;
String[] filenames;
int row = 0;
int column = 0;
int i = 0;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
if (resumeprocess > 0) {i = resumeprocess - 1;frameCount = i;}
size(1920, 1080); // Resolution of the frames. It's likely there's a better way of doing this..
filenames = folder.list(extfilter);
}
void draw() {
if (i +1 > filenames.length) {println("Uh.. Done!"); System.exit(0);}
row = 0;
column = 0;
img = loadImage(basedir+"/"+filenames[i]);
image(img,0,0);
while(column < width-1) {
img.loadPixels();
sortColumn();
column++;
img.updatePixels();
}
while(row < height-1) {
img.loadPixels();
sortRow();
row++;
img.updatePixels();
}
image(img,0,0);
saveFrame(basedir+"/out/"+filenames[i]);
println("Frames processed: "+frameCount+"/"+filenames.length);
i++;
}
essentially I want to do the same thing only with a different image process but my code is not doing this to all with in the folder... just one file.
You seem to be confused about what the setup() function does. It runs once, and only once, at the beginning of your code's execution. You don't have any looping structure for processing the other files, so it's no wonder that it only processes the first one. Perhaps wrap the entire thing in a for loop? It looks like you kind of thought about this, judging by the global variable i, but you never increment it to go to the next image and you overwrite its value in several for loops later anyway.

Making falling objects come at random angles in AS3

I am making a missile defense type of game and am trying to get the missiles to fall at random angles. I also need the bullet image to turn at the angle I am shooting at. I am very unfamiliar with angles in AS3 so I need some help.
Code:
import spark.components.Image;
public var missiles:Array;
public var bullets:Array;
public var playerLife:Number;
public var targetX:Number;
public var targetY:Number;
public function init():void {
startGame();
}
public function onEnterFrame(e:Event):void {
if(Math.random() <.05 ){
//make a new missle
var newMissile:Image = new Image();
//draw to is
newMissile.source = "assets/missileDown.jpg";
//position it
newMissile.x = Math.random() * stage.stageWidth;
//animate it
newMissile.addEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//add it to missle array
missiles.push(newMissile);
//add it to the screen
gameGroup.addElement(newMissile);
}
}
public function startGame():void {
//makes new arrays
//gets rid of old arrays
missiles = new Array();
bullets = new Array();
//set player life
playerLife = 5;
//show player life
playerHealth.text = String(playerLife);
//add animation and mouse interation
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.CLICK, fireWeapon);
//set game over alpha
gameEnd.alpha = 0;
reset.alpha = 0;
//set game start alpha
playerHealth.alpha = 1;
healthLabel.alpha = 1;
}
//updates the missle
public function onMissileEnterFrame(e:Event):void {
//reference to target
var targetMissile:Image = Image(e.currentTarget);
//move missle down
targetMissile.y += 10;
//if missle has gone too far, remove it and player loses life
if(targetMissile.y > stage.stageHeight) {
playerLife --;
removeMissile(targetMissile);
//show player life
playerHealth.text = String(playerLife);
}
//if player is dead, game over
if(playerLife <= 0) {
gameOver();
}
}
//update bullet
public function onBulletEnterFrame(e:Event):void {
//get reference to bullet
var thisBullet:Bullet = Bullet(e.currentTarget);
//animate towards point..
//calculate difference between current position and desired position
var diffX:Number = thisBullet.targX - thisBullet.x;
var diffY:Number = thisBullet.targY - thisBullet.y;
//move 10% of difference closer
thisBullet.x += diffX * .1;
thisBullet.y += diffY * .1;
//chekc for overlap between bullet and missles
for(var i:Number = 0; i < missiles.length; i++) {
//if they do overlap, remove missle
if( thisBullet.hitTestObject(missiles[i]) ) {
removeMissile(missiles[i]);
removeBullet(thisBullet);
break;
}
}
//if we're 'close enough' to the target position, remove bullet
if(Math.abs(diffX) < 10 && Math.abs(diffY) < 10) {
removeBullet(thisBullet);
}
}
//gets rid of a missle
public function removeMissile(targetMissile:Image):void {
//removes the missle from the missiles array
for(var i:Number = missiles.length - 1; i >= 0; i--) {
if(missiles[i] == targetMissile) {
missiles.splice(i,1);
break;
}
}
//don't animate anymore
targetMissile.removeEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//remove from stage
gameGroup.removeElement(targetMissile);
}
//removes bullet from stage
public function removeBullet(targetBullet:Bullet):void {
//stop animation
targetBullet.removeEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//remove from stage
gameGroup.removeElement(targetBullet);
}
//shoot a bullet at the mouse position
public function fireWeapon(e:MouseEvent):void {
//make a new bullet
var newBullet:Bullet = new Bullet();
newBullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//position near the earth in the center
var halfStage:Number = stage.stageWidth / 2;
newBullet.x = halfStage;
newBullet.y = 500;
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
//add it to the stage
gameGroup.addElement(newBullet);
}
//you lose
public function gameOver():void {
//remove missles
for(var i:Number = 0; i < missiles.length; i++) {
removeMissile(missiles[i]);
}
//stop interaction
stage.removeEventListener(MouseEvent.CLICK, fireWeapon);
//stop animation
this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
//set game start alpha
playerHealth.alpha = 0;
healthLabel.alpha = 0;
//set game end alpha
gameEnd.alpha = 1;
reset.alpha = 1;
}
]]>
</fx:Script>
onEnterFrame
...
//position it
newMissile.x = Math.random() * stage.stageWidth;
//rotate it
newMissile.rotation = - (Math.random() * 60 - 30);
onMissileEnterFrame
...
//move missle down
//targetMissile.y += 10;
targetMissile.x -= 10 * Math.sin(targetMissile.rotation * Math.PI/180);
targetMissile.y += 10 * Math.cos(targetMissile.rotation * Math.PI/180);
fireWeapon
...
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
newBullet.rotation = - Math.atan((newBullet.x - newBullet.targX) / (newBullet.y - newBullet.targY)) * 180/Math.PI;

Slicing up a Rectangle

I need to get AS3 Rectangle objects from a function receiving other Rectangles as parameters. The result is very similar to the slice tool in Photoshop. It is quite hard to explain, so here is a picture:
(source: free.fr)
The blue squares are the rectangles that are given as parameters and the green ones are the result. Given Rectangles can overlap, as seen on picture 2 or be out of frame.
I don't look for a graphical realisation but for a way to get Rectangle objects as result.
Do you know any lib to do that?
Looked like a fun problem, so I gave it a crack. My idea was to just brute force it by:
Determine which points where the corners of the generated rectangles could be.
Remove all duplicates from this list of points.
Check all rectangles that could theoretically be drawn where the rect would have all 4 corners in the list of point.
Filter out all invalid rectangles (it intersects with one of our original rectangles etc.)
Reduce all valid rectangles to the minimum amount needed (if a valid rectangle contains another valid rectangle the "child" is removed.
It seems to work (although I haven't tested extensively).
Here's a demo. Sorry about the color palette. I was winging it.
Here's the source code (could probably be optimized quite a bit):
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.getTimer;
public class Main extends Sprite {
private var m_colors : Array = [0xffaaaa, 0x77ff77, 0xaaaaff, 0xffff44, 0xff44ff, 0xaaffff, 0x444444, 0xffaa55, 0xaaff55, 0x55aaff, 0x55ffaa];
private var m_roomRect : Rectangle;
private var m_sourceRects : Vector.<Rectangle> = new Vector.<Rectangle>();
private var m_currentDragRect : Rectangle;
private var m_dragMousePoint : Point = new Point();
private var m_outputTextField : TextField;
public function Main() : void {
m_roomRect = new Rectangle(40, 40, 400, 400);
m_sourceRects.push(new Rectangle(60, 60, 60, 80));
m_sourceRects.push(new Rectangle(130, 220, 70, 80));
m_sourceRects.push(new Rectangle(160, 260, 100, 80));
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseEvent);
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseEvent);
this.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
var tf : TextField = new TextField();
tf.defaultTextFormat = new TextFormat("_sans", 12);
tf.text = "Click and drag blue rectangles to move them";
tf.autoSize = TextFieldAutoSize.LEFT;
tf.x = (m_roomRect.left + m_roomRect.right) / 2 - tf.width / 2;
tf.y = m_roomRect.top - tf.height;
this.stage.addChild(tf);
m_outputTextField = new TextField();
m_outputTextField.defaultTextFormat = tf.defaultTextFormat;
m_outputTextField.width = m_roomRect.width;
m_outputTextField.x = m_roomRect.x;
m_outputTextField.y = m_roomRect.bottom + 5;
this.stage.addChild(m_outputTextField);
redraw();
}
private function onMouseEvent(event : MouseEvent):void {
switch(event.type) {
case MouseEvent.MOUSE_DOWN:
checkMouseDownOnRect();
break;
case MouseEvent.MOUSE_MOVE:
checkMouseDrag();
break;
case MouseEvent.MOUSE_UP:
m_currentDragRect = null;
break;
}
}
private function checkMouseDownOnRect():void {
m_currentDragRect = null;
m_dragMousePoint = new Point(this.stage.mouseX, this.stage.mouseY);
for each(var sourceRect : Rectangle in m_sourceRects) {
if (sourceRect.containsPoint(m_dragMousePoint)) {
m_currentDragRect = sourceRect;
break;
}
}
}
private function checkMouseDrag():void {
if (m_currentDragRect != null) {
m_currentDragRect.x += this.stage.mouseX - m_dragMousePoint.x;
m_currentDragRect.y += this.stage.mouseY - m_dragMousePoint.y;
m_dragMousePoint.x = this.stage.mouseX;
m_dragMousePoint.y = this.stage.mouseY;
redraw();
}
}
private function redraw():void {
// calculate data
var time : int = getTimer();
var data : CalculationData = calculate();
var calcTime : int = getTimer() - time;
// draw room bounds
this.graphics.clear();
this.graphics.lineStyle(3, 0x0);
this.graphics.drawRect(m_roomRect.x, m_roomRect.y, m_roomRect.width, m_roomRect.height);
// draw generated rectangles
for (var i : int = 0; i < data.outputRects.length; i++) {
var color : int = m_colors[i % m_colors.length];
var rect : Rectangle = data.outputRects[i];
this.graphics.lineStyle(2, color, 0.5);
this.graphics.beginFill(color, 0.5);
this.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
this.graphics.endFill();
}
// draw horisontal lines (a line that crosses each red point) for debug purposes
for each (var lineY : int in data.lines) {
this.graphics.lineStyle(1, 0, 0.2);
this.graphics.moveTo(m_roomRect.x, lineY);
this.graphics.lineTo(m_roomRect.x + m_roomRect.width, lineY);
this.graphics.endFill();
}
// the original rectangles
for each (var sourceRect : Rectangle in m_sourceRects) {
this.graphics.lineStyle(2, 0x0);
this.graphics.beginFill(0x0000aa, 0.5);
this.graphics.drawRect(sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height);
this.graphics.endFill();
}
// draw all points that was used to generate the output rectangles for debug purposes
for each (var p : Point in data.points) {
this.graphics.lineStyle(0, 0, 0);
this.graphics.beginFill(0xff0000, 1);
this.graphics.drawCircle(p.x, p.y, 3);
this.graphics.endFill();
}
m_outputTextField.text = "Rect count: " + data.outputRects.length + " (calculation time: " + calcTime + "ms)";
}
private function calculate(): CalculationData {
// list of y coords for horisontal lines,
// which are interesting when determining which rectangles to generate
var lines : Vector.<int> = new Vector.<int>();
// list of all points which are interesting
// when determining where the corners of the generated rect could be
var points : Vector.<Point> = new Vector.<Point>();
// add the 4 corners of the room to interesting points
points.push(new Point(m_roomRect.left, m_roomRect.top));
points.push(new Point(m_roomRect.right, m_roomRect.top));
points.push(new Point(m_roomRect.left, m_roomRect.bottom));
points.push(new Point(m_roomRect.right, m_roomRect.bottom));
for (var i:int = 0; i < m_sourceRects.length; i++) {
var sourceRect : Rectangle = m_sourceRects[i];
// source rect is completely outside of the room, we shoud ignore it
if (!m_roomRect.containsRect(sourceRect) && !m_roomRect.intersects(sourceRect)) {
continue;
}
// push the y coord of the rect's top edge to the list of lines if it's not already been added
if (lines.indexOf(sourceRect.y) == -1) {
lines.push(sourceRect.y);
}
// push the y coord of the rect's bottom edge to the list of lines if it's not already been added
if (lines.indexOf(sourceRect.bottom) == -1) {
lines.push(sourceRect.bottom);
}
// add the 4 corners of the source rect to the list of interesting points
addCornerPoints(points, sourceRect);
// find the intersections between source rectangles and add those points
for (var j:int = 0; j < m_sourceRects.length; j++) {
if (j != i) {
var intersect : Rectangle = m_sourceRects[i].intersection(m_sourceRects[j]);
if (intersect.width != 0 && intersect.height != 0) {
addCornerPoints(points, intersect);
}
}
}
}
for (i = 0; i < lines.length; i++) {
// add the points where the horisontal lines intersect with the room's left and right edges
points.push(new Point(m_roomRect.x, lines[i]));
points.push(new Point(m_roomRect.right, lines[i]));
var lineRect : Rectangle = new Rectangle(m_roomRect.x, m_roomRect.y,
m_roomRect.width, lines[i] - m_roomRect.y);
// add all points where the horisontal lines intersect with the source rectangles
for (a = 0; a < m_sourceRects.length;a++) {
intersect = m_sourceRects[a].intersection(lineRect);
if (intersect.width != 0 && intersect.height != 0) {
addCornerPoints(points, intersect);
}
}
}
// clamp all points that are outside of the room to the room edges
for (i = 0; i < points.length; i++) {
points[i].x = Math.min(Math.max(m_roomRect.left, points[i].x), m_roomRect.right);
points[i].y = Math.min(Math.max(m_roomRect.top, points[i].y), m_roomRect.bottom);
}
removeDuplicatePoints(points);
var outputRects : Vector.<Rectangle> = new Vector.<Rectangle>();
var pointsHash : Object = { };
for (a = 0; a < points.length; a++) {
pointsHash[points[a].x + "_" + points[a].y] = true;
}
for (var a:int = 0; a < points.length; a++) {
for (var b:int = 0; b < points.length; b++) {
if (b != a && points[b].x > points[a].x && points[b].y == points[a].y) {
for (var c:int = 0; c < points.length; c++) {
// generate a rectangle that has its four corners in our points of interest
if (c != b && c != a && points[c].y > points[b].y && points[c].x == points[b].x) {
var r : Rectangle = new Rectangle(points[a].x, points[a].y, points[b].x - points[a].x, points[c].y - points[b].y);
// make sure the rect has the bottom left corner in one of our points
if (pointsHash[r.left+"_"+r.bottom]) {
var containsOrIntersectsWithSource : Boolean = false;
for (i = 0; i < m_sourceRects.length;i++) {
if (r.containsRect(m_sourceRects[i]) || r.intersects(m_sourceRects[i])) {
containsOrIntersectsWithSource = true;
break;
}
}
// we don't add any rectangles that either intersects with a source rect
// or completely contains a source rect
if (!containsOrIntersectsWithSource) {
outputRects.push(r);
}
}
}
}
}
}
}
trace("outputRects before cleanup:", outputRects.length);
combineOutputRects(outputRects)
trace("outputRects after cleanup", outputRects.length);
var data : CalculationData = new CalculationData();
data.outputRects = outputRects;
data.lines = lines;
data.points = points;
return data;
}
private function addCornerPoints(points : Vector.<Point>, rect : Rectangle) : void {
points.push(new Point(rect.left, rect.top));
points.push(new Point(rect.right, rect.top));
points.push(new Point(rect.left, rect.bottom));
points.push(new Point(rect.right, rect.bottom));
}
// removes all rectangle that are already contained in another rectangle
private function combineOutputRects(outputRects : Vector.<Rectangle>):Boolean {
for (var a : int = 0; a < outputRects.length; a++) {
for (var b : int = 0; b < outputRects.length; b++) {
if (b != a) {
if (outputRects[a].containsRect(outputRects[b])) {
trace("\tremoved rect " + outputRects[b] + ", it was contained in " + outputRects[a]);
outputRects.splice(b, 1);
b--;
a = 0;
}
}
}
}
return false;
}
private function removeDuplicatePoints(points : Vector.<Point>) : void {
var usedPoints : Object = {};
for (var i : int = 0; i < points.length; i++) {
if (usedPoints[points[i].toString()]) {
points.splice(i, 1);
i--;
} else {
usedPoints[points[i].toString()] = true;
}
}
}
}
}
import flash.geom.Point;
import flash.geom.Rectangle;
class CalculationData {
public var outputRects : Vector.<Rectangle> = new Vector.<Rectangle>;
public var lines : Vector.<int> = new Vector.<int>;
public var points : Vector.<Point> = new Vector.<Point>;
}

Resources