I should be beyond this, but I can't get to the bottom of this error. I'm trying to write a sketch that records the feed of my Mac camera and stores each recording "session" into a PImage array, then adds that to a list of sessions (a PImage[] ArrayList). I'm using a 'Replay' class to access the images stored in memory to and replay them at a random position. The code below should be ready to be copied straight into the IDE.
Any help would be greatly appreciated. I have no idea why the replay objects are always displaying the live image. Thanks!
import processing.video.*;
Capture cam;
ArrayList<PImage[]> allImages;
ArrayList<PImage> currentImages;
ArrayList<Replay> replays;
boolean recording = false;
boolean finishedSaving = true;
int currentIndex = 0;
void setup() {
size(1056, 704, P2D);
frameRate(30);
allImages = new ArrayList<PImage[]>();
currentImages = new ArrayList<PImage>();
replays = new ArrayList<Replay>();
String[] cams = Capture.list();
if (cams.length == 0) {
println("No cams!");
exit();
} else {
cam = new Capture(this, 1056, 704, cams[0], 30);
cam.start();
}
}
void draw() {
background(0);
if (cam.available() == true) {
cam.read();
}
for (Replay r : replays) {
r.display();
}
if (recording) {
currentImages.add(cam);
noFill();
stroke(255, 0, 0);
strokeWeight(5);
rect(0, 0, cam.width/3, cam.height/3);
} else {
saveToArray();
}
image(cam, 0, 0, cam.width/3, cam.height/3);
}
void saveToArray() {
if (!finishedSaving) {
PImage[] tempImages = currentImages.toArray(new PImage[currentImages.size()]);
allImages.add(tempImages);
currentImages.clear();
println("Finished saving to allImages array");
println("allImages array size now = " + allImages.size());
replays.add(new Replay(currentIndex));
println("Added new Replay (index: " + currentIndex + ")");
currentIndex++;
finishedSaving = true;
println();
}
}
void keyPressed() {
if (key == 'r' || key == 'R') {
recording = !recording;
println("Recording: " + recording);
finishedSaving = false;
}
}
class Replay {
PVector position;
float w, h;
PImage[] images;
int count;
Replay(int allImagesIndex) {
w = cam.width/3;
h = cam.height/3;
position = new PVector(random(width-w), random(height-h));
count = 1;
images = allImages.get(allImagesIndex);
}
void display() {
image(images[count], position.x, position.y, w, h);
count++;
if (count > images.length-1) count = 1;
}
}
Looks like this was due to the camera feed always being assignment to each individual image. To get a "copy" of the "current" video stream frame, I just added .get() to the feed so it fetches the pixels and stores them in a PImage variable.
currentImages.add(cam.get());
Related
I'm trying to make a very simple game where the yellow ball bouncing back and fourth. If it collides with one of the moving blue squares, the square is supposed to disappear and a new one should appear (always 3 in the window) elsewhere. When my code reaches this part, all 3 squares disappear (then reappears as intended it is not a problem) and I just cant figure out why. It would be a huge help if somebody could run over my methods responsible for the problem. Thank you in advance.
So my timer_Tick method, responsible for every frame:
void timer_Tick(object sender, EventArgs e)
{
logic.MoveBall();
if (model.Enemy.Count<3)
{
logic.AddEnemy();
}
int iii = 0;
foreach (MyShape enemy in model.Enemy) //the whole thing from here is me trying to solve list modification during iteration
{
if (logic.MoveEnemy(enemy) == -1)
{
logic.MoveEnemy(enemy);
}
else iii = logic.MoveEnemy(enemy);
}
if (iii > -1)
{
for (int j = model.Enemy.Count - 1; j >= 0; j--)
{
if (j == model.Enemy.Count - iii)
{
model.Enemy.RemoveAt(j);
}
}
}
}
MoveEnemy: I try to decide whether there is collusion and if yes, then try to remove the given shape object (blue square). Because This whole method is in a foreach, I just save the removable element and forward it to timer_Tick
public int MoveEnemy(MyShape shape)
{
int i = 0;
int ii = -1;
if ((shape.Area.IntersectsWith(model.Ball.Area)))
{
i = 0;
foreach (var e in model.Enemy)
{
i++;
if (shape == e)
{
ii = i;
}
}
}
shape.ChangeX(shape.Dx);
shape.ChangeY(shape.Dy);
bool coll = false;
foreach (var e in model.Enemy)
{
if ((e.Area.IntersectsWith(shape.Area)) && (shape != e))
{
coll = true;
}
}
if (shape.Area.Left < 0 || shape.Area.Right > Config.Width-40 || coll)
{
shape.Dx = -shape.Dx;
}
if (shape.Area.Top < 0)
{
shape.Dy = -shape.Dy;
}
if (shape.Area.Bottom > Config.Height/2)
{
shape.Dy = -shape.Dy;
}
RefreshScreen?.Invoke(this, EventArgs.Empty);
return ii;
}
And finally AddEnemy:
public void AddEnemy()
{
rnd = new Random();
int r = rnd.Next(-300, 300);
model.Enemy.Add(new MyShape(Config.Width / 2+r, 0, 40, 40));
RefreshScreen?.Invoke(this, EventArgs.Empty);
}
List<T> (or IList and Enumerable) exposes some useful methods to compact code:
int itemIndex = list.IndexOf(item); // Gets the index of the item if found, otherwise returns -1
list.Remove(item); // Remove item if contained in collection
list.RemoveAll(item => item > 5); // Removes all items that satisfy a condition (replaces explicit iteration)
bool hasAnyMatch = list.Any(item => item > 5); // Returns true as soon as the first item satisfies the condition (replaces explicit iteration)
A simplified version, which should eliminate the flaw:
void timer_Tick(object sender, EventArgs e)
{
if (model.Enemy.Count < 3)
{
logic.AddEnemy();
}
logic.MoveBall();
model.Enemy.ForeEach(logic.MoveEnemy);
model.Enemy.RemoveAll(logic.IsCollidingWithBall);
}
public void AddEnemy()
{
rnd = new Random();
int r = rnd.Next(-300, 300);
model.Enemy.Add(new MyShape(Config.Width / 2 + r, 0, 40, 40));
RefreshScreen?.Invoke(this, EventArgs.Empty);
}
public bool IsCollidingWithBall(MyShape shape)
{
return shape.Area.IntersectsWith(model.Ball.Area);
}
public int MoveEnemy(MyShape shape)
{
shape.ChangeX(shape.Dx);
shape.ChangeY(shape.Dy);
bool hasCollision = model.Enemy.Any(enemy => enemy.Area.IntersectsWith(shape.Area)
&& enemy != shape);
if (hasCollision || shape.Area.Left < 0 || shape.Area.Right > Config.Width - 40)
{
shape.Dx = -shape.Dx;
}
if (shape.Area.Top < 0)
{
shape.Dy = -shape.Dy;
}
if (shape.Area.Bottom > Config.Height / 2)
{
shape.Dy = -shape.Dy;
}
RefreshScreen?.Invoke(this, EventArgs.Empty);
}
I am implementing drop-drown feature in my app. Its implemented using container with list of elements in it.
Suppose the drop down list has following items aa1, aa2, aa3, aa4 aa5 and so on. And if i search as 'aa' it displays items starting from 'aa', if I select aa5 from list, it takes aa1 and displays that. But whereas if I scroll the items and select its working fine. This problem occurring only on iOS device working perfectly fine on simulator.
the first picture depicts how drop down looks like, in second picture if I search 'ee', it gives list of items starting with 'ee'. If I select 'ee5', it sets to ee1 as shown in picture 3. Problem only on device. Any workaround for this?
So, please let me know whats the issue with this.
Thanks
[![enter image description here][1]][1]
private CustomList itemList;
class CustomList extends List {
int startYPos = -1;
long lastDiff = 0;
Timer t = null;
int draggingState = 0;
public CustomList() {
this.setTensileDragEnabled(false);
}
}
private class ButtonListener implements ActionListener {
public void actionPerformed(final ActionEvent evt) {
final Runnable rn = new Runnable() {
public void run() {
// Create and show a dialog to allow users to make a selection.
final UiBuilder uib = dm.UiBuilder();
dialog = (Dialog) uib.createContainer(DESIGNER_NAME_DIALOG_COMBOBOX_CONTAINER);
GenericSpinner itemSpinner = (GenericSpinner) uib.findByName(DESIGNER_NAME_DIALOG_COMBOBOX_GENERIC_SPINNER, dialog);
itemSpinner.setPreferredW(Display.getInstance().getDisplayWidth() * 4 / 5);
//remove from parent and replace with a linear list
Container parent = itemSpinner.getParent();
parent.removeComponent(itemSpinner);
// Add the searchable text field box
final TextField tf = (TextField)uib.findByName("Search", dialog);
tf.addDataChangedListener(new DataChangedListener() {
#Override
public void dataChanged(int type, int index) {
Object[] items = model.getFilteredItems(tf.getText());
itemList.setModel(new DefaultListModel(items));
}
});
itemList = new CustomList();
itemList.getAllStyles().setBgTransparency(0);
itemList.setItemGap(0);
parent.addComponent(BorderLayout.CENTER, itemList);
final String[] items = model.getItems();
itemList.setModel(new DefaultListModel(items));
itemList.getStyle().setMargin(10, 10, 10, 10);
itemList.setFireOnClick(true);
itemList.setLongPointerPressActionEnabled(false);
ActionListener list = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (model.isUserEditable() && model.getItemCount() > 0) {
int i = itemList.getSelectedIndex();
if (i > items.length - 1) {
return;
}
itemList.getModel().setSelectedIndex(i);
model.onUserDataEntered((String) itemList.getModel().getItemAt(i));
String textToDisplay = (String) itemList.getModel().getItemAt(i);
button.setText(textToDisplay);
}
dialog.dispose();
}
};
itemList.addActionListener(list);
CommonTransitions tran = CommonTransitions.createEmpty();
dialog.setTransitionInAnimator(tran);
dialog.setTransitionOutAnimator(tran);
itemList.setRenderer(new ListRenderer());
//related to dialog to show list of items
//how much space do we really need???
if (cellHeight == 0) {
int dip = Display.getInstance().convertToPixels(1);
int siz = 2;
if (Display.getInstance().isTablet()) {
siz = 4;
}
siz *= 2;
cellHeight = siz * dip;
}
int heightRequired = cellHeight * (items.length + 8);
//is this too much for the screen - we will use 3/4 of the screen height max
int availableHeight = Display.getInstance().getDisplayHeight() * 3;
availableHeight /= 4;
if (heightRequired > availableHeight) {
int topPos = Display.getInstance().getDisplayHeight() / 8;
int bottomPos = topPos + availableHeight;
dialog.show(topPos, topPos, 40, 40);
}
else {
int topPos = (Display.getInstance().getDisplayHeight() - heightRequired) / 2;
int bottomPos = topPos + heightRequired;
dialog.show(topPos, topPos, 40, 40);
}
}
};
}
}
//new code using Multibutton implementation
final String[] listItems = model.getItems();
Display.getInstance().callSerially(() ->{
multiButton= new MultiButton();
multiButton.setTextLine1(s);
dialog.add(multiButton);
multiButton.addActionListener(e -> Log.p("you picked " + multiButton.getSelectCommandText(), Log.ERROR));
}
dialog.revalidate();
});
I would recommend using a Container and simple layout search as demonstrated by code such as this. The code below was taken from the Toolbar javadoc:
Image duke = null;
try {
duke = Image.createImage("/duke.png");
} catch(IOException err) {
Log.e(err);
}
int fiveMM = Display.getInstance().convertToPixels(5);
final Image finalDuke = duke.scaledWidth(fiveMM);
Toolbar.setGlobalToolbar(true);
Form hi = new Form("Search", BoxLayout.y());
hi.add(new InfiniteProgress());
Display.getInstance().scheduleBackgroundTask(()-> {
// this will take a while...
Contact[] cnts = Display.getInstance().getAllContacts(true, true, true, true, false, false);
Display.getInstance().callSerially(() -> {
hi.removeAll();
for(Contact c : cnts) {
MultiButton m = new MultiButton();
m.setTextLine1(c.getDisplayName());
m.setTextLine2(c.getPrimaryPhoneNumber());
Image pic = c.getPhoto();
if(pic != null) {
m.setIcon(fill(pic, finalDuke.getWidth(), finalDuke.getHeight()));
} else {
m.setIcon(finalDuke);
}
hi.add(m);
}
hi.revalidate();
});
});
hi.getToolbar().addSearchCommand(e -> {
String text = (String)e.getSource();
if(text == null || text.length() == 0) {
// clear search
for(Component cmp : hi.getContentPane()) {
cmp.setHidden(false);
cmp.setVisible(true);
}
hi.getContentPane().animateLayout(150);
} else {
text = text.toLowerCase();
for(Component cmp : hi.getContentPane()) {
MultiButton mb = (MultiButton)cmp;
String line1 = mb.getTextLine1();
String line2 = mb.getTextLine2();
boolean show = line1 != null && line1.toLowerCase().indexOf(text) > -1 ||
line2 != null && line2.toLowerCase().indexOf(text) > -1;
mb.setHidden(!show);
mb.setVisible(show);
}
hi.getContentPane().animateLayout(150);
}
}, 4);
hi.show();
Sorry for the horrible wording of the title. I'm creating a game of "War" in Processing for my Programming class. I need to change my code so that each card that is used is removed from the deck/array. I stumbled upon some posts and Google results mentioning "ArrayList", but I'm still sort of clueless.
The following code displays two separate, random cards and displays two new random cards when the mouse is clicked.
(First Tab 'War')
void draw(){
image(card[imageIndex],40,150);
image(card2[imageIndex2],340,150);
}
void mousePressed(){
imageIndex = int(random(card.length));
imageIndex2 = int(random(card2.length));
}
(Second Tab 'Card')
PImage[] card = new PImage[13];
PImage[] card2 = new PImage[13];
int imageIndex = int(random(0,12)),
imageIndex2 = int(random(0,12));
void setup(){
size(500,500);
card[0] = loadImage("2_of_clubs.jpg");
card[1] = loadImage("3_of_clubs.jpg");
card[2] = loadImage("4_of_clubs.jpg");
card[3] = loadImage("5_of_clubs.jpg");
card[4] = loadImage("6_of_clubs.jpg");
card[5] = loadImage("7_of_clubs.jpg");
card[6] = loadImage("8_of_clubs.jpg");
card[7] = loadImage("9_of_clubs.jpg");
card[8] = loadImage("10_of_clubs.jpg");
card[9] = loadImage("jack_of_clubs.jpg");
card[10] = loadImage("queen_of_clubs.jpg");
card[11] = loadImage("king_of_clubs.jpg");
card[12] = loadImage("ace_of_clubs.jpg");
card2[0] = loadImage("2_of_clubs.jpg");
card2[1] = loadImage("3_of_clubs.jpg");
card2[2] = loadImage("4_of_clubs.jpg");
card2[3] = loadImage("5_of_clubs.jpg");
card2[4] = loadImage("6_of_clubs.jpg");
card2[5] = loadImage("7_of_clubs.jpg");
card2[6] = loadImage("8_of_clubs.jpg");
card2[7] = loadImage("9_of_clubs.jpg");
card2[8] = loadImage("10_of_clubs.jpg");
card2[9] = loadImage("jack_of_clubs.jpg");
card2[10] = loadImage("queen_of_clubs.jpg");
card2[11] = loadImage("king_of_clubs.jpg");
card2[12] = loadImage("ace_of_clubs.jpg");
}
Using ArrayList would look more or less like:
// gonna use strings instead of images
// just to show the idea. I don't have all this images...
ArrayList<String> card = new ArrayList<String>();
ArrayList<String> card2;
int imageIndex, imageIndex2;
String display1, display2;
void setup() {
size(500, 500);
card.add("2_of_clubs.jpg");
card.add("3_of_clubs.jpg");
card.add("4_of_clubs.jpg");
card.add("5_of_clubs.jpg");
card.add("6_of_clubs.jpg");
card.add("7_of_clubs.jpg");
card.add("8_of_clubs.jpg");
card.add("9_of_clubs.jpg");
card.add("10_of_clubs.jpg");
card.add("jack_of_clubs.jpg");
card.add("queen_of_clubs.jpg");
card.add("king_of_clubs.jpg");
card.add("ace_of_clubs.jpg");
card2 = new ArrayList<String>(card);
imageIndex = int(random(card.size()));
imageIndex2 = int(random(card2.size()));
display1 = card.get(imageIndex);
display2 = card2.get(imageIndex2);
card.remove(imageIndex);
card2.remove(imageIndex2);
println("\ncard draw from card : "+ display1);
println("card draw from card2: "+ display2 + "\n");
}
void draw() {
}
void mousePressed() {
if (card.size() > 0) {
imageIndex = int(random(card.size()));
imageIndex2 = int(random(card2.size()));
display1 = card.get(imageIndex);
display2 = card2.get(imageIndex2);
card.remove(imageIndex);
card2.remove(imageIndex2);
println("\ncard draw from card : "+ display1);
println("card draw from card2: "+ display2 + "\n");
} else {
println("The deck is empty...");
}
}
if you have to use arrays then you would have to do something similar to the following code:
PImage[] removeCardFromDeck(PImage deck, int index){
PImage[] newdeck = new PImage[deck.length -1];
int count=0;
for(int i =0 ; i<newdeck.length;i++){
if(count==index) count++;
newdeck[i] = deck[count];
count++;
}
return newdeck;
}
but for this task it is better to use ArrayLists.
I'm working on a boids flocking project.
My goal is to have several draggable objects which have to be avoided by the boids.
There are several different flocks with a different starting position.
I managed to get the boids to avoid one draggable object. But I can't seem to make them avoid all. (using a for loop)
I really can't figure out why this won't do the trick..
I hope you could give me some suggestions.
the code:
int initBoidNum = 100; //amount of boids to start the program with
BoidList flock1, flock2, flock3;
Draggable draggable;
NullDraggableObject nullDraggableObject;
ArrayList draggables;
int id;
float[] xposs= new float[10];
float[] yposs= new float[10];
String turn;
void setup() {
size(1000, 700);
//create and fill the list of boids
flock1 = new BoidList(150, 0, 10, 100);
flock2 = new BoidList(150, 255, 10, 200);
flock3 = new BoidList(150, 150, 10, 300);
turn = "turn";
nullDraggableObject = new NullDraggableObject();
draggables = new ArrayList();
for (int i = 0; i < 10; i++) {
draggables.add(new DraggableObject(random(width), random(height/2)));
}
}
void draw() {
background(100, 60);
flock1.run();
flock2.run();
flock3.run();
stroke(255);
noFill();
draggable = nullDraggableObject;
for (id = 0; id < draggables.size (); id++) {
Draggable d = (Draggable)draggables.get(id);
d.draw();
if (d.isBeingMouseHovered()) {
draggable = d;
}
}
}
void mousePressed() {
draggable.mousePressed();
}
void mouseDragged() {
draggable.mouseDragged();
}
void mouseReleased() {
draggable.mouseReleased();
}
interface Draggable {
boolean isBeingMouseHovered();
boolean inside(float ix, float iy);
void draw();
void mousePressed();
void mouseDragged();
void mouseReleased();
}
class NullDraggableObject implements Draggable {
boolean isBeingMouseHovered() {
return false;
}
boolean inside(float ix, float iy) {
return false;
}
void draw() {
}
void mousePressed() {
}
void mouseDragged() {
}
void mouseReleased() {
}
}
public class DraggableObject implements Draggable {
float XX, YY;
float radius;
boolean drag;
float dragX, dragY;
DraggableObject(float _x, float _y) {
XX = _x;
YY = _y;
radius = 50;
drag = false;
dragX = 0;
dragY = 0;
}
boolean isBeingMouseHovered() {
return inside(mouseX, mouseY);
}
boolean inside(float ix, float iy) {
return (dist(XX, YY, ix, iy) < radius);
}
void draw() {
ellipseMode(CENTER);
ellipse(XX, YY, 2*radius, 2*radius);
String space = "__";
println(id);
println(XX);
println(YY);
xposs[id] = XX;
yposs[id] = YY;
}
void mousePressed() {
drag = inside(mouseX, mouseY);
if (drag) {
dragX = mouseX - XX;
dragY = mouseY - YY;
}
}
void mouseDragged() {
if (drag) {
XX = mouseX - dragX;
YY = mouseY - dragY;
}
}
void mouseReleased() {
drag = false;
}
}
class Boid {
//fields
PVector pos, vel, acc, ali, coh, sep; //pos, velocity, and acceleration in a vector datatype
float neighborhoodRadius; //radius in which it looks for fellow boids
float maxSpeed = 1; //maximum magnitude for the velocity vector
float maxSteerForce = .05; //maximum magnitude of the steering vector
float sMod, aMod, cMod; //modifiers for the three forces on the boid
float h; //hue
Boid(PVector inPos) {
pos = new PVector();
pos.set(inPos);
vel = new PVector(random(-1, 1), random(-1, 1));
acc = new PVector(0, 0);
neighborhoodRadius = 20;
sMod = 1;
aMod = 1;
cMod = 4;
}
Boid(PVector inPos, PVector inVel, float r) {
pos = new PVector();
pos.set(inPos);
vel = new PVector();
vel.set(inVel);
acc = new PVector(0, 0);
neighborhoodRadius = r;
}
void run(ArrayList bl) {
for (int i =0; i < 10; i++) {
acc.add(attract(new PVector(width/2, height/2), true));
acc.add(avoid(new PVector(xposs[i], yposs[i]), true));
if (i == 10) i = 0;
}
if (pos.x>width-10)acc.add(bounce(new PVector(width, pos.y), true));
if (pos.x<10) acc.add(bounce(new PVector(0, pos.y), true));
if (pos.y>height-10) acc.add(bounce(new PVector(pos.x, height), true));
if (pos.y<10) acc.add(bounce(new PVector(pos.x, 0), true));
ali = alignment(bl);
coh = cohesion(bl);
sep = seperation(bl);
for (int i =0; i < 10; i++) {
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)>180) {
acc.add(PVector.mult(ali, aMod));
acc.add(PVector.mult(coh, cMod));
acc.add(PVector.mult(sep, sMod));
}
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)<80) maxSpeed = 1000;
if (i == 10) i = 0;
}
if (PVector.dist(new PVector(width, height), pos)<60) maxSpeed = 1000;
if (PVector.dist(new PVector(0, 0), pos)<50) {
maxSpeed = 1000;
} else {
maxSpeed = 1;
}
move();
checkBounds();
render();
}
void move() {
vel.add(acc); //add acceleration to velocity
vel.limit(maxSpeed); //make sure the velocity vector magnitude does not exceed maxSpeed
pos.add(vel); //add velocity to position
acc.mult(0); //reset acceleration
}
void checkBounds() {
}
void render() {
pushMatrix();
translate(pos.x, pos.y);
rotate(atan2(vel.y, vel.x)); //rotate drawing matrix to direction of velocity
stroke(0);
noFill();
ellipse(0, 0, neighborhoodRadius/2, neighborhoodRadius/2);
noStroke();
fill(h);
//draw triangle
beginShape(TRIANGLES);
rect(0, 0, 6, 2);
endShape();
popMatrix();
}
//steering. If arrival==true, the boid slows to meet the target. Credit to Craig Reynolds
PVector steer(PVector target, boolean arrival) {
PVector steer = new PVector(); //creates vector for steering
if (!arrival) {
steer.set(PVector.sub(target, pos)); //steering vector points towards target (switch target and pos for avoiding)
steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
} else {
PVector targetOffset = PVector.sub(target, pos);
float distance=targetOffset.mag();
float rampedSpeed = maxSpeed*(distance/100);
float clippedSpeed = min(rampedSpeed, maxSpeed);
PVector desiredVelocity = PVector.mult(targetOffset, (clippedSpeed/distance));
steer.set(PVector.sub(desiredVelocity, vel));
}
return steer;
}
//avoid. If weight == true avoidance vector is larger the closer the boid is to the target
PVector avoid(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector attract(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(target, pos)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(target, pos)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector bounce(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector seperation(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector repulse;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
repulse = PVector.sub(pos, b.pos);
repulse.normalize();
repulse.div(d);
posSum.add(repulse);
}
}
return posSum;
}
PVector alignment(ArrayList boids) {
PVector velSum = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
velSum.add(b.vel);
count++;
}
}
if (count>0) {
velSum.div((float)count);
velSum.limit(maxSteerForce);
}
return velSum;
}
PVector cohesion(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector steer = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = dist(pos.x, pos.y, b.pos.x, b.pos.y);
if (d>0&&d<=neighborhoodRadius) {
posSum.add(b.pos);
count++;
}
}
if (count>0) posSum.div((float)count);
steer = PVector.sub(posSum, pos);
steer.limit(maxSteerForce);
return steer;
}
}
class BoidList {
ArrayList boids; //will hold the boids in this BoidList
float h; //for color
BoidList(int n, float ih, int xstart, int ystart) {
boids = new ArrayList();
h = ih;
for (int i=0; i<n; i++) {
boids.add(new Boid(new PVector(xstart, ystart)));
}
}
void run() {
for (int i=0; i<boids.size (); i++) {
Boid tempBoid = (Boid)boids.get(i); //create a temporary boid to process and make it the current boid in the list
tempBoid.h = h;
tempBoid.run(boids); //tell the temporary boid to execute its run method
}
}
}
I'd like to cache my spritesheet (tilesheet) into an array. I do this because every spritesheet shall be cached inside of an array so my objects can pull their tiles from them easily. But my cache doesn't seem to work because absolutely nothing gets rendered out of it. I can't see anything.
There is something inside my cache (likely bitmapData) and it is not null so currently I don't know where the problem might be.
Can someone help me out with this issue, please?
this function shall render each tile of an array to a background via copypixels
public function renderCachedTile(canvasBitmapData:BitmapData, tileArray:Array):void
{
tileCache = tileArray;
tileArray = [];
x = nextX;
y = nextY;
point.x = x;
point.y = y;
tileRect.x = tileWidth;
tileRect.y = tileHeight;
if (animationCount >= animationDelay)
{
animationCount = 0;
if(reverse)
{
currentTile--;
if (currentTile < 1)
{
currentTile = tilesLength - 1;
}
} else {
currentTile++;
if (currentTile >= tilesLength - 1)
{
currentTile = 0;
}
}
} else {
animationCount++;
}
canvasBitmapData.lock();
canvasBitmapData.copyPixels(tileCache[currentTile], tileRect, point);
canvasBitmapData.unlock();
}
this function 'separates' my spritesheet into tiles and throws them into an array
private function tileToCache():void {
var tileBitmapData:BitmapData = new BitmapData(tileWidth, tileHeight, true, 0x00000000);
var tilePt:Point = new Point(0, 0);
var tileRect:Rectangle = new Rectangle;
tileCache = [];
for (var tileCtr:int = 0; tileCtr < tilesLength; tileCtr++) {
tileBitmapData.lock();
tileRect.x = int((tileCtr % spritesPerRow)) * tileWidth;
tileRect.y = int((tileCtr / spritesPerRow)) * tileHeight;
tileBitmapData.copyPixels(tileSheet, tileRect, tilePt);
tileBitmapData.unlock();
tileCache.push(tileBitmapData);
}
}
Unless there is code missing from your example, in your tileToCache you instantiate and use tileRect without defining a width and height:
private function tileToCache():void {
var tileRect:Rectangle = new Rectangle;
/* ... */
tileBitmapData.copyPixels(tileSheet, tileRect, tilePt);
If your source was at 0, 0 I presume you would want:
var tileRect:Rectangle = new Rectangle(0, 0, tileWidth, tileHeight);