[Project ended] game problem moving character with mouse, ball going through the character

//A problem with the character movement as it relied with the mouse. Also trouble with the ball script of which my character meant to bounce back up, as the ball went through the character.

float circleX=1;
float circleY=1;   

float speedX=3;
float speedY=1;

float xpos;       
float ypos;      

void setup() {
  size(640,480);
  
  xpos=0;
  ypos=0;
  
}

void draw() {
  
  background(44,56,245);
  fill(2,188,34);
  noStroke();
  rect(0,440,width,height);
       
  pushMatrix();
  translate(mouseX,280);
  fill(255,224,189);
  rect(100,100,60,50);  
  fill(210,105,30);
  rect(110,120,15,5);  
  rect(135,120,15,5);  
  fill(0);
  ellipse(130,136,10,2);  
  fill(0);
  rect(85,96,90,4);  
  
  fill(255,0,0);
  rect(110,150,40,20); 
  
  fill(0);
  rect(110,170,5,10); 
  rect(145,170,5,10); 
  popMatrix();
    
  ypos+=speedY;
  xpos+=speedX;
  
  fill(180);
  stroke(0);
  strokeWeight(2);
  ellipse(xpos,ypos,50,50);
    
  if(xpos>width-50 || xpos<0){
    speedX*=-1;
  }
  
    
   if(ypos>height-50){
    speedY*=-1*.99;
  
  }else{
   speedY+=1; 
  }
 
  if(ypos<0){
   speedY*=-1; 
  }
    
  if(speedY==0){
    xpos=0;
    ypos=0;
  }
}

hi robin,

you bumped that 3 times by changing text
but the code is still same
and not formatted by the

</> code tag

we assume this is homework,
possibly the code basic was given to you?
and you just post it here, hoping we do your work?

but ok, let’s start slowly

+a+ if you ever want to find out if the ball hits not only the ground
also the HAT of the ‘character’
you need to know ( as global variables ):
ball:
bposx, bposy, bradius
character’s hat:
cposx, cwide, cposy,

i think your translate makes it more difficult to get that required values
for a ‘collision check’ ( but not impossible )

+b+ with that must check if the ball falls down on the HAT and not on the ground,
for that need a additional logic function like

if( ypos>height-50 || ball_hits_HAT() ){}

a general collision example for

ball with line ( top of HAT )
https://github.com/jeffThompson/CollisionDetectionFunctionsForProcessing/blob/master/ballLine/ballLine.pde ,

but again, your problem is to call such a collision_detect_function
need to know above list of values…

and we still wait you repair your first post regarding
paste the code in </> code tag.

My apologises once again about the code not display in the </> code tag.

1 Like

ok, where is the ball, where is the HAT

boolean ball_hits_HAT() {
  float bposx = ?;
  float bposy = ?;
  float bradius = ?;
  float cposx = ?;
  float cwide = ?;
  float cposy = ?;
  if (? ) return true;
  return false;
}

that is how you draw it, but for the collision with the ball you need to know where it actually is?
work on the boolean function i layout for you
and run it in your code ( as i show above. ).

Any appropriate location for the boolean function by inserting the void draw and put below the hat drawing.

no, outside of draw,
but a call with

if( ypos>height-50 || ball_hits_HAT() ){}

only possible if all used variables are global.


a small tip,
if you change

translate(mouseX,280);

to

translate(mouseX-85,280);

your mouse control works
and the collision position calculation gets much easier

1 Like

