programmatically edit images for puzzle usage - java

I'm making a sliding puzzle ( 3x3/4x4/5x5 with the lower-right corner cut out ). However I can't figure out where to start with programmatically cutting images ( which will be loaded from own gallery in sdcard or database from app ) in the puzzle pieces.
I've been looking over the internet and nothing really helped me.
What is the best way to cut up this image and store it in a new database (and still will be able to slide them)? Just a push in the right direction would be appreciated.

Check the PhotoGaffe app..
Its available on Google code here.
It allows user to choose between 3x3, 4x4, 5x5, and 6x6 puzzles.
This may help you in doing your task.

Straight from something I'm working on at the moment!
Bitmap main = BitmapFactory.decodeResource(getResources(), R.drawable.puzzle);
if( main.getHeight() > main.getWidth() ){
rescalefactor =((float)screenHeight)/main.getHeight();}
else {
rescalefactor = ( (float)screenWidth)/main.getWidth();
}
main = Bitmap.createScaledBitmap(main,(int)(main.getWidth()*rescalefactor),(int)(main.getHeight()*rescalefactor), false);
Bitmap cropped;
LinearLayout layout[] = new LinearLayout[rows];
int x=0,y=0,i=0,j=0,width=main.getWidth()/column,height=main.getHeight()/rows;
int count = 1;
for(i=0;i<rows;++i)
{
layout[i] = new LinearLayout(this);
for(j=0;j<column;++j)
{
cropped = Bitmap.createBitmap(main,x,y,width,height);
image[i][j] = new Tile(this);
image[i][j].setImageBitmap(cropped);
image[i][j].row =i;image[i][j].column =j;
image[i][j].setPadding(1, 1, 1, 1);
image[i][j].setOnClickListener(this);
image[i][j].setDrawingCacheEnabled(true);
image[i][j].setId(count); count++;
layout[i].addView(image[i][j]);
x += width;
}
x = 0; y += height;
root.addView(layout[i]);
}
This is the line where the work is really done:
cropped = Bitmap.createBitmap(main,x,y,width,height);
The Tile class is super simple. Just an extended ImageView with row and column fields:
public class Tile extends ImageView {
public int row, column;
public Tile(Context context)
{ super(context);}
}

Related

LibGdx - How can I not load my textures every single frame?

