How to avoid object overlapping and overtaking? - arrays

I am trying to draw circles from same y coordinate.
and creating arrays for xPos. I put the speed and xPos random, how to make sure they are not overlapping and the one behind it match the speed to the front one so it wouldn't overtake?
I have retried the code, but it still overlapping for some reason that I couldn't find out?
OK now I initialise the k with i+1, so whichever behind it.
and I ran flow chart as well, the logic looks alright, still not doing what it should being doing.
int Num=10;
float dia=50;
float[] xPos= new float[Num];
float[] xSpeed=new float[Num];
void setup() {
size(300, 300);
for (int i= 0; i<xPos.length; i++) {
xPos[i]=random(-dia*Num);
xSpeed[i]=3;
boolean overlapping=false;
for(int k=;k<xPos.length;k++){
float newPos=xPos[k];
float dist=(newPos-xPos[i]);
if(dist<dia+50){
overlapping=true;
break;
}
}
if(!overlapping){
draw();
}
}
}
void draw() {
background(255);
drawBall();
moveBall();
reset();
}
void drawBall() {
for (int i= 0; i<xPos.length; i++) {
circle(xPos[i], 50, 50);
}
}
void moveBall() {
for (int i= 0; i<xPos.length; i++) {
xPos[i]+=xSpeed[i];
}
}
void reset() {
for (int i= 0; i<xPos.length; i++) {
if (xPos[i]>width) {
xPos[i]=0;
}
}
}