you can make 2 new variables
int hposx=mouseX-85, hposy=280;
and add this inside each rect and ellipse to (x,y like
rect(100,100,60,50);
will be
rect(100+hposx,100+hposy,60,50);

and make the whole “character” to a function.

void character() {
  int hposx=mouseX-85, hposy=280;
  // no push no translate
  rect(100+hposx,100+hposy,60,50);
  //...
}

after that your mouse will be at left top HAT

the problem with mouse and the character is in the translate(). note: all the lines below translate(), the Y and X are relative to 0. meaning if you

translate(100, 200);
ellipse(30, 40, 10, 10);

you’ll get the actual X and Y:

X = 100 + 30 = 130; //and 
Y = 200 + 40 = 240;

so to solve this problem, you can pick some constants for X and Y (in this case i picked from the body of the character, so the body will in the origin (0,0)) and subtract every X and Y with those constants.


fill(255,224,189);
  rect(100,100,60,50);  // the body
  fill(210,105,30); 
  rect(110,120,15,5);  
  rect(135,120,15,5);

to this

fill(255,224,189);
  rect(0,0,60,50);  // the body
  fill(210,105,30); 
  rect(10, 20,15,5);  
  rect(35,20,15,5);

And for the second problem, you can use collision detection function for Rectangle and circle.
first, define the Hat x and y. in this case the hat x and y:

//below translate
hatX = -15;
hatY = -4;

actual hatX and hatY are

hatX = mouseX - 45; // + x Translate
hatY =  376; // + y Translate

so,

boolean ballHitsHat() {
  // Rectangle and circle collision detection
  if (ballPos.y + ballRadius > hatY && ballPos.x + ballRadius > hatX && ballPos.x + ballRadius < hatX + hatW) {
    return true;
  }
  return false;
}

finally, i’ve got something done for you, some adjustments and corrections

PVector ballPos;
PVector speed;
PVector gravity;

float friction = 0.8;
float ballRadius = 25;

float hatX;
float hatY = 376;
float hatW = 90;
float hatH = 4;

void setup() {
  size(640, 480);
  ballPos = new PVector(0, 0);
  speed = new PVector(3, 1);
  gravity =new PVector(0, 1);
}

void draw() {
  background(44, 56, 245);
  fill(2, 188, 34);
  noStroke();
  rect(0, 440, width, height); 

  updateBall();
  checkBall();
  drawPuppy();
  drawBall();
}

void updateBall() {
  speed.add(gravity);
  ballPos.add(speed);
}

boolean ballHitsHat() {
  // Rectangle and circle collision detection
  if (ballPos.y + ballRadius > hatY && ballPos.x + ballRadius > hatX && ballPos.x + ballRadius < hatX + hatW) {
    return true;
  }
  return false;
}

void checkBall() {

  if (ballHitsHat()) {
    speed.y *= -1;
  }

  // checking Edges
  if (ballPos.x > width - ballRadius) {
    if (speed.x > 0) speed.x *= -1;
  } else if (ballPos.x < ballRadius) {
    if (speed.x < 0) speed.x *= -1;
  }

  if (ballPos.y > height - ballRadius - 34) {
    ballPos.y = height - ballRadius - 34;
    speed.y *= -friction;
  }
}

void drawBall() {
  fill(180);
  stroke(0);
  strokeWeight(2);
  ellipse(ballPos.x, ballPos.y, ballRadius*2, ballRadius*2);
}

void drawPuppy() {
  pushMatrix();
  hatX = mouseX - 45;
  translate(mouseX - 30, 380);
  fill(255, 224, 189);
  rect(0, 0, 60, 50);
  fill(210, 105, 60, 50);
  rect(10, 20, 15, 5);
  rect(35, 20, 15, 5);
  fill(0);
  ellipse(30, 36, 10, 2);
  fill(0);

  rect(-15, -4, hatW, hatH);

  fill(0);
  rect(10, 50, 40, 20);

  fill(0);
  rect(10, 70, 5, 10);
  rect(45, 70, 5, 10);
  popMatrix();
}
1 Like
float ballX, ballY;

you never had PVector in your code,
you can use, OK, but why you use if you not like??


somewhere you are supposed to use
hatX = mouseX -45 ; // middle HAT

to limit move must check:

hatX = constrain(mouseX,45,width-45) - 45;

for the draw of all that rectangles use
hatX and not mouseX to make that limit happen,
sorry need to move all rect again.

void drawPuppy() {
  hatX = constrain(mouseX, 45, width-45) - 45;
  hatY = 400;
  fill(0);
  rect(hatX, hatY, 90, 10);                  //HAT
  fill(255, 224, 189);                       //head
  rect(hatX+15, hatY+10, 60, 40);
  fill(210, 105, 30);
  rect(hatX+25, hatY+20, 15, 5);             //left eye
  rect(hatX+25+20, hatY+20, 15, 5);          //right eye
  fill(0);
  ellipse(hatX+42, hatY+36, 10, 2);          //mouth 
  fill(255, 0, 0);
  rect(hatX+25, hatY+50, 40, 20);            //body
  fill(0);
  rect(hatX+35, hatY+70, 5, 10);             //legs        
  rect(hatX+35+15, hatY+70, 5, 10);
}

also the “ball hit hat” logic i would change
( still your pvector )


boolean ballHitsHat() {
  // Rectangle and circle collision detection
//  if (ballPos.y + ballRadius > hatY && ballPos.x + ballRadius > hatX && ballPos.x + ballRadius < hatX + hatW) {
  if (ballPos.y < hatY && ballPos.y + ballRadius > hatY && ballPos.x > hatX && ballPos.x < hatX + hatW) {
    ballPos.y = hatY-ballRadius;                   // anti rebounce
    return true;
  }
  return false;
}

so we are not able to deal with a hit on the hat corner,
( if ball center outside hatX ( + hatW ) )
but that would require real circle // rect collision logic!!!

1 Like
1 Like

No need to apologise of moving all the rect again, it just my confidence of trying to fix everything. And I’m only struggling to work on the entire project. The only problem is just the PVector that the earlier post by humayung provided it line of code and it have the PVector. And I’m trying my very best to change and altered a fraction of the code into something more appropriated from his one. But the results are the same as the code really operate properly with the PVector. Also doesn’t mean to be a bugger but I’ve decided to use my own code of the character to make it more appropriate in my point of view and only I need is just simply fix the character movement.

2 Likes

great!
sorry for making you confusing.
the PVector just a class that helpful to work with Vector Operation. It just hold x and y, or if you need z, it included that too! i know it quite silly to use PVector just for moving something :sweat_smile:, it is not reveal the greatest power of the PVector class!
but to make the code more clean, i’d better use PVector in my code, it packed X and Y in one variable so you can do happier debugging since it cleanly looking, but sometimes i use basic data type

// using primitive data type (basic structure of data type)
xPos = xPos + 10;
yPos = yPos + 2;

xPos = xPOs - 5;
yPos = yPos - 6;

xPos = xPos * 3;
yPos = yPos * 3;

//using PVector object
// we packed the position into PVector pos
pos.add(10, 2); // Vector addition
pos.sub(5,6) //vector subtraction
pos.mult(3); //Vector multiplication

love to discuss!
sorry for my english

2 Likes

No need to apologise mate, it all good. My English is not good too sometimes.

nope, i mean
redefine all the PVector using primitive data type. so

float xPos;
float yPos;

float gravity; 
float speedX;

replace all ballPos.y with yPos
replace all ballPos.x with xPos

for speed.add(gravity) change to:

speedY += gravity

since the gravity only vertical acceleration.

and pos.add(speed) change to

xPos += speedX;
yPos += speedY

all done

1 Like

Any possible suggestion for the character to stay in the barrier of the screen
without the character going out of it.
By using a if instead of constrain or dist?
This is the last question I’m going to ask
robinyashed90


void drawBill() {
  
  hatX = mouseX - 45;//bouncing hat
  background(44, 56, 245);//sky
  fill(2, 188, 34);
  noStroke();
  rect(0, 420, width, height);//grass

  fill(255, 224, 189);
  rect(mouseX, 400, 60, 50);//head

  fill(210, 105, 30);
  rect(mouseX+10, 420, 15, 5);  //left eye

  rect(mouseX+35, 420, 15, 5);  //right eye

  fill(0);
  ellipse(mouseX+30, 436, 10, 2); //mouth 

  fill(0);
  rect(mouseX-15, 390, 90, 10); //hat
  
  fill(165, 42, 42);
  rect(mouseX-3, 400, 65, 10); //hair


a functioning code was provided
The problem with my game here

yes, a command like

hatX = constrain(mouseX, 45, width-45) - 45;

can be replaced with if…

// concept: 
// hatX is left corner of HAT 
// hatX + hatW is right corner of HAT
// mouseX controlls the middle of the HAT

float hatW=90;
float hatX,hatXt;

void setup() {
  size(640,80);
}

void draw() {
  background(200,200);
  // way A
  hatX = constrain(mouseX, 45, width-45) - 45;
  // way B
  hatXt = mouseX;
  if ( hatXt > width -45 ) hatXt = width -45;
  if ( hatXt < 45 )        hatXt = 45;
  hatXt -= 45;
  // print
  println("mouseX "+mouseX+" hatX "+hatX+" hatXt "+hatXt);
  fill(200,0,0);
  rect(hatXt,50,hatW,10);
}

pls. no coding questions per message!

1 Like