I am kinda new to Java and LibGdx but for my school project I need to Animate a Player-Sprite.
For only one Animation per Player everything went fine with the Methode I made for this but now I also need a Walking, Idling and Fighting Animation. I managed to get the Animations to switch but the Problem is now, that only one Frame of each Animation gets Displayed. After some research I know that I need to stop updating my Textures every frame but I cant get to know how to do so.
So far Ive tried a simple timer before updating but this just looks weird.
Here is my Code:
public Player(){
img3 = new Texture("platform_metroidvania asset pack v1.01/herochar sprites(new)/herochar_idle_anim_strip_4.png");
img = new Texture("platform_metroidvania asset pack v1.01/herochar sprites(new)/herochar_idle_anim_strip_4.png");
img1 = new Texture("platform_metroidvania asset pack v1.01/herochar sprites(new)/herochar_run_anim_strip_6.png");
img2 = new Texture("platform_metroidvania asset pack v1.01/herochar sprites(new)/herochar_sword_attack_anim_strip_4.png");
animation();
changeCharacter();
}
public static void animation(){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
img3 = img2;
amount = 3;
tileWidth = 32;
}else if(Gdx.input.isKeyPressed(Input.Keys.D) || Gdx.input.isKeyPressed(Input.Keys.A)){
img3 = img1;
tileWidth = 16;
amount = 3;
}else{
img3 = img;
amount = 3;
tileWidth = 16;
}
}
public static void changeCharacter(){
batch = new SpriteBatch();
regions = TextureRegion.split(img3, tileWidth, 16);
sprite = new Sprite(regions[0][0]);
sprite.setPosition(x,y);
Timer.schedule(new Timer.Task() {
#Override
public void run() {
frame++;
if (frame > amount) {
frame = 0;
}
sprite.setRegion(regions[0][frame]);
}
}, 0, 1 / 12f);
}
Both Methodes "animation" and "changeCharacter" are called in render().
I know there are simpler solutions for this in LibGdx but the rest of my code is based on this and I basically would have to rewrite the entire Project...
If you need any other classes just ask. I'm probably asking a very easy thing but I dont know what to do with this.
You need to rename first.
img3 looks like it serves the purpose of being the pointer to the currentTextureSet. so when you initialise in Player() you might want to rename img3 to currentTextureSet and then, instead of the duplicate load of herochar_idle_anim_strip_4.png, set
currentTextureSet = img;
after
(you may also want to rename img, img1, img2 to idleTextureSet, runTextureSet and swordAttackTextureSet).
That aside,
definitely get rid of Timer.schedule which you are calling from render will run in a background thread you don't want that.
Looking at the asset pack here https://o-lobster.itch.io/platformmetroidvania-pixel-art-asset-pack?download if this is the same one, the images should be selected left to right i.e. x should be incremented not y. However, it looks like you increment y...
sprite.setRegion(regions[0][frame]); and the incorrect array access is swallowed because in a background timer task and the only textureRegion you can access is [0][0] i.e. you just see a single frame.
So dump this
Timer.schedule(new Timer.Task() {
#Override
public void run() {
frame++;
if (frame > amount) {
frame = 0;
}
sprite.setRegion(regions[0][frame]);
}
}, 0, 1 / 12f);
and replace with
frame++;
if (frame > amount) {
frame = 0;
}
sprite.setRegion(regions[frame][0]);
*EDIT
So this means that your frame updates with every render, which is too fast. So the -easy fragile way- (not the best which would be deltaTime please read this excellent article https://gafferongames.com/post/fix_your_timestep/ ). The easy way, not the best in the case there is no time left, would be to declare
long renderCallCount =0;
put the above where frame is declared, then in your render method
renderCallCount++; //One more render call
if (renderCallCount % 60 == 0) { //Should I update frame?
frame++;
if (frame > amount) {
frame = 0;
}
sprite.setRegion(regions[0][frame]);
}
So whenever renderCallCount is divisible by 60 using the mod operator https://www.edureka.co/blog/mod-method-in-java/ , which would be once a second if your refresh rate is 60hz, then your frame is incremented. To switch frames twice a second change 60 to 30.
This assumes your monitor is ONLY going to run at 60hz. I think your application probably depends on the timing on the refresh rate for position updates so you may want to update that in the future based on some thinking from the article. On a monitor with a faster frame rate everything will speed up (consistently).
I just put some stuff in the right order and it now works! I dont really get why the number after the mod operator needs to be so small but otherwise it just doesnt look right. Also I know that you shouldnt create the Spritebatch in render() but when I do it in the constructor the Program just crashesbecause of the missing Spritebatch??? But thanks for the help :) Here is the working code for anyone whos interested in this:
public static void animation(){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT) && InfoGame.cl.isGrounded() && current > Enemy.lastDmg + Enemy.dmgCool){
currentTextureSet = attackTexture;
amount = 3;
tileWidth = 32;
}else if(Gdx.input.isKeyPressed(Input.Keys.D) || Gdx.input.isKeyPressed(Input.Keys.A)){
currentTextureSet = runTexture;
tileWidth = 16;
amount = 3;
}else{
currentTextureSet = idleTexture;
amount = 3;
tileWidth = 16;
}
}
public static void changeCharacter(){
batch = new SpriteBatch();
regions = TextureRegion.split(currentTextureSet, tileWidth, 16);
sprite = new Sprite(regions[0][0]);
sprite.setPosition(x,y);
sprite.setOrigin(8,8);
if (renderCallCount % 6 == 0) {
frame++;
if (frame > amount) {
frame = 0;
}
}
sprite.setRegion(regions[0][frame]);
}

How to change 4 ImageView resources on every Click?

