I'm having trouble loading my game's tilemap onto the screen. My code seems fine and it doesn't contain any errors. I'm new to android game development and I can't seem t figure out what I'm doing wrong. I've read up on how to access access what's in the assets folder but I don't think I'm getting it right. For this code I'm getting throwifrecycled error, please help.
public class PlayState extends State {
private Amani amani;
private Background background, background2;
private static final int PLAYER_WIDTH = 66;
private static final int PLAYER_HEIGHT = 100;
InputStream is;
private float recentTouchY;
private ArrayList<Tile> tilearray = new ArrayList<Tile>();
#Override
public void init() {
background = new Background(0, 0);
background2 = new Background(800, 0);
amani = new Amani(145, MainActivity.GAME_HEIGHT - 45 - PLAYER_HEIGHT,
PLAYER_WIDTH, PLAYER_HEIGHT);
try {
is = MainActivity.assets.open("map.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
loadMap();
}
private void loadMap() {
ArrayList lines = new ArrayList();
int width = 0;
int height = 0;
BufferedReader reader = new BufferedReader(new InputStreamReader((is)));
while (true) {
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (line == null) {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
if (!line.startsWith("!")) {
lines.add(line);
width = Math.max(width, line.length());
}
}
height = lines.size();
for (int j = 0; j < 12; j++) {
String line = (String) lines.get(j);
for (int i = 0; i < width; i++) {
if (i < line.length()) {
char ch = line.charAt(i);
Tile t = new Tile(i, j, Character.getNumericValue(ch));
tilearray.add(t);
}
}
}
}
#Override
public void update(float delta) {
background.update(delta);
background2.update(delta);
Assets.runAnim.update(delta);
amani.update(delta);
for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
t.update();
}
}
#Override
public void render(Painter g) {
renderBackground(g);
renderTiles(g); // 114
renderAmani(g);
}
private void renderTiles(Painter g) {
for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY()); //122
}
}
public void renderAmani(Painter g) {
if (amani.isGrounded()) {
Assets.runAnim.render(g, (int) amani.getX(), (int) amani.getY(),
amani.getWidth(), amani.getHeight());
} else {
g.drawImage(Assets.jump, (int) amani.getX(), (int) amani.getY(),
amani.getWidth(), amani.getHeight());
}
}
public void renderBackground(Painter g) {
g.drawImage(Assets.savanah, (int) background.getX(),
(int) background.getY(), MainActivity.GAME_WIDTH,
MainActivity.GAME_HEIGHT);
g.drawImage(Assets.savanah, (int) background2.getX(),
(int) background2.getY(), MainActivity.GAME_WIDTH,
MainActivity.GAME_HEIGHT);
}
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {
recentTouchY = scaledY;
} else if (e.getAction() == MotionEvent.ACTION_UP) {
if (scaledY - recentTouchY < -50) {
amani.jump();
}
}
return true;
}
}
Painter class is as follows:
public class Painter {
private Canvas canvas;
private Paint paint;
private Rect srcRect;
private Rect dstRect;
private RectF dstRectF;
public Painter(Canvas canvas) {
this.canvas = canvas;
paint = new Paint();
srcRect = new Rect();
dstRect = new Rect();
dstRectF = new RectF();
}
public void setColor(int color) {
paint.setColor(color);
}
public void setFont(Typeface typeface, float textSize) {
paint.setTypeface(typeface);
paint.setTextSize(textSize);
}
public void drawString(String str, int x, int y) {
canvas.drawText(str, x, y, paint);
}
public void fillRect(int x, int y, int width, int height) {
dstRect.set(x, y, x + width, y + height);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(dstRect, paint);
}
public void drawImage(Bitmap bitmap, int x, int y) {
canvas.drawBitmap(bitmap, x, y, paint); // line 46
}
public void drawImage(Bitmap bitmap, int x, int y, int width, int height) {
srcRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
dstRect.set(x, y, x + width, y + height);
canvas.drawBitmap(bitmap, srcRect, dstRect, paint);
}
public void fillOval(int x, int y, int width, int height) {
paint.setStyle(Paint.Style.FILL);
dstRectF.set(x, y, x + width, y + height);
canvas.drawOval(dstRectF, paint);
}
}
Logcat:
09-06 01:26:42.538: W/dalvikvm(3054): threadid=11: thread exiting with uncaught exception (group=0x40a741f8)
09-06 01:26:42.538: E/AndroidRuntime(3054): FATAL EXCEPTION: Game Thread
09-06 01:26:42.538: E/AndroidRuntime(3054): java.lang.NullPointerException
09-06 01:26:42.538: E/AndroidRuntime(3054): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1037)
09-06 01:26:42.538: E/AndroidRuntime(3054): at android.graphics.Canvas.drawBitmap(Canvas.java:1078)
09-06 01:26:42.538: E/AndroidRuntime(3054): at com.game.util.Painter.drawImage(Painter.java:46)
09-06 01:26:42.538: E/AndroidRuntime(3054): at com.game.state.PlayState.renderTiles(PlayState.java:122)
09-06 01:26:42.538: E/AndroidRuntime(3054): at com.game.state.PlayState.render(PlayState.java:114)
09-06 01:26:42.538: E/AndroidRuntime(3054): at com.game.framework.GameView.updateAndRender(GameView.java:127)
09-06 01:26:42.538: E/AndroidRuntime(3054): at com.game.framework.GameView.run(GameView.java:113)
09-06 01:26:42.538: E/AndroidRuntime(3054): at java.lang.Thread.run(Thread.java:856)
Related
I were trying to make a camera application, I'm unable to find a way to change camera brightness, contrast using Camera.Parameters
So my question is how to add Brightness and contrast feature to increase/decrease brightness/contrast. For example if I increase the seekbarit increase the brightness. if I decrease the seekbar it decrease the brightness.
Please edit my code or put your seprate answer to help me.
package com.example.beautymaker;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.zomato.photofilters.imageprocessors.Filter;
import com.zomato.photofilters.imageprocessors.subfilters.BrightnessSubFilter;
import java.io.IOException;
import java.util.List;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
/*Camera.Parameters params = camera.getParameters();
final int[] previewFpsRange = new int[2];
params.getPreviewFpsRange(previewFpsRange);
if (previewFpsRange[0] == previewFpsRange[1]) {
final List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange();
for (int[] range : supportedFpsRanges) {
if (range[0] != range[1]) {
params.setPreviewFpsRange(range[0], range[1]);
break;
}
}
}*/
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera;
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
Camera.Parameters parameters = mCamera.getParameters();
// parameters.setPreviewFpsRange(1500,3000);
parameters.setExposureCompensation(parameters.getMaxExposureCompensation());
if(parameters.isAutoExposureLockSupported())
{
parameters.setAutoExposureLock(false);
}
// parameters.setColorEffect(Camera.Parameters.WHITE_BALANCE_INCANDESCENT);
parameters.getAutoExposureLock();
parameters.set("iso",50);
// parameters.setWhiteBalance();
parameters.setAutoWhiteBalanceLock(true);
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_SHADE);
/*Filter filter = new Filter();
filter.addSubFilter(new BrightnessSubFilter(parameters));*/
mCamera.setParameters(parameters);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
// mCamera.release();
}
//for brightness
public static Bitmap doBrightness(Bitmap src, int value) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// increase/decrease each channel
R += value;
if(R > 255) { R = 255; }
else if(R < 0) { R = 0; }
G += value;
if(G > 255) { G = 255; }
else if(G < 0) { G = 0; }
B += value;
if(B > 255) { B = 255; }
else if(B < 0) { B = 0; }
// apply new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
}
there is no method in Camera.Parameters to achieve this. You have to read this documentation for this class to check the available parameters and this class is deprecated in API 21 and above.
I'm having an error doing the Update when checking if(Game::vector.at(i).alivez()), the error is C2280.
The error says: "Enemy &Enemy::operator =(const Enemy &)': attempting to reference a deleted function. Project: Avoidance Game File:xutility
Game.cpp:
void Game::Init()
{
int i = 0;
while(i< Game::Enemies)
{
srand(time(NULL));
Game::vector.push_back(Enemy(0, (rand()% (int)Console::WindowWidth), (rand() % (int)Console::WindowHeight), rand()%1500/1000.0f));
i++;
}
GameOver = false;
Paused = false;
}
void Game::GameMenu()
{
cout << "1. Start Game\n2. Instructions\n3. Close Game\nChoose an option:";
}
void Game::Instructions()
{
Console::Clear();
cout << "Left arrow = left (duh)\nRight arrow = right (surprise)\nSpace Bar = Shoot\nEsc = Close Game\nP Key = Pause\n ";
system("pause");
}
void Game::fire(Player a)
{
a.mX;
}
void Game::Run()
{
while (!GameOver)
{
if (GetAsyncKeyState(VK_ESCAPE))
{
GameOver = true;
}
else if (GetAsyncKeyState((int)'P'))
{
Paused = !Paused;
}
}
}
void Game::Update()
{
if (!Paused)
{
mPlayer.Update();
for (int i = 0; i < Game::Enemies; i++)
{
Game::vector.at(i).Update();
if (Game::vector.at(i).alivez())
{
Game::vector.erase(Game::vector.begin() + i);
i--;
Game::Enemies--;
}
}
}
}
Game.h:
#pragma once
#include "stdafx.h"
#include "targetver.h"
#include <vector>
class Enemy;
class Game
{
int Enemies = 30;
bool Paused;
bool GameOver;
int Score;
Player mPlayer = Player();
std::vector<Enemy> vector;
public:
void Init();
void GameMenu();
void Instructions();
void fire(Player a);
void Run();
void Update();
};
Enemy.h:
class Enemy
{
enum Enemy_type {NormalEnemy};
Game game;
float mX;
float mY;
float speed;
Enemy_type type;
public:
bool alive;
Enemy(int type, int x, int y, float _speed)
{
switch (type)
{
case 0:
type = Enemy_type::NormalEnemy;
break;
}
mX = (float)x;
mY = (float)y;
speed = _speed;
alive = true;
}
float GetX() { return mX; }
float GetY() { return mY; }
bool alivez() { return alive; }
void Kill() { alive = false; }
void Update();
void Draw();
};
I was able to follow the csharp-sample-apps from the github repo for Affectiva. I ran the demo using my webcam and the processing and performance was great.I am not getting the same processing speed from the PhotoDetector when I try to run it over images in filesystem. Any help or improvement would be appreciated.
namespace Logical.EmocaoFace
{
public class AnaliseEmocao : Affdex.ImageListener, Affdex.ProcessStatusListener
{
private Bitmap img { get; set; }
private Dictionary<int, Affdex.Face> faces { get; set; }
private Affdex.Detector detector { get; set; }
private ReaderWriterLock rwLock { get; set; }
public void processaEmocaoImagem()
{
for (int i = 0; i < resultado.count; i++){
RetornaEmocaoFace();
if (faceAffdex != null)
{
}
}
}
public void RetornaEmocaoFace(string caminhoImagem)
{
Affdex.Detector detector = new Affdex.PhotoDetector(1, Affdex.FaceDetectorMode.LARGE_FACES);
detector.setImageListener(this);
detector.setProcessStatusListener(this);
if (detector != null)
{
//ProcessVideo videoForm = new ProcessVideo(detector);
detector.setClassifierPath(#"D:\Desenvolvimento\Componentes\Afectiva\data");
detector.setDetectAllEmotions(true);
detector.setDetectAllExpressions(false);
detector.setDetectAllEmojis(false);
detector.setDetectAllAppearances(false);
detector.start();
((Affdex.PhotoDetector)detector).process(LoadFrameFromFile(caminhoImagem));
detector.stop();
}
}
static Affdex.Frame LoadFrameFromFile(string fileName)
{
Bitmap bitmap = new Bitmap(fileName);
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int numBytes = bitmap.Width * bitmap.Height * 3;
byte[] rgbValues = new byte[numBytes];
int data_x = 0;
int ptr_x = 0;
int row_bytes = bitmap.Width * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < bitmap.Height; y++)
{
Marshal.Copy(ptr + ptr_x, rgbValues, data_x, row_bytes);//(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
bitmap.UnlockBits(bmpData);
//Affdex.Frame retorno = new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
//bitmap.Dispose();
//return retorno;
return new Affdex.Frame(bitmap.Width, bitmap.Height, rgbValues, Affdex.Frame.COLOR_FORMAT.BGR);
}
public void onImageCapture(Affdex.Frame frame)
{
frame.Dispose();
}
public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame frame)
{
byte[] pixels = frame.getBGRByteArray();
this.img = new Bitmap(frame.getWidth(), frame.getHeight(), PixelFormat.Format24bppRgb);
var bounds = new Rectangle(0, 0, frame.getWidth(), frame.getHeight());
BitmapData bmpData = img.LockBits(bounds, ImageLockMode.WriteOnly, img.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int data_x = 0;
int ptr_x = 0;
int row_bytes = frame.getWidth() * 3;
// The bitmap requires bitmap data to be byte aligned.
// http://stackoverflow.com/questions/20743134/converting-opencv-image-to-gdi-bitmap-doesnt-work-depends-on-image-size
for (int y = 0; y < frame.getHeight(); y++)
{
Marshal.Copy(pixels, data_x, ptr + ptr_x, row_bytes);
data_x += row_bytes;
ptr_x += bmpData.Stride;
}
img.UnlockBits(bmpData);
this.faces = faces;
frame.Dispose();
}
public void onProcessingException(Affdex.AffdexException A_0)
{
throw new NotImplementedException("Encountered an exception while processing " + A_0.ToString());
}
public void onProcessingFinished()
{
string idArquivo = CodEspaco + "," + System.Guid.NewGuid().ToString();
for(int i = 0; i < faces.Count; i++)
{
}
}
}
public static class GraphicsExtensions
{
public static void DrawCircle(this Graphics g, Pen pen,
float centerX, float centerY, float radius)
{
g.DrawEllipse(pen, centerX - radius, centerY - radius,
radius + radius, radius + radius);
}
}
}
Found the answer to my own question:
Using PhotoDetector is not ideal in this case since it is expensive to use the Face Detector configuration on subsequent frame calls.
The best option to improve the performance would be to use an instance of the FrameDetector Class.
Here is a getting started guide to analyze-frames.
Item class:
public class Item {
public float x, y, speedx, speedy;
public Rectangle container;
public Texture texture;
static Timer timer = new Timer();
static int amount;
static int spawned;
public int itemtype;
// float delay = 1; // seconds
public void move() {
x += speedx;
y += speedy;
container.x = x;
container.y = y;
}
public void setTexture(int itemtype){
switch(itemtype){
case 1:
texture = new Texture("items/item1.png");
break;
case 2:
texture = new Texture("items/item2.png");
break;
case 3:
texture = new Texture("items/item3.png");
break;
case 4:
texture = new Texture("items/item4.png");
break;
case 5:
texture = new Texture("items/item5.png");
break;
case 6:
texture = new Texture("items/item6.png");
break;
case 7:
texture = new Texture("items/item7.png");
break;
case 8:
texture = new Texture("items/item8.png");
break;
case 9:
texture = new Texture("items/item9.png");
break;
case 10:
texture = new Texture("items/item10.png");
break;
default:
texture = new Texture("items/error.png");
break;
}
}
public static void spawnItem(int amount){
Item.amount = amount;
mainscreen.items.clear();
// for(int spawned = 0; spawned <= amount; spawned++){
timer.schedule(new Timer.Task() {
#Override
public void run() {
if (mainscreen.canclick == false) {
Item item = new Item();
item.x = 600;
item.y = -42;
item.speedx = -20;
item.speedy = 0;
Rectangle itemcontainer = new Rectangle();
itemcontainer.x = item.x;
itemcontainer.y = item.y;
itemcontainer.width = mainscreen.container.getWidth() / 4f;
itemcontainer.height = mainscreen.container.getHeight() - 15f;
item.container = itemcontainer;
item.itemtype = MathUtils.random(1, 10);
item.setTexture(item.itemtype);
mainscreen.items.add(item);
spawned++;
}
for (Item item : mainscreen.items) {
if (item.x <= -4000) {
if (spawned >= Item.amount) {
mainscreen.canclick = true;
timer.stop();
spawned = 0;
}
} else {
}
}
}
}, 0, 0.325f);
}
public void dispose(){
texture.dispose();
}
}
Mainscreen class:
public class mainscreen implements Screen, GestureDetector.GestureListener,InputProcessor {
#Override
public void render(float delta) {
this.delta = delta;
Gdx.gl.glClearColor(115 / 255F, 115 / 255F, 115 / 255F, 1 / 255F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
if(Gdx.input.justTouched()) {
Vector3 touch1 = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touch1);
if (debug.contains(touch1.x, touch1.y)) {
items.clear();
}
if (start.contains(touch1.x, touch1.y)) {
if (canclick == true) {
canclick = false;
Item.spawnItem(20);
}
}
}
}
LOG:
On first click start:
(After the Timer has finished)
canclick: true
items list: [com.abc.luckyllama.Item#37237aa0, com.abc.luckyllama.Item#2de938e3, com.abc.luckyllama.Item#3cb912d5, com.abc.luckyllama.Item#2bae592c, com.abc.luckyllama.Item#774c083, com.abc.luckyllama.Item#633edeae, com.abc.luckyllama.Item#176557a6, com.abc.luckyllama.Item#4edb1b5f, com.abc.luckyllama.Item#6f8abadf, com.abc.luckyllama.Item#7a54d22e, com.abc.luckyllama.Item#473162a5, com.abc.luckyllama.Item#51a698ff, com.abc.luckyllama.Item#6bc08c56, com.abc.luckyllama.Item#37d9e6a2, com.abc.luckyllama.Item#7bb19eb6, com.abc.luckyllama.Item#1eb5805f, com.abc.luckyllama.Item#71780de3, com.abc.luckyllama.Item#9ec0998, com.abc.luckyllama.Item#7edf723d, com.abc.luckyllama.Item#4c5aa2c1]
After clicking the debug button(clears arraylist):
canclick: true
items list: []
After clicking the start button again:
(After the Timer has finished)
canclick: true
items list: [com.abc.luckyllama.Item#7d7cb9bc, com.abc.luckyllama.Item#1435cf42, com.abc.luckyllama.Item#117e1963, com.abc.luckyllama.Item#82bfd27, com.abc.luckyllama.Item#108214c7, com.abc.luckyllama.Item#2a77864a, com.abc.luckyllama.Item#4b232766, com.abc.luckyllama.Item#1cb629e0, com.abc.luckyllama.Item#1c92229d, com.abc.luckyllama.Item#ac1b293, com.abc.luckyllama.Item#588bbcba, com.abc.luckyllama.Item#75df6762, com.abc.luckyllama.Item#78d4358e, com.abc.luckyllama.Item#7f86452d, com.abc.luckyllama.Item#7aed480b, com.abc.luckyllama.Item#7407d443, com.abc.luckyllama.Item#2da6e708, com.abc.luckyllama.Item#604470bc, com.abc.luckyllama.Item#70f9d1af, com.abc.luckyllama.Item#3a16a63f, com.abc.luckyllama.Item#201288d2, com.abc.luckyllama.Item#6310ddfc, com.abc.luckyllama.Item#5d5a1c98, com.abc.luckyllama.Item#52727e52, com.abc.luckyllama.Item#669228d6]
You see that the Items inside the ArrayList didn't get cleared. It increased. I think that's because the instances of Item created in spawnItem() are still there. How do I fix this?
I noticed that every time I click the button there aren't more items. The items are spawned faster. But how to stop this?
I fixed it! The problem was that I needed to create a Timer.Task seperately and the use task.cancel(); to stop the Timer.Task:
import com.badlogic.gdx.utils.Timer;
public class Item {
public static Timer.Task task;
public static void spawnItem(int amount){
Item.amount = amount;
task = new Timer.Task() {
#Override
public void run() {
if (mainscreen.canclick == false) {
item = new Item();
item.x = 600;
item.y = -42;
item.speedx = -20;
item.speedy = 0;
Rectangle itemcontainer = new Rectangle();
itemcontainer.x = item.x;
itemcontainer.y = item.y;
itemcontainer.width = mainscreen.container.getWidth() / 3f;
itemcontainer.height = mainscreen.container.getHeight() - 15f;
item.container = itemcontainer;
item.itemtype = MathUtils.random(1, 10);
item.setTexture(item.itemtype);
mainscreen.items.add(item);
mainscreen.itemsspawned += 1;
// mainscreen.items.remove(item);
spawned++;
}
for (Item item : mainscreen.items) {
if (item.x <= -4000) {
if (spawned >= Item.amount) {
mainscreen.canclick = true;
timer.clear();
timer.stop();
task.cancel();
spawned = 0;
}
}
}
}
};
timer.schedule(task, 0, 0.4f);
}
}
pdfbox / java
Im trying to draw a rectangle starting the first horizontal line in the first page and ending draw the second horizontal line in the second page.
But, When I try to draw programmaticaly the second horizontal line in the 2nd page, It draws in the first page.
How to do that ?
BT - Begin Table
ET - End Table
in my bean :
pdf.BT();
pdf.drawText(arraylist with a lof of text lines);
pdf.ET();
in my pdf class :
class constructor :
public generatePDF(Integer pageRotation){
try {
pdDocto = new PDDocument();
font = PDType1Font.TIMES_ROMAN;
pdPage = new PDPage();
pdPage.setMediaBox(PDPage.PAGE_SIZE_A4);
this.rotation = pageRotation;
pdPage.setRotation(rotation);
pdDocto.addPage(pdPage);
this.getContentStream();
x = new Float(0.0);
y = new Float(0.0);
} catch (IOException e) {
e.printStackTrace();
}
}
public void BT(String alinhamento,Integer Width){
this.BT = true;
this.WidthBT = Width;
}
public void ET(){
this.ET = true;
}
public PDPageContentStream getContentStream() throws IOException {
contentStream = new PDPageContentStream(pdDocto, pdPage,true,true);
if(this.rotation == 90){
contentStream.concatenate2CTM(0, 1, -1, 0, this.pdPage.getMediaBox().getWidth(), 0);
}
contentStream.setFont( font, 11 );
return contentStream;
}
public void drawText(){
if(this.getBT() != null){
if(this.getBT() == true){
contentStream.drawLine(this.getX(), this.getY(), this.getX(), this.getX() + 50);
this.setBT(false);
}else if(this.getET() == true){
contentStream.drawLine(this.getX(), this.getY(), this.getX(), this.getX() + 50);
this.setET(false);
}
}
for (int i = 0; i < numberOfLines; i++) {
if (y <= marginTopBottom) {
contentStream.close(); //fecha o antigo contentStream da primeira página.
pdPage = new PDPage();
pdPage.setMediaBox(PDPage.PAGE_SIZE_A4);
pdPage.setRotation(this.rotation);
pdDocto.addPage(pdPage);
this.setPdPage(pdPage);
this.getContentStream();
y = yOriginal + this.marginTopBottom;
this.setY(y);
this.setPdPage(pdPage);
}
if (i < numberOfLines ) {
contentStream.beginText();
contentStream.setFont(font, fontSize);
y -= this.alturaLinha;
contentStream.moveTextPositionByAmount( x , y - height);
contentStream.drawString(lines.get(i));
contentStream.endText();
this.setY(y);
}
}
}
public generatePDF(Integer pageRotation){
try {
pdDocto = new PDDocument();
font = PDType1Font.TIMES_ROMAN;
pdPage = new PDPage();
pdPage.setMediaBox(PDPage.PAGE_SIZE_A4);
this.rotation = pageRotation;
pdPage.setRotation(rotation);
pdDocto.addPage(pdPage);
this.getContentStream();
x = new Float(0.0);
y = new Float(0.0);
} catch (IOException e) {
e.printStackTrace();
}
}
public void BT(String alinhamento,Integer Width){
this.BT = true;
this.WidthBT = Width;
}
public void ET(){
this.ET = true;
}
public PDPageContentStream getContentStream() throws IOException {
contentStream = new PDPageContentStream(pdDocto, pdPage,true,true);
if(this.rotation == 90){
contentStream.concatenate2CTM(0, 1, -1, 0, this.pdPage.getMediaBox().getWidth(), 0);
}
contentStream.setFont( font, 11 );
return contentStream;
}
public void drawText(){
if(this.getBT() != null){
if(this.getBT() == true){
contentStream.drawLine(this.getX(), this.getY(), this.getX(), this.getX() + 50);
this.setBT(false);
}else if(this.getET() == true){
contentStream.drawLine(this.getX(), this.getY(), this.getX(), this.getX() + 50);
this.setET(false);
}
}
for (int i = 0; i < numberOfLines; i++) {
if (y <= marginTopBottom) {
contentStream.close(); //fecha o antigo contentStream da primeira página.
pdPage = new PDPage();
pdPage.setMediaBox(PDPage.PAGE_SIZE_A4);
pdPage.setRotation(this.rotation);
pdDocto.addPage(pdPage);
this.setPdPage(pdPage);
this.getContentStream();
y = yOriginal + this.marginTopBottom;
this.setY(y);
this.setPdPage(pdPage);
}
if (i < numberOfLines ) {
contentStream.beginText();
contentStream.setFont(font, fontSize);
y -= this.alturaLinha;
contentStream.moveTextPositionByAmount( x , y - height);
contentStream.drawString(lines.get(i));
contentStream.endText();
this.setY(y);
}
}
}