how to make sure they are not overlapping
For this, you could naively check if the new position has already been taken by another such as follows (I haven't run the code, so i probably has bugs, think of it more as a pseudocode):
boolean isItTaken(float[] xPos, float newPos) {
for (int i= 0; i<xPos.length; i++) {
if (abs(newPos - xPos[i]) < circleSize) return true;
}
return false;
}
for (int i= 0; i<xPos.length; i++) {
float newPos = random(-50);
while (isItTaken(xPos, newPos)) {
newPos = random(-50);
}
}
I'm sure there are better methods though. Also I think using ArrayList is better than using a simple array.
and the one behind it match the speed to the front one so it wouldn't overtake?
You could set it as a constant number? If you want it to be random, but slower than the previous one, you could set the upper limit of the random function to be the speed of the previous one such as(again, probably buggy):
ArrayList<Float> xSpeed = new ArrayList<Float>;
for (int i= 0; i < Num; i++) {
xSpeed.push(random(2, xSpeed.get(xSpeed.length - 1)));
}

Related

How to check elements from array? Avoid overlapping of my circles and match the speed for the circle spawn behind

Hi what I am trying to achieve here is not overlap the circle moving from left to right. the x coordinate is random generated, so should I check and make sure a minimum gap there so it execute draw? If so how do I do it.
Also speed is random as well, so I want to match the speed from behind to the front one(also not going backwards) and do no overtake it.
Sorry I am doing very basic coding now, so I can't use class or array for functions.
//declare global variables
int N_CARS_IN_LANE = 30;
int MIN_GAP = 50;
float xPed;
float yPed;
float dia;
boolean isCollide=false;
float [] xPos;
float [] yPos;
float [] dias;
float [] xSpeed;
void setup() {
size(1200, 400);
background(255);
xPed=width/2;
yPed=7*height/8;
dia=height/4;
init();
}
void init() {
xPos= new float[N_CARS_IN_LANE];
yPos= new float[N_CARS_IN_LANE];
dias= new float [N_CARS_IN_LANE];
xSpeed= new float [N_CARS_IN_LANE];
for ( int i=0; i<xPos.length; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) {
xPos[i]= random(-150);
xPos[k]=xPos[i]-k;
yPos[i]=height/8;
dias[i]=50;
xSpeed[i]=random(10);
}
}
}
void draw() {
//reset background
background(255);
balls();
moveballs();
ballsisOffscreen();
collideballs();
}
void balls() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
if (isCollide!=true) {
fill(0, 255, 0);
circle (xPos[i], yPos[i], dias[i]);
//should I put conditions here to make sure balls are separated for a MIN_GAP when draw?
}
}
}
void moveballs() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
//for (int k=i+1; k<N_CARS_IN_LANE; k++) {
xPos[i] = xPos[i] + xSpeed[i];
}
}
//check balls draw is not overlapping? and maintain a MIN_GAP
void collideballs() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) { //check elements from array?
if (isCollide&&xPos[i]!=xPos[k]) {
xSpeed[k]=xSpeed[i]; // match speed from behind to from?
}
}
}
}
boolean isCollide() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
for (int k=i+1; k< N_CARS_IN_LANE; k++) {
// distance between balls
float leftright =((xPos[i]-dias[i]/2) -(xPos[k]+dias[k]/2));
float rightleft=((xPos[k]-dias[k]/2)-(xPos[i]+dias[i]/2));
if ((leftright<MIN_GAP)&&(xPos[i]!=xPos[k])&&rightleft>MIN_GAP) {
return true;
}
}
}
return false;
}
//reset ball
void ballsisOffscreen() {
for (int i=0; i<N_CARS_IN_LANE; i++) {
if (xPos[i]>width) {
xPos[i]=-200;
}
}
}
I'm not sure if I understud correctly what you were asking for, but I hope I did it right.
I just added the speed to the position of the ball and then checked if this moves it to close to the ball in the front of it. In that case I just set it right behind the ball in front.
But for this to work you have to know which ball is in front of the current ball.
For that you could loop through all of your balls and search for the ball whoose coordinate is closest but bigger than the current balls.
Also I think it would make your code much more readable if you used Objects for the balls. That way you also don't have to search for the next ball and it makes it easier to expand later.
Here is a version I've coded up quickly that implements the balls/cars as objects and also solves your problem with collision. I hope that helps you to fix your code [Or you just copy&paste this one ;-) ]
ArrayList<Car> cars;
int carAmount = 10;
int carSize = 50;
int gab = 5;
void setup(){
size(1200, 400);
cars = new ArrayList<Car>();
}
void draw(){
background(255);
float posLastCar = width+ carSize*2 + gab; //could also be any other big number
if(random(100) > 97 && cars.size()< carAmount){
//if there are not enought cars there is a 3% chance of a new one spaning
cars.add(new Car(carSize, gab, 100));
}
for(Car car: cars){ //loops through all cars
car.update(posLastCar);
posLastCar = car.posX; //save pos of this car for the next
}
if(cars.size() > 0){
if(cars.get(0).isAtEnd()){ //checks if first car is at the end
cars.remove(0); //then removes it
}
}
}
class Car {
float posY;
float radius;
float gab;
float posX;
float speed;
Car(float radius, float gab, float posY){
this.radius = radius;
this.gab = gab;
this.posY = posY;
speed = random(3, 10); //picks random speed between 3 and 10
// to reduce the amount of extremly slow, blocking cars
posX = 0;
}
void move(float posNextCar) {
posX += speed;
if(posX + radius + gab > posNextCar){
posX = posNextCar - radius - gab;
}
}
void update(float posNextCar){
move(posNextCar);
fill(0, 255, 0);
circle (posX, posY, radius);
}
boolean isAtEnd(){
if (posX >= width + radius){
return true;
}
return false;
}
}

Extracting an image from an array in Processing