this is my first question here so I apologize in advance for any question format mistakes. I am trying to make a sound quiz with the sounds of a game. The idea is for the user to click on the button (round speaker icon) and play the sound. Then, choose one of the four images that correspond to the icon of that sound. App layout On every click on one of the ImageViews all four ImageViews should change the resources. However, when I click on any of those ImageViews the app becomes really slow and I get the dialog asking me to wait for it to respond or click OK to close it.
The CPU monitor shows really high percentage at that moment. memory and CPU usage monitor But, I do not get any Memory Out of Bounds Exception.
This is the code of my Array and ArrayLists
int chosenSound;
int locationOfCorrectAnswer = 0;
Integer[] answers = new Integer[4];
ArrayList<Integer> sounds = new ArrayList<Integer>(Arrays.<Integer>asList(R.raw.dismember, R.raw.duel, R.raw.glimpse, R.raw.reapers_scythe, R.raw.vacuum));
ArrayList<Integer> icons = new ArrayList<Integer>(Arrays.<Integer>asList(R.drawable.dismember, R.drawable.duel, R.drawable.glimpse, R.drawable.reapers_schyte, R.drawable.vacuum));
And this is the method for generating new question:
public void generateQuestion() {
Random random = new Random();
chosenSound = random.nextInt(sounds.size());
if (alreadyUsedSounds.size() == icons.size()) {
Toast.makeText(getApplicationContext(), "You used all the sounds!!!", Toast.LENGTH_SHORT).show();
return;
} else {
while (alreadyUsedSounds.contains(icons.get(chosenSound))) {
chosenSound = random.nextInt(sounds.size());
}
}
locationOfCorrectAnswer = random.nextInt(4);
int incorrectAnswerLocation;
for (int i = 0; i < 4; i++) {
if (i == locationOfCorrectAnswer) {
answers[i] = icons.get(chosenSound);
} else {
incorrectAnswerLocation = random.nextInt(sounds.size());
while (incorrectAnswerLocation == chosenSound || Arrays.asList(answers).contains(icons.get(incorrectAnswerLocation))) {
incorrectAnswerLocation = random.nextInt(sounds.size());
}
answers[i] = icons.get(incorrectAnswerLocation);
}
}
button0.setImageResource(answers[0]);
button1.setImageResource(answers[1]);
button2.setImageResource(answers[2]);
button3.setImageResource(answers[3]);
}
Now, I am not sure how to set those ImageView resources without the app crashing. I guess there is a pretty much straightforward way to do this, but being a beginner I would really appreciate any help. Thank you in advance.

How to plot the real-time graph using achartengine similar to oscilloscope

