Newb- AI for 2d Games - player object to be recognized by physics engine

hello sketchers, I am a newb here, newb in programming. I have a project for one of my classes, and I am using Quarks AI for 2D Games to get a basic functionality. I am unsure how many people have used this library yet, but, I am trying to figure out how to get my ‘motor’ to get recognized by the physics engine.
programming is not my second language (artist!!), so any ideas would be beneficial…

import g4p_controls.*;
import game2dai.*;
import game2dai.entities.*;
import game2dai.entityshapes.*;
import game2dai.entityshapes.ps.*;
import game2dai.fsm.*;
import game2dai.graph.*;
import game2dai.maths.*;
import game2dai.steering.*;
import game2dai.utils.*;



// GettingStarted_01, both of these are required to run the world
World world;
StopWatch sw;
MovingEntity mover0;
Motor motor;
//set up bools for keyboard:
boolean[] keys;

public void setup() {
  frameRate (45);
  size(480, 320);
  world = new World(width, height);
  sw = new StopWatch();
  motor = new Motor();
  
  // Other setup code here

  // Create the mover
  mover0 = new MovingEntity(
      new Vector2D(width/2, height/2), // position
      32,                              // collision radius
     new Vector2D(50, 0),            // velocity
      40,                              // maximum speed
      new Vector2D(1, 1),              // heading
      1,                               // mass
      120,                             // turning rate
      200                              // max force
      );
 
  PersonPic view = new PersonPic(this);
  view.showHints(Hints.HINT_COLLISION | Hints.HINT_HEADING | Hints.HINT_VELOCITY);
  mover0.renderer(view);
  Domain d = new Domain(60, 60, width-60, height-60);
  mover0.worldDomain(d, SBF.REBOUND);
  world.add(mover0); 
  
// set up keys boolean, to be a,w,d,SPACE
  keys = new boolean[4]; 
  for (int i = 0; i < keys.length; i++){
    keys[i] = false;
 }// end of keys

  sw.reset(); // should always be last line in setup

}// end of setup

public void draw() {
  double elapsedTime = sw.getElapsedTime();
  world.update(elapsedTime);
  background(200, 255, 200);
  //make the movers constraint area visible
  Domain d = mover0.worldDomain();
  fill(255, 200, 200);
  noStroke();
  rect((float)d.lowX, (float)d.lowY, (float)d.width, (float)d.height);
  motor.display();
  motor.move();
  
  world.draw(elapsedTime);

}// end of draw

void keyPressed(){
  if (key == 'w' || key == 'W')
    keys[2] = true;
  if (key == 's' || key == 'S')
    keys[3] = true;
  if (key == 'a' || key == 'A')
    keys[0] = true;
  if (key == 'd' || key == 'D')
    keys[1] = true;
}// end of key pressed

void keyReleased(){
  if (key == 'w' || key == 'W')
    keys[2] = false;
  if (key == 's' || key == 'S')
    keys[3] = false;  
  if (key == 'a' || key == 'A')
    keys[0] = false;
  if (key == 'd' || key == 'D')
    keys[1] = false;

}// end of key release

class Motor{
 
   PVector pos;
   PVector vel;
   PVector gravity;
   float rotation;
   int x;
   int y;
   int r = 8;
   
 
  Motor(){
    pos = new PVector(width/2, height/2);
    vel = new PVector(5, 5);
    gravity = new PVector(0, 0.01);
    rotation = 0;
  
  };

 void move(){
      //vel.add(gravity);
      //pos.add(gravity);
      //pos.add(vel);
    if (keys[0]) { //a
      pos.x = pos.x - 3;
    }
    if (keys[1]) { //d
      pos.x = pos.x + 3;
    }      
    if (keys[2]) {
      pos.y = pos.y - 3;
    }
    if (keys[3]) {
      pos.y = pos.y + 3;
    }    
    if (pos.y < 0) pos.y = 0;
    if (pos.y + 80 > height) pos.y = height - 80;    
    if (pos.x > width+ r || pos.x < 0-r) pos.y = 190;
    
    }// end of class
    
    void display(){
      fill(255);
      stroke(255,0,255);
      rect(pos.x, pos.y, 32, 32);
  
    }// end of display

}// end of class
1 Like

Before creating code you need to be very clear about what you are trying to achieve. In your code snippet you are adapting one of the library examples by adding your own entity, Motor. At the moment Motor objects cannot be controlled by the library so I assume you want to provide all the functionality to control it i.e. a ‘physics engine’. So the problem is not related to the library so the answer does not require knowledge of the library.

So working on that premise I have modified your code to update the position based on velocity (pixels per second) and gravity (pixels per second per second). See the update method in Motor which is called in draw()

import g4p_controls.*;
import game2dai.*;
import game2dai.entities.*;
import game2dai.entityshapes.*;
import game2dai.entityshapes.ps.*;
import game2dai.fsm.*;
import game2dai.graph.*;
import game2dai.maths.*;
import game2dai.steering.*;
import game2dai.utils.*;



// GettingStarted_01, both of these are required to run the world
World world;
StopWatch sw;
MovingEntity mover0;
Motor motor;
//set up bools for keyboard:
boolean[] keys;

