Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Buy OSRS Gold

Sell OSRS Gold
Deltac0

[TUT] [PAINT] ★★★ Advanced Paint Tutorial - Calculations, images & more! ★★★

Recommended Posts

★★★ Advanced Paint Tutorial ★★★



So, you made a script and now you want to know how much gp/h or xp/h it makes for you?
Or perhaps you already made a paint for your script, but you just think it's too ugly with the white text everywhere?
 
Here's a few examples of different paints (all rights to the image owners):
 
diLPJrJ.png



Table of contents

1. Adding a paint

2. Let's edit the font & color

3. Calculations & time etc.

4. Adding image background & little style to your paint

5. Mouse paint [COMING SOON]



1. Adding a paint
Ok, let's add a paint to your script.

Import these:
 

import java.awt.Color; //to get different colors
import java.awt.Font; //to change font
import java.awt.Graphics; //paint
import java.awt.Graphics2D; //needed for the image
import java.awt.Image; //same as above
import java.io.IOException; //this is needed for the loading of the image
import java.net.URL; //same as above

import javax.imageio.ImageIO; //same as above

import org.tribot.api.Timing; //to calculate time things
import org.tribot.api2007.Skills; //to get XP/levels
import org.tribot.script.interfaces.Painting; //for onPaint()


First we need to change something from your script. Find a line looking about like this:

public class fisher extends Script {

 
and add before the bracket "implements Painting"
 

public class fisher extends Script implements Painting {

 
Now your IDE will probably tell we need to add an unimplemented method called onPaint().
I like to add onPaint() at the end of script:
 

public class fisher extends Script implements Painting {
    public void run() {
        //DO SOMETHING
    }
 
    @Override
    public void onPaint(Graphics g)  {
    }

}

 
 
Great! Now we can actually draw something to the screen:
 

public class fisher extends Script implements Painting {
    public void run() {
        //DO SOMETHING
    }

    public void onPaint(Graphics g)  {
        g.drawString("Some text here?", 300, 300);
    }
}

The text you want to display is in quotes, the 300s are the coordinates on the screen, (x,y).
 

eJ6aTSE.png

 
 
 
 
 
2. Let's edit the font & color
Ok now let's edit the look of the text. You can of course change the font, styling and the size.
Add something like this:

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
    g.setFont(font);
    g.drawString("Some text here?", 300, 300);
}


Let's edit the color. Colors are made in RGB.

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
    g.setFont(font);
    g.setColor(new Color(200, 0, 200));
    g.drawString("Some text here?", 300, 300);
}

GWP1Clo.png

 
 
 
 
3. Calculations & time etc.
So you want to display the runtime for example? Before your onPaint() method, add something like this:

private static final long startTime = System.currentTimeMillis();
Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
    g.setFont(font);
    g.setColor(new Color(200, 0, 200));
    g.drawString("Some text here?", 300, 300);
}

 
 
and on your onPaint() add this:

private static final long startTime = System.currentTimeMillis();
Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
    long timeRan = System.currentTimeMillis() - startTime;
    g.setFont(font);
    g.setColor(new Color(200, 0, 200));
    g.drawString("Some text here?", 300, 300);
}

 
 
Now every time your onPaint() method runs, it calculates the runtime, so let's print it on the screen:
 
 

private static final long startTime = System.currentTimeMillis();
Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
    long timeRan = System.currentTimeMillis() - startTime;
    g.setFont(font);
    g.setColor(new Color(200, 0, 200));
    g.drawString("Runtime: " + timeRan, 300, 300);
}

 
Now you'll notice that the time looks pretty weird. Well, it's in milliseconds so lets convert it:
 
 

private static final long startTime = System.currentTimeMillis();

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {

long timeRan = System.currentTimeMillis() - startTime;
g.setFont(font);

g.setColor(new Color(200, 0, 200));
g.drawString("Runtime: " + Timing.msToString(timeRan), 300, 300);
}

 
 

BuApbtr.png