Does anyone have any suggestions on what might be going wrong with this code? I'm trying to load tiles of images into a large array and then display them. Later on I'll shuffle the pieces. The issue I'm running into is seen near the bottom. I have a for loop that should plug the value of i into the output array and display the relevant image at that index value. Instead I get a null pointer exception. If I replace the letter i with an integer it works perfectly. What could be preventing processing from passing that value if i into the array? Any thoughts? Thanks.
int tileSize = 100;
PImage out; PImage sample;
PImage img;
PImage img2;
String[] imageNames = {"arctic_fox.jpg", "bbridge_in_the_am.jpg", "Kali2.jpg"};
PImage[] images = new PImage[imageNames.length];
//PImage[] output = new PImage[((1440/tileSize)*imageNames.length)*(900/tileSize)];
PImage[] output = new PImage[2000];
int tintScale = 200;
void setup() {
fullScreen();
for (int i=0; i < imageNames.length; i++) {
String imageName = imageNames[i];
images[i] = loadImage(imageName);
}
out = createImage(width, height, RGB);
noLoop();
println("test");
}
void draw() {
background(0);
println(width, height);
println(output.length);
int counter=0;
for (int i = 0; i < imageNames.length; i++) {
img = loadImage(imageNames[i]);
img.resize(0,900);
for (int y=0; y<img.height; y+=tileSize) {
for (int x=0; x<img.width; x+=tileSize/3) {
sample = img.get(x, y, tileSize, tileSize);
output[counter] = sample;
tint(255, tintScale);
counter++;
//println(counter);
//image(out, random(0, width-img_x), random(0, height-img_y));
}
//image(output[i],30,30);
}
}
for (int i=0;i<output.length;i++){
image(output[30],i*tileSize,i*tileSize);
}
//for (int y=0; y<out.height; y+=tileSize) {
// for (int x=0; x<out.width; x+=tileSize) {
// i = 800;
// //tint(255, tintScale);
// image(output[i], x, y);
// }
//}
}
I hope you solved it, but this is the problem:
PImage[] output = new PImage[2000];
You are initializing the array with 2000 null values, and then enter less then 300 tiles. That's why you get a null pointer error. You have to calculate how large your array will be before you initialize it. Or perhaps better, use an arraylist:
ArrayList<PImage> output = new ArrayList<PImage>();
//to add a tile:
output.add(sample);
//to draw all tile:
for(int i = 0; i< output.size();i++)
{
image(output[i],i*tileSize,i*tileSize);
}
You can read more about arraylists here
Final note: as Kevin Workman says, loadImage() and this process of dividing into tiles does not belong in 'void draw()'. It should be in setup() or in a separate function, called from setup().

C Space Invaders enemy movement

