Making a turn based game

So i'm making a turn based role-playing game for a project and i'm not exactly sure how to set some of it up. The game uses WASD to move and mouse functions to make decisions (start game, choose character, attack, use potion etc...). My problem is initiating battles based off where the character is positioned. Initially I was going to spawn 3 enemies in somewhat random areas of the screen and have the battle initiate when the character moves within a certain vicinity of any given enemy. Would this be possible? Or is there an easier way to initiate battles? Keep in mind, this is my very first year in processing and most of my class-mates are remaking pong or snake... Any ideas are greatly appreciated. I should also mention that I am using the currentScreen variable to make sure buttons can only be clicked and your character can only be moved when they are visible (when you are on the right screen). Here are some parts of my code that may be useful to know:

if (keyPressed) {
    if (battle == false) {
    if (key == 'w' || key == 'w') { 
      playerPosY = playerPosY - moveSpeed;
    } else if (key == 's' || key == 's') {
      playerPosY = playerPosY + moveSpeed;
    } else if (key == 'a' || key == 'a') {         
      playerPosX = playerPosX - moveSpeed;
    } else if (key == 'd' || key == 'd') {
      playerPosX = playerPosX + moveSpeed;
    }
  }
}



  if (currentScreen == 3) {
    if (ranEnemy1 == 1) {
      image(goblin, enemy1PosX, enemy1PosY, 80, 80);
    } else if (ranEnemy1 == 2) {
      image(skeleton2, 310, 510, 110, 110);
    } else if (ranEnemy1 == 3) {
      image(skeleton, 530, 360, 80, 80);
    }
    if (ranEnemy2 == 1) {
      image(goblin, 600, 330, 80, 80);
    } else if (ranEnemy2 == 2) {
      image(skeleton2, 720, 190, 110, 110);
    } else if (ranEnemy2 == 3) {
      image(skeleton2, 570, 160, 110, 110);
    }
    if (ranEnemy3 == 1) {
      image(goblin, 390, 480, 80, 80);
    } else if (ranEnemy3 == 2) {
      image(skeleton2, 620, 240, 110, 110);
    } else if (ranEnemy3 == 3) {
      image(skeleton2, 810, 420, 110, 110);
    }
  }

As you can see, I really had to complicate things already to randomize what kind of enemy would spawn and other related details. Some tips on how to simplify this would also be appreciated.

Tagged:

Answers

  • You need to select it after pasting and hit Ctrl+o.

  • Hope I did it right this time? lol

  • Good enough for me. When is your assignment due? Are there limitations on your code? Could you, for example, use arrays and objects?

  • It's due on the 27th and there aren't really any specified limitations but we haven't learned arrays or objects so I would just have no clue how to use them. I wouldn't mind learning though.

  • edited January 2016

    arrays or objects would simplify things. A lot. But let's leave this aside for the moment. Let's use arrays here.

    you wrote

    I was going to spawn 3 enemies in somewhat random areas of the screen and have the battle initiate when the character moves within a certain vicinity of any given enemy. Would this be possible?

    I suggest that you have a list of vicinity in an Array (this is before setup()! ):

      PVector[] vicinities = new PVector();       // where are the vicinities 
      boolean[] vicinityIsFighting; // does this vicinity hold a fight? all false. 
    

    (the two arrays are parallel in that sense that index 0 or 1 hold information on the 0 or 1st vicinity (position and if it's fighting), ok? Think of two shopping lists lying next to each other.)

    now when does the player enter the region ?

    Check this with dist() against the player position:

    loop over all vicinities

    for (int i..............) { 
        if( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {
             vicinityIsFighting[i]=true; 
        }
     }
    

    ok.

    What then?

    You already have currentScreen / state of the program. Very good.

    Similar to this I recommend a var gameMode what tells you if you currently fight.

    gameMode behaves similar to currentScreen in that it tells the program what to do (on a higher level).

    You might even give the gameModes names (constants)

    final int gameModeRunAround = 0; 
    final int gameModeFight = 1; 
    int gameMode = gameModeRunAround ; 
    

    so in the code above enter

    for (int i..............) { 
        if ( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {
             vicinityIsFighting[i]=true; 
             gameMode = gameModeFight; 
        }
     }
    

    So your program knows when to start a fight.

    do the fight. You have to program this... with dice...?

    When all enemies are dead (or the player) say gameMode = gameModeRunAround ; and vicinityIsFighting[fightIndex]=false; and fightIndex=-1; (with fightIndex storing the i from first loop).

    for (int i..............) { 
        if ( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {
             vicinityIsFighting[i]=true; 
             fightIndex=i;
             gameMode = gameModeFight; 
             break; // leave the loop, we only want one vicinity
        }
     }
    
  • Alright well thank you for the quick and awesome response. Like I said, this is almost all new to me so forgive me if I don't understand some things at first. So, one thing I don't understand is the beginning of the for loop - when you said for (int i..............) am I supposed to replace this with something else? You used the i variable throughout the code many times and i'm not exactly sure what it represents. I also don't fully understand how PVector vicinities works, how is the program going to know where the enemies are/decide where exactly the vicinities are? Again, sorry if I sound like a total noob.. I only started coding in November.

  • edited January 2016

    when you said for (int i..............) am I supposed to replace this with something else?

    Yes. It just loops over the array. So start by 0 increase by one until vicinities.length is reached.

    The idea of PVector is that it represents a point with x and y.

    PVector pv = new PVector(234,123);
    

    since it holds x and y you reach them with pv.x and pv.y (with the dot)

    with the array it's similar

    vicinities[0] = new PVector(234,123); // in setup() 
    vicinities[1] = new PVector(634,123);
    vicinities[2] = new PVector(34,323);
    

    just enter the locations where you want the battles to happen in setup()

    (and before setup() just the declaration as shown in last post)

    i represents the index of the array

    think of a shopping list, i is the line number.

    array is like a shopping list, with the line number (e.g. i) you reach the item (e.g. milk or vinity position / vector / PVector)

    you wrote

    how is the program going to know where the enemies are/decide where exactly the vicinities are?

    you have to enter the vicinities in setup() as shown above

    when the player meets a vicinity, the battle starts

    I suggest you spawn the enemies around the vicinity (in a circle) :

    float radius = random (110);   // radius with 110 is the max 
    
    float angle = random (360); // this is in degrees!!!!!!!
    
    // from here we calculate the enemy position 
    float xEnemy = vicinityIsFighting[fightIndex].x + radius * cos(radians(angle));  // radians converts degrees to radians 
    float yEnemy = vicinityIsFighting[fightIndex].y + radius * sin(radians(angle)); 
    
    // repeat for all enemies
    

    [EDITED]

  • for (int i..............) was a shortening of for (int i = 0; i<vicinities.length, i++) Read about for loops.

    i here is a counter and it is used to access the elements of array it goes each cycle 0 then 1 then 2 until it reaches the last element in the array. Read this topic.

    PVector is a variable that holds x and y and represents mathematical vector. If you don't know about using vectors in geometry, you may use 2 arrays instead for x and y. Read about PVector in reference and in very good book.

  • Well.. That kind of clears things up but this is still so confusing to me :/ I hate to ask this of you but I think what's confusing me is that I can't see the code together and in the right order.. Any chance you could put it all together including void setup, void draw and all that? If it would help, I can also paste more of my code, just let me know. Thanks so much for your help thus far

  • actually....

    I suggest you give it a try and post it....

    I mean, we wrote this is in setup()..... and that is before setup()... so I bet you can do it....

    try it.

    post it.

    and ask more.

    we are here

  • edited January 2016

    Well I can't really try it out at the moment, I'm in class but when I get home I'll see what I can do and I'll let you know.

  • you should implement this

    boolean booleanBattleSignIsOn = false; 
    int countBattleSign = 0; 
    final int maxCountBattleSign = 6; 
    String stringBattle = "B A T T L E"; 
    final int maxMillisWhenOn  = 780; // how ling ON
    final int maxMillisWhenOff = 200;  // how ling OFF
    int timerMillis=0;
    
    void setup()
    {
      size(900, 400);
      background(60);
      timerMillis=millis();
    }
    
    void draw() 
    {
      background(60); 
      showBattleSign();
    }
    
    void showBattleSign() {
    
      if (countBattleSign<maxCountBattleSign) {
        if (booleanBattleSignIsOn) {
          textSize(96);
          fill(255, 0, 0); // red       
          text (stringBattle, width/2-textWidth(stringBattle)/2, height/2);
        }
    
        if (booleanBattleSignIsOn) {
          if (millis()-timerMillis>maxMillisWhenOn) {
            booleanBattleSignIsOn = false;
            timerMillis=millis();
          }
        }
        else 
        {
          if (millis()-timerMillis>maxMillisWhenOff) {
            booleanBattleSignIsOn = true;
            countBattleSign++;
            timerMillis=millis();
          }
        }//else
      }//if
    }//func
    
    void keyPressed() {
      countBattleSign=0;
    }
    
  • Sure wish I knew what that did :-?

  • it just a flashing "BATTLE" for one second just shows that your battle begins ;-)

    just a small gimmick...

  • Sounds cool. Just gotta wait till I'm home before I can try it

  • I can't believe you asked us to put the code together for you just because you're in school now ;-)

    -1 point

  • I'm a noob I'm sorry :((

  • you're forgiven

  • So I haven't added everything yet but I added the variables and the for loop (including what Ater said) and I get a syntax error maybe missing a semicolon expecting SEMI, found "," i'm assuming this is just because im not very good at making for loops...

  • Use semicolons in your for loop:

    for( int i = 0 ; i < limit ; i++ ){
    
  • post your entire code please

  • Ok now it says consider adding "=" and when I run it it says IdentifierOrNew" to complete ReferenceExpression

  • edited January 2016

    All of it? it's 220 lines :P It's also not commented yet which I know is a big no no in processing but for reasons I cant really explain, i'm gonna have to comment it later

  • 220 lines is not that big really and I think everyone will be able to understand what you're doing even wiothout comments. Try to implement some of suggestions given and post it. The code just needs to be runnable.

  • edited January 2016

    This is pretty much my code when it worked fine, with a few of the suggestions added but I couldn't really get any of them to work xD Its quite buggy and I'm gonna have to fix things like movement in the future... Like how as soon as I implemented the title screen, my character got really laggy and the buttons don't always work which is strange... I'm working on getting the image links one sec.. image links: - I turned this one into a png - turned this one into a png too And for some reason I couldn't find warrior and title page so just replace those with something else

    PFont medieval;
    PFont basic;
    PImage soldier;
    PImage warrior;
    PImage mage;
    PImage titlePage;
    PImage goblin;
    PImage skeleton;
    PImage skeleton2;
    PVector vicinities = new PVector();
    boolean vicinityIsFighting;
    final int gameModeRunAround = 0; 
    final int gameModeFight = 1; 
    int gameMode = gameModeRunAround ; 
    int currentScreen = 1;
    int playerPosX = 100;
    int playerPosY = 350;
    int moveSpeed = 11;
    int Char;
    int hp;
    int atk;
    int speed;
    int ranEnemy1;
    int ranEnemy2;
    int ranEnemy3;
    
    
    void setup() {
      size(900, 670);
      background(0);
      frameRate(60);
      medieval = loadFont("PalatinoLinotype-BoldItalic-48.vlw");
      ranEnemy1 = int(random(1, 4));
      ranEnemy2 = int(random(1, 4));
      ranEnemy3 = int(random(1, 4));
    }
    
    void draw() {
      background(0);
    
      if (playerPosX > 820) {
        playerPosX = 820;
      } else if (playerPosX < -32) {
        playerPosX = -32;
      } else if (playerPosY < -32 ) {
        playerPosY = -32;
      } else if (playerPosY > 530) {
        playerPosY = 530;
      }
    
      //for (int i = 0; i<vicinities; length, i++) {
      //  if ( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {
      //    vicinityIsFighting[i]=true; 
      //    fightIndex=i;
      //    gameMode = gameModeFight; 
      //    break;
      //  }
      //}
    
    
      fill(0);
      soldier = loadImage("Soldier.png");
      warrior = loadImage("Warrior.png");
      mage = loadImage("Mage.png");
      titlePage = loadImage("title_page.jpg");
      goblin = loadImage("Goblin.png");
      skeleton = loadImage("Skeleton.png");
      skeleton2 = loadImage("Skeleton2.gif");
      basic = loadFont("MicrosoftYaHeiUI-48.vlw");
    
    
      if (currentScreen == 3) {
        if (ranEnemy1 == 1) {
          image(goblin, 450, 230, 80, 80);
        } else if (ranEnemy1 == 2) {
          image(skeleton2, 310, 510, 110, 110);
        } else if (ranEnemy1 == 3) {
          image(skeleton, 530, 360, 80, 80);
        }
        if (ranEnemy2 == 1) {
          image(goblin, 600, 330, 80, 80);
        } else if (ranEnemy2 == 2) {
          image(skeleton2, 720, 190, 110, 110);
        } else if (ranEnemy2 == 3) {
          image(skeleton2, 570, 160, 110, 110);
        }
        if (ranEnemy3 == 1) {
          image(goblin, 390, 480, 80, 80);
        } else if (ranEnemy3 == 2) {
          image(skeleton2, 620, 240, 110, 110);
        } else if (ranEnemy3 == 3) {
          image(skeleton2, 810, 420, 110, 110);
        }
        if (keyPressed) {
          if (key == 'w' || key == 'w') { 
            playerPosY = playerPosY - moveSpeed;
          } else if (key == 's' || key == 's') {
            playerPosY = playerPosY + moveSpeed;
          } else if (key == 'a' || key == 'a') {         
            playerPosX = playerPosX - moveSpeed;
          } else if (key == 'd' || key == 'd') {
            playerPosX = playerPosX + moveSpeed;
          }
        }
      }
    
    
    
    
    
    
    
      if (currentScreen == 2) {
        textFont(medieval, 54);
        fill(255, 0, 0);
        text("Choose Your Character!", 160, 100);
        image(soldier, 75, 230, 225, 325);
        image(warrior, 385, 250, 200, 245);
        image(mage, 615, 240, 275, 415);
    
    
        textFont(basic, 48);
        fill(#9D9C9C);
        text("Soldier", 105, 260);
        text("Warrior", 400, 260);
        text("Mage", 695, 260);
    
    
        textFont(basic, 26);
        text("hp: 35", 85, 590);
        text("atk: 5", 85, 625); 
        text("speed: 11", 85, 655);
        text("hp: 45", 375, 590);
        text("atk: 4", 375, 625); 
        text("speed: 9", 375, 655);
        text("hp: 25", 665, 590);
        text("atk: 6", 665, 625);
        text("speed: 12", 665, 655);
      }
      if (currentScreen == 1) {
        image(titlePage, 0, 0, 990, 670);
    
        textFont(medieval, 68);
        fill(255, 0, 0);
        text("Heroscape", 310, 120);
        fill(255, 0, 0);
        rect(395, 365, 120, 70);
        textFont(medieval, 48);
        fill(0);
        text("Begin", 395, 410);
      }
    
      if (Char == 1) {
        hp = 35;
        atk = 5;
        speed = 11;
        image(soldier, playerPosX, playerPosY, 100, 150);
      } else if (Char == 2) {
        hp = 45;
        atk = 4;
        speed = 9;
        image(warrior, playerPosX, playerPosY, 80, 120);
      } else if (Char == 3) {
        hp = 25;
        atk = 6;
        speed = 12;
        image(mage, playerPosX, playerPosY, 100, 215);
      }
    
      if (mousePressed) {
        if (currentScreen == 1) {
          if ((mouseX > 394) && (mouseX < 515) && (mouseY > 364) && (mouseY < 436)) {
            fill(0);
            rect(0, 0, 900, 670);
            currentScreen = currentScreen + 1;
          }
        }
      }
      if (mousePressed) {
        if (currentScreen == 2) {
          if ((mouseX > 98) && (mouseX < 270) && (mouseY > 229) && (mouseY < 555)) {
            fill(0);
            rect(0, 0, 900, 670);
            Char = 1;
            currentScreen = currentScreen + 1;
          }
        }
      }
    }
    
    
    void mousePressed() {
    
      if (currentScreen == 2) {
        if ((mouseX > 384) && (mouseX < 586) && (mouseY > 249) && (mouseY < 430)) {
          fill(0);
          rect(0, 0, 900, 670);
          Char = 2;
          currentScreen = currentScreen + 1;
        }
      }
    
    
      if (currentScreen == 2) {
        if ((mouseX > 614) && (mouseX < 891) && (mouseY > 239) && (mouseY < 656)) {
          fill(0);
          rect(0, 0, 900, 670);
          Char = 3;
          currentScreen = currentScreen + 1;
        }
      }
    }
    
  • all loadImage lines must be setup()

    since this belongs to the preparation part of the game, ok ?

  • edited January 2016

    same goes for loadFont

    your draw() got very long

    since you use currentScreen

    why not use functions and say

    void draw() {
      background(0);
    
      switch (currentScreen) {
    
      case currentScreenTitlePage:
        functionTitlePage(); 
        break; 
    
      case ChooseYourCharacter:
        functionChooseCharacter(); 
        break; 
    
      case currentScreenGame:
        functionGamePlay(); 
        break;
      }// switch
    }// func draw
    

    ==========================================================

    so the code would like this

    I corrected some other smaller stuff so it runs now

    PFont medieval;
    PFont basic;
    
    PImage soldier;
    PImage warrior;
    PImage mage;
    PImage titlePage;
    PImage goblin;
    PImage skeleton;
    PImage skeleton2;
    
    PVector vicinities[] = new PVector[3];
    boolean vicinityIsFighting[] = new boolean[3];
    int fightIndex=0;
    
    // we name the screens we have
    final int currentScreenTitlePage = 1;
    final int currentScreenChooseYourCharacter = 2;
    final int currentScreenGame      = 3; 
    int currentScreen = currentScreenTitlePage; // current screen 
    
    final int gameModeRunAround = 0; 
    final int gameModeFight = 1; 
    int gameMode = gameModeRunAround; 
    
    int playerPosX = 100;
    int playerPosY = 350;
    
    int moveSpeed = 11;
    int Char;
    int hp;
    int atk;
    int speed;
    
    int ranEnemy1;
    int ranEnemy2;
    int ranEnemy3;
    
    // ----------------------------------------------------
    
    void setup() {
      size(900, 670);
    
      background(0);
      frameRate(60);
    
      medieval = loadFont("PalatinoLinotype-BoldItalic-48.vlw");
      basic = loadFont("MicrosoftYaHeiUI-48.vlw");
    
      ranEnemy1 = int(random(1, 4));
      ranEnemy2 = int(random(1, 4));
      ranEnemy3 = int(random(1, 4));
    
      soldier = loadImage("Soldier.png");
      warrior = loadImage("Warrior.png");
      mage = loadImage("Mage.png");
      titlePage = loadImage("title_page.jpg");
      goblin = loadImage("Goblin.png");
      skeleton = loadImage("Skeleton.png");
      skeleton2 = loadImage("Skeleton2.gif");
    }
    
    void draw() {
      background(0);
    
      switch (currentScreen) {
    
      case currentScreenTitlePage:
        functionTitlePage(); 
        break; 
    
      case currentScreenChooseYourCharacter:
        functionChooseCharacter(); 
        break; 
    
      case currentScreenGame:
        functionGamePlay(); 
        break;
      }// switch
      //
    }// function draw()
    
    // ----------------------------------------------------
    
    void functionTitlePage() {
    
      text("titlePage", 20, 20, 990, 670);
    
      //  textFont(medieval, 68);
      fill(255, 0, 0);
      text("Heroscape", 310, 120);
      fill(255, 0, 0);
      rect(395, 365, 120, 70);
      //   textFont(medieval, 48);
      fill(0);
      text("Begin", 395, 410);
    
      if (mousePressed) {
    
        if ((mouseX > 394) && (mouseX < 515) && (mouseY > 364) && (mouseY < 436)) {
          fill(0);
          rect(0, 0, 900, 670);
          currentScreen = 2;
        }
      }
    }
    
    void functionChooseCharacter() {
    
      textFont(medieval, 54);
      fill(255, 0, 0);
      text("Choose Your Character!", 160, 100);
      image(soldier, 75, 230, 225, 325);
      image(warrior, 385, 250, 200, 245);
      image(mage, 615, 240, 275, 415);
    
    
      textFont(basic, 48);
      fill(#9D9C9C);
      text("Soldier", 105, 260);
      text("Warrior", 400, 260);
      text("Mage", 695, 260);
    
    
      textFont(basic, 26);
      text("hp: 35", 85, 590);
      text("atk: 5", 85, 625); 
      text("speed: 11", 85, 655);
      text("hp: 45", 375, 590);
      text("atk: 4", 375, 625); 
      text("speed: 9", 375, 655);
      text("hp: 25", 665, 590);
      text("atk: 6", 665, 625);
      text("speed: 12", 665, 655);
    
      // ----------------------
    
      if (Char == 1) {
        hp = 35;
        atk = 5;
        speed = 11;
        image(soldier, playerPosX, playerPosY, 100, 150);
      } else if (Char == 2) {
        hp = 45;
        atk = 4;
        speed = 9;
        image(warrior, playerPosX, playerPosY, 80, 120);
      } else if (Char == 3) {
        hp = 25;
        atk = 6;
        speed = 12;
        image(mage, playerPosX, playerPosY, 100, 215);
      }
    
      if (mousePressed) {
        if ((mouseX > 98) && (mouseX < 270) && (mouseY > 229) && (mouseY < 555)) {
          fill(0);
          rect(0, 0, 900, 670);
          Char = 1;
          currentScreen = 3;
        }
      }
    }
    
    void functionGamePlay() {
    
      if (playerPosX > 820) {
        playerPosX = 820;
      } else if (playerPosX < -32) {
        playerPosX = -32;
      } else if (playerPosY < -32 ) {
        playerPosY = -32;
      } else if (playerPosY > 530) {
        playerPosY = 530;
      }
    
      for (int i = 0; i<vicinities.length; i++) {
        if ( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {
          vicinityIsFighting[i]=true; 
          fightIndex=i;
          gameMode = gameModeFight; 
          println ("gameMode = gameModeFight");
          break;
        }
      }
    
    
      fill(0);
    
    
      if (ranEnemy1 == 1) {
        image(goblin, 450, 230, 80, 80);
      } else if (ranEnemy1 == 2) {
        image(skeleton2, 310, 510, 110, 110);
      } else if (ranEnemy1 == 3) {
        image(skeleton, 530, 360, 80, 80);
      }
      if (ranEnemy2 == 1) {
        image(goblin, 600, 330, 80, 80);
      } else if (ranEnemy2 == 2) {
        image(skeleton2, 720, 190, 110, 110);
      } else if (ranEnemy2 == 3) {
        image(skeleton2, 570, 160, 110, 110);
      }
      if (ranEnemy3 == 1) {
        image(goblin, 390, 480, 80, 80);
      } else if (ranEnemy3 == 2) {
        image(skeleton2, 620, 240, 110, 110);
      } else if (ranEnemy3 == 3) {
        image(skeleton2, 810, 420, 110, 110);
      }
      if (keyPressed) {
        if (key == 'w' || key == 'w') { 
          playerPosY = playerPosY - moveSpeed;
        } else if (key == 's' || key == 's') {
          playerPosY = playerPosY + moveSpeed;
        } else if (key == 'a' || key == 'a') {         
          playerPosX = playerPosX - moveSpeed;
        } else if (key == 'd' || key == 'd') {
          playerPosX = playerPosX + moveSpeed;
        }
      }
    }
    
    
    // -----------------------------------------
    
    void mousePressed() {
    
      if (currentScreen == 2) {
        if ((mouseX > 384) && (mouseX < 586) && (mouseY > 249) && (mouseY < 430)) {
          fill(0);
          rect(0, 0, 900, 670);
          Char = 2;
          currentScreen = currentScreen + 1;
        }
      }
    
    
      if (currentScreen == 2) {
        if ((mouseX > 614) && (mouseX < 891) && (mouseY > 239) && (mouseY < 656)) {
          fill(0);
          rect(0, 0, 900, 670);
          Char = 3;
          currentScreen = currentScreen + 1;
        }
      }
    }
    //
    
  • edited January 2016

    Alright I can arrange that Edit: I put them all in setup and the lag is gone :) thanks!

  • in the meantime I made a new version for you, see above

  • you need this

    vicinities[0] = new PVector(234,123); // in setup() 
    vicinities[1] = new PVector(634,123);
    vicinities[2] = new PVector(34,323);
    
  • Hmm.. for some reason when I run it there is a problem with the medieval font that I used. Could not run the sketch (target VM failed to initialize). Also, should I keep the comments such as:

    // switch
      //
    // function draw()
    

    or are they not important?

  • don't need the comments

    it's better to use createFont instead of loadFont

    just place ,45); at the end of createFont

  • edited January 2016

    Ok so I fixed the font issue fairly easily but now when I choose a character in game, the screen goes black and I get target VM failed to initialize :( i'm starting to think I should have done an easier game xD The error highlights this line btw :

    if ( dist (playerPosX, playerPosY, vicinities [i].x, vicinities [i].y) < 30 ) {

    Edit: it also says NullPointerException if that helps

  • edited January 2016

    you need this

    vicinities[0] = new PVector(234,123); // in setup() 
    vicinities[1] = new PVector(634,123);
    vicinities[2] = new PVector(34,323);
    

    in setup()

  • you need to move this

    if (Char == 1) {
        hp = 35;
        atk = 5;
        speed = 11;
        image(soldier, playerPosX, playerPosY, 100, 150);
      } else if (Char == 2) {
        hp = 45;
        atk = 4;
        speed = 9;
        image(warrior, playerPosX, playerPosY, 80, 120);
      } else if (Char == 3) {
        hp = 25;
        atk = 6;
        speed = 12;
        image(mage, playerPosX, playerPosY, 100, 215);
      }
    

    into functionGamePlay() I think

  • edited January 2016

    Yup I just figured that out. Now I need to make it so that a battle starts whenever the character goes near en enemy. Right now it starts a battle when it goes to certain areas on screen. Is this going to be difficult? If it's complicated I can simply make the enemies spawn in specific locations every time

  • edited January 2016

    no, it's not hard .

    just enter the places of the enemies here:

    vicinities[0] = new PVector(234,123); // in setup() 
    vicinities[1] = new PVector(634,123);
    vicinities[2] = new PVector(34,323);
    

    meaning: change the numbers in the () brackets which are x,y

  • Yeah I understand that, my problem is that I want to randomize what kind of enemy spawns in each of those 3 spots. What do you think would be the easiest way to do this?

  • I'm off now

  • Answer ✓

    similar to Char=1

    have

    enemyChar1 = 0 or 1 or 2

    enemyChar2 = 0 or 1 or 2

    enemyChar3 = 0 or 1 or 2

    set those via random

    then act accordingly and display a different image (as you did with if(Char==1....)

  • Well thanks so much for your help! I feel like I should be crediting you at the end of my game :P

  • edited January 2016

    The easiest way to do it would be to learn how to do Object Oriented Programming.

    That way, you can define a "Combat Zone" object that HAS A position (which would be a PVector), and HAS An array of Enemy objects. And then you could define and "Enemy" object to keep track of that enemies's relative position in the combat zone (PVector), as well as it's health (int), max health (int), level (int), name (String), attack patterns (functions), type (int), etc, etc, etc.

  • Guess ill look into it :) thanks for your help too :D

  • Here's a start on an enemy (well, I called it a foe) class:

    class Foe {
      String name;
      int type;
      int level;
      int health;
      int max_health;
      PVector rel_pos;
      Foe(String iname, int itype, int ilevel){
        name = iname;
        type = itype;
        level = ilevel;
        max_health = 10 * level;
        health = max_health;
        rel_pos = new PVector(0,0);
      }
      void draw(){
        pushMatrix();
        translate(rel_pos.x,rel_pos.y);
        if(type == 0 ){ // Skeleton
          noStroke();
          fill(255);
          ellipse(0,0,20,20);
          fill(0);
          ellipse(-5,-5,3,3);
          ellipse( 5,-5,3,3);
          rect(-5,4,10,2);
        }
        if(type == 1 ){ // Zombie
          noStroke();
          fill(0,128,0);
          ellipse(0,0,20,20);
          fill(0);
          ellipse(-5,-5,3,3);
          ellipse( 5,-5,3,3);
          rect(-5,4,10,2);
        }
        fill(255,255,0);
        textAlign(CENTER);
        text(name + "\n(Level " + level + ")\n" + health + "/" + max_health,0,24);
        popMatrix();
      }
    }
    
    Foe foe0 = new Foe( "Skeleton", 0, 10 );
    Foe foe1 = new Foe( "Zombie", 1, 5 );
    
    
    void setup(){
      size(600,400);
      foe1.rel_pos.x = -60;
    }
    
    void draw(){
      background(64);
      translate(width/2,height/2);
      foe0.draw();
      foe1.draw();
    }
    

    Really study this example. It's going to save you a ton of time.

  • edited February 2016 Answer ✓

    approach without objects:

    it's important that those numbers match with where the enemies must stand later:

    vicinities[0] = new PVector(234,123); // in setup() 
    vicinities[1] = new PVector(634,123);
    vicinities[2] = new PVector(34,323);
    

    now, next:

    this is a variable :

    int a = 1;

    it is a box named a that holds a value 1. it is allowed to hold only type int (these are integer numbers)

    now PVector:

    PVector b = new PVector (23, 21);
    

    PVector is a special box for a point. Since a point needs x and y, the box has two chambers / compartements with a value each. To get those values (x=23, y=21) we say b.x and b.y.

    try it:

    this is a complete sketch (entire sketch)

    PVector b = new PVector (23, 21);
    
    println(b.x); 
    

    Nice!

    ;-)

  • edited February 2016

    now we can like we have a var a also a list / array of vars

    the array is called c

    int [] c = new int [3];
    
    c[0] = 17;
    

    so it's a shopping list and at position/ line number 0 we hold the value 17

    smilar we can make a array from PVector

    PVector[] d = new PVector [3];
    

    list has 3 lines (each holds a PVector)

    d = new  PVector(423,189);
    
    println(d[0].x);
    

    now since you can for-loop over an array and do something with each item in a list, a list or array is very powerful tool.

Sign In or Register to comment.