And now we can see for how long the script has ran.
Let's add something else... Current lvl for example:
 

private static final long startTime = System.currentTimeMillis();

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {

long timeRan = System.currentTimeMillis() - startTime;
int currentLvl = Skills.getActualLevel("Fishing");
g.setFont(font);

g.setColor(new Color(200, 0, 200));
g.drawString("Runtime: " + Timing.msToString(timeRan), 300, 300);
g.drawString("Current lvl: " + currentLvl, 200, 100);
}

 
Notice I used coordinate (200, 100) this time:
 
 

MKPju05.png

 
 
Let's add gained levels and a few xp things:
 

private static final long startTime = System.currentTimeMillis();
private int startLvl = Skills.getActualLevel("Fishing");
private int startXP = Skills.getXP("Fishing");


Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {

long timeRan = System.currentTimeMillis() - startTime;
int currentLvl = Skills.getActualLevel("Fishing");
int gainedLvl = currentLvl - startLvl;
int gainedXP = Skills.getXP("Fishing") - startXP;
int xpToLevel = Skills.getXPToNextLevel("Fishing");
int xpPerHour = (long)(gainedXP * 3600000 / timeRan);


g.setFont(font);

g.setColor(new Color(44, 44, 44));
g.drawString("Runtime: " + Timing.msToString(timeRan), 300, 370);
g.drawString("Current lvl: " + currentLvl + " (+" + gainedLvl + ")", 300, 390);
g.drawString("XP Gained: " + gainedXP, 300, 410);
g.drawString("XP TNL: " + xpToLevel, 300, 430);
g.drawString("XP/H: " + xpPerHour, 300, 450);

}

 
 
Notice I also changed the color and coordinates to make the paint look better:
 
 

s3ept76.png

 
 
Starting to look a little better, huh?
 
 
 
4. Adding image background & little style to your paint
 
So, you wanna make your paint look superdupercool? Well, let's add some images to it.
First you should edit your code like this:
 

private Image getImage(String url) {
try {
return ImageIO.read(new URL(url));
} catch(IOException e) {
return null;
}
}
private final Image img = getImage("your_img_url");


private static final long startTime = System.currentTimeMillis();
private int startLvl = Skills.getActualLevel("Fishing");
private int startXP = Skills.getXP("Fishing");

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {
 
Graphics2D gg = (Graphics2D)g;
gg.drawImage(img, 0, 300, null);

 
long timeRan = System.currentTimeMillis() - startTime;
int currentLvl = Skills.getActualLevel("Fishing");
int gainedLvl = currentLvl - startLvl;
int gainedXP = Skills.getXP("Fishing") - startXP;
int xpToLevel = Skills.getXPToNextLevel("Fishing");
int xpPerHour = (long)(gainedXP * 3600000d / timeRan);

g.setFont(font);

g.setColor(new Color(44, 44, 44));
g.drawString("Runtime: " + Timing.msToString(timeRan), 300, 370);
g.drawString("Current lvl: " + currentLvl + " (+" + gainedLvl + ")", 300, 390);
g.drawString("XP Gained: " + gainedXP, 300, 410);
g.drawString("XP TNL: " + xpToLevel, 300, 430);
g.drawString("XP/H: " + xpPerHour, 300, 450);
}

 
 
Replace "your_img_url" with your image url and edit the coordinates so it looks good. I used coordinate (0, 300) as you can see.
 
I made these images for my tutorial in just a few minutes with Photoshop:
 
DqEsuRc.png

eeTP0S9.png
 
Finally I changed the text color to light grey and aligned the image correctly:
 
 

private Image getImage(String url) {
try {
return ImageIO.read(new URL(url));
} catch(IOException e) {
return null;
}
}
private final Image img = getImage("http://i.imgur.com/DqEsuRc.png");

private static final long startTime = System.currentTimeMillis();
private int startLvl = Skills.getActualLevel("Fishing");
private int startXP = Skills.getXP("Fishing");