I have to write a clone of space invaders game for university in C language using SDL library for graphics.I am very new to C and programming in general so i struggle with it a lot. For now I have one row of enemies and I'm trying to make it move correctly. This are functions for movement of aliens, which check for the collision with right/left wall(which are SDL_Rects near window edges) and if it happens, enemies move one line lower in the opposite direction. The problem is it works okay for all ten enemies except the first one. Each time when collision with left wall occurs the first alien sort of moves away a bit from others instead of moving in one block as I want it to. I noticed that if I change the first for loop in move_aliens function to start from i=11 and i--, the same thing will happen to the enemy in last column. But I still dont know how to fix it.
I would appreciate if someone could tell me what I'm doing wrong, give me an idea or sollution :).
I uploaded a video of whats happening http://sendvid.com/dt1reizc
void move_down (GameState *game)
{
int i=0;
for(; i < HMALIENS; i++)
game->alien1[i].y += 25;
}
int collided(int a1, int b1, int a2, int b2, int width1,
int height1, int width2, int height2)
{
return (!((a1 > (a2+width2)) || (a2 > (a1+width1)) ||
(b1 > (b2+height2)) || (b2 > (b1+height1))));
}
void move_aliens(GameState *game)
{
int i=0;
for(; i < HMALIENS; i++)
{
if (game->alien1[i].dir==LEFT)
game->alien1[i].x -= 10;
if (game->alien1[i].dir==RIGHT)
game->alien1[i].x += 10;
if (collided(game->alien1[i].x, game->alien1[i].y,
game->leftwall.x, game->leftwall.y, 50, 50, 1, 600))
{
int i = 0;
for(; i < HMALIENS; i++)
game->alien1[i].dir=RIGHT;
move_down(game);
}
}
if(collided(game->alien1[i].x, game->alien1[i].y, game->rightwall.x,
game->rightwall.y, 50, 50, 1, 600))
{
int i = 0;
for(; i < HMALIENS; i++)
game->alien1[i].dir=LEFT;
move_down(game);
}
}
}
//edit
HMALIENS is just a constant (11), the number of living enemies at the start
GameState is a structure.
LEFT/RIGHT stand for direction of movement (quite obvious) [enum Direction {LEFT, RIGHT};]. I have in my alien1 structure enum Direction dir and in the function which load_game function i set it to RIGHT.
typedef struct
{
Player player;
Rightwall rightwall;
Leftwall leftwall;
Alien1 alien1[HMALIENS];
SDL_Texture *bulet;
SDL_Texture *ship;
SDL_Texture *Alien1;
SDL_Renderer *renderer;
} GameState;
Without rewriting your code, the problem is that you have already moved the first alien ([0]) left,
if (game->alien1[i].dir==LEFT)
game->alien1[i].x -= 10;
and then you are doing the collision test and flagging all of them to move right, but the loop continues with [1..10], while [0] has already moved.
typedef enum{
LEFT,
RIGHT
}GAME_DIRECTION;
int dir=LEFT;
#define SPRITE_WIDTH 50
#define SPRITE_HEIGHT 50
#define BOTTOM_LINE 600
void move_down (GameState *game)
{
int i;
for(i=0; i < HMALIENS; i++)
game->alien1[i].y += 25;
}
void do_slide(GameState *game)
{
int i;
for(i=0; i < HMALIENS; i++)
game->alien1[i].x += dir?10:-10;
}
int collided(GameState *game)
{
int i;
for(i=0; i < HMALIENS; i++){
if(
game->alien1[i].x <= game->leftwall.x ||
game->alien1[i].x >= game->rightwall.x +SPRITE_WIDTH ||
game->alien1[i].y >= BOTTOM_LINE - SPRITE_HEIGHT
)
return true;
}
return false;
}
void move_aliens(GameState *game)
{
if(collided(game)){
move_down (game);
dir=!dir; // update direction;
}else{
do_slide (game);
}
}
Maybe something like:
void move_aliens(GameState *game)
{
int i=0;
for(; i < HMALIENS; i++)
{
if (game->alien1[i].dir==LEFT)
game->alien1[i].x -= 10;
if (game->alien1[i].dir==RIGHT)
game->alien1[i].x += 10;
}
if (collided(
game->alien1[0].x, game->alien1[0].y,
game->leftwall.x, game->leftwall.y,
50, 50, 1, 600))
{
int i = 0;
for(; i < HMALIENS; i++)
game->alien1[i].dir=RIGHT;
move_down(game);
}
if(collided(
game->alien1[HMALIENS-1].x, game->alien1[HMALIENS-1].y,
game->rightwall.x, game->rightwall.y,
50, 50, 1, 600))
{
int i = 0;
for(; i < HMALIENS; i++)
game->alien1[i].dir=LEFT;
move_down(game);
}
}
I have tried to make the minimum changes. But #milevyo's more extensive rewrite looks good as well.
The problem, I think (just from looking), is you has the left collision test inside the loop so when that hits, the movement gets out of sync.
Also it was pretty subtle that the right collision test used i from the previous loop which happens to index the last element (the rightmost alien). I changed that to explicitly use HMALIENS - 1. When you start destroying aliens,
you'll have to track the first (leftmost) and last (rightmost) living aliens and use them for you collision tests.
Your indentation and formatting were a little off which makes the code much harder to read. Formatting is important, and will be even more so when your code gets more complicated.

Array of text don't fade out until the last one is appended