public void setup() {
  frameRate (45);
  size(480, 320);
  world = new World(width, height);
  sw = new StopWatch();
  motor = new Motor();

  // Other setup code here

  // Create the mover
  mover0 = new MovingEntity(
    new Vector2D(width/2, height/2), // position
    32, // collision radius
    new Vector2D(50, 0), // velocity
    40, // maximum speed
    new Vector2D(1, 1), // heading
    1, // mass
    120, // turning rate
    200                              // max force
    );

  PersonPic view = new PersonPic(this);
  view.showHints(Hints.HINT_COLLISION | Hints.HINT_HEADING | Hints.HINT_VELOCITY);
  mover0.renderer(view);
  Domain d = new Domain(60, 60, width-60, height-60);
  mover0.worldDomain(d, SBF.REBOUND);
  world.add(mover0); 

  // set up keys boolean, to be a,w,d,SPACE
  keys = new boolean[4]; 
  for (int i = 0; i < keys.length; i++) {
    keys[i] = false;
  }// end of keys

  sw.reset(); // should always be last line in setup
}// end of setup

public void draw() {
  double elapsedTime = sw.getElapsedTime();
  world.update(elapsedTime);
  background(200, 255, 200);
  //make the movers constraint area visible
  Domain d = mover0.worldDomain();
  fill(255, 200, 200);
  noStroke();
  rect((float)d.lowX, (float)d.lowY, (float)d.width, (float)d.height);
  motor.move();
  motor.update((float) elapsedTime);
  motor.display();

  world.draw(elapsedTime);
}// end of draw

void keyPressed() {
  if (key == 'w' || key == 'W')
    keys[2] = true;
  if (key == 's' || key == 'S')
    keys[3] = true;
  if (key == 'a' || key == 'A')
    keys[0] = true;
  if (key == 'd' || key == 'D')
    keys[1] = true;
}// end of key pressed

void keyReleased() {
  if (key == 'w' || key == 'W')
    keys[2] = false;
  if (key == 's' || key == 'S')
    keys[3] = false;  
  if (key == 'a' || key == 'A')
    keys[0] = false;
  if (key == 'd' || key == 'D')
    keys[1] = false;
}// end of key release

class Motor {

  PVector pos;
  PVector vel;
  PVector gravity;
  float rotation;
  int x;
  int y;
  int r = 8;


  Motor() {
    pos = new PVector(width/2, height/2);
    vel = new PVector(5, 5);
    gravity = new PVector(0, 0.01);
    rotation = 0;
  };

  void move() {
    //vel.add(gravity);
    //pos.add(gravity);
    //pos.add(vel);
    if (keys[0]) { //a
      pos.x = pos.x - 3;
    }
    if (keys[1]) { //d
      pos.x = pos.x + 3;
    }      
    if (keys[2]) {
      pos.y = pos.y - 3;
    }
    if (keys[3]) {
      pos.y = pos.y + 3;
    }    
    if (pos.y < 0) pos.y = 0;
    if (pos.y + 80 > height) pos.y = height - 80;    
    if (pos.x > width+ r || pos.x < 0-r) pos.y = 190;
  }// end of class

  void display() {
    fill(255);
    stroke(255, 0, 255);
    rect(pos.x, pos.y, 32, 32);
  }// end of display

  void update(float et) {
    vel.add(gravity);
    pos.x += vel.x * et;
    pos.y += vel.y * et;
  }
}// end of class
1 Like

I see how the motor object now is affected by gravity, thanks for that input.
What I want to accomplish is to add collision to the motor object. I am struggling with something that is probably right in front of my face, and just need to test ideas out.
as always I appreciate the input, I apologize for any misuse of this forum. I am still learning, been at programming for all of 6 weeks total time… its a struggle moving from art into this kind of thinking.

There was no misuse.

Unless you need autonomous agents then the AI library might be a sledge hammer to crack a nut.

You might also consider the Sprites library as it has several collision detection methods.

1 Like

Peter let me rephrase my question as I asked the wrong thing.
what I want to do is use your AI system to control my enemies, I know I can lock them in the x-coordinate but still use gravity to pull them off platforms when chasing the player object. the platforms will use the Buildings and the enemies will use Vehicles. I’m making the assumption that I can make my player-controlled object, the ‘motor’ object, a movingEntity through your system there for implementing the collision and the detection system that you’ve created with your AI system. If I can figure that out, I can implement a projectile the player fires at the enemy AI.

I will look at your Sprites library and see what i can get from it. I came to your library after trying to figure out Box2D for processing. this AI library makes more sense to me. I will bug you more in a bit…

Yes your Motor class would need to inherit from MovingEntity and then you can use player input to modify its velocity etc.

You would use vehicles for the enemies and the projectiles.

The library also provides a FSM (finite state machine) which means that your entities can have state.
So an enemy might have several states e.g. is-on-platform, is-in-freefall, is-jumpimg etc. The Cat and Mouse example uses FSM.

I got some things to work decent enough!
Curious question, does the AI library have your Sprite tools implemented already? I get “Stopwatch/Domain/ are ambiguous” errors all over the place when I have both libraries in

Both libraries have some common utility classes such as timers (Stopwatch) and game areas (Domain). I didn’t anticipate the two libraries would be used at the same time since the AI library does much the same but with a lot more bells and whistles.