Font font = new Font("Verdana", Font.BOLD, 14);
public void onPaint(Graphics g) {

Graphics2D gg = (Graphics2D)g;
gg.drawImage(img, 0, 304, null);

long timeRan = System.currentTimeMillis() - startTime;
int currentLvl = Skills.getActualLevel("Fishing");
int gainedLvl = currentLvl - startLvl;
int gainedXP = Skills.getXP("Fishing") - startXP;
int xpToLevel = Skills.getXPToNextLevel("Fishing");
int xpPerHour = (long)(gainedXP * 3600000d / timeRan);

g.setFont(font);

g.setColor(new Color(200, 200, 200));
g.drawString("Runtime: " + Timing.msToString(timeRan), 300, 370);
g.drawString("Current lvl: " + currentLvl + " (+" + gainedLvl + ")", 300, 390);
g.drawString("XP Gained: " + gainedXP, 300, 410);
g.drawString("XP TNL: " + xpToLevel, 300, 430);
g.drawString("XP/H: " + xpPerHour, 300, 450);
}

 
 
 
And the final result:
 

WrSl1bp.png




6. Antialiasing
I already posted this to snippets but I think it's good to add it here too:
Just a quick trick to make your paint look smoother. This works with shapes & text.

bnkoMhc.png
Antialiased is on the right.
 

I assume you already have added a paint. I think onPaint() method only accepts Graphics as an arg0, so you need to "convert" it to Graphics2D in order to make antialiasing work:



public void onPaint(Graphics g) {
    Graphics2D gg = (Graphics2D) g;
    gg.drawString("Runtime: " + Timing.msToString(timeRan), 300, 370);
}


before your onPaint() add this

private final RenderingHints aa = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);


and inside your onPaint() add this

gg.setRenderingHints(aa);

 
Also import any needed stuff like java.awt.Graphics2D and java.awt.RenderingHints.
 
 
Finished code:

private final RenderingHints aa = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
public void onPaint(Graphics g) {
    Graphics2D gg = (Graphics2D) g;
    gg.setRenderingHints(aa);
    gg.drawString("Runtime: " + Timing.msToString(timeRan), 300, 370);
}

Edited by Deltac0
  • Like 7

Share this post


Link to post
Share on other sites

When I use the exact same function for exp/hour as you, I get negative numbers after a certain amount of time. Like: -3495xp/hour. Do you know what could cause this? I'm thinking about the use of int, but when I try long, it's just the same.

Share this post


Link to post
Share on other sites

Good stuff.

But also experiencing the same problem:

When I use the exact same function for exp/hour as you, I get negative numbers after a certain amount of time. Like: -3495xp/hour. Do you know what could cause this? I'm thinking about the use of int, but when I try long, it's just the same.

Edited by KMJT

Share this post


Link to post
Share on other sites

Amazing tutorial! Followed step by step and now i'm a paint master :D

 

Found out a typo though..

 

long xpPerHour = (long)(gainedXP * 3600000 / timeRan);

 

should be

 

long xpPerHour = (long)(gainedXP * (3600000 / timeRan));

 

or it will say weird numbers like -41, 421...

 

Actually nevermind. It still shows like half of the real xp it should get in hour

Edited by thunderkill

Share this post


Link to post
Share on other sites

To anyone who uses this tutorial, two things to note when calculating XP per hour (Or anything per hour)

 

In this code where it says 

int xpPerHour = (long)(gainedXP * 3600000 / timeRan);