I am working with achartengine. I have to read a txt file and plot the graph. I get the graph plot. But, what I want to do is when the graph reaches the end of the layout view, it should get plotted from the beginning view as similar to oscilloscope view.
I want my graph exactly similar to the graph in this link
http://www.youtube.com/watch?v=N6BuRqeUhqc.
What I have done so far is:
private class ChartTask extends AsyncTask<Void, String, Void>{
String[] values = new String[2];int i1=0;
// Generates dummy data in a non-ui thread
#Override
protected Void doInBackground(Void... params) {
int i = 0;
try{
do{
values[0] = Integer.toString(i);
values[1] = Integer.toString(amplitude[i]);
if(i<=600){
multiRenderer.setXAxisMax(600);
}
else if(i>600){
double minX = amplitudeSeries.getMaxX();
multiRenderer.setXAxisMin(minX);
}
publishProgress(values);
Thread.sleep(1);
i++;
}while(i<=amplitude.length);}
catch (Exception e1){
}
return null;
}
Can someone help me with this. Thanks for anyone's help.
It should be quite easy to draw dynamic charts using AChartEngine. Just update the contents of your dataset and call chartView.repaint().
This is an animation task. Use Bitmap to hold the chart and use timer to plot periodically one X,Y pair per call into bitmap. After that, call invalidate() to repaint the bitmap on the screen of device.
The last thing you need is a trivial mod operation. Here are the possible code fragments of this periodically called code:
// Get position in bitmap from the iteration index
int ig = mIteration % bitmap.getWidth();
// Erase the vertical line in bitmap
for (int y = 0, y < bitmap.getHeight(); i++)
bitmap.setPixel(ig, y, Color.WHITE);
// Plot the point
bitmap.setPixel(ig, data[mIteration], Color.BLACK);
// Advance mIteration field value.
mIteration = (mIteration + 1) % data.length;
// Force to repaint component containing the bitmap.
invalidate();
this will care for you about returning the cursor back and repeating the animation after reaching the end of data.

Shooting sprite android

I am developing an Android game in java where I will have a sprite that follows the user's finger and is supposed to fire a bullet every second. In other words, I am trying to attach a bitmap that moves up every second. The bitmap starts at the x and y coordinates of the main character sprite. I can't get it to draw more than one missile at a time, and I have run out of ideas of how to do so. I have tried so many things, and I really could use some help.
By the way, my Main Game Panel class extends a surfaceView and implements a SurfaceHolder.Callback:
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback{
Thanks!
As far as I understand you want to have the ability to shoot more than 1 bullet at a time? You can use a Vector or Array to do this. With an Array you can set a default amount of visible bullets and in a Vector you could have as mant bullets that your finger is capable of producing.
Here's my code that I use to generate lasers (I store the values in an Array).
public void updatePlayerLaser(boolean shootLaser) {
// Check if a new Laser should be created
if(shootLaser == true) {
if(timeLastCreatedLaser + 100 < System.currentTimeMillis()) {
timeLastCreatedLaser = System.currentTimeMillis();
boolean createdNewLaser = false;
for(int i = 0; i < this.amountOfVisibleLasers; i++) {
if(createdNewLaser == false) {
if(holderLaser[i].isDisposed()) {
this.generateNewLaser(i);
createdNewLaser = true;
}
}
}
}
}
// Update all the other Lasers
for(int i = 0; i < this.amountOfVisibleLasers; i++) {
if(holderLaser[i].isDisposed() == false) {
holderLaser[i].update();
}
}
}
Disposed in this contexts means that the laser is dead, thus making space for a new laser to take the old lasers spot.

Drawing list of animated bitmaps

So I've got this nice Android game (a snake-clone with animations), doing the final testing, when BAM! My second testing device (Nexus 1, HTC Magic was my 1.) flickers when drawing.
Does anyone know why this code won't work correctly with the Nexus 1?
public void draw(Canvas canv) {
int count = 0;
isHead = false;
for (int i = 0; i < SPACES; i++) {
if (mDrawSpaces[i]) {
count++;
if (count == SPACES - 1) {
setDrawSpacesToFalse();
if (bmp != null)
super.drawPlaceable(canv);
}
} else {
mDrawSpaces[i] = true;
return;
}
}
}
I have a list of Birds (Birds / UFOs / others) with SPACES (4) times as many elements which are being drawn on the screen. So I thought to myself, instead of calculating the rotation and scale of the pictures for every Bird, I merely have 3 placeholders between the Birds which each have a picture to be drawn once they're set to visible. These pictures are generated by the first Bird:
public void drawHead(Canvas canv) {
//calculate the rotation & mirroring of the picture
super.drawPlaceable(canv);
//generate the pics for smaller birds following it
mat.preScale((float) 0.6, (float) 0.6);
this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame
* BIG_W[mUseBird], 0, BIG_W[mUseBird], BIG_H[mUseBird],
mat, true);
}
Any ideas? Is my draw(Canvas) method wrong in some part?
EDIT: I don't know why, I don't know how, but this afternoon when I tested it again, it magically worked...
I can see you are using matrix to scale - another option would be to use
canvas.DrawBitmap(spriteSheet, fromRect, toRect, paint);
Where toRect should be a Rect class of any size, in this way you would create no bitmap objects when drawing game frames. The piant should have filter bitmap enabled.
To rotate you would have to use:
canvas.save();
canvas.rotate(spriteAngle,spriteCenterX, spriteCenterY);
canvas.DrawBitmap(spriteSheet, fromRect, toRect, paint);
canvas.restore();
This is a fast enough code for many 2D games, though not as fast and powerful as OpenGL.

Categories