so I am trying to make lorries move towards an entity (site) only if it meets certain criteria (using "ifs").
So the plan is that I have 2 lorries (created inside an array in case I want to add more in the future and for easier manipulation in the script), and they are originally placed at a concrete plant in the center. The user makes a site appears on the screen when he clicks (other sites are added at every click).
There are three criteria in order to choose which truck to move to the site when a site is created:
If the truck is available (not in delivery, delivery = deliv);
If the truck as enough cement (each lorry start with 2 units (u), and every time it goes to a site, it looses 1 unit. When it reaches 0 it needs to go back to the concrete plant to "fill up")
The truck that is the nearest (by checking the distance);
I have created a series of loops to check these conditions in the draw function. Starting by saying that if the lorries are available, then check if it has units of cement. If no then destinations are changed to concreteplant, if yes then calculate the distance between the lorry and the site.
The I have another loop that will allow to select the lorry with the smallest distance (smallD).
Another loop to say to take that lorry with the smallest distance and assign the destination as site and go to the next site etc + setting delivery to true as it is become unavailable (so it doesnt change direction while it is going to the first site when a new site is clicked).
The I have created a final loop to say to update the lorry which means to move it, display it and checked progress (functions in the lorry class).
This is my script:
/*preload = "factory_12.png";*/
/*preload = "sign.png";*/
/*preload = "simple_truck.png";*/
ArrayList<Lorry> lorries;
ArrayList<Site> sites;
PImage concretePlant;
PFont aFont;
int xCoord;
int yCoord;
int siteSize = 30;
int siteNumber = 0;
void setup() // What is called once at the beginning
{
size (500, 500);
concretePlant = loadImage("factory_12.png");
aFont = createFont("IndustrialRevolution-Regular", 12);
textFont(aFont);
xCoord = int(width/2);
yCoord = int(height/2);
//Creating empty Array List where store sites objects
sites = new ArrayList<Site>();
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
//storing lorries
lorries = new ArrayList<Lorry>();
lorries.add(new Lorry(xCoord, yCoord));
lorries.add(new Lorry(xCoord, yCoord));
}
void draw() // Draw the background and concrete plant
{
background (235, 247, 255);
image(concretePlant, xCoord, yCoord, 60, 60);
fill(1);
text("Concrete Plant", xCoord-20, yCoord+70);
//Calling the sites
for (int i = sites.size () - 1; i>=0; i--) {
Site site = sites.get(i);
site.displaySites();
}
float[] distanceCheck = new float[lorries.size()];
for (int i = 0; i< lorries.size (); i++) {
if (lorries.get(i).deliv == false) {
println ("delivery check");
if (lorries.get(i).u > 0) {
PVector siteTemp = new PVector (sites.get(siteNumber).x, sites.get(siteNumber).y);
PVector lorryTemp = new PVector (lorries.get(i).location.x, lorries.get(i).location.y);
distanceCheck[i] = PVector.dist(siteTemp, lorryTemp);
println ("distanceChecked");
} else {
lorries.get(i).destination.x = xCoord;
lorries.get(i).destination.y = yCoord;
println("goingBack");
}
println("first for done");
}
}
int smallestD = -1;
for (int i = 0; i <lorries.size (); i++) {
if ((distanceCheck[i] > 0) && (distanceCheck[i] == min(distanceCheck))) {
smallestD = i;
}
println("smallest found");
}
if (smallestD >= 0) {
lorries.get(smallestD).destination.x = sites.get(siteNumber).x;
lorries.get(smallestD).destination.y = sites.get(siteNumber).y;
if (siteNumber < sites.size() -1) {
siteNumber++; // siteNumber = siteNumber + 1;
}
lorries.get(smallestD).deliv = true;
}
for (int i = 0; i < lorries.size (); i++) {
lorries.get(i).updateLorry();
}
}
void mousePressed() {
sites.add(new Site(mouseX, mouseY, siteSize));
}
class Lorry
{
PVector location;
PVector concretePlant;
PVector velocity;
float d; //distance
int u; //unit of cement
boolean r; //Reserved lorry
boolean deliv; //
PImage mixer;
boolean changeDirection;
PVector destination;
Lorry(float xCoord, float yCoord)
{
concretePlant = new PVector(xCoord, yCoord); //Initial start point
location = new PVector(xCoord, yCoord, 0); //Initial start point
velocity = new PVector(2, 2);
u = 2;
r = false;
deliv = false;
mixer = loadImage("simple_truck.png");
//destination = sites.get(siteNumber);
destination = concretePlant;
//PVector temp = new PVector (destination.x, destination.y);
changeDirection = false;
//d = PVector.dist(location, temp);
}
void displayLorry()
{
image(mixer, location.x, location.y, 30, 30);
}
void move()
{
float xdir = destination.x - location.x;
float ydir = destination.y - location.y;
PVector dir = new PVector (xdir, ydir);
dir.normalize();
location.add(dir);
print("going");
//deliv = true;
}
void checkProgress()
{
if (dist(destination.x, destination.y, location.x, location.y) < 1) {
deliv = false;
//u --;
// if (siteNumber <sites.size() -1) {
// siteNumber++; // siteNumber = siteNumber + 1;
// }
}
}
void updateLorry()
{
displayLorry();
move();
checkProgress();
}
}
class Site
{
float x,y;
float size;
PImage picture;
Site (float xin, float yin, float sin)
{
x = xin;
y = yin;
size = sin;
picture = loadImage("sign.png");
}
void displaySites()
{
image(picture, x, y, 60, 60);
}
}
Site
Lorry
Concrete Plant
I made a few modifications:
first it was not compiling
then I added a few utilities on the Lorry class which simplifies the code in the draw method
And finally, I tweaked the algorithm in the draw method to pick the correct Lorry
I think the following code works as expected.
You still need to make a Site for the plant, this way you can set it as destination for a Lorry when it needs to reload. Then when it reaches the plant, you set the units back to 2, and it should keep going to the next site after that. Good luck!
/*preload = "factory_12.png";*/
/*preload = "sign.png";*/
/*preload = "simple_truck.png";*/
ArrayList<Lorry> lorries;
ArrayList<Site> sites;
PImage concretePlant;
PFont aFont;
int xCoord;
int yCoord;
int siteSize = 30;
int siteNumber = 0; // keeps track of the index of the nest site to deliver to
void setup() // What is called once at the beginning
{
size (500, 500);
concretePlant = loadImage("factory_12.png");
aFont = createFont("IndustrialRevolution-Regular", 12);
textFont(aFont);
xCoord = int(width/2);
yCoord = int(height/2);
//Creating empty Array List where store sites objects
sites = new ArrayList<Site>();
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
//storing lorries
lorries = new ArrayList<Lorry>();
lorries.add(new Lorry("Lorry 1", xCoord, yCoord));
lorries.add(new Lorry("Lorry 2", xCoord, yCoord));
}
void mousePressed() {
sites.add(new Site(mouseX, mouseY, siteSize));
}
// This returns the next site to deliver to
// Returns null if no more sites
Site getNextSite() {
Site site = null;
if(siteNumber < sites.size()) {
site = sites.get(siteNumber);
}
return site;
}
void draw() {
// Draw the background and concrete plant
background (235, 247, 255);
image(concretePlant, xCoord, yCoord, 60, 60);
fill(1);
text("Concrete Plant", xCoord-20, yCoord+70);
// Displaying the sites
for (int i = sites.size () - 1; i>=0; i--) {
sites.get(i).display();
}
// Ckeck if there is a next site to deliver to
Site nextSite = getNextSite();
if(nextSite!=null) {
// If yes, find out which lorry should go
Lorry lorryToGo = null;
// List all available lorries (not delivering or out of units)
ArrayList<Lorry> availableLorries = new ArrayList();
for(Lorry l : lorries) {
if(l.isAvailableForDelivery()) {
availableLorries.add(l);
}
}
// if any, find the closest
if(!availableLorries.isEmpty()) {
lorryToGo = availableLorries.get(0);
for(Lorry l : availableLorries) {
if(l.checkDistanceToSite(nextSite) < lorryToGo.checkDistanceToSite(nextSite)) {
lorryToGo = l;
}
}
}
// If a lorry has to go, set its new destination
// and increase the siteNumber
if(lorryToGo != null) {
println(lorryToGo.name + " to go");
lorryToGo.destination = nextSite;
lorryToGo.delivering = true;
siteNumber++;
}
}
// update all lorries
for(Lorry l : lorries) {
l.updateLorry();
}
}
class Lorry {
String name;
PVector location;
PVector concretePlant;
PVector velocity;
int units; //unit of cement
boolean reserved; //Reserved lorry
boolean delivering; //
PImage mixer;
boolean changeDirection;
Site destination;
Lorry(String name, float xCoord, float yCoord) {
this.name = name;
concretePlant = new PVector(xCoord, yCoord); //Initial start point
location = new PVector(xCoord, yCoord); //Initial start point
velocity = new PVector(2, 2);
units = 2;
reserved = false;
delivering = false;
mixer = loadImage("simple_truck.png");
destination = getNextSite();
changeDirection = false;
}
boolean isAvailableForDelivery() {
return !delivering && units > 0;
}
boolean needsToReload() {
return units <= 0;
}
void displayLorry() {
image(mixer, location.x, location.y, 30, 30);
}
float checkDistanceToSite(Site site) {
return PVector.dist(location, new PVector(site.x, site.y));
}
void move() {
float xdir = destination.x - location.x;
float ydir = destination.y - location.y;
PVector dir = new PVector (xdir, ydir);
dir.normalize();
location.add(dir);
}
void checkProgress() {
if (destination != null && checkDistanceToSite(destination) < 1) {
println(name + " reached destination");
delivering = false;
units--;
if(needsToReload()) {
println(name + " needs to reload");
destination = null;
// put some code here to send the truck back to the plant
//destination = plant
} else {
destination = getNextSite();
println("assigning new destination with index: "+siteNumber);
println("assigning new destination: "+destination);
}
}
}
void updateLorry() {
if(delivering)
move();
displayLorry();
checkProgress();
}
}
class Site {
float x,y;
float size;
PImage picture;
Site (float xin, float yin, float sin) {
x = xin;
y = yin;
size = sin;
picture = loadImage("sign.png");
}
void display() {
image(picture, x, y, 60, 60);
}
}
Related
After following a tutorial, I was able to form a simple shadowcasting algorithm that casts rays in different directions and connects those rays sorted by angle to form a polygon. Now that that's done with, I want to use this "field of view", in order to only show/render sprites inside that polygon. However, I do not really have an idea of how to do this.
Code in my render() method:
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
//Render my stuctues
for (Structure s : worldStructures)
{
for (Vector2[] polygon : s.polygonList)
{
float[] vertices = s.getPolygonVectors(polygon);
shapeRenderer.polygon(vertices);
}
}
//Re-initiate my array
rayAngles = new float[rays.size()];
rayPolygon = new float[rays.size()*2];
//Go through each of my rays, calculate their angle and point of intersection, put the latter in
a Map
//Go through the keyset of my map (T1 values) and find which ray is the closest
//render a ray according to that point of intersection's values
Map<Float,PointOfIntersection> angleMap = new HashMap<>();
for (Line2D.Float ray : rays)
{
float x2 = 0f;
float y2 = 0f;
Vector2 rV = new Vector2(ray.x2-player.getPos().x,ray.y2-player.getPos().y);
float angle = (float) Math.atan2(rV.y,rV.x);
Map<Float,PointOfIntersection> closestMap =new HashMap<Float,PointOfIntersection>();
for(Structure structure : worldStructures) {
for (Line2D.Float[] segments : structure.getBodySegments()) {
for (int i = 0; i < segments.length; i++) {
PointOfIntersection currentInt = getIntersection(ray, segments[i]);
if (currentInt != null) {
closestMap.put(currentInt.T1, currentInt);
}
}
}
}
Float[] allPoints = closestMap.keySet().toArray(new Float[0]);
if (allPoints.length > 0) {
float closestPoint = allPoints[0];
for (int i = 0; i < allPoints.length; i++) {
if(allPoints[i]<closestPoint)
{
closestPoint = allPoints[i];
}
}
PointOfIntersection closestIntersection = closestMap.get(closestPoint);
int index = rays.indexOf(ray);
rayAngles[index] = angle;
angleMap.put(rayAngles[index],closestIntersection);
x2 = closestIntersection.pointOfIntersection.x;
y2 = closestIntersection.pointOfIntersection.y;
}
shapeRenderer.line(ray.x1,ray.y1,x2,y2);
}
//Sort angles, Make a polygon according to those sorted angles and their point of intersection
//Lets me connect said polygon clockwise
Arrays.sort(rayAngles);
for (int i = 0, j = 0; i < rayAngles.length; i++, j += 2) {
PointOfIntersection point = angleMap.get(rayAngles[i]);
rayPolygon[j] = point.pointOfIntersection.x;
rayPolygon[j + 1] = point.pointOfIntersection.y;
}
System.out.println(rayPolygon.length);
shapeRenderer.end();
//Initialize my Region, texture and batch to render the polygon.
if (gameLightOn) {
polyReg = new PolygonRegion(new TextureRegion(textureSolid), rayPolygon,
triangulator.computeTriangles(rayPolygon).toArray());
poly = new PolygonSprite(polyReg);
poly.setOrigin(0, 0);
polyBatch = new PolygonSpriteBatch();
polyBatch.setProjectionMatrix(camera.combined);
polyBatch.begin();
poly.draw(polyBatch);
polyBatch.end();
}
(new to java). So I am have created the following script and I would like my object called "site" to appear only when the mouse is pressed and then stay on the screen. Then at every mouse pressed it created a new "site".
What it does now is that it creates a site at the beginning and the adds one when the mouse is pressed. But I don't want that site in the beginning, I just want it when I click.
Is anyone could help me that would be great!
/*preload = "factory_12.png";*/
/*preload = "sign.png";*/
/*preload = "simple_truck.png";*/
Lorry lorry;
PImage concretePlant;
PFont aFont;
int xCoord;
int yCoord;
ArrayList<Site> sites;
int siteSize = 30;
void setup() // What is called once at the beginning
{
size (500, 500);
concretePlant = loadImage("factory_12.png");
aFont = createFont("IndustrialRevolution-Regular", 12);
textFont(aFont);
xCoord = int(width/2);
yCoord = int(height/2);
//Creating empty Array List where store sites objects
sites = new ArrayList<Site>();
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
//storing lorries
lorry = new Lorry(xCoord, yCoord);
}
void draw() // Draw the background and concrete plant
{
background (235, 247, 255); //light blue background, not in draw as it wouldn't allow the site image to stay
image(concretePlant, xCoord, yCoord, 60, 60);
fill(1);
text("Concrete Plant", xCoord-20, yCoord+70);
//Calling the sites
for (int i = sites.size () - 1; i>=0; i--) {
Site site = sites.get(i);
site.displaySites();
}
//calling the lorry functions
lorry.updateLorry();
}
void mousePressed() {
sites.add(new Site(mouseX, mouseY, siteSize));
}
class Site
{
float x,y;
float size;
PImage picture;
Site (float xin, float yin, float sin)
{
x = xin;
y = yin;
size = sin;
picture = loadImage("sign.png");
}
void displaySites()
{
image(picture, x, y, 60, 60);
}
}
class Lorry
{
PVector location;
PVector concretePlant;
PVector velocity;
PImage mixer;
boolean changeDirection;
int siteNumber = 0;
Site destination;
Lorry(float xCoord, float yCoord)
{
concretePlant = new PVector(xCoord, yCoord); //Initial start point
location = new PVector(xCoord, yCoord); //Initial start point
velocity = new PVector(2, 2);
mixer = loadImage("simple_truck.png");
destination = sites.get(siteNumber);
changeDirection = false;
}
void displayLorry()
{
image(mixer, location.x, location.y, 30, 30);
}
void Move()
{
float xdir = destination.x - location.x;
float ydir = destination.y - location.y;
PVector dir = new PVector (xdir, ydir);
dir.normalize();
location.add(dir);
print("going");
}
void reachDestination()
{
//println(destination,location);
//if ((destination.x == location.x) && (destination.y == location.y)) {
if (dist(destination.x, destination.y, location.x, location.y) < 1) {
if (siteNumber <sites.size() -1) {
siteNumber++; // siteNumber = siteNumber + 1;
destination = sites.get(siteNumber);
changeDirection = true;
} else {
println("reached final site");
}
println("reachedDestination");
}
}
void updateLorry()
{
displayLorry();
Move();
reachDestination();
}
}
Thank you :)
Get rid of this line:
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
This line in your setup() function adds a Site. If you don't want to add a Site at startup, remove this line.
You should also try to go through the process of debugging your problem. For example, step through the code line-by-line with a piece of paper and a pencil, or add print statements, or use the debugger that comes with the Processing editor. That will help you figure out problems like this in the future. Good luck!
I am very new to coding and my aim is to make and object (a lorry) change destination when it reaches the first one (site).
As for now, the lorry leaves its original place (concrete plant) and moves to the first site created. The user can add sites with mousePress (I used an array of sites). But then my lorry gets stuck on the first site and doesn't go to the next one. I also want the lorry to go to 2 sites and then come back to the concrete plant to then again leave for 2 sites etc...
Can somebody help me, I am desperate and my deadline is next Monday.
This is my code:
Lorry lorry;
int xCoord;
int yCoord;
ArrayList<Site> sites;
int siteSize = 30;
void setup() // What is called once at the beginning
{
size (500, 500);
xCoord = int(width/2);
yCoord = int(height/2);
//Creating empty Array List where store sites objects
sites = new ArrayList<Site>();
//Adding first site
sites.add(new Site(random(width), random(height), siteSize));
//storing lorries
lorry = new Lorry(xCoord, yCoord);
}
void draw() // Draw the background and concrete plant
{
background (235, 247, 255);
ellipse(xCoord, yCoord, 60, 60);
//Calling the sites
for (int i = sites.size () - 1; i>=0; i--) {
Site site = sites.get(i);
site.displaySites();
}
//calling the lorry functions
lorry.updateLorry();
}
void mousePressed() {
sites.add(new Site(mouseX, mouseY, siteSize));
}
class Site
{
float x,y;
float size;
Site (float xin, float yin, float sin)
{
x = xin;
y = yin;
size = sin;
}
void displaySites()
{
rectangle(x, y, 60, 60);
}
}
class Lorry
{
PVector location;
PVector concretePlant;
PVector velocity;
boolean changeDirection;
int siteNumber = 0;
Site destination;
Lorry(float xCoord, float yCoord)
{
concretePlant = new PVector(xCoord, yCoord); //Initial start point
location = new PVector(xCoord, yCoord); //Initial start point
velocity = new PVector(2, 2);
destination = sites.get(siteNumber);
changeDirection = false;
}
void displayLorry()
{
rectangle(location.x, location.y, 30, 30);
}
void Move()
{
float xdir = destination.x - location.x;
float ydir = destination.y - location.y;
PVector dir = new PVector (xdir, ydir);
dir.normalize();
location.add(dir);
}
void reachDestination()
{
if ((destination.x == location.x) && (destination.y == location.y)) {
siteNumber++; // siteNumber = siteNumber + 1;
destination = sites.get(siteNumber);
changeDirection = true;
}
}
void updateLorry()
{
displayLorry();
Move();
reachDestination();
}
}
You're super close Lily, literally.
If you print the values of destination and location you'll notice they're getting super close, however, due to the increments they never "meet". The values never match (aren't equal).
You could easily swap your equals conditions for a more practical threshold distance condition (e.g. if the distance between the destination and location are smaller than 1px):
void reachDestination()
{
println(destination,location);
//if ((destination.x == location.x) && (destination.y == location.y)) {
if(dist(destination.x,destination.y,location.x,location.y) < 1){
if(siteNumber < sites.size() -1){
siteNumber++; // siteNumber = siteNumber + 1;
destination = sites.get(siteNumber);
changeDirection = true;
}else{
println("reached final site");
}
println("reachDestination");
}
}
Bare in mind that dist() uses the square root which could become a slow calculation for a large number of sites (due to sqrt), however you could use the squared distance instead.
Additionally, PVector has a lerp() function that returns the interpolated position between two given positions (e.g. destination and site) and an interpolation amount (a value between 0.0 (start position) and 1.0 (end position)).
Here's a proof of concept sketch:
PVector[] destinations = {
new PVector(10,10),
new PVector(90,10),
new PVector(90,90),
new PVector(10,90)
};
float traversal = 0.0;
void setup(){
}
void draw(){
background(255);
//draw destinations
for(PVector d : destinations){
ellipse(d.x,d.y,9,9);
}
//calculate traversal
PVector traversed = traversePoints(destinations,0.01);
//draw traversal
ellipse(traversed.x,traversed.y,3,3);
}
PVector traversePoints(PVector[] destinations,float speed){
if(speed < 0){
speed = 0.05;
}
//increment full path traversal (the higher the increment, the faster the move)
traversal += speed;
//loop back to 0 when fully traversed
if(traversal > destinations.length) traversal = 0.0;
//compute the current point index
int pointIndex = (int)traversal;
//compute the local traversal (0.0 -> 1.0 = 0% to 100% in between two points: current and next)
float pointT = traversal - pointIndex;
//compute the next current point index
int pointIndexNext = (pointIndex + 1) % destinations.length;
//interpolate between current and next points using above local traversal, offsetting by the last mainHingeition)
return PVector.lerp(destinations[pointIndex],
destinations[pointIndexNext],
pointT);
}
You can actually run this as demo bellow:
var destinations;
var traversal = 0.0;
function setup(){
createCanvas(100,100);
destinations = [
createVector(10,10),
createVector(90,10),
createVector(90,90),
createVector(10,90)
];
}
function draw(){
background(255);
//draw destinations
for(var i = 0 ; i < destinations.length; i++){
var d = destinations[i];
ellipse(d.x,d.y,9,9);
}
//calculate traversal
var traversed = traversePoints(destinations,0.01);
//draw traversal
ellipse(traversed.x,traversed.y,3,3);
}
function traversePoints(destinations,speed){
if(speed < 0){
speed = 0.05;
}
//increment full path traversal (the higher the increment, the faster the move)
traversal += speed;
//loop back to 0 when fully traversed
if(traversal > destinations.length) traversal = 0.0;
//compute the current point index
var pointIndex = Math.floor(traversal);
//compute the local traversal (0.0 -> 1.0 = 0% to 100% in between two points: current and next)
var pointT = traversal - pointIndex;
//compute the next current point index
var pointIndexNext = (pointIndex + 1) % destinations.length;
//interpolate between current and next points using above local traversal, offsetting by the last mainHingeition)
return p5.Vector.lerp(destinations[pointIndex],
destinations[pointIndexNext],
pointT);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>
I'm trying to run this code:
import TUIO.*;
TuioProcessing tuioClient;
// Grid
int cols = 6, rows = 6;
boolean[][] states = new boolean[cols][rows];
int videoScale = 100;
// these are some helper variables which are used
// to create scalable graphical feedback
float cursor_size = 15;
float object_size = 60;
float table_size = 760;
float scale_factor = 1;
PFont font;
boolean verbose = false; // print console debug messages
boolean callback = true; // updates only after callbacks
void setup(){
size(600,600);
noCursor();
noStroke();
fill(0);
// periodic updates
if (!callback) {
frameRate(60); //<>//
loop();
} else noLoop(); // or callback updates
font = createFont("Arial", 18);
scale_factor = height/table_size;
// finally we create an instance of the TuioProcessing client
// since we add "this" class as an argument the TuioProcessing class expects
// an implementation of the TUIO callback methods in this class (see below)
tuioClient = new TuioProcessing(this);
}
void draw()
{
// Begin loop for columns
for (int i = 0; i < cols; i++) {
// Begin loop for rows
for (int j = 0; j < rows; j++) {
// Scaling up to draw a rectangle at (x,y)
int x = i*videoScale;
int y = j*videoScale;
fill(255);
stroke(0);
//check if coordinates are within a box (these are mouse x,y but could be fiducial x,y)
//simply look for bounds (left,right,top,bottom)
rect(x,y,videoScale,videoScale);
}
}
textFont(font,18*scale_factor);
float obj_size = object_size*scale_factor;
float cur_size = cursor_size*scale_factor;
ArrayList<TuioObject> tuioObjectList = tuioClient.getTuioObjectList();
for (int i=0;i<tuioObjectList.size();i++) {
TuioObject tobj = tuioObjectList.get(i);
stroke(0);
fill(0,0,0);
pushMatrix();
translate(tobj.getScreenX(width),tobj.getScreenY(height));
rotate(tobj.getAngle());
rect(-obj_size/2,-obj_size/2,obj_size,obj_size);
popMatrix();
fill(255);
text(""+tobj.getSymbolID(), tobj.getScreenX(width), tobj.getScreenY(height));
}
ArrayList<TuioCursor> tuioCursorList = tuioClient.getTuioCursorList();
for (int i=0;i<tuioCursorList.size();i++) {
TuioCursor tcur = tuioCursorList.get(i);
ArrayList<TuioPoint> pointList = tcur.getPath();
if (pointList.size()>0) {
stroke(0,0,255);
TuioPoint start_point = pointList.get(0);
for (int j=0;j<pointList.size();j++) {
TuioPoint end_point = pointList.get(j);
line(start_point.getScreenX(width),start_point.getScreenY(height),end_point.getScreenX(width),end_point.getScreenY(height));
start_point = end_point;
}
stroke(192,192,192);
fill(192,192,192);
ellipse( tcur.getScreenX(width), tcur.getScreenY(height),cur_size,cur_size);
fill(0);
text(""+ tcur.getCursorID(), tcur.getScreenX(width)-5, tcur.getScreenY(height)+5);
}
}
ArrayList<TuioBlob> tuioBlobList = tuioClient.getTuioBlobList();
for (int i=0;i<tuioBlobList.size();i++) {
TuioBlob tblb = tuioBlobList.get(i);
stroke(0);
fill(0);
pushMatrix();
translate(tblb.getScreenX(width),tblb.getScreenY(height));
rotate(tblb.getAngle());
ellipse(-1*tblb.getScreenWidth(width)/2,-1*tblb.getScreenHeight(height)/2, tblb.getScreenWidth(width), tblb.getScreenWidth(width));
popMatrix();
fill(255);
text(""+tblb.getBlobID(), tblb.getScreenX(width), tblb.getScreenX(width));
}
}
// --------------------------------------------------------------
// these callback methods are called whenever a TUIO event occurs
// there are three callbacks for add/set/del events for each object/cursor/blob type
// the final refresh callback marks the end of each TUIO frame
// called when an object is added to the scene
void addTuioObject(TuioObject tobj) {
if (verbose) println("add obj "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getAngle());
double fx = tobj.getX();
double fy = tobj.getY();
println (fx + " " + fy);
if( (fx >= x && fx <= x + videoScale) && //check horzontal
(fy >= y && fy <= y + videoScale)){
//coordinates are within a box, do something about it
fill(0);
stroke(255);
//you can keep track of the boxes states (contains x,y or not)
states[i][j] = true;
}
}
But I get the error "The field component.x is not visible" regarding the last if statement. I tried to make x and y public when I declared them in the draw method but I get the error "illegal modifier for the variable x; only final is permitted".
How could I fix this ?
Thanks for taking the time to read and for your help !
You never declare x and y outside of your draw() method, so they are not visible to addTuioObject(). If you need values from inside the draw method, you could declare class fields instead like you did with cursor_size or object_size. Use
int x, y;
outside of any methods and then assign accordingly, or add parameters to your addTuioObject() method:
void addTuioObject(TuioObject tobj, int x, int y) {
// Your code
}
Hey everyone thanks for all the help so far !. I have finally finished this project and it runs fine in eclipse but when I export it I get this error from stack trace also any help on how this could be improved in terms of architecture is much appreciated.
Exception is Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeExcepti
on: com.badlogic.gdx.utils.GdxRuntimeException: File not found: assets\font.fnt
It runs fine in eclipe but fails when exported
public class ConnectFourApplication extends Game implements ApplicationListener {
private Screen screen;
private Game game;
public static void main(String[] args) {
new LwjglApplication(new ConnectFourApplication(), "PennyPop", 1280, 720,
true);
}
public ConnectFourApplication(){
game = this;
}
#Override
public void create() {
screen = new MainScreen(game);
setScreen(screen);
screen.show();
}
#Override
public void dispose() {
screen.hide();
screen.dispose();
}
/** Clears the screen with a white color */
private void clearWhite() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
#Override
public void pause() {
screen.pause();
}
#Override
public void render() {
clearWhite();
super.render();
}
#Override
public void resize(int width, int height) {
screen.resize(width, height);
}
#Override
public void resume() {
screen.resume();
}
public class MainScreen implements Screen {
private final Stage stage;
private final SpriteBatch spriteBatch;
//Parameter for drawing the buttons
private final BitmapFont font;
private final TextureAtlas buttons;
private final Button SFXButton;
private final Button APIButton;
private final Button GameButton;
private final Skin images;
//Parameter for Sound
private final com.badlogic.gdx.audio.Sound SFXClick;
//Parameter for the api call
private final String WeatherUrl;
private final HttpRequest request;
private final City SanFrancisco;
//The screen to load after the game button is hit
private Screen gamescreen;
private Game game;
public MainScreen(Game game) {
this.game = game;
//Set up our assets
spriteBatch = new SpriteBatch();
stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, spriteBatch);
font = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
buttons = new TextureAtlas("assets/GameButtons.pack");
images = new Skin(buttons);
images.addRegions(buttons);
SFXButton = new Button(images.getDrawable("sfxButton"));
SFXButton.setPosition(295, 310);
APIButton = new Button(images.getDrawable("apiButton"));
APIButton.setPosition(405, 310);
GameButton = new Button(images.getDrawable("gameButton"));
GameButton.setPosition(515, 310);
SFXClick = Gdx.audio.newSound(Gdx.files.internal("assets/button_click.wav"));
//Add our actors to the stage
stage.addActor(SFXButton);
stage.addActor(APIButton);
stage.addActor(GameButton);
//Set up our Url request to be used when clicking the button
WeatherUrl = "http://api.openweathermap.org/data/2.5/weather?q=San%20Francisco,US";
request = new HttpRequest(HttpMethods.GET);
request.setUrl(WeatherUrl);
SanFrancisco = new City("Unavailable","Unavailable","0","0"); //init san fran to be displayed before they have clicked the button
}
#Override
public void dispose() {
spriteBatch.dispose();
stage.dispose();
}
#Override
public void render(float delta) {
stage.act(delta);
stage.draw();
//Begin sprite batch
spriteBatch.begin();
//Set our on click listeners for our buttons
if (SFXButton.isPressed())
SFXClick.play();
if(APIButton.isPressed())
{
CallApi();
}
if(GameButton.isPressed())
LoadGame();
//Set font color and render the screen
font.setColor(Color.RED);
font.draw(spriteBatch, "PennyPop", 455 - font.getBounds("PennpyPop").width/2,
460 + font.getBounds("PennyPop").height/2);
font.setColor(Color.BLACK);
font.draw(spriteBatch, "Current Weather", 900 - font.getBounds("PennpyPop").width/2,
460 + font.getBounds("PennyPop").height/2);
font.setColor(Color.LIGHT_GRAY);
font.draw(spriteBatch, SanFrancisco.Name, 940 - font.getBounds("PennpyPop").width/2,
420 + font.getBounds("PennyPop").height/2);
font.setColor(Color.RED);
font.draw(spriteBatch, SanFrancisco.CurrentCondition, 950 - font.getBounds("PennpyPop").width/2,
300 + font.getBounds("PennyPop").height/2);
font.draw(spriteBatch, SanFrancisco.Temperature + " Degrees,", 920 - font.getBounds("PennpyPop").width/2,
270 + font.getBounds("PennyPop").height/2);
font.draw(spriteBatch, SanFrancisco.WindSpeed, 1200 - font.getBounds("PennpyPop").width/2,
270 + font.getBounds("PennyPop").height/2);
//End or sprite batch
spriteBatch.end();
}
//Handles calling our API
public void CallApi(){
//Sends our stored HTTPRequest object
Gdx.net.sendHttpRequest(request, new HttpResponseListener() {
#Override
public void handleHttpResponse(HttpResponse httpResponse) {
//Uses our private response reader object to give us a the JSON from the api call
JSONObject json = HttpResponseReader(httpResponse);
//Gets the name of the city
SanFrancisco.Name = (String) json.get("name");
//Parsed through our returned JSON for the weather key
JSONArray WeatherArray = (JSONArray) json.get("weather");
//Gets the actual weather dictionary
JSONObject Weather = (JSONObject) WeatherArray.get(0);
//Finally get the value with the key of description and assign it
//To the San Fran current conditions field
SanFrancisco.CurrentCondition = (String) Weather.get("description");
//Gets the actual main dictionary
JSONObject main = (JSONObject) json.get("main");
//Finally get the values based on the keys
SanFrancisco.Temperature = (String) Double.toString((double) main.get("temp"));
//Finally get the wind speed
JSONObject wind = (JSONObject) json.get("wind");
SanFrancisco.WindSpeed = (String) Double.toString((double) wind.get("speed"));
}
#Override
public void failed(Throwable t) {
Gdx.app.log("Failed ", t.getMessage());
}
});
}
//When the button game button is clicked should load the connect four game
public void LoadGame(){
game.setScreen(new GameScreen(game));
}
//Converts our HttpResponse into a JSON OBject
private static JSONObject HttpResponseReader(HttpResponse httpResponse){
BufferedReader read = new BufferedReader(new InputStreamReader(httpResponse.getResultAsStream()));
StringBuffer result = new StringBuffer();
String line = "";
try {
while ((line = read.readLine()) != null) {
result.append(line);
}
JSONObject json;
try {
json = (JSONObject)new JSONParser().parse(result.toString());
return json;
} catch (ParseException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
public void resize(int width, int height) {
stage.setViewport(width, height, false);
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
render(0);
}
#Override
public void pause() {
// Irrelevant on desktop, ignore this
}
#Override
public void resume() {
// Irrelevant on desktop, ignore this
}
public class GameScreen implements Screen {
//Our stage and sprites
private final Stage gamestage;
private final SpriteBatch gamesprites;
//Parameter for drawing the pieces
private final BitmapFont gamefont;
private final TextureAtlas pieces;
private final Skin piecesskin;
//this will be the sprite and texture for our red connect four buttons
private Texture redtexture;
private Sprite redsprite;
//this will be the sprite and texture for our red connect four buttons
private Texture yellowtexture;
private Sprite yellowsprite;
//Setup the board
//renders the line
private ShapeRenderer boardlineshape;
//setup the line locations
private int linestartx;
private int linestarty;
private int lineendx;
private int lineendy;
private int linexdistance;
private int lineydistance;
//for this game we will define a board size as the amount of lines the board should contain
private double boardsize;
//Lines required to win
private int linestowin;
private String playersturnstring;
private OrthographicCamera camera;
//Holds all the parameters for our players
//Keeps track of who's turn it is, if 0 player one if 1 player two
private int playersturn;
//Holds the location of all of player ones pieces
//Needs to be two Dimensional to hold x and y values
private int[][] playeronepieces;
private int playeronepieceindex;
//Holds the location of all of player twos pieces
//Needs to be two Dimensional to hold x and y values
private int[][] playertwopieces;
private int playertwopieceindex;
//make the number of pieces per player variable so it can be changed for the future
private int numberofpiecesperplayer;
private Game game;
public boolean gameover;
private boolean isready;
private int[][] RowsAndColumns;
private int columnvalue = 538;
public GameScreen(Game game){
this.game = game;
//Set up our assets
gamesprites = new SpriteBatch();
gamestage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, gamesprites);
//Sets up our font
gamefont = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
pieces = new TextureAtlas("assets/GameButtons.pack");
piecesskin = new Skin(pieces);
piecesskin.addRegions(pieces);
//set up our camera
camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.update();
//sets up our red connect four piece
redtexture = new Texture(Gdx.files.internal("assets/red.png"));
redsprite = new Sprite(redtexture);
//sets up our yellow connect four piece
yellowtexture = new Texture(Gdx.files.internal("assets/yellow.png"));
yellowsprite = new Sprite(yellowtexture);
//setup the board
SetUpGameBoard(8,4,Color.BLACK);
linestartx = 300;
linestarty = 100;
lineendx = 300;
lineendy = 600;
linexdistance = 100;
lineydistance = 100;
//setup the pieces
numberofpiecesperplayer = 60;
//initialize anything else we need for the game
playersturnstring = "";
//start with player one's turn
playersturn = 0;
//setup or pieces locations as blank
playeronepieces = new int[2][numberofpiecesperplayer]; //create two arrays one for x values one for y
playeronepieceindex = 0;
playertwopieces = new int[2][numberofpiecesperplayer]; //create two arrays one for x values one for y
playertwopieceindex = 0;
gameover = false;
isready = false;
linestowin = 4;
}
//Should initialize our game board
public void SetUpGameBoard(int boardsize,int linestowin, Color linecolor){
this.boardsize = boardsize;
this.linestowin = linestowin;
boardlineshape = new ShapeRenderer();
boardlineshape.setProjectionMatrix(camera.combined);
boardlineshape.setColor(linecolor);
//holds the board cells
RowsAndColumns = new int[2][(int) boardsize];
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void render(float delta) {
//set the stage
gamestage.act(delta);
gamestage.draw();
//if the mouse is clicked and the game is not over send us back to the main screen
if (Gdx.input.justTouched() && gameover == true){
//if the game is over and the user clicks send us back to the main screen
game.setScreen(new MainScreen(game));
}
if(isready){
//if the mouse is clicked and the game is not over add a piece to player one
if (Gdx.input.justTouched() && gameover != true){
AddPiece(Gdx.input.getX(), Gdx.input.getY());
}
}
//Draw our board
boardlineshape.begin(ShapeType.Line);
///Draw all of the lines for our board
DrawBoard(linestartx,linestarty,lineendx,lineendy);
boardlineshape.end();
//Starts our game sprite batch
gamesprites.begin();
//Draw all of player ones pieces
DrawPlayerOnePieces();
//Draw all of player twos pieces
DrawPlayerTwoPieces();
gamefont.draw(gamesprites, playersturnstring, 515, 650);
//End our game sprite batch
gamesprites.end();
//Lastly check to make sure our the game is not over
CheckForGameOver();
isready = true;
}
//draw the board
private void DrawBoard(int linestartx, int linestarty, int lineendx, int lineendy){
camera.update();
boardlineshape.setProjectionMatrix(camera.combined);
//For each line in our board draw a line
for(int i =0; i < boardsize; i++)
{
//first we will draw the vertical lines then we will change to the horizontal lines
boardlineshape.line(linestartx, linestarty,lineendx, lineendy);
//if the x value exceeds a certian amount then change to the horizontal lines
//increment the start x position to draw another line
linestartx += linexdistance;
lineendx += lineydistance;
//if the x start is over 1200 we have drawn the last vertical line so switch to th
//horizontal lines
if(linestartx > 1000)
{
//set our x values and render our horizontal lines
lineendx = linestartx - linexdistance;
linestartx = this.linestartx;
linestarty = this.linestarty;
lineendy = this.linestarty;
for(int index =0; index < boardsize -2; index++){
//increment the start y position to draw another line
boardlineshape.line(linestartx, linestarty,lineendx, lineendy);
linestarty += lineydistance;
lineendy += lineydistance;
}
}
}
}
//Draws all the current pieces for player one
private void DrawPlayerOnePieces(){
//For all of player one's pieces
for(int i = 0; i < playeronepieces[1].length;i++)
{
//of its not an empty piece draw it
if(playeronepieces[0][i] != 0){
gamesprites.draw(redtexture, playeronepieces[0][i], playeronepieces[1][i]);
}
}
}
//Draws all the current pieces for player two
private void DrawPlayerTwoPieces(){
//For all of player two's pieces
for(int i = 0; i < playertwopieces[1].length;i++)
{
//of its not an empty piece draw it
if(playertwopieces[0][i] != 0){
gamesprites.draw(yellowtexture, playertwopieces[0][i], playertwopieces[1][i]);
}
}
}
//Adds a piece to whichever players current turn it is
private void AddPiece(int clickx, int clicky){
RestPlayersTurn(playersturn);
int computedx = GetComputedX(clickx,linestartx);
int computedy = GetComputedY(clicky,linestarty);
if(playeronepieceindex != 60)
{
//makes sure they are clicking inside our board and that there is not already a piece on that part of the board
if(
(clickx > linestartx && clickx < linestartx + ((boardsize - 1) * linexdistance))&&
(clicky > linestarty && clicky < lineendy)&&
(CheckIfPieceExists(computedx,computedy,playeronepieces) == false) &&
(CheckIfPieceExists(computedx,computedy,playertwopieces) == false)
)
{
if(playersturn == 0)
{
playeronepieces[0][playeronepieceindex] = computedx; //set the x value
playeronepieces[1][playeronepieceindex] = 700 - computedy; //set the y value
playeronepieceindex++;
playersturnstring = "Player Two's turn";
gamefont.setColor(Color.YELLOW);
}
else if(playersturn == 1)
{
playertwopieces[0][playertwopieceindex] = computedx; //set the x value
playertwopieces[1][playertwopieceindex] = 700 - computedy; //set the y value
playertwopieceindex++;
playersturnstring = "Player One's turn";
gamefont.setColor(Color.RED);
}
//every time we add a piece change the players turn
playersturn++;
}
}
}
//puts our x value in the center of its cell
public int GetComputedX(int touchx, int linestartx){
//compute our x depending on the nearest line
int lineendx = linestartx + linexdistance;
//for the images width
int imagewidth = redtexture.getWidth();
for(int i = 0; i < boardsize; i++)
{
//if the touched x is in this range than assign the computed x value to
//half the cell
if(touchx > linestartx && touchx < lineendx){
touchx = (lineendx - (linexdistance/2)) - (imagewidth/2);
break;
}
linestartx += linexdistance;
lineendx += linexdistance;
}
return touchx;
}
//puts our y value in the center of the cell
public int GetComputedY(int touchy, int linestarty)
{
//compute our x depending on the nearest line
int lineendy = linestarty + lineydistance;
//for the images width
int imageheight = redtexture.getHeight();
//computer our x depending on the nearest line
for(int i =0; i < boardsize; i++)
{
//if the touched x is in this range than assign the computed x value to
//half the cell
if(touchy > linestarty && touchy < lineendy){
touchy = ((lineendy - (lineydistance/2)) + (imageheight/4));
break;
}
linestarty += lineydistance;
lineendy += lineydistance;
}
return touchy;
}
//Sets the next players turn
private void RestPlayersTurn(int playerturn){
if(playerturn == 2){
playersturn = 0;
}
}
//check for game over
private void CheckForGameOver(){
//check if player one has a connect four
CheckForConnectFourHorizontal();
CheckForConnectFourVertical();
CheckForConnectFourDiagonal();
}
private void CheckForConnectFourHorizontal(){
int rowvalue = 318;
int columnvalue = 534;
//for each column on the board check the row for a horizontal connect four for player one
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckRowForConnectFour(rowvalue,columnvalue,playeronepieces);
rowvalue = 318;
columnvalue = columnvalue - 100;
}
rowvalue = 318;
columnvalue = 534;
//for each column on the board check the row for a horizontal connect four for player two
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckRowForConnectFour(rowvalue,columnvalue,playertwopieces);
rowvalue = 318;
columnvalue = columnvalue - 100;
}
}
private void CheckForConnectFourVertical(){
int rowvalue = 318;
int columnvalue = 534;
//for each column on the board check the row for a horizontal connect four
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckColumnForConnectFour(rowvalue,columnvalue,playeronepieces);
rowvalue = rowvalue + 100 ;
columnvalue = 534;
}
rowvalue = 318;
columnvalue = 534;
//for each column on the board check the row for a horizontal connect four
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckColumnForConnectFour(rowvalue,columnvalue,playertwopieces);
rowvalue = rowvalue + 100 ;
columnvalue = 534;
}
}
private void CheckForConnectFourDiagonal(){
int rowvalue = 318;
int columnvalue = 534;
int originalrowvalue = 318;
//finally do this for every column
for(int index = 0; index < RowsAndColumns[0].length; index++ ){
//for each row on the board check the next four diagonal
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckDiagonalSegment(rowvalue,columnvalue,playeronepieces);
rowvalue = rowvalue + 100;
}
rowvalue = originalrowvalue;
columnvalue -= 100;
}
rowvalue = 318;
columnvalue = 534;
originalrowvalue = 318;
//finally do this for every column
for(int index = 0; index < RowsAndColumns[0].length; index++ ){
//for each row on the board check the next four diagonal
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckDiagonalSegment(rowvalue,columnvalue,playertwopieces);
rowvalue = rowvalue + 100;
}
rowvalue = originalrowvalue;
columnvalue -= 100;
}
}
private void CheckRowForConnectFour(int rowvalue, int columnvalue, int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//for all the rows in this column
for(int index = 0; index < playerpieces[0].length; index++){ //go through the row
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[0].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
//check the next cell
rowvalue += 100;
}
}
private void CheckColumnForConnectFour( int rowvalue, int columnvalue, int[][] playerpieces)
{
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//for all the rows in this column
for(int index = 0; index < RowsAndColumns[1].length; index++){ //go through the column
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[1].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
//check the next cell
columnvalue -= 100;
}
}
private void CheckDiagonalSegment(int rowvalue, int columnvalue, int[][] playerpieces){
CheckForForwardDiagonal(rowvalue,columnvalue,playerpieces);
CheckForBackwardDiagonal(rowvalue,columnvalue,playerpieces);
}
private void CheckForForwardDiagonal(int rowvalue, int columnvalue,int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//check for four to the right
for(int index = 0; index < RowsAndColumns[0].length; index++){ //for every square in the diagonal
for(int i = 0; i < playeronepieces[0].length;i++) // for every player peice check for a red
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
rowvalue += 100;
columnvalue -= 100;
}
}
public void CheckForBackwardDiagonal(int rowvalue, int columnvalue,int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//checks the diagonal to the left
for(int index = 0; index < RowsAndColumns[0].length; index++){ //for every square in the diagonal
for(int i = 0; i < playerpieces[0].length;i++) // for every player peice check for a red
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
rowvalue -= 100;
columnvalue -= 100;
}
}
//checks if a piece is already in this position on the board
public boolean CheckIfPieceExists(int row,int column,int[][] playerpieces){
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[0].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == row && playerpieces[1][i] == column )
{
//there is already a piece here
return true;
}
}
return false;
}
#Override
public void resize(int arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void show() {
//set the processor to the new screen
Gdx.input.setInputProcessor(gamestage);
//render our game screen
render(0);
}
The Problem is related to that line
font = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
The file search patch (and classpath) is handled in a different way when starting applications from within your eclipse workspace.
The font is not exported (or not present) in your installed application.
1)
Try to print the file path to console or debug your application. I assume that the file-root is different.
2)
the font is not exported correctly and has to be aded to the build.properties
It runs fine in eclipe but fails when exported
The correct way to export is:
File -> Export -> Java -> Runnable JAR file.
Be sure to check:
Package required libraries into Generated JAR.
That way, your assets will be packaged in the jar and the font will be found.