I want to make a group of array fade out until the last array in this group was appended. for example, I use append to create zoog[0], zoog[1], zoog[2], and I want these three objects not fadeout until zoog[2] is created and wait for a second, the same situation with zoog[3], zoog[4],zoog[5], these three objects don't fadeout until zoog[5] is created. But now what I can do is make each object fadeout as soon as it is created.
Zoog[]zoog = new Zoog[1];
float count=0;
int xpos =0;
int ypos =0;
String message="haha";
int ntextsize = 20;
int nopacity =200;
int thistime = 0;
int thiscount = 0;
//Zoog zoog;
void setup() {
size(400, 400);
xpos = int(random(width/2-200, width/2+40));
ypos = int(random(height/2, height/2-40));
zoog[0] = new Zoog(xpos,ypos,message,nopacity);
}
void draw(){
background(255,255,255);
for(int i=0; i<zoog.length; i++){
// if(millis()-thistime>4000){
// zoog[i].disappear();
// }
zoog[i].jiggle();
zoog[i].display();
}
}
void mousePressed(){
count = count + 1;
// int thiscount = 0;
if(count%3 ==0){
xpos=int(random(30, width-30));
ypos=int(random(10, height-10));
}
else{
ypos = ypos+50;
// thiscount = thiscount +1;
// thistime = millis();
// }
}
nopacity = int(random(100,255));
// text(message, xpos, ypos);
Zoog b = new Zoog(xpos,ypos,message,nopacity);
zoog =(Zoog[]) append(zoog,b);
}
Zoog class
class Zoog {
int x;
int y;
String thatmessage;
int opaci =0;
Zoog(int xpo, int ypo, String thismessage, int opa) {
x = xpo;
y = ypo;
thatmessage = thismessage;
opaci = opa;
}
void jiggle() {
x = x+int(random(-2, 2));
y = y+int(random(-2, 2));
}
void display() {
fill(0, opaci);
text(thatmessage, x, y);
print("x position is "+ x);
print("y position is "+y);
}
void disappear() {
for (int j=0; j<255; j++) {
opaci = opaci -j;
}
}
}
If I understand correctly you want to make 3 zoogs and then start fading those three out until they're gone. If this is correct there are a couple of ways I'd go about doing this.
First, I wouldn't use an array especially if you're dynamically updating the amount inside it. If you want to do that I'd use, arraylists. Here's the javadocs reference. Basically you'd initialize an arraylist of Zoogs and put the zoog.add(new Zoog...) in the mousepressed. The good thing about arraylists is that they have a number of member functions that can help you manipulate them. For instance, you can check the size of the arraylist in your draw function instead of the time. Once you're above 3 start fading the first 3 out until they're dead (using a Zoog member function to say they're dead). You can check that "isDead" member function in your draw loop and remove the correct dead Zoog while in your for loop.
Here's a rough implementation, assuming you created an isDead function in your Zoog class that just returns whether the opacity is greater than 0:
void Draw()
{
for (Zoog zoog : zoogs) //for each statement simplifying the code -
//says for each Zoog in zoogs do
{
zoog.jiggle();
zoog.display();
}
if(zoogs.size() >= 3) {
for(int i = 0; i < 3; i++) {
zoogs.get(i).disappear();
}
}
if (zoogs.get(0).isDead() && zoogs.get(1).isDead() && zoogs.get(2).isDead()) {
zoogs.remove(2);
zoogs.remove(1);
zoogs.remove(0);
}
}
This is by no means a perfect example but it shows how to remove 3 zoogs at a time by lessening their opacity and checking whether they are dead. If you're clicking a million times then it will take a while for each chain of three to die.

Moving average algorithm issue

I want to smooth values in realtime. For a reason this code seems to make the microcontroller(arduino - atmel) crash or not respond at least.
This is my code
float tilttemp[] = { 1,1,1,1,1,1,1,1 };
float rolltemp[] = { 1,1,1,1,1 };
float pantemp[] = { 1,1,1,1,1 };
float tiltausgabe = 0;
float rollausgabe = 0;
float panausgabe = 0;
void trackerOutput()
{
for(int i=0; i < sizeof(tilttemp) - 1; i++)
{
tilttemp[i] = tilttemp[i+1];
}
tilttemp[sizeof(tilttemp)] = tiltAngleLP; //tiltAngleLP is a value that is available
tiltausgabe = 0;
for(int i=0; i < sizeof(tilttemp); i++)
{
tiltausgabe += tilttemp[i];
}
tiltausgabe = tiltausgabe/(sizeof(tilttemp));
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
}
If I leave everything but
Serial.print(tiltausgabe);
Serial.print(",");
Serial.print(rollausgabe);
Serial.print(",");
Serial.println(panausgabe);
out I get the output, so something is wrong in the first part.
You don't want sizeof. You want countof.
If you want to know what that is, it is:
#define countof(a) (sizeof(a)/sizeof((a)[0]))
and
array[ countof(array) ] = ...
will not set the last element of array.
It will set the element beyond the last element.

Resources