this will give you negative numbers for xpPerHour(because gainedXp  * 3600000 will very quickly go over 2^31 -1 and give big negative numbers messing up your calculations, so you shuold write it like this: 

long xpPerHour = (gainedXP * (3600000 / timeRan));

i see no reason to leave xp Per hour as an int aswell

 

However, if you look closely at these calculations, you will realize that it is slightly off, and it starts to get more and more wrong the longer your script runs, this is because we are using integer division.. So, for it to do the rounding last, we will now write it like this: 

long xpPerHour = (long)(gainedXP * (3600000 / (double)timeRan));

By first casting one of the numbers in the fraction to a double, it will now return a decimal that we can then switch back to an integer and removing any rounding issues.

 

 

Hope this helps!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Our picks

    • Hi everyone,

      I'd like to thank everyone for their patience in this transition period. Since last week, we've worked out the remaining bugs with this integration.

      Some users have still been having issues with connecting their forums account to their Auth0 account. To resolve this, we've imported all forums accounts into Auth0.

      Unfortunately, the accounts which were imported today were using an unsupported password hashing algorithm. Hence, random passwords were set during the import.

      What does this mean for me?

      If you've previously linked your forums account to your Auth0 account, you don't have to do anything. Nothing changes for you.


      If you haven't logged in via our new login yet,

      Try logging in with your forums email address and the last password you used


      If you are unable to login, please use the "Forgot password" tool on the login page:
      Follow the instructions to reset your password
       
      • 1 reply
    • Hello everyone,

      Last week we tried to roll out Auth0 Login, but we lost that battle. Now it's time to win the war!

      Important changes

      When logging into the client, you'll now have to enter your Auth0 account credentials instead of your forums credentials

      Note: 2FA is still handled through your forums account (for the time being)



      Changes for existing users

      You'll have to link your Auth0 account to your forums account here: https://tribot.org/forums/settings/login/?service=11


      Auth0 accounts have been created for most existing users. Please use your forums email address and password to login.



      Important notes

      Make sure to verify your email address upon creating a new Auth0 account


      When we mention your Auth0 account, we mean your account used for auth.tribot.org as displayed below
      • 71 replies
    • To better support the upcoming changes (TRiBot X, new repository), we're switching our login handler to Auth0. Instead of logging in with the standard form, you'll now be required to login through our Auth0 application.

      All existing accounts which have been used within approximately the past year have been imported into Auth0 using the same email and password combination which has been stored on the forums.

      What does this mean for users?

      Your account credentials are now even more securely stored


      You'll be able to login via Facebook, Google, and others in the future


      Is there anything users have to do differently now?

      Existing users: You'll have to login with the standard login, open your Account Settings, then link your Auth0 account


      New users: You'll be redirected to our Auth0 app (auth.tribot.org) where you'll be able to create an account


      Why was this change made?

      The new apps we are creating (such as the new repository) aren't able to use the forums to handle user logins


      To centralize all user accounts in one area


      To ensure that the client login doesn't go down when the forums are having problems


      To speed up our development


      Other considerations

      There's no documentation or official support for using Invision Community combined with Auth0, so there are still a few kinks we're working out


      We're in the works of creating an account management panel specifically for Auth0 accounts (ETA August)


      It's not possible to change email addresses for the time being (this will be resolved this August)


      Changing passwords is a weird process for the time being. To change your password, you'll have to use the "Don't remember your password" tool on the Auth0 login page
      • 11 replies
    • Over the past month, we've been working hard on TRiBot's new repository - a much needed update. This change has been deemed necessary for TRiBot X, and will allow us to really speed up development of all aspects of TRiBot.

      Today we are going to share what we've been working on!


      Now you must be wondering what kind of features the new repository will have.... well, you'll have to be patient for a little while longer. We're still figuring out various technical aspects so we can't provide answers to all possible questions. We're also focusing on development rather than writing about it so that everyone can get access to our latest developments at lightning speed. I will however answer a few users' questions.

      We're planning on a release of this early to mid August, giving users some goodies before TRiBot X's release.

      Thank you all for being patient. I hope everyone is excited as much as I am!
      • 17 replies
    • Over the past few months, I’ve been working diligently on a new project - TRiBot X. Everything has been written from the ground up, with all of the best practices of software engineering. Every aspect of TRiBot has been re-imagined to support three main goals: flexibility, useability, and reliability.
        • Like
      • 50